Compare commits

...

819 Commits

Author SHA1 Message Date
Wayne Davison
a058cbc410 Preparing for release of 2.6.7 2006-03-11 18:43:42 +00:00
Wayne Davison
1ef7913497 Mention solo-dir fix for a dir without S_IWUSR. 2006-03-11 17:59:37 +00:00
Wayne Davison
88a16c8b4f Don't force S_IWUSR on a solo directory transfer. 2006-03-10 15:57:03 +00:00
Wayne Davison
8030b28ff8 Make extra sure that authbuf can't overflow. 2006-03-07 08:46:29 +00:00
Wayne Davison
1c598b1db8 Mention fix for Proxy-Authorization header. 2006-03-06 18:28:06 +00:00
Wayne Davison
6854bf69a8 Call base4_encode() with "1" for its new "pad" arg so that the
Proxy-Authorization header is properly padded with trailing '='
chars.
2006-03-06 18:22:26 +00:00
Wayne Davison
293def601d The base4_encode() function now takes a "pad" arg which indicates
if the caller wants to pad the value with trailing '=' chars.
2006-03-06 18:22:20 +00:00
Wayne Davison
651dc65efc Tweaked the mode of the files in the tar file. 2006-03-04 08:21:58 +00:00
Wayne Davison
c2b2bd6a93 Since the samba.org rsync is so old that it doesn't handle
out-of-order hard-linked files, changed the script to do the
hard-linking manually.
2006-03-02 23:42:56 +00:00
Wayne Davison
e32a48d256 Preparing for release of 2.6.7pre3 2006-03-02 22:49:27 +00:00
Wayne Davison
b5cf121d70 Mention the get_local_name() change. 2006-03-02 03:56:14 +00:00
Wayne Davison
44c26bf2a1 Don't allow overwriting a non-directory with a directory (just
like cp).
2006-03-02 03:53:42 +00:00
Wayne Davison
cc8c5057fe If get_local_name() fails to stat() the destination for any
reason other than the destination does not exist, mention the
error and exit.
2006-03-02 03:40:09 +00:00
Wayne Davison
b4c7c1ca99 A couple more improvements for --list-only. 2006-03-01 01:04:57 +00:00
Wayne Davison
16d3b31b2c Improved a couple sentences. 2006-03-01 00:59:22 +00:00
Wayne Davison
89a8180c5e One more bugfix. 2006-02-28 21:48:45 +00:00
Wayne Davison
34f961bbf3 Got the order of s1 and s2 right in the debug output. 2006-02-28 21:48:15 +00:00
Wayne Davison
2384f9e1db Update for hash-table change. 2006-02-28 21:21:44 +00:00
Wayne Davison
48cce779a2 Decided to drop the dynamically sized hash table for now. This was
due to timing tests showing that the per-byte modulus calculation
slowed down regular sized files.  Kept the other improvements
because they lessened our memory use and actually sped up the code.
2006-02-28 21:20:08 +00:00
Wayne Davison
6820753732 Renamed sum_table -> hash_table. 2006-02-28 07:32:48 +00:00
Wayne Davison
fbbe9a016d Changed the name of GETTAG() to SUM2HASH(). 2006-02-28 01:00:03 +00:00
Wayne Davison
c64ca7ef58 Eliminated one variable from hash_search(). 2006-02-28 00:31:51 +00:00
Wayne Davison
900cfcb584 - Fixed a problem with the new gettag2() macro by getting rid of the
need for it.
- Fixed a really old bug in the verbose output where it would output
  the wrong sum value (off by one).
- Renamed the tag_hit variables & debug output to hash_hit.
2006-02-28 00:09:19 +00:00
Wayne Davison
beab3078d6 Added --no-H and --no-hard-links. 2006-02-27 23:35:18 +00:00
Wayne Davison
530a2199da Mention the hash table change. 2006-02-27 21:29:44 +00:00
Wayne Davison
d9bca0c32f This is Shachar Shemesh's patch for making the hash-table code
work better with large files.  I further modified it to eliminate
the extra level of indirectness (and the qsort()), which saves
memory.
2006-02-27 21:16:04 +00:00
Wayne Davison
d733de97f5 Added a "chain" item to the struct sum_buf. 2006-02-27 21:11:56 +00:00
Wayne Davison
f06c11ed40 Tweaked a sentence. 2006-02-27 20:53:35 +00:00
Wayne Davison
c638caa63e In read_sum_head(): if we read a negative checksum count, die
with an error.
2006-02-27 03:12:26 +00:00
Wayne Davison
d775372a34 Tweaked a sentence. 2006-02-24 19:50:22 +00:00
Wayne Davison
07affc3d93 Document the latest changes. 2006-02-24 17:58:24 +00:00
Wayne Davison
f2ebbebead - Document the new --copy-dirlinks option.
- Improved the docs for --no-implied-dirs and --keep-dirlinks
  (based on a patch from Matt).
- Improved a few other misc. sentences.
- Shuffled the order of a couple options.
2006-02-24 17:54:47 +00:00
Wayne Davison
a695b379b5 Make sure the receiver resets copy_dirlinks (so that it can't
affect the delete scan).
2006-02-24 17:54:41 +00:00
Wayne Davison
88c2190a7c - Got rid of unused externs.
- Added support for copy_dirlinks.
- Fixed a bug where --copy-links would not affect implied dirs
  unless --copy-unsafe-links was also specified.
2006-02-24 17:54:35 +00:00
Wayne Davison
2dbf36ef55 Added the new --copy-dirlinks (-k) option. 2006-02-24 17:54:30 +00:00
Wayne Davison
cca9208697 Got rid of unused externs. 2006-02-24 16:43:44 +00:00
Wayne Davison
aa37022ef7 A recently added stat() call needed to be do_stat(). 2006-02-24 09:35:47 +00:00
Wayne Davison
85c417579f Made create_directory_path() return -1 if it couldn't create some
portion of the filename's path.
2006-02-24 09:34:44 +00:00
Wayne Davison
baed67efc4 Need to define an orig_umask value now that utils.c uses it. 2006-02-24 01:56:29 +00:00
Wayne Davison
c5b7aa1532 The orig_umask value is now a mode_t. 2006-02-24 01:56:26 +00:00
Wayne Davison
904e5af128 The create_directory_path() function no longer takes a base_umask
arg.
2006-02-24 01:56:21 +00:00
Wayne Davison
a41d110647 - The orig_umask value is now a mode_t.
- Use CHMOD_BITS instead of 07777.
2006-02-24 01:56:18 +00:00
Wayne Davison
a92d6ff13c Moved the orig_umask variable's definition into main.c since it
has nothing to do with option settings.
2006-02-24 01:56:14 +00:00
Wayne Davison
05278935a3 - 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 01:56:10 +00:00
Wayne Davison
a56cdef9b1 Call mkdir_defmode() instead of do_mkdir(). 2006-02-24 01:56:07 +00:00
Wayne Davison
e9357a2deb + Added mkdir_defmode().
+ Changed create_directory_path() to drop the (now) unneeded
  base_umask arg and to call mkdir_defmode().
2006-02-24 01:56:01 +00:00
Wayne Davison
8d94d27af0 Moved an extern into its proper place. 2006-02-24 01:39:10 +00:00
Wayne Davison
6f2a222c59 One more fuzzy tweak. 2006-02-23 20:29:55 +00:00
Wayne Davison
8470a515ef Some improved fuzzy-parent-dir logic. 2006-02-23 20:27:17 +00:00
Wayne Davison
06982ac43b Mention latest fixes. 2006-02-23 20:17:09 +00:00
Wayne Davison
865c3b5f92 The new fuzzy-dir logic once again avoids calling get_dirlist()
until a regular file is found in the current parent directory.
2006-02-23 20:00:48 +00:00
Wayne Davison
8c9e06d7b9 Fixed the creation of symlinks and devices when both --relative
and --no-implied-dirs are specified and the destination dir does
not yet exist.
2006-02-23 19:43:54 +00:00
Wayne Davison
a9cc128308 Renamed fuzzy_dirname -> parent_dirname. 2006-02-23 19:07:33 +00:00
Wayne Davison
ccb16b467b Make sure that the --fuzzy option's dir-scan doesn't generate an
I/O error when --no-relative is used and the destination dir does
not exist yet.
2006-02-23 18:58:30 +00:00
Wayne Davison
1e44aeb92a Mention the --list-arg change. 2006-02-23 00:43:17 +00:00
Wayne Davison
c897f7119a Document the revised --list-only behavior and the ability to use
rsync with one local source arg (i.e. no destination).
2006-02-23 00:40:58 +00:00
Wayne Davison
ee8e2b1547 Rsync no longer returns a usage error when used with one local
source arg and no destination: this now implies the --list-only
option, just like one remote source arg has always done.
2006-02-23 00:38:34 +00:00
Wayne Davison
5fa38cd679 - Improved the way we generate the tar file.
- The second run of verify-patches is in a better spot now.
- Made various improvements to the output.
2006-02-22 19:09:51 +00:00
Wayne Davison
65535b5482 Mentioned that the daemon now logs connections. 2006-02-21 17:19:49 +00:00
Wayne Davison
439a198d02 Log every connect to the daemon. 2006-02-21 17:09:23 +00:00
Wayne Davison
f041b02557 Added a comment. 2006-02-21 00:29:55 +00:00
Wayne Davison
4d8639eb2d A few more tweaks and fixes. 2006-02-20 19:58:06 +00:00
Wayne Davison
519c8de16f - Moved the checkout of the cvs source above the version prompting so
that we can use the version from the configure.in file to provide
  good default values for the user.
- When moving old tar/diff files into the old-* dirs, first hard-link
  them into place, then (if "live"), use rsync to update these new
  files on the server (which saves us later re-sending), and _then_
  delete the old names.
2006-02-20 19:36:56 +00:00
Wayne Davison
7f20af4674 Made the new warning more visible. 2006-02-20 18:35:41 +00:00
Wayne Davison
55d24e5fed Mention if any of the CVS files we're putting in the tar file
aren't up-to-date.
2006-02-20 18:34:27 +00:00
Wayne Davison
81f654e396 Mention a couple more bug fixes. 2006-02-20 18:03:55 +00:00
Wayne Davison
8f1dc165e2 A brief msleep() in option_error() may be helpful to ensure that
an option error always arrives intact from the remote rsync.
2006-02-20 17:58:13 +00:00
Wayne Davison
9a0cfff57f Don't try to obey bwlimit restriction until bwlimit_writemax is set.
This fixes a bug with option errors not getting reported because the
write code gets called with bwlimit != 0 and bwlimit_writemax == 0.
2006-02-20 17:50:36 +00:00
Wayne Davison
d749eb6896 When starting up a transfer, substitute the remember_children()
SIGCHLD handler in place of the minimal one that socket.c enabled.
2006-02-20 17:17:51 +00:00
Wayne Davison
6d59ac192b Made the formerly static sigchld_handler() available as a
public function named remember_children().
2006-02-20 17:16:21 +00:00
Wayne Davison
94d3725cf2 In dest_mode(), we now apply any "incoming chmod" changes from
the daemon.
2006-02-20 00:01:27 +00:00
Wayne Davison
8840ec0f49 Set a new daemon_chmod_modes pointer with the daemon's chmod
(incoming or outgoing) changes.
2006-02-20 00:00:35 +00:00
Wayne Davison
44a8e86d47 Mention the change in how "incoming chmod" works when --perms was
not specified.
2006-02-19 23:58:59 +00:00
Wayne Davison
73abdda442 Slightly tweaked the output in non-live mode. 2006-02-19 23:33:15 +00:00
Wayne Davison
15b03ab1a8 Changed parse_chmod() to return the pointer to the new items on
success.
2006-02-19 23:31:56 +00:00
Wayne Davison
dc5245679a Preparing for release of 2.6.7pre2 2006-02-19 16:21:30 +00:00
Wayne Davison
60414e5bce The tar command needed --no-recursion. 2006-02-19 16:14:39 +00:00
Wayne Davison
af40c7d667 The hide filter rule is no longer needed. 2006-02-19 16:05:08 +00:00
Wayne Davison
7eb2ecda0f Improved the description of a fix in 2.6.4. 2006-02-19 15:52:59 +00:00
Wayne Davison
6d12a859bc The perl script I use to create new rsync releases. This is an
adapted and extended version of an old shell script.
2006-02-18 21:27:54 +00:00
Wayne Davison
920071e242 A perl script I wrote to make a new "nightly" tar file and
maintain the nightly dir on samba.org.
2006-02-18 21:26:48 +00:00
Wayne Davison
2a24b4bd0c Some more refinement of the --checksum section. 2006-02-16 07:40:55 +00:00
Wayne Davison
a753502200 Don't try to help the ACKs for the --remove-sent-file option
when --delay-updates was specified.
2006-02-15 20:09:49 +00:00
Wayne Davison
8958fae362 One last change to make the --checksum distinction very clear. 2006-02-15 19:58:53 +00:00
Wayne Davison
e2d68210d7 Another attempt to make --checksum clearer. 2006-02-15 19:24:39 +00:00
Wayne Davison
99534debc8 Improved the --checksum description and mention our whole-file
checksum verification checksum is different.
2006-02-15 18:20:23 +00:00
Wayne Davison
5b98629747 Improved the while's logic in increment_active_files(). 2006-02-15 08:26:51 +00:00
Wayne Davison
42003f6af3 Mention the change to --remove-sent-files. 2006-02-15 08:16:42 +00:00
Wayne Davison
434573b226 Call increment_active_files() during the first phase of a transfer
where --remove-sent-files was specified.
2006-02-15 08:06:45 +00:00
Wayne Davison
d6081c829c Added increment_active_files() and decrement_active_files() which
allows the generator to ask us to limit the number of files that
are currently active in the transfer when --remove-sent-files is
enabled.
2006-02-15 08:05:31 +00:00
Wayne Davison
58718881ef - Changed "called" to "named".
- Fixed a filter option to have the right syntax.
- Mention --prune-empty-dirs in a couple more places.
2006-02-14 16:45:38 +00:00
Wayne Davison
ac669e8b92 Tweaked a comment. 2006-02-14 16:44:11 +00:00
Wayne Davison
567f1566a9 List more of the doc improvements, list some of the best diffs in
the patches dir, and unified the discussion of the "dest" options.
2006-02-13 18:45:04 +00:00
Wayne Davison
59a5687105 Modified the sentence about doc improvements. 2006-02-13 18:19:59 +00:00
Wayne Davison
7b13ff9704 Document what all the items in the --stats output mean. 2006-02-13 18:19:26 +00:00
Wayne Davison
5e7b826a4f Made the receiver count the size of symlinks in the total_size
value, just like the sender does.
2006-02-13 18:08:45 +00:00
Wayne Davison
cbc63b9b48 Added missing release-history lines for 2.6.6 and 2.6.7. 2006-02-12 19:15:35 +00:00
Wayne Davison
71a84cbab0 Mention the ignoring of SIGXFSZ. 2006-02-11 02:37:58 +00:00
Wayne Davison
55e54e464b We now ignore the SIGXFSZ signal (if it is defined). 2006-02-11 02:36:35 +00:00
Wayne Davison
467688dc06 More improvements for "--help", and a couple hyphenation fixes. 2006-02-11 00:02:15 +00:00
Wayne Davison
375d8f913b Added a backward-compatibility note about -h to the --help option
in the help text.
2006-02-11 00:01:22 +00:00
Wayne Davison
021849204a Fixed some typos, got rid of some extraneous spaces, got rid of
a hyphen in hard-link (since we consistently use it unhyphenated),
and refer to "unix" as "*nix".
2006-02-09 17:32:36 +00:00
Wayne Davison
b635f2e964 The -h was missing from the daemon's option summary. 2006-02-09 11:56:33 +00:00
Wayne Davison
1e2b96bbee - Improved the description of how 'D' because 'D' and 'S' for -i.
- Improved the --devices and --specials item, and moved it next to
  the --super item.
- Mention that "rsync -h" still works as before.
2006-02-09 10:25:25 +00:00
Wayne Davison
2857451ca2 Got rid of an statement that is no longer true. 2006-02-09 04:08:38 +00:00
Wayne Davison
2bc3835ee0 Preparing for release of 2.6.7pre1 2006-02-09 03:59:17 +00:00
Wayne Davison
4f417448b4 Updated the %i section. 2006-02-09 01:27:03 +00:00
Wayne Davison
503f163446 Decided against shortening the output of --itemize-changes. 2006-02-09 01:17:01 +00:00
Wayne Davison
f17e769e28 There's no need to send --size-only to a remote sender. 2006-02-09 01:15:04 +00:00
Wayne Davison
f65e6a1276 Tweaked the mention of --human-readable. 2006-02-08 17:03:00 +00:00
Wayne Davison
4c248a3615 Documented the change in the --human-readable option. 2006-02-08 16:54:10 +00:00
Wayne Davison
7794db7c0d Tweaked the --human-readable code to work with the new option parsing. 2006-02-08 16:52:51 +00:00
Wayne Davison
3ca9e5d8ad Changed -h to mean powers of 1000 when used once, and powers of 1024
when repeated.  Got rid of --si.
2006-02-08 16:52:25 +00:00
Wayne Davison
5ca8a90c24 Tweaked the name of one of dest_mode()'s args. 2006-02-08 02:34:06 +00:00
Wayne Davison
0679ac4ca9 Tweaked a comment. 2006-02-08 02:32:35 +00:00
Wayne Davison
20a0269782 Mention --dry-run doesn't force --verbose. 2006-02-07 20:08:30 +00:00
Wayne Davison
a892d905bb Don't force verbose for --dry-run; let the user decide. 2006-02-07 20:06:43 +00:00
Wayne Davison
bc880cb8d2 Don't look for $RSYNC_PARTIAL_DIR on the server side. 2006-02-07 19:12:37 +00:00
Wayne Davison
2243a9353e Clarified something in "incoming chmod". 2006-02-07 18:45:16 +00:00
Wayne Davison
10f994a52a Moved the delay-bit functions into util.c, making them more generic. 2006-02-07 18:15:51 +00:00
Wayne Davison
0f86c74eba Call renamed cmp_time() function (was cmp_modtime()). 2006-02-07 18:15:46 +00:00
Wayne Davison
c2b5407678 - Renamed cmp_modtime() -> cmp_time().
- Moved the delay-bit functions here from receiver.c and transformed
  them into some more generic "bitbag" functions.
2006-02-07 18:15:37 +00:00
Wayne Davison
350879d8d1 Only call the just-added "touch" if autoheader succeeded. 2006-02-07 17:30:35 +00:00
Wayne Davison
a6a276027c Changed --8-bit to --8-bit-output. 2006-02-06 18:51:25 +00:00
Wayne Davison
45b79c8959 Mentioned --8-bit (-8). 2006-02-06 18:45:48 +00:00
Wayne Davison
d0022dd908 Document --8-bit (-8). 2006-02-06 18:43:12 +00:00
Wayne Davison
e0f4a661be Don't setup ic_chck if --8-bit was specified. 2006-02-06 18:42:46 +00:00
Wayne Davison
507433f6ca Don't call isprint() if --8-bit was specified. 2006-02-06 18:42:02 +00:00
Wayne Davison
5974c662ff Added the --8-bit (-8) option. 2006-02-06 18:41:32 +00:00
Wayne Davison
aa0bec8a52 Ensure that the timestamp for config.h.in is changed after
running autoheader.
2006-02-06 18:27:45 +00:00
Wayne Davison
2d2f71fb27 Got rid of a newly-added trailing tab. 2006-02-06 18:00:37 +00:00
Wayne Davison
36f59b5802 Mention the new output-escaping idiom and the multibyte support. 2006-02-06 17:58:29 +00:00
Wayne Davison
7fc87d2daf Allow the iconv_open() call to fail since we can now fall-back on
isprint().  Got rid of the "646" mapping kluge too.
2006-02-06 16:55:01 +00:00
Wayne Davison
3648ab3a24 - The iconv-supporting code can now ask filtered_fwrite() to use
isprint() when iconv() could not be setup.
- Changed the output idiom for escaped chars to use \#123 instead
  of \0123 because that makes it possible for a script to know for
  sure what version of rsync did the output (and thus, what the
  unescape rules are).
2006-02-06 16:54:12 +00:00
Wayne Davison
7a9d183fc4 Have default_charset() try mapping "646" -> "ASCII" instead of "ascii". 2006-02-06 09:04:20 +00:00
Wayne Davison
2a62f5ee19 Added "const" to the default_charset() return. 2006-02-06 09:00:37 +00:00
Wayne Davison
f9cfaae952 Solaris 9 and HP-UX 11.11 need us to look for libiconv_open,
not iconv_open (perhaps because iconf.h wasn't included in
the autoconf test).
2006-02-06 08:57:16 +00:00
Wayne Davison
bd4576fe4b Check to see if we need to include the iconv library. 2006-02-06 08:35:18 +00:00
Wayne Davison
4e194bf178 Mention the prepare-source script and the changes in the patches
dir.
2006-02-06 07:57:03 +00:00
Wayne Davison
ef4e0d5e7e Added dependencies for proto.h. 2006-02-06 05:06:52 +00:00
Wayne Davison
e6d8e70925 The "proto" target now builds target "proto.h" from the new
prepare-source.mak makefile.
2006-02-06 04:54:30 +00:00
Wayne Davison
a6c5741c37 Changed the "proto" target to "proto.h". 2006-02-06 04:53:02 +00:00
Wayne Davison
3ea7fc6ccf Moved the targets "gen", "proto", and "man" to prepare-source.mak. 2006-02-06 04:09:48 +00:00
Wayne Davison
20926fbd63 An easy way to run all the commands in prepare-source.mak. 2006-02-06 04:08:14 +00:00
Wayne Davison
2a3f3ba45d Moved the rules for generating files such as configure, config.h.in,
proto.h, and the manpages into this separate makefile, allowing it to
be used without first running configure (which builds the Makefile).
2006-02-06 04:07:49 +00:00
Wayne Davison
662127e6c7 Include --no-g in the popt-alias example in --perms. 2006-02-05 15:31:31 +00:00
Wayne Davison
0be05d6038 In default_charset(): if nl_langinfo() gives us "646", return "ascii". 2006-02-05 07:20:10 +00:00
Wayne Davison
1f77038ef2 Added a missing comma. 2006-02-05 07:00:21 +00:00
Wayne Davison
77ed253c73 Some more improvements to --perms and --executability from Matt and me. 2006-02-05 06:40:18 +00:00
Wayne Davison
b988781801 Allow itemize() to flag ITEM_REPORT_PERMS anytime the permissions
change (even if -p or -E aren't set).
2006-02-05 06:13:34 +00:00
Wayne Davison
595251de24 Make sure that we don't try to use iconv() without iconv.h. 2006-02-05 04:52:11 +00:00
Wayne Davison
c85631421d Changed HAVE_ICONV to HAVE_ICONV_OPEN. 2006-02-05 04:45:23 +00:00
Wayne Davison
12c8cd02fc Switched back to checking for iconv_open() due to HP-UX. 2006-02-04 23:06:39 +00:00
Wayne Davison
9656de5d13 Call setup_iconv(). 2006-02-04 22:03:44 +00:00
Wayne Davison
9a31746b10 Use iconv() (when available) to allow us to output multibyte
characters that are legal in the current locale.
2006-02-04 22:03:39 +00:00
Wayne Davison
ceccbacc34 The new function setup_iconv() initializes the ic_chck var. 2006-02-04 22:03:33 +00:00
Wayne Davison
ff2e2ccfc1 - Changed the check for iconv_open() to just iconv().
- Got rid of the --enable-iconv option for now.
2006-02-04 22:03:21 +00:00
Wayne Davison
12bda6f710 Don't do so much memory copying in mplex_write(). 2006-02-04 21:52:32 +00:00
Wayne Davison
c53b6fd0ac In the compatibility comments: mention why we don't use grep -q. 2006-02-04 19:44:19 +00:00
Wayne Davison
b31243b472 Test directory setgid inheritence when --perms is not in effect. 2006-02-04 19:42:47 +00:00
Wayne Davison
c8d19f90a6 Added a missing '(' in the opening comments. 2006-02-04 19:29:13 +00:00
Wayne Davison
114bafe0d0 Added a special permission (o+t) to one of the files in the test. 2006-02-04 19:28:45 +00:00
Wayne Davison
5ef8c5c6d4 Tweaked a function declaraion. 2006-02-04 19:27:07 +00:00
Wayne Davison
9b499e9537 - When not preserving permissions, ensure that a newly-created
directory's inherited sgid bit is preserved.
- When not preserving permissions, ensure that newly-created
  files/dirs don't inherit any special permissions.
2006-02-04 19:09:46 +00:00
Wayne Davison
00f00f846b Ignore setfacl unless it tells us that it supports the -k option. 2006-02-04 18:41:47 +00:00
Wayne Davison
998113fedf Needed to make %G output "DEFAULT" when gid == GID_NONE. 2006-02-04 18:40:41 +00:00
Wayne Davison
ee5544112a Improved the --partial-dir section. 2006-02-03 23:50:16 +00:00
Wayne Davison
7eaabd8fac Decided to undo the last change to avoid backward compatibility
inconsistencies (it would have been the right thing to do if it
were done that way from the start, but not now).
2006-02-03 23:40:37 +00:00
Wayne Davison
4fc808dd98 Avoid adding our own exclude of the partial-dir name if the
user's filter rules already match it.
2006-02-03 23:16:46 +00:00
Wayne Davison
7cfb250c93 Made the new %M escape handle multiple spaces in the timestamp
(which can occur if the user's system doesn't have strftime()).
2006-02-03 22:41:19 +00:00
Wayne Davison
47f480b619 Removed completed items. 2006-02-03 20:49:25 +00:00
Wayne Davison
fa9e950b1a Mention who is outputting the "rsync error" or "rsync warning". 2006-02-03 20:39:58 +00:00
Wayne Davison
49f4d850ce Mention latest changes. 2006-02-03 20:32:27 +00:00
Wayne Davison
b3e15181ae Log when someone requests a module list. 2006-02-03 20:28:19 +00:00
Wayne Davison
aca5500aea Document the new "log format" options: %M (modtime), %U (uid),
%G (gid), and %B (perm bits).
2006-02-03 20:00:24 +00:00
Wayne Davison
427b6179b9 - Allow tab characters to appear in rwrite() messages.
- Added %M (modtime), %U (uid), %G (gid), and %B (perm bits) to
  log_formatted().
2006-02-03 19:59:25 +00:00
Wayne Davison
afa73c75b5 A minor optimization to timestring. 2006-02-03 19:40:16 +00:00
Wayne Davison
8261af7422 Allow sigaction() to be used even if sigprocmask() isn't around
(or was manually disabled).
2006-02-03 18:48:26 +00:00
Wayne Davison
44e604f416 Simplified the conditional prior to the SIGACTION code. 2006-02-03 18:46:38 +00:00
Wayne Davison
5173f99e68 A slight tweak to the conditionalized definition of SIGACTION(). 2006-02-03 18:34:09 +00:00
Wayne Davison
8a3d4658eb Decided I don't like "set -x". 2006-02-03 17:58:48 +00:00
Wayne Davison
6b43924848 The calls to check_perms now pass a test number arg and
don't check for failure (it will die on failure).
2006-02-03 17:55:24 +00:00
Wayne Davison
eace352b39 Improved check_perms() to work with a directory, to have better
output on error, and to call test_fail on error.
2006-02-03 17:54:18 +00:00
Wayne Davison
fdbe8989fe Moved check_perms() into rsync.fns and tweaked how it is called. 2006-02-03 17:29:43 +00:00
Wayne Davison
18d7e9f46e Added a new function: check_perms(). 2006-02-03 17:28:03 +00:00
Wayne Davison
c6fbd563d8 Matt's executability test with a few tweaks (e.g. to avoid using
"stat").
2006-02-03 06:47:26 +00:00
Wayne Davison
a5df33bb62 Scratch-dir normalization from Matt: turn off any default ACLs (if
setfacl is available) and disable any directory setgid bit to avoid
confusing some tests.
2006-02-03 06:15:46 +00:00
Wayne Davison
5cf4896050 Mention the sigaction() and sigprocmask() goodness. 2006-02-02 22:38:55 +00:00
Wayne Davison
2fb450bd99 Fixed a hang. 2006-02-02 22:34:30 +00:00
Wayne Davison
4ea58045e2 Moved the potential disabling of __attribute__ above the
relocated UNUSED() define.
2006-02-02 22:24:33 +00:00
Wayne Davison
29433538ff Tweaked a couple lines in the code that handles --version. 2006-02-02 11:40:32 +00:00
Wayne Davison
d382140904 Changed default logfile setting from /var/adm/rsyncd.log to
/var/log/rsyncd.log.
2006-02-02 10:20:13 +00:00
Wayne Davison
b8e9c234e6 Changed sig_int() to use a standard signal-handler prototype. 2006-02-02 02:39:40 +00:00
Wayne Davison
60ee01f517 - Call SIGACTION() instead of signal().
- Umask all the signals we need using sigprocmask() (if available).
2006-02-02 02:39:29 +00:00
Wayne Davison
2b28968dfb Call SIGACTION() instead of signal(). 2006-02-02 02:39:25 +00:00
Wayne Davison
90b13cf606 - Moved definition of UNUSED() above inclusion of proto.h.
- Replaced definition of SIGNAL_CAST with new SIGACTION() define,
  which will use sigaction() if it is available, else signal().
2006-02-02 02:39:19 +00:00
Wayne Davison
d81894fc21 Added checks for sigaction() and sigprocmask(). 2006-02-02 02:32:39 +00:00
Wayne Davison
f5cbae9329 Look for public functions that return RETSIGTYPE. 2006-02-02 02:29:30 +00:00
Wayne Davison
7a6653bc6c Ignore the --quiet option if someone sent it to us (which doesn't
happen when talking to a normal client).
2006-02-01 19:36:37 +00:00
Wayne Davison
72f2d1b384 When complaining about a socket-read problem, use an FSOCKERR
code instead of a normal FERROR.  The generator is the only
process that will receive this, and it uses it to close down
the multi-I/O over the socket so that it won't ever hang trying
to write an error down a dead socket.
2006-02-01 19:35:17 +00:00
Wayne Davison
b66e31bf15 Turn an FSOCKERR into a normal FERROR if it's not going to our
sibling.
2006-02-01 19:33:12 +00:00
Wayne Davison
ea26c854af Added FSOCKERR and MSG_SOCKERR (a sibling-only message). 2006-02-01 19:26:34 +00:00
Wayne Davison
ef1f62807e We should be using wait_process(), not waitpid() directly. 2006-02-01 19:25:34 +00:00
Wayne Davison
d8aeda1e50 Changed a few "ret" variables to have better names. 2006-02-01 19:24:28 +00:00
Wayne Davison
07efba8ec0 The itemize() output now mentions -E permissions changes. 2006-01-31 06:25:46 +00:00
Wayne Davison
2959fe7447 Mention the --executability option. 2006-01-31 03:40:22 +00:00
Wayne Davison
4601589720 Another help-text tweak. 2006-01-31 03:11:07 +00:00
Wayne Davison
9f8225566e Moved where --chmod was listed. 2006-01-31 03:05:24 +00:00
Wayne Davison
5e65c96705 Moved --chmod in the help output. 2006-01-31 03:04:00 +00:00
Wayne Davison
a9d6e6fcac When permissions aren't being preserved, set them via the new
dest_mode() function.
2006-01-31 02:30:09 +00:00
Wayne Davison
860dcf68ad Got rid of the orig_umask-based file->mode tweak in receive_file()
(which got moved into the dest_mode() function).
2006-01-31 02:30:05 +00:00
Wayne Davison
812848323b Added the dest_mode() function: it figures out the permissions for
a file when we aren't preserving permissions, including the honoring
of the new --executability option.
2006-01-31 02:30:02 +00:00
Wayne Davison
344f9ba7fa Added the --executability (-E) option. 2006-01-31 02:29:58 +00:00
Wayne Davison
2d5279ac9a Documented the new --executability (-E) option, with improvements
to the --perms and --chmod sections as well.
2006-01-31 02:29:55 +00:00
Wayne Davison
fa3e4a0548 Mention the chmod utility's manpage number. 2006-01-31 02:26:49 +00:00
Wayne Davison
656c20715e Mention that --chmod's work can still be masked by the receiving
end's umask when permissions are not being preserved.
2006-01-30 22:10:33 +00:00
Wayne Davison
a72885e042 Mention files-to-excludes. 2006-01-30 21:54:00 +00:00
Wayne Davison
b587adda1f This perl script automates the conversion of a list of pathnames
to a set of includes/excludes needed for rsync to copy just the
listed files.
2006-01-30 21:52:17 +00:00
Wayne Davison
50fd4832c2 Mentioned the new "outgoing chmod" daemon option. 2006-01-30 21:47:23 +00:00
Wayne Davison
c094d9320d Documented the new "outgoing chmod" daemon option. 2006-01-30 21:47:08 +00:00
Wayne Davison
aaccaa887d Added support for the new "outgoing chmod" daemon option. 2006-01-30 21:47:02 +00:00
Wayne Davison
5481e42cd6 Mentioned the early-EOF bugfix (which was fixed a while ago). 2006-01-30 20:09:46 +00:00
Wayne Davison
b3964d1d86 Improved the documentation for --force. 2006-01-30 18:46:17 +00:00
Wayne Davison
e35d9f2d6d I realized that there were instances where --force could still be
required to be combined with a delete option (if a non-dir was
overwriting a dir in a directory that was not included in the
transfer), so I extended the change I just made for --delete-after
to include all delete modes.
2006-01-30 18:45:57 +00:00
Wayne Davison
4d16780366 Allow --force to work even if --recurse was not specified. 2006-01-30 18:35:54 +00:00
Wayne Davison
1661fe9b0c Made get_dirlist() always include directories. 2006-01-30 18:32:47 +00:00
Wayne Davison
63344ad4e1 Mention the latest improvements. 2006-01-30 18:19:55 +00:00
Wayne Davison
90cf7d199f Allow a non-empty dir to be overwritten by a non-dir with all the
delete options (--delete-after used to require --force).
2006-01-30 18:14:02 +00:00
Wayne Davison
730df9d222 If the module has defined an "incoming chmod" option, call
parse_chmod() on it.
2006-01-30 17:53:38 +00:00
Wayne Davison
882d8c1cab Added the "incoming chmod" config option. 2006-01-30 17:53:32 +00:00
Wayne Davison
17af842d2d Document the new "incoming chmod" config option. 2006-01-30 17:53:27 +00:00
Wayne Davison
bbe42182df Call the parse_chmod() with its new syntax. 2006-01-30 17:53:19 +00:00
Wayne Davison
81b096feef Changed the way the parse_chmod() function is called. 2006-01-30 17:53:13 +00:00
Wayne Davison
7627e92c54 Added extern for io_write_phase. 2006-01-30 17:39:43 +00:00
Wayne Davison
f7bce90cf0 - Got rid of the externs for io_read_phase and io_write_phase.
- Added stub definition for chmod_mode_struct.
2006-01-30 17:39:34 +00:00
Wayne Davison
b33ce4c800 Moved the filter_outfile() function to rsync.fns. 2006-01-30 08:12:17 +00:00
Wayne Davison
757287d8a5 Moved the filter_outfile() function here since it was identical
in devices.test and itemize.test.
2006-01-30 08:11:50 +00:00
Wayne Davison
3ed8eafccb The robust_rename() function now takes a "partialptr" arg that, if
non-NULL, will be used if we are forced to copy the file.
2006-01-30 07:18:16 +00:00
Wayne Davison
d8b1c923ef The finish_transfer() function now takes a "partialptr" arg that, if
non-NULL, will be used if robust_rename() is forced to copy the temp
file.
2006-01-30 07:18:13 +00:00
Wayne Davison
4a4d2b1ba0 Call finish_transfer() with a valid partialptr string, when
appropriate.
2006-01-30 07:18:10 +00:00
Wayne Davison
12fa790ea0 Call finish_transfer() with its newly-added arg. 2006-01-30 07:18:06 +00:00
Wayne Davison
21955d9c92 Call robust_rename() with its newly-added arg. 2006-01-30 07:18:03 +00:00
Wayne Davison
a0d9819f8c Document the side-effect that --partial-dir can have on --temp-dir. 2006-01-30 07:18:00 +00:00
Wayne Davison
a9af5d8eba More improvements to --temp-dir. 2006-01-30 06:34:57 +00:00
Wayne Davison
65854cf91a Changed the mode arg from an int to a mode_t. 2006-01-30 00:39:59 +00:00
Wayne Davison
9ec1ef2535 Improved the --temp-dir description and a couple other sentences. 2006-01-29 20:31:59 +00:00
Wayne Davison
36119f6e2a - Renamed set_perms() to set_file_attrs().
- Use the renamed PERMS_* defines: ATTRS_*.
2006-01-29 20:30:24 +00:00
Wayne Davison
e912bd4dfb - Use the renamed PERMS_* defines: ATTRS_*.
- Call the new name of set_perms():  set_file_attrs().
2006-01-29 20:30:18 +00:00
Wayne Davison
c3ef136d41 Call the new name of set_perms(): set_file_attrs(). 2006-01-29 20:30:12 +00:00
Wayne Davison
8eda7a4bb8 Renamed the PERMS_* defines to ATTRS_* defines. 2006-01-29 20:30:07 +00:00
Wayne Davison
78d146e866 Use PERMSTRING_SIZE rather than a hard-wired "11". 2006-01-29 20:30:02 +00:00
Wayne Davison
77860bacd0 No need to send --partial when we're the receiver. 2006-01-29 19:17:13 +00:00
Wayne Davison
63cf5ae72c Made a bunch of char* args const. 2006-01-29 18:52:53 +00:00
Wayne Davison
120cde9562 Avoid forwarding the --temp-dir option to the server when we're
the receiver.
2006-01-29 07:19:38 +00:00
Wayne Davison
e6ffb966dd Made the new --prune-empty-dirs code a little more memory efficient. 2006-01-28 19:20:02 +00:00
Wayne Davison
207522aef5 Tweaked a variable name in flist_find(). 2006-01-28 08:12:16 +00:00
Wayne Davison
a1cc199b34 We enforce at least protocol 29 for --prune-empty-dirs because the
file-list's sort order can be slightly wrong in older versions.
2006-01-28 07:40:52 +00:00
Wayne Davison
c22260706c Don't add the "protect" filter rule for backup-suffix filenames
if --backup was not specified.
2006-01-28 01:55:55 +00:00
Wayne Davison
d5782b52a2 - We need to send exclude info from the client to a server-receiver
when --prune-empty-dirs was specified.
- Changed the output of debug include/exclude/show/hide/risk/protect
  messages to use the appropriate filter terminology instead of
  always using the (potentially unclear) include/exclude terms.
2006-01-28 00:14:02 +00:00
Wayne Davison
85aecef6c3 The user can now use a "protect" filter to avoid pruning one or
more empty directories when --prune-empty-dirs is in effect.
2006-01-28 00:13:59 +00:00
Wayne Davison
876c993680 Changed --skip-empty-dirs (-k) to --prune-empty-dirs (-m). 2006-01-28 00:13:55 +00:00
Wayne Davison
a272ff8c1b Changed --skip-empty-dirs (-k) to --prune-empty-dirs (-m) and
improved the docs a bit more, including documenting how "protect"
filtering affects empty dirs.
2006-01-28 00:13:52 +00:00
Wayne Davison
7402d58369 Improved flist_find()'s empty-entry handling to deal with the case
where more entries may have been removed since the last find.
2006-01-27 14:29:58 +00:00
Wayne Davison
c0b134a445 Optimized flist_find() so that we never scan a series of empty
file-list items twice (which can be very important with the new
--skip-empty-dirs option).  Also optimized the code that strips
root slashes in clean_flist().
2006-01-27 12:59:07 +00:00
Wayne Davison
a324d49bfc Mention the --skip-empty-dirs option. 2006-01-27 01:20:11 +00:00
Wayne Davison
9c000f5e7b Implement the new --skip-empty-dirs (-k) option. 2006-01-27 00:32:57 +00:00
Wayne Davison
0e887ef29a Added the --skip-empty-dirs (-k) option. 2006-01-27 00:32:53 +00:00
Wayne Davison
fb72aaba48 Document the new --skip-empty-dirs (-k) option. 2006-01-27 00:32:49 +00:00
Wayne Davison
a3869e9227 Include popt.h using <popt.h> instead of "popt.h". 2006-01-26 22:32:59 +00:00
Wayne Davison
d671ccfc8e Mention the change in the --itemize-changes output. 2006-01-26 22:32:18 +00:00
Wayne Davison
35bf8fa084 - Include popt.h using <popt.h>, not "popt.h".
- A minor twiddle in server_options().
2006-01-26 22:28:08 +00:00
Wayne Davison
f7916cbf3f Mention --sockopts and an improvement to the testsuite environment. 2006-01-26 22:10:08 +00:00
Wayne Davison
2b7dab686c The setting of HOME got moved to rsync.fns. 2006-01-26 21:23:25 +00:00
Wayne Davison
a98cad00eb Set $HOME to $scratchdir so that our tests are not affected by
anything unexpected, such as a ~/.popt file.
2006-01-26 21:22:57 +00:00
Wayne Davison
facdce2c1f Fixed two typos. 2006-01-26 12:41:52 +00:00
Wayne Davison
34937987a6 Make use of the new sockopts variable. 2006-01-26 12:31:47 +00:00
Wayne Davison
831f06a5a5 Added the --sockopts option. 2006-01-26 12:31:24 +00:00
Wayne Davison
5fe3c86f25 Mention the --sockopts option. 2006-01-26 12:31:14 +00:00
Wayne Davison
04f48837d1 Document the new --sockopts option. 2006-01-26 12:30:20 +00:00
Wayne Davison
f5b14759fb Mentioned the --super option. 2006-01-26 11:14:10 +00:00
Wayne Davison
def97ff9a9 Added the --super option. 2006-01-26 11:10:32 +00:00
Wayne Davison
d38772e06f Document the new --super option and how it affects other options. 2006-01-26 11:10:28 +00:00
Wayne Davison
351f5e2f6c Check MY_UID() directly instead of accessing am_root. 2006-01-26 11:01:00 +00:00
Wayne Davison
8778174936 Mention new --specials option and --devices change. 2006-01-26 10:50:18 +00:00
Wayne Davison
e5f6a04d15 The itemized output for the fifo changed. 2006-01-26 10:39:04 +00:00
Wayne Davison
f8d47c1cb4 Added 'S' to the itemized output for special files. 2006-01-26 10:39:01 +00:00
Wayne Davison
b5c6a6aeeb Handle separated devices and special files. 2006-01-26 10:38:58 +00:00
Wayne Davison
4e7d07c8d4 Document the new --specials option and how -D and --devices now work. 2006-01-26 10:38:54 +00:00
Wayne Davison
fc2dd77ec7 One more minor tweak. 2006-01-25 17:34:39 +00:00
Wayne Davison
7b6fa00ff8 Decided to hold off on the potential memory savings of indexed
uid/gid pairs until the next release.
2006-01-25 17:10:29 +00:00
Wayne Davison
9ac3591366 Added testing of the --itemize-changes output for devices. 2006-01-24 22:23:51 +00:00
Wayne Davison
6a819e02da Changed to handle removed 'a' slot in %i output. 2006-01-24 22:23:14 +00:00
Wayne Davison
4cff7c50db Fixed a problem in the output of %i's 'T' flag on devices and
got rid of the unused 'a' flag.
2006-01-24 22:22:17 +00:00
Wayne Davison
669302a172 Got rid of the description of 'a' in the %i flags. 2006-01-24 22:14:40 +00:00
Wayne Davison
c738605098 Got rid of some debug code. 2006-01-24 21:40:43 +00:00
Wayne Davison
90cf838b18 Dump some debug code. 2006-01-24 21:39:10 +00:00
Wayne Davison
67e4043e8c Optimized id_pair() so that clumps of IDs get handled more
efficiently.
2006-01-24 19:39:09 +00:00
Wayne Davison
5e58e3f9cf The uid & gid are now stored using an id_pair structure. 2006-01-24 19:02:55 +00:00
Wayne Davison
49140b27c6 Another small improvement to the --one-file-system option. 2006-01-24 19:02:48 +00:00
Wayne Davison
9cdadbb13a The in_del_hier code needs to use lastname instead of thisname
because the latter gets cleaned and (possibly) sanitized.
2006-01-24 17:26:24 +00:00
Wayne Davison
0ace7b2567 FERROR messages also need to leave leading newlines unmangled. 2006-01-24 01:07:19 +00:00
Wayne Davison
ccb8f5788b Tweaked the copyright message. 2006-01-23 18:48:12 +00:00
Wayne Davison
4e5baafedf More improvements to the -x option (some from Matt & some from me). 2006-01-22 21:04:21 +00:00
Wayne Davison
0e82af2d27 New -x code had some problems, so restore the old code for now
(keeping the more optimal stat() calling, though).
2006-01-22 20:37:00 +00:00
Wayne Davison
535737bf39 New -x code had some problems, so restore the old code for now. 2006-01-22 20:30:56 +00:00
Wayne Davison
6e6cc16399 Matt's disambiguation. 2006-01-21 21:02:13 +00:00
Wayne Davison
bb0d8edfad - Got rid of the filesystem_dev variable now that --one-file-system
is handled in a new way.
- Moved a stat out of delete_in_dir() into do_delete_pass() to make
  --delete-during more efficient.
- Added a missing "#ifdef SUPPORT_LINKS...#endif" block around some
  symlink code.
2006-01-21 20:59:19 +00:00
Wayne Davison
ebec5eb689 - Changed how --one-file-system works so that we can skip all mount
points (including "bind" mounts).
- The --chmod option now affects devices (only skipping symlinks).
2006-01-21 20:59:16 +00:00
Wayne Davison
5cb31dcf92 Fixed a problem with the FLAG_* defines. 2006-01-21 20:16:37 +00:00
Wayne Davison
0ccffd7c80 Disable popt aliases when we're a server so that any user-redefined
options can't cause a compatibility problem.
2006-01-21 20:15:49 +00:00
Wayne Davison
57b66a2458 A tweak to --dirs and --chmod. 2006-01-21 19:55:47 +00:00
Wayne Davison
b8a39ed58a Use the new saw_delete* variables to ensure that the server side
always reads the exclude information when it is present.
2006-01-21 19:54:14 +00:00
Wayne Davison
f5a910dd73 - We now set some saw_delete* vars to keep track of the case where
we disabled a delete option that the client sent us (since we may
  still need to await exclude information from the client in such a
  case).
- If -d and --delete are in effect without -r, we may need to send
  the -d to the server even if it was implied, and we may need to
  send --no-r to the server to ensure that we don't get into a
  protocol-corrupting situation should the remote rsync disable the
  --delete option (this works because the --no-r option was added in
  the same version as the functionality which allows --delete to
  work with -d sans -r.
2006-01-21 19:52:55 +00:00
Wayne Davison
e16adcdff3 - Allow multiple --chmod options to be specified.
- Call parse_chmod() with its new arg.
2006-01-21 09:14:42 +00:00
Wayne Davison
cf9b4794fd Tweaked parse_chmod() so that it takes a pointer to an existing list
of chmod items (or NULL) and appends the new items onto the end.
2006-01-21 09:14:39 +00:00
Wayne Davison
6d8c6bdbe5 Document the new --one-file-system behavior, with improvements to
the option's text taken from Matt's patch in bugzilla.
2006-01-21 08:10:45 +00:00
Wayne Davison
8bbe41b53b Handle the --chmod option as either the sender or the receiver so
that only the client needs to know about --chmod (but if an older
version sends the option to the server, we'll still handle it).
2006-01-21 08:03:18 +00:00
Wayne Davison
ba30fb5c3c For a local rsync, turn off the --chmod option on the receiving
side so that only the sending side does the work.
2006-01-21 07:58:35 +00:00
Wayne Davison
0938e8eee5 We don't ever need to send the --chmod option to the remote rsync. 2006-01-21 07:53:40 +00:00
Wayne Davison
3b17384631 Implemented the -xx behavior that skips mount-point dirs. 2006-01-21 01:20:03 +00:00
Wayne Davison
243c995f5f Allow the -x option to be repeated. 2006-01-21 00:36:15 +00:00
Wayne Davison
96b87581ff - Changed send_file_entry() into a static function again.
- Made send_file_entry() derive the base_flag value from *file.
- Added a flags arg to make_file().
- The flag we send to send_file_name() is a FLAG_* value, not an
  XMIT_* value.
2006-01-20 21:21:43 +00:00
Wayne Davison
3de73827d7 Call make_file() with one more arg (the base flags). 2006-01-20 21:21:36 +00:00
Wayne Davison
458aeea4a6 Mentioned the addition of -ii. 2006-01-20 19:33:24 +00:00
Wayne Davison
14cbb64539 Document the behavior of -ii. 2006-01-20 18:52:52 +00:00
Wayne Davison
a9e4762634 Handle the extra output needed when log_format_has_i > 1. 2006-01-20 18:49:38 +00:00
Wayne Davison
487094a0d7 Allow the --itemize-changes (-i) option to be repeated to indicate
that unchanged files should also be itemized.
2006-01-20 18:49:07 +00:00
Wayne Davison
f608ebb106 Got rid of unused function u_strcmp(). 2006-01-20 00:14:04 +00:00
Wayne Davison
87001ac6c2 Improved a sentence. 2006-01-19 21:21:28 +00:00
Wayne Davison
ede1f0ebc9 The code in send_file_list() needed a little more improvement to
handle --relative really well:
- We must set "is_dot_dir" when we strip off a trailing "/" or "/.".
- If a trailing "/" or "/." caused us to treat a symlink as a dir,
  we now pass our stat() info down to make_file() so that it will
  always treat the cleaned-up name as a dir too.
- We must not strip a leading "/".
- Improved the check for ".." elements in the implied dirs.
2006-01-19 21:16:44 +00:00
Wayne Davison
b435d7174c Added a new arg to the make_file() call. 2006-01-19 21:16:40 +00:00
Wayne Davison
2a59d2cc31 Another bugfix. 2006-01-19 19:05:49 +00:00
Wayne Davison
b8595e609a In delete_in_dir(), skip a directory that isn't really a directory on
the local disk (can easily happen if --dry-run was specified).
2006-01-19 18:53:48 +00:00
Wayne Davison
d37bc73a48 Mention the changes made in recent checkins. 2006-01-19 07:34:41 +00:00
Wayne Davison
1902a7652f When --relative is active, simply trim off trailing slashes and
dot dirs.  Also, reject a ".." dir if it would be sent as part
of the relative path.
2006-01-19 01:43:10 +00:00
Wayne Davison
6ab423a5b6 - Fixed the --help and --version output to avoid using embedded
newlines (which are no longer allowed in rprint()).
- Updated the Copyright info for 2006.
2006-01-17 04:26:12 +00:00
Wayne Davison
c2be690cc6 Got rid of a few empty lines. 2006-01-17 02:16:57 +00:00
Wayne Davison
f5a49d0e44 Got rid of a now-unused static variable. 2006-01-17 01:26:35 +00:00
Wayne Davison
03e23e0730 A few more items to check for, including libcharset.h, langinfo.h,
locale_charset(), and nl_langinfo().
2006-01-15 14:52:12 +00:00
Wayne Davison
eb598fac4f - Improved get_local_name() using ideas from Matt McCutchen's
version:  lots more comments, and a "local name" copy now
  does a chdir to the parent dir of the destination file.
- Moved the setlocale() call prior to the parse_arguments() call.
2006-01-15 07:11:23 +00:00
Wayne Davison
be0602ec3c - We now filter all rwrite() output when it goes out to the terminal
to make sure that it contains readable characters.
- Got rid of the buf[len] = '\0' in rwrite().
- Call f_name() with revised args (which also replaces f_name_to()).
2006-01-14 20:26:28 +00:00
Wayne Davison
6cbde57d88 Call f_name() with revised args (which also replaces f_name_to()). 2006-01-14 20:26:23 +00:00
Wayne Davison
5e4ff5f9c5 Merged f_name() with f_name_to(). 2006-01-14 20:26:20 +00:00
Wayne Davison
18e1289f27 Defined new FNAME logcode enum (only used on the client side when
logging a filename).
2006-01-14 20:26:17 +00:00
Wayne Davison
99aaa6ca25 Fixed a couple out-of-memory function-name strings in make_file(). 2006-01-14 17:19:12 +00:00
Wayne Davison
24172e4b2f If the --human-readable option is in effect, output the size of
each file in human-readable units instead of a raw byte count.
2006-01-14 17:10:52 +00:00
Wayne Davison
beaf495400 Added a "continue" missing from a recent change. 2006-01-14 00:29:50 +00:00
Wayne Davison
79f48760f3 Added --enable-iconv and cleaned up the other enable/disable options. 2006-01-13 23:05:16 +00:00
Wayne Davison
785abd4802 Got rid of the safe_fname() function and the calls to it. 2006-01-13 22:06:34 +00:00
Wayne Davison
0ee6ca9800 Got rid of calls to the (soon to vanish) safe_fname() function. 2006-01-13 22:06:31 +00:00
Wayne Davison
7543020807 Fixed a bug in the explode_mode code that was causing a crash
on BSD systems.
2006-01-13 21:40:26 +00:00
Wayne Davison
47b50b9bd0 We now use lib/compat.o when building wildtest. 2006-01-13 21:38:43 +00:00
Wayne Davison
45c49b52a4 Got rid of calls to (the soon to vanish) safe_fname() function. 2006-01-13 21:17:09 +00:00
Wayne Davison
0ee32c62d3 Improved a couple sentences. 2006-01-13 21:10:11 +00:00
Wayne Davison
70e98a4348 Changed RSYNC_ARGn to RSYNC_ARG#. 2006-01-12 19:35:54 +00:00
Wayne Davison
fddf529df9 Mention the new RSYNC_ARGn environment variables for pre-xfer exec. 2006-01-12 19:24:25 +00:00
Wayne Davison
141c62659e We now send all the option args to the pre-exec command. 2006-01-12 19:15:31 +00:00
Wayne Davison
61e16468f0 We need to call clearerr() when getc() returns EOF with errno == EINTR. 2006-01-06 22:20:07 +00:00
Wayne Davison
b74b3d538e + Changed two buffers to use BIGPATHBUFLEN instead of MAXPATHLEN+512.
+ Changed a strncpy() call into a (more appropriate) memcpy() call.
+ Made the ellipsis[] string static because some older compilers may
  not like the dynamic initialization of a character string.
+ Expanded some 1-line "case ... break;" statements onto separate
  lines.
2006-01-05 02:29:16 +00:00
Wayne Davison
d3db3eef1b Document the new "dir/***" feature. 2006-01-02 17:46:32 +00:00
Wayne Davison
90d5b12e72 Added a test for the new "dir/***" feature. 2006-01-02 17:46:27 +00:00
Wayne Davison
955a3a3ded We now test all the patterns using both a normal wildtest run and
a wildtest run with various -x and -e options.
2006-01-02 17:46:24 +00:00
Wayne Davison
aec75b037b Added -x and -e options, which are used to exercise wildmatch_array(). 2006-01-02 17:46:21 +00:00
Wayne Davison
e5daa2731a We use the new wildmatch_array() and litmatch_array() functions to
make our include/exclude code easier to read and maintain, and to
eliminate a buffer copy when handling an absolute-path pattern
(which eliminated the full_name[] buffer).  Also added handling
for the new MATCHFLG_WILD3_SUFFIX define that allows a string that
ends with "dir/***" to match the "dir" as well as its contents.
2006-01-02 17:46:18 +00:00
Wayne Davison
390621a7ab Added a new function, wildmatch_array(), that lets the caller pass
the text-string as an array of strings (with a terminating NULL
pointer at the end).  Also added litmatch_array(), which does a
literal match (no wildcards or special chars) against an array of
strings.
2006-01-02 17:46:15 +00:00
Wayne Davison
478bb47c40 The latest prototypes. 2006-01-02 17:46:12 +00:00
Wayne Davison
685517abd1 Added MATCHFLG_WILD3_SUFFIX define, shuffling a few others to put
it in a nice spot.
2006-01-02 17:46:09 +00:00
Wayne Davison
515afe7cf1 Mention dont-compress fix. 2005-12-30 07:24:17 +00:00
Wayne Davison
ec497df1a0 Optimized set_compression() to remove the per-file strdup(), strlower(),
and free() calls (it now uses iwildmatch()).
2005-12-30 07:19:16 +00:00
Wayne Davison
8e74463643 - Added a new public function, iwildmatch(), which will treat all
upper-case letters in the "text" as lower-case.
- Renamed variable "ch" -> "p_ch" and "prev" -> "prev_ch".
- Added variable "t_ch" to hold the current *text value.
- Return ABORT_ALL if we reach the end of the text string with
  more pattern to match.
2005-12-30 07:12:48 +00:00
Wayne Davison
933d1dfd0f Added a prototype for iwildmatch(). 2005-12-30 07:09:34 +00:00
Wayne Davison
0fe987e226 Fixed a bug in set_compression() where the default dont-compress
patterns (e.g. *.gz) would not match a pathname containing a slash.
2005-12-30 06:03:40 +00:00
Wayne Davison
770de8994e - Renamed match_start -> anchored_match.
- Twiddled one comment and added another.
- Twiddled the placement of two else statements.
2005-12-24 08:00:12 +00:00
Wayne Davison
37cf7b4191 Improved the usage info in the opening comment. 2005-12-19 16:57:55 +00:00
Wayne Davison
1a3ef40da9 A few extra directory-style matching tests. 2005-12-19 02:30:59 +00:00
Wayne Davison
0314302e9c Added an anchored exclude to a filter file. 2005-12-19 02:23:57 +00:00
Wayne Davison
9639c71842 + Put --existing back in the main option summary.
+ Improved the discussion of wildcard characters.
2005-12-19 02:18:16 +00:00
Wayne Davison
d2da915cd0 Made --existing the main option, with --ignore-non-existing
as its alias.
2005-12-19 01:59:00 +00:00
Wayne Davison
e725abcf4e Added a comment, improved a comment, tweaked the recursive function's
name, tweaked the arg names to wildmatch(), and tweaked the style of
the "else" statements when they follow a brace.
2005-12-18 19:40:50 +00:00
Wayne Davison
de01941274 Tweaked the name of the first arg to wildmatch(). 2005-12-18 19:38:47 +00:00
Wayne Davison
d802ea54da Fixed one config-file reference that was misspelled. 2005-12-18 15:48:00 +00:00
Wayne Davison
c81a20fb7a Tweaked the debug output for cvs_filter_list and server_filter_list. 2005-12-17 21:03:25 +00:00
Wayne Davison
6bf32edb8c Return RERR_SIGNAL1 from sigusr1_handler(). 2005-12-16 23:48:34 +00:00
Wayne Davison
4a50a2176e Added RERR_SIGNAL1's message and tweaked ERR_SIGNAL. 2005-12-16 23:48:31 +00:00
Wayne Davison
9e90555fd1 Added RERR_SIGNAL1 to separate SIGUSR1 from the rest of the
signals that return RERR_SIGNAL.
2005-12-16 23:48:28 +00:00
Wayne Davison
2067ec7342 Mentioned the auto-protect rule for --backup. 2005-12-16 17:20:22 +00:00
Wayne Davison
c2c5682c0b If the user specifies --backup with --delete (but without --backup-dir
and --delete-excluded), append a protect-filter rule onto the list of
filter rules.  We run this on both the client and server side so that
an older client talking to a newer server still gets the protection
rule.  (This rule will not cause compatibility problems with older
versions of rsync due to the graceful way that a protect rule turns
into an exclude rule if it needs to be sent to an older server.)
2005-12-16 17:18:29 +00:00
Wayne Davison
4c72f27dd9 Document the new auto-added protect filter-rule when using --backup
with --delete (but without --backup-dir and --delete-excluded).
2005-12-16 17:18:26 +00:00
Wayne Davison
36d8d1a626 - Added a comment about configure figuring out the default user
and group to use in daemon mode.
- Belatedly updated the version of popt that comes with rsync.
- Updated the Mac OS X info.
2005-12-16 16:57:26 +00:00
Wayne Davison
3447d61048 Fixed a bug in the hard-linking of a group of fifos/devices in a
transfer where the leader got hard-linked to a --link-dest item.
2005-12-16 04:02:54 +00:00
Wayne Davison
a3887c2644 Improved the RERR_SIGNAL message to include all possible signals. 2005-12-16 00:18:41 +00:00
Wayne Davison
8a1f3153b9 Mention the improvements in the comare-dest/link-dest/copy-dest handling. 2005-12-15 23:00:23 +00:00
Wayne Davison
165dd4a636 Improved the tests we run to test more output variations and to work
with the new way link-dest handles symlinks.
2005-12-15 23:00:05 +00:00
Wayne Davison
541b23d144 When compare-dest/link-dest/copy-dest are in effect, we now check
if the file we're about to hard-link to the leader is present in
one of the dest dirs -- if it is, we adjust the text we output
accordingly.
2005-12-15 23:00:02 +00:00
Wayne Davison
7987ece7cc The ITEM_NO_DEST_AND_NO_UPDATE define is no longer needed. 2005-12-15 22:59:59 +00:00
Wayne Davison
48224e4c43 Improved the compare-dest/link-dest/copy-dest code to make it more
readable, to make it output properly in double-verbose mode, and
to allow the hard-linking of symlinks and devices (if supported by
the OS).
2005-12-15 22:59:56 +00:00
Wayne Davison
6d4ecad122 - Eliminate an all-dot itemization for a locally-copied file.
- Got rid of some redundant output in maybe_log_item().
2005-12-15 22:59:53 +00:00
Wayne Davison
1578919c37 Improved an old bullet point. 2005-12-15 21:23:44 +00:00
Wayne Davison
10a1d6b4a0 Use AC_SEARCH_LIBS() instead of AC_CHECK_LIB() to figure out if
we need to include libresolv or not.
2005-12-14 22:54:54 +00:00
Wayne Davison
2b7e12924d Mention that the MD4 password protection is weaker than
previously thought.
2005-12-14 22:14:26 +00:00
Wayne Davison
82f0c63e8a Parse single- and double-quotes in the --rsh/-e option (and RSYNC_RSH). 2005-12-14 22:00:01 +00:00
Wayne Davison
5d9530fe47 Mention new quote-parsing for the --rsh/-e and RSYNC_RSH handling. 2005-12-14 21:59:11 +00:00
Wayne Davison
37f35d89d1 Made msg_list_push() static and renamed it to msg_list_flush(). 2005-12-08 21:19:22 +00:00
Wayne Davison
08c88178aa Tweaked the msg_list code so that the head and tail pointers
are contained by a structure.
2005-12-08 21:01:38 +00:00
Wayne Davison
0fb2fc4a1d Fixed a typo in a comment. 2005-12-08 16:12:25 +00:00
Wayne Davison
da2d13e3ce Improved/fixed some of the entries. 2005-11-29 15:53:18 +00:00
Wayne Davison
64318670a8 Improved the description of how --delay-updates chooses it's dir. 2005-11-16 16:12:04 +00:00
Wayne Davison
3c19f72c16 Made the parsing in parse_size_arg() a little more strict. 2005-11-15 17:49:59 +00:00
Wayne Davison
8938d67ef8 Fixed a typo in the --help output for --no-OPTION. 2005-11-15 07:05:55 +00:00
Wayne Davison
05724c07cf Changed -h to be an alias for --human-readable (getting rid of -m).
Also added backward-compatibility code so that "rsync -h" shows the
help page on stdout like it would in older versions.
2005-11-15 06:35:27 +00:00
Wayne Davison
955c3145c3 Document the change in the -h option. 2005-11-15 06:35:22 +00:00
Wayne Davison
8ea17b5098 Twiddled some brace positions and removed a superfluous ';' in a macro. 2005-11-14 21:24:30 +00:00
Wayne Davison
b20fe0e6ac Improved an error message. 2005-11-13 17:15:00 +00:00
Wayne Davison
24787acd08 Moved the DEL_* flags into generator.c. 2005-11-12 20:30:40 +00:00
Wayne Davison
d71dad3bd3 Moved the DEL_* flags from rsync.h here and got rid of DEL_NO_RECURSE. 2005-11-12 20:30:36 +00:00
Wayne Davison
889439c205 Mention the latest options. 2005-11-12 20:08:10 +00:00
Wayne Davison
bee9df73c1 Changed the parsing of suffixes for --min-size and --max-size a little. 2005-11-12 20:08:00 +00:00
Wayne Davison
60613dc896 Output the stats and the end-of-run verbose output using the new
human_num() and human_dnum() functions, which both honor the
new --human-readable option.
2005-11-12 19:53:26 +00:00
Wayne Davison
e175fb07f7 Added two new functions: human_num() and human_dnum(), which
output numbers in human-readable units if the --human-readable
option was specified.
2005-11-12 19:53:23 +00:00
Wayne Davison
4a70af6f81 Added the human_readable variable (for linking with util.o). 2005-11-12 19:53:20 +00:00
Wayne Davison
8f14cc496b Parse the new --human-readable (-m) option. 2005-11-12 19:53:17 +00:00
Wayne Davison
3b4ecc6b80 Document the new --human-readable (-m) option. 2005-11-12 19:53:12 +00:00
Wayne Davison
a7e60f0c59 Only call cleanup_set() if keep_partial is set. 2005-11-10 16:57:30 +00:00
Wayne Davison
3d7cc5710d If cleanup_set() gets passed a NULL fnametmp or fname, set
cleanup_fname to NULL.
2005-11-10 16:56:32 +00:00
Wayne Davison
86fc7e6880 Got rid of a superfluous newline. 2005-11-10 16:47:52 +00:00
Wayne Davison
acee11fc60 - Indent the "oom:" label away from column 0.
- Got rid of a superfluous newline.
2005-11-10 16:47:27 +00:00
Wayne Davison
b2e7c91313 Indent the "prepare_to_open:" and "notify_others:" labels away
from column 0.
2005-11-10 16:47:03 +00:00
Wayne Davison
97b7bff4d6 - Got rid of a superfluous empty line.
- Indent the "oom:" and "skip_filters:" labels away from column 0.
2005-11-10 16:45:00 +00:00
Wayne Davison
e16ca9ef31 Got rid of a superfluous empty line. 2005-11-10 16:44:06 +00:00
Wayne Davison
b2e6caa01e Indent the "failure:" label away from column 0. 2005-11-10 16:43:44 +00:00
Wayne Davison
2997e9f769 Indent the "oom:" label away from column 0. 2005-11-10 16:42:46 +00:00
Wayne Davison
2374023982 Mention the big improvement when --delete and --checksum were
specified.
2005-11-10 06:43:10 +00:00
Wayne Davison
902f03d101 In make_file(), only compute the checksum when we're the sender.
This stops computing useless checksums during the delete scan
when --checksum (-c) was specified.
2005-11-10 06:01:55 +00:00
Wayne Davison
cfe3978049 Use the new checksum_len value instead of recomputing the
right value for the current protocol_version over and over.
2005-11-10 03:07:18 +00:00
Wayne Davison
7752df41b7 Compute the right checksum length for the current protocol_version
only once instead of over and over again.
2005-11-10 03:00:38 +00:00
Wayne Davison
d8b108c2a1 If a partial-dir file is present but the main file is up-to-date,
just remove the partial-dir file.
2005-11-10 02:56:58 +00:00
Wayne Davison
184dd27a18 Call delete_in_dir(NULL, NULL, NULL) in do_delete_pass(). 2005-11-09 19:46:42 +00:00
Wayne Davison
0e5665d3ab Made recursively deleting extraneous directories more memory
efficient by removing the need for a MAXPATHLEN buffer on the
stack of delete_item().
2005-11-09 19:39:46 +00:00
Wayne Davison
ef3bb69ad8 Mention the new --chmod option. 2005-11-07 04:47:06 +00:00
Wayne Davison
45d41d08bd Test the --chmod option. 2005-11-07 04:28:52 +00:00
Wayne Davison
dd32e2c3d4 Added support for the new --chmod option. 2005-11-07 04:28:35 +00:00
Wayne Davison
2b7e0f33a6 Call tweak_mode() on regular files and dirs if --chmod was specified. 2005-11-07 04:28:32 +00:00
Wayne Davison
0582cdae8d Added chmod.o to OBJS2. 2005-11-07 04:28:29 +00:00
Wayne Davison
9e8ea423e2 Document the new --chmod option. 2005-11-07 04:28:23 +00:00
Wayne Davison
0c983c1fd4 New --chmod support routines. 2005-11-07 04:23:22 +00:00
Wayne Davison
3381ffa6ea Fixed a sign error in the output. 2005-11-03 19:55:30 +00:00
Wayne Davison
3b15340966 Mention the change in the output of --progress. 2005-11-03 19:46:45 +00:00
Wayne Davison
91683c434b Make the just-updated file-count status even less cryptic. 2005-11-03 19:45:59 +00:00
Wayne Davison
9e7530c414 Improved the output of the transferred-file count and the position
in the flist (which was changed to a countdown of files to check)
so that it's clearer what the numbers mean.
2005-11-03 19:38:14 +00:00
Wayne Davison
8fd30fc43c Got rid of some early-checksum code that accidentally got committed. 2005-11-02 07:22:02 +00:00
Wayne Davison
b1b04fcdd4 Mention lower stack requiements for recursion. 2005-11-01 20:13:20 +00:00
Wayne Davison
56f0c976be Decreased the amount of stack needed for each level of directory
recursion by eliminating the need for a MAXPATHLEN buffer in
send_if_directory().  Also improved a few variable names in
send_file_list().
2005-11-01 20:09:41 +00:00
Wayne Davison
9aacb4df0e Fixed a typo pointed out by Peter Strazovec. 2005-10-30 22:29:59 +00:00
Wayne Davison
0fdb1aa8ff In the device section, avoid calling unlink() if the stat() failed. 2005-10-30 22:28:11 +00:00
Wayne Davison
bad0110609 Document the new --compress-level option. 2005-10-26 16:48:44 +00:00
Wayne Davison
3cc185a088 Handle new def_compress_level setting. 2005-10-26 16:48:07 +00:00
Wayne Davison
e8a8167ad9 Obey new def_compress_level setting. 2005-10-26 16:47:49 +00:00
Wayne Davison
854a1aad35 Added --compress-level option. 2005-10-26 16:47:15 +00:00
Wayne Davison
84e6d6fdcd - Changed the "status" variables into "exit_code" variables.
- Added an error message to wait_process_with_flush() that
  reports the errno we get when waitpid() fails.
- Increased the value of MAXCHILDPROCS.
2005-10-26 15:53:04 +00:00
Wayne Davison
f14a65d94c Tweaked the error message for RERR_WAITCHILD. 2005-10-26 15:50:14 +00:00
Wayne Davison
37439b36e7 Updated the docs for pre-/post-xfer exec. 2005-10-24 21:03:53 +00:00
Wayne Davison
c95ca2a228 Enhanced the "pre-xfer exec" handling so that it gets the user's
request info and puts that into the environment as RSYNC_REQUEST.
2005-10-24 21:03:50 +00:00
Wayne Davison
97d8e7095f Changed wait_process() into a simpler, yet more versatile function,
and used it in the new wait_process_with_flush() function (the old
function's new name).  Made wait_process() public.
2005-10-24 21:03:47 +00:00
Wayne Davison
20c1926a01 Fixed a typo in a comment. 2005-10-20 18:30:33 +00:00
Wayne Davison
d030233def Get rid of some superfluous empty lines. 2005-10-19 07:49:10 +00:00
Wayne Davison
35812ea1f9 One extra tweak to the just-committed code. 2005-10-15 19:15:29 +00:00
Wayne Davison
d649b78920 Added relative_paths extern. 2005-10-15 19:11:36 +00:00
Wayne Davison
7e43da819e If we're sanitizing paths with --relative enabled, we need to
preserve the first /./ dir so that we can use its position to
trim the implied directories.
2005-10-15 19:08:31 +00:00
Wayne Davison
40aaa571b4 Document --ignore-non-existing (not --existing) and what happens
if the option is combined with --ignore-existing.
2005-10-15 16:39:31 +00:00
Wayne Davison
470319d33b Changed the --help text to mention --ignore-non-existing
instead of --existing.
2005-10-15 16:38:35 +00:00
Wayne Davison
1db954e9bc Made parse_size_arg()'s parsing a little stricter. 2005-10-15 06:53:04 +00:00
Wayne Davison
d697314b42 Mention --min-size/--max-size changes. 2005-10-14 20:40:31 +00:00
Wayne Davison
59dd678603 Documented --min-size. 2005-10-14 20:16:21 +00:00
Wayne Davison
02b5cb238b Added code to implement the --min-size logic. 2005-10-14 20:16:09 +00:00
Wayne Davison
74de13d19c Added handling of the --min-size option. 2005-10-14 20:15:18 +00:00
Wayne Davison
837d01dd5a Improved parse_size_arg() a little more. 2005-10-14 19:48:34 +00:00
Wayne Davison
926d86d1f9 Document the extended parsing of --max-size values. 2005-10-14 19:03:05 +00:00
Wayne Davison
aeb213ea0c Improved parse_size_arg() so that it can be told to use powers of
ten instead of binary K/M/G powers, and so that it can be told to
add or subtract one from the result.  We also make sure to pass
the arg to --max-size in a compatible manner with older versions.
2005-10-14 18:56:07 +00:00
Wayne Davison
7c6ea3d8c7 Fixed a typo in an option name. 2005-10-12 23:59:00 +00:00
Wayne Davison
d409c6ac9c Mention va_copy change. 2005-10-11 20:21:56 +00:00
Wayne Davison
92f0b9d6ab If va_copy is defined, use it when defining VA_COPY. 2005-10-11 20:21:03 +00:00
Wayne Davison
2c8c8bbaad Pass XFLG_ABS_IF_SLASH instead of XFLG_ANCHORED2ABS for server excludes. 2005-10-07 18:40:30 +00:00
Wayne Davison
4fc8140a60 Support new XFLG_ABS_IF_SLASH flag. 2005-10-07 18:39:40 +00:00
Wayne Davison
699f7024f1 Added XFLG_ABS_IF_SLASH. 2005-10-07 18:38:25 +00:00
Wayne Davison
ce0da32a9c Mention recent changes. 2005-10-07 18:24:35 +00:00
Wayne Davison
82360c6b17 Clarify how the fitler rule "-/" works. 2005-10-07 18:18:16 +00:00
Wayne Davison
493568465b Improved the usage comments. 2005-10-04 04:12:28 +00:00
Wayne Davison
bf485d3d6b A simple filter script to output messages from a single module. 2005-10-03 18:40:59 +00:00
Wayne Davison
e90aab4982 Changed the variable names for --existing and --ignore-existing. 2005-09-29 18:07:55 +00:00
Wayne Davison
550d4e2346 Reverted one xfer_dirs change from the last commit that should not
have gone in.
2005-09-29 17:27:11 +00:00
Wayne Davison
991daf008d Keeping silent about stat() errors is never a good idea -- it hides
files that are not up-to-date.
2005-09-29 17:07:45 +00:00
Wayne Davison
505ada146c Mention that --delete now works with --dirs. 2005-09-29 08:15:34 +00:00
Wayne Davison
75c51953f1 - When --dirs is specified w/o --recursive, avoid marking solo dirs
with the XMIT_TOP_DIR flag.
- Only set in_del_hier if --recursive is enabled.
2005-09-29 07:48:05 +00:00
Wayne Davison
8d6c1c4e97 Allow deletions to occur in directories transferred with the
--dirs option in addition to the regular --recursive behavior.
2005-09-29 07:41:50 +00:00
Wayne Davison
10a1a3f511 Fixed a poorly-worded sentence and a misspelled word. 2005-09-29 07:37:00 +00:00
Wayne Davison
40e6752fba Some systems don't define WCOREDUMP(), so #ifdef that code. 2005-09-26 17:41:14 +00:00
Wayne Davison
dbefb6b4e4 Fixed wait_process() to handle cases where waitpid() fails or
the child process did not exit cleanly.
2005-09-26 17:12:13 +00:00
Wayne Davison
6016841086 Changed RERR_CRASH to RERR_CRASHED. 2005-09-26 17:11:03 +00:00
Wayne Davison
0047f535ef Handle new RERR_CRASH AND RERR_TERMINATED exit codes. 2005-09-26 17:07:50 +00:00
Wayne Davison
90eca40d27 Defined RERR_CRASH and RERR_TERMINATED. 2005-09-26 17:06:33 +00:00
Wayne Davison
0417c34e2d Mention some chanages in the patches dir. 2005-09-26 04:47:25 +00:00
Wayne Davison
d64c2b226a Use AC_HELP_STRING() in the two AC_ARG_WITH() macros that used a
hard-wired string.
2005-09-24 17:17:30 +00:00
Wayne Davison
868676dc15 Reordered the usage lines to cover push, then pull (which has a
better visible pattern than covering push & pull for each host-type).
2005-09-21 22:39:49 +00:00
Wayne Davison
e31058d41e Cast some time values to (int), just to silence some warnings on
Stratus VOS.
2005-09-21 17:42:15 +00:00
Wayne Davison
ea8291d8f7 Include limits.h (if it exists), which defines NAME_MAX on some
systems.
2005-09-21 17:38:44 +00:00
Wayne Davison
1348267518 If we get less data than expected from a read() in map_ptr(), we
need to try to keep reading to see if we get an error or more data.
2005-09-21 17:37:41 +00:00
Wayne Davison
f0323d68eb Check for limits.h. 2005-09-21 17:35:51 +00:00
Wayne Davison
12a01be14f Tweaked the output that the mknod() tests generate. 2005-09-21 17:15:58 +00:00
Wayne Davison
e0a18ce3f7 Tweaked some comments. 2005-09-19 17:21:00 +00:00
Wayne Davison
8ad5cea371 Changed one strcpy() into a strlcpy(). 2005-09-17 21:49:24 +00:00
Wayne Davison
9059e0ac2f Improved the sDefault initialization so that the prefixed
comments exactly match the variable names (making sure that
they will sort exactly the same way as the variables).
2005-09-16 20:35:05 +00:00
Wayne Davison
29fad7a3d8 Got rid of some old command-line parsing code that was only
useful when talking to a 1.x client.
2005-09-16 16:40:30 +00:00
Wayne Davison
02efda9f01 Mention '!' fix. 2005-09-16 16:14:24 +00:00
Wayne Davison
35a388b141 Really fix '!' in a .cvsignore file this time. 2005-09-16 16:10:01 +00:00
Wayne Davison
9a4a237ede Tweaked the code a little in the always_checksum handling of the
send & receive file-list functions.
2005-09-16 05:52:54 +00:00
Wayne Davison
5efbddbadb Mention that the dir used with --delay-updates cannot be on a
different filesystem from the destination files.
2005-09-15 22:27:14 +00:00
Wayne Davison
6a94c58b00 Added a comment. 2005-09-15 22:25:55 +00:00
Wayne Davison
e3f8395360 Mention doc changes. 2005-09-15 17:19:30 +00:00
Wayne Davison
f2b4c0840e Removed conflicting ssh citation in the SETUP section. 2005-09-15 15:36:27 +00:00
Wayne Davison
08d82b84cb The --help text was outputting some incomplete information on how
SRC is expanded or word-split, so I removed that text and replaced
it with an explaination of how ':' differs from '::' & 'rsync://'.
2005-09-13 01:02:54 +00:00
Wayne Davison
fbe57fdc95 Mention the latest fix. 2005-09-09 17:07:39 +00:00
Wayne Davison
92cdc39372 When pop_dir(olddir) fails, pass the right string pointer
in the error message.
2005-09-09 16:17:01 +00:00
Wayne Davison
78be8e0fc9 Improved the -F, --exclude-from, and --include-from sections. 2005-09-09 07:27:25 +00:00
Wayne Davison
a5b786d80f Tweaked the calculation that goes into sum->count so that it cannot
overflow into a negative value (which is particularly important if
configure didn't find a real int64 type).
2005-09-06 18:12:38 +00:00
Wayne Davison
f853b777be Complicate the lseek64() function prototype because some systems
don't have off64_t.
2005-09-03 16:56:53 +00:00
Wayne Davison
fed1f3f4fe Make use of the per-module "temp dir" setting. 2005-09-03 16:50:20 +00:00
Wayne Davison
18cad44967 Added a per-module "temp dir" setting. 2005-09-03 16:24:23 +00:00
Wayne Davison
d17c9a4486 Sorted some of the data structures (using vim's "!sort" command
makes it easy).
2005-09-03 16:22:06 +00:00
Wayne Davison
b6e22a47d3 - Allow --no-v and --no-verbose in the daemon options.
- If a too-long --temp-dir is specified when starting a daemon,
  omplain to the daemon-starting user, not later to the client.
2005-08-30 16:13:54 +00:00
Wayne Davison
ec69bdbd64 Mention latest changes. 2005-08-30 05:12:49 +00:00
Wayne Davison
a8cbb57c9b Mention how --inplace conflicts with --sparse and how --append
does not.
2005-08-30 05:10:51 +00:00
Wayne Davison
b8cc35874e Allow --temp-dir to be specified with --daemon to set the default. 2005-08-30 05:00:56 +00:00
Wayne Davison
c3851185f3 Fixed a comment. 2005-08-30 02:59:30 +00:00
Wayne Davison
e7ee91defc When --append is entering the redo phase, make sure that
sparse_files is disabled (because it conflicts with an
inplace update).
2005-08-30 02:58:42 +00:00
Wayne Davison
cfce9f6dc3 Reject attempts to combine --sparse with --inplace. 2005-08-30 02:57:19 +00:00
Wayne Davison
4afcb709a7 Forgot the --no-v option. 2005-08-28 00:43:51 +00:00
Wayne Davison
a912a980ec Mention the new --no-* options. 2005-08-28 00:34:46 +00:00
Wayne Davison
2c64b25827 A small improvement to the daemon-connecting instructions. 2005-08-28 00:25:44 +00:00
Wayne Davison
38b9170c52 One more tweak to the option data. 2005-08-27 21:12:44 +00:00
Wayne Davison
f40aa6fb07 Documented the new --no-* options. 2005-08-27 21:07:27 +00:00
Wayne Davison
b616493883 Added the ability to prefix "no-" to various options, which gives the
user an easy way to override implied option switches.
2005-08-27 21:01:45 +00:00
Wayne Davison
e86e2fa173 A little more reordering of the option data. 2005-08-27 20:43:35 +00:00
Wayne Davison
11bfaf6351 Reordered some of the option data to make their grouping more logical. 2005-08-27 20:01:45 +00:00
Wayne Davison
d37d1c44ff Make the --append docs a little better. 2005-08-20 17:21:06 +00:00
Wayne Davison
c89330313e Moved a variable in glob_expand_one(). 2005-08-03 04:51:29 +00:00
Wayne Davison
c9dc1300ba Got rid of the argp var that is not needed now that argv is no
longer a literal array.
2005-08-03 04:42:56 +00:00
Wayne Davison
53cf0b8bfb Improved the --relative section a little more. 2005-08-03 01:13:15 +00:00
Wayne Davison
56961becc2 Mention the latest changes. 2005-08-01 22:18:11 +00:00
Wayne Davison
1dc42d123d Improved the --relative section, including mentioning the addition
of dot-dir path trimming.
2005-08-01 22:18:00 +00:00
Wayne Davison
d2ea5980ba Allow the user to specify a dot dir in the source path when
using --relative, making it trim the duplicated dirs.
2005-08-01 21:58:16 +00:00
Wayne Davison
15cf186b85 Don't recreate a device if just the permissions bits have changed
in the st_mode.
2005-08-01 04:09:58 +00:00
Wayne Davison
4fdb03a648 Mention hard-link fix. 2005-07-31 23:21:46 +00:00
Wayne Davison
8f5b554f0b Hard-link a device in order to test that this works properly. 2005-07-31 23:20:12 +00:00
Wayne Davison
8cd3db27b6 There is no longer a need to check file->link_u.links at the start
of hard_link_check() (because the caller has already checked it).
2005-07-31 23:19:42 +00:00
Wayne Davison
273a7ed59f Fixed the handling of hard-linked symlinks and devices. 2005-07-31 23:18:28 +00:00
Wayne Davison
23deb0bcee Export RUNSHFLAGS. 2005-07-31 23:15:38 +00:00
Wayne Davison
7ea7bebf6b Mention the --inplace new-file permissions fix. 2005-07-30 16:17:21 +00:00
Wayne Davison
97894c6473 - The combination of --update and --progress now outputs progress
information during the checksum scan of the already-sent data.
- When --inplace creates a file, give it 0600 permissions, not 0000.
2005-07-30 16:14:22 +00:00
Wayne Davison
1f86fcf5dc The combination of --update and --progress now outputs progress
information during the checksum scan of the already-sent data.
2005-07-30 16:13:19 +00:00
Wayne Davison
bb9bdba4c9 Improved the text around the last example in the USAGE section. 2005-07-29 19:52:50 +00:00
Wayne Davison
5b9cc6953a Mention the latest changes. 2005-07-29 18:48:58 +00:00
Wayne Davison
33544bf422 - Use BIGPATHBUFLEN for the length of several buffers.
- If io_printf() tries to overflow the buffer, die with
  an error instead of sending a truncated buffer.
2005-07-29 18:31:12 +00:00
Wayne Davison
20accf4d06 - Use BIGPATHBUFLEN for the length of two line buffers.
- Improved the handling of the start_glob variable.
- Made the line buffer in start_daemon() a little bigger.
2005-07-29 18:31:10 +00:00
Wayne Davison
3fac51e21e Use BIGPATHBUFLEN for the length of two line buffers. 2005-07-29 18:31:07 +00:00
Wayne Davison
d999d312c4 Use BIGPATHBUFLEN for the length of a line buffer. 2005-07-29 18:31:05 +00:00
Wayne Davison
a22ca88565 Define BIGPATHBUFLEN -- a roomy line-buffer that can hold a
MAXPATHLEN string plus a message, and it's at least 4096+1024
bytes for those systems where MAXPATHLEN is overly short.
2005-07-29 18:31:03 +00:00
Wayne Davison
9ec8bd87bb Updated to match 2.6.6 release (which occurred on a branch). 2005-07-28 20:00:43 +00:00
Wayne Davison
f11ece28ff Changed the version to 2.6.7cvs. 2005-07-28 19:49:47 +00:00
Wayne Davison
f90f71498e Updated to reflect new 2.6.7cvs status. 2005-07-28 19:49:24 +00:00
Wayne Davison
32199c6b00 Removed a duplicated item. 2005-07-28 18:17:56 +00:00
Wayne Davison
870dddc5eb Mention the recent changes. 2005-07-28 17:42:56 +00:00
Wayne Davison
9d0d18b590 If the user has specified "pre-xfer exec" or "post-xfer exec", run
the indicated command(s), each at the appropriate time.
2005-07-28 17:15:47 +00:00
Wayne Davison
bec617b934 Added 2 new config options: "pre-xfer exec" and "post-xfer exec". 2005-07-28 17:15:44 +00:00
Wayne Davison
c20936b88b Document the new pre-/post-xfer exec config options. 2005-07-28 17:15:42 +00:00
Wayne Davison
0869881764 Regenerated. 2005-07-28 16:58:04 +00:00
Wayne Davison
a840b5c736 Removed one more client-oriented command-line syntax sentence. 2005-07-28 09:40:08 +00:00
Wayne Davison
2907884f94 Removed erroneous section on using daemon features over a
remote-shell connection -- client-use is better described in the
rsync manpage, and the advanced restricted-ssh section needs a
better treatment (perhaps as a support script).
2005-07-28 09:36:12 +00:00
Wayne Davison
754a080ffc Improved the sections dicussing the various types of transfer
connections and how a normal transfer differs from a daemon
transfer.
2005-07-28 09:18:20 +00:00
Wayne Davison
94f20a9f45 Document new --append option. 2005-07-28 01:46:16 +00:00
Wayne Davison
6cc1198288 Support new --append option. 2005-07-28 01:46:12 +00:00
Wayne Davison
a015788d21 Added the --append option. 2005-07-28 01:46:09 +00:00
Wayne Davison
c8d3465726 - Call set_modtime() with its new mode arg.
- Don't mask the mode bits being sent to do_chmod().
- Don't skip calling set_modtime() or do_chmod() when the item
  is a symlink.
2005-07-27 23:30:58 +00:00
Wayne Davison
00b9618460 - Fixed the mode comparison in itemize() to mask off the bits
outside of the CHMOD_BITS mask.
- Don't call do_chmod() unless HAVE_CHMOD is defined.
- Don't mask the mode bits being sent to do_chmod().
2005-07-27 23:30:55 +00:00
Wayne Davison
d11f5c6e2b - Don't call do_chmod() unless HAVE_CHMOD is defined.
- Made do_chmod() handle symlinks or return 1 if not possible.
- We now mask off the mode bits in do_chmod() sing CHMOD_BITS.
2005-07-27 23:30:53 +00:00
Wayne Davison
25007999df - Changed set_modtime() to take the file's mode as an arg.
- Made set_modtime() handle symlinks or return 1 if not possible.
2005-07-27 23:30:51 +00:00
Wayne Davison
8ce6546310 Check for the lchmod() and lutimes() functions. 2005-07-27 23:18:28 +00:00
Wayne Davison
151f59f155 Tweaked a comment and some null-char assignments. 2005-07-22 19:09:45 +00:00
Wayne Davison
89f2a4c231 Changed implied_dirs to only be non-0 if relative_paths is non-0. 2005-07-22 19:05:25 +00:00
Wayne Davison
496be30db6 Got rid of some unused externs. 2005-07-22 17:59:21 +00:00
Wayne Davison
cd426074e1 Updated to zlib 1.2.3. 2005-07-22 15:54:43 +00:00
Wayne Davison
3f7bfac2a0 Avoid newest test when no destination was specified. 2005-07-15 19:10:03 +00:00
Wayne Davison
9425918d74 Output a syntax error if both the source and destination are remote. 2005-07-15 19:06:43 +00:00
Wayne Davison
cc637fcc51 Preparing for release of 2.6.6pre1 2005-07-07 22:53:59 +00:00
Wayne Davison
9db1743490 Mentioned the zlib changes and tweaked a couple sentences. 2005-07-07 22:50:12 +00:00
Wayne Davison
ba3542cfcb - Attempt to make the discussion of host-specifying args less confusing.
- Fixed the names of the uid and gid daemon options in a sentence.
2005-07-07 21:33:40 +00:00
Wayne Davison
81f5b275db Changes for new zlib. 2005-07-07 21:29:57 +00:00
Wayne Davison
f3ee726894 Fixed a typo. 2005-07-07 21:19:14 +00:00
Wayne Davison
b5be9e6c5f Fix latest zlib security exploit (CAN-2005-2096). 2005-07-07 21:14:29 +00:00
Wayne Davison
1e1cf68934 Upgraded to version 1.2.2. 2005-07-07 20:48:02 +00:00
Wayne Davison
4a2744cee3 One more "#undef BAD" for AIX. 2005-07-07 20:37:31 +00:00
Wayne Davison
12febd804f Use a define to handle conflicting function read_buf instead of
renaming it in the code.
2005-07-07 20:17:35 +00:00
Wayne Davison
687c6b14a0 Changed "Overflow" back to "overflow". 2005-07-07 20:16:41 +00:00
Wayne Davison
a1f99493b3 Changed overflow() to overflow_exit(). 2005-07-07 19:49:14 +00:00
Wayne Davison
9819f005b6 Changed zBAD back to BAD (with a simpler kluge for AIX). 2005-07-07 19:31:23 +00:00
Wayne Davison
2a6793bf1f Fixed some whitespace to match the original source. 2005-07-07 19:22:55 +00:00
Wayne Davison
bf287ee946 Got rid of bogus RCS keyword expansions (that create differences
between these files and the original zlib source).
2005-07-07 19:15:44 +00:00
Wayne Davison
b8b0668e85 Mention the EEXIST fix. 2005-06-30 17:18:30 +00:00
Wayne Davison
092906933b Ignore EEXIST on second mkdir() call. 2005-06-30 17:03:14 +00:00
Wayne Davison
e8432be95f Mention the latest time-comparing fixes. 2005-06-28 00:15:44 +00:00
Wayne Davison
6ff2f4ba67 Use cmp_modtime() in a couple more spots where a local modtime is
compared with a remote modtime.
2005-06-28 00:12:08 +00:00
Wayne Davison
309a5be873 Fixed test to work when objdir != srcdir (thanks to Art Haas). 2005-06-24 02:14:12 +00:00
Wayne Davison
26c87bb630 Changed the arg-splitting code so that it can handle a literal
backslash prior to whitespace without treating it as escaped
whitespace (e.g. if we receive "foo\\ bar", it is two args,
while "foo\ bar" and "foo\\\ bar" are each just one).
2005-06-23 15:58:57 +00:00
Wayne Davison
ea9b2add97 Tweaked a comment in the perl code we output. 2005-06-23 15:53:26 +00:00
Wayne Davison
301569f081 Improved a couple sentences. 2005-06-20 07:01:29 +00:00
Wayne Davison
b21456102a Changed the code to use the single long-option hash from cull_options. 2005-06-17 23:23:00 +00:00
Wayne Davison
b8a47c9bc6 - Fixed a bug where the --*-dest options weren't being culled.
- Simplified the output format by putting all the long-name
  options into a single hash.
2005-06-17 23:16:22 +00:00
Wayne Davison
85fbfa10a8 - Improved some comments (some taken from the new cull-options output).
- Made the user-config sections easier to find.
- Default to running a fully-specified rsync executable so that there
  are not PATH surprises.
- A few minor tweaks to the arg-checking code to make it clearer without
  actually changing its logic.
2005-06-17 16:48:02 +00:00
Wayne Davison
555bc0e31a Another readability improvement in the perl code we output. 2005-06-17 16:29:21 +00:00
Wayne Davison
ef1233cbb3 Improved some of the comments that are output into the perl code. 2005-06-17 16:12:05 +00:00
Wayne Davison
1524815ed3 - Make sure that the command contained the '.' arg at the end of the
options.
- Fixed the expanding of wildcards for a restriction of '/'.
2005-06-17 05:14:15 +00:00
Wayne Davison
985af7035e - Be restrictive on matching the --sender option so that the user
can't fool us into thinking we're the sender by using a filename
  of --sender (or similar ploy).
- Make sure that our '..' check can't be fooled by sly backslashing.
- Tweaked some comments.
2005-06-17 04:50:22 +00:00
Wayne Davison
b3181708f2 Output a leading comment and surrounding blank lines. 2005-06-17 04:46:02 +00:00
Wayne Davison
3f6c17cf14 Mention rrsync changes. 2005-06-17 01:26:33 +00:00
Wayne Davison
2e5a7629c0 If SUBDIR is specified as a non-absolute path, make it absolute. 2005-06-17 01:17:44 +00:00
Wayne Davison
70318468df - Made it easy to configure the path of the rsync executable.
- Fully parse all legal options that might come from a stock rsync and
  validate/restrict any option's args (previously we rejected options
  with args).
- Made it easy to disable specific options.
- Properly handle a multi-arg copy's multiple args.
- Make sure that the restricted dir actually exists and we can chdir
  to it.
- Just reject any dangerous args that have .. in them instead of trying
  to munge them.
- We don't treat single-or double-quotes specially, just backslash-
  escaped characters.
- Turn on strict mode.
- Use the array-arg version of exec() so that we don't spawn a shell.
- Use File::Glob to glob wildcards in args.
- Tweaked the log-file format so that it logs the modified command
  without any "OK" suffix.
2005-06-16 19:30:53 +00:00
Wayne Davison
782d109121 A developer-oriented script that outputs perl code for valid server
options.
2005-06-16 19:17:47 +00:00
Wayne Davison
30e7b0b28d Mention latest fix. 2005-06-12 06:10:14 +00:00
Wayne Davison
910ee8c92e In clean_flist(), fixed the setting of the flist->high value for an
empty list so that it can't cause a crash if it gets passed to
flist_find().
2005-06-12 06:07:23 +00:00
Wayne Davison
8af1bc9011 - Added a comment to the filter_outfile function.
- Twiddled where the calls to filter_outfile happen.
2005-06-10 23:36:57 +00:00
Wayne Davison
6a12f0d619 Simplified the regular expressions for sed due to problems on some
OSes.
2005-06-10 21:56:52 +00:00
Wayne Davison
4f3be36e30 - Put the output we're expecting into an rsync.chk file, for easier
debugging on failures.
- Added the function filter_outfile() and used it in place of the
  various output-filtering commands.
- Use the sed rules for filtering the combination of --itemized
  output with double-verbose output so that we're sure there's no
  superfluous lines being output (which the old grep filtering
  would have ignored).
2005-06-10 20:33:57 +00:00
Wayne Davison
fc9d64c947 Several expansions of $srcdir were not double-quoted. 2005-06-10 20:04:42 +00:00
Wayne Davison
db10766ab2 One expansion of $srcdir wasn't double-quoted. 2005-06-10 20:04:11 +00:00
Wayne Davison
a3dcb79085 One more instance of the umask kluge was needed. 2005-06-10 18:02:14 +00:00
Wayne Davison
20667b6d7f Mention backup change. 2005-06-10 17:58:39 +00:00
Wayne Davison
93e28fbd99 Fixed a problem in the backing up of symlinks and devices: we
need to remove any old symlink/device/file to create the backup.
Also fixed a couple minor logic errors in the handling of symlinks
and devices.  NOTE:  the code still doesn't handle the changing of
a name from a dir to a non-dir or visa versa (which is a very old
deficiency in the code).
2005-06-10 17:57:18 +00:00
Wayne Davison
87a57a3072 Use umask kluge from rsync.fns to try to get rid of a potential
permissions difference when copying symlinks.
2005-06-10 17:51:33 +00:00
Wayne Davison
bad1fa4476 Make the sed commands compatible with Solaris (hopefully). 2005-06-10 17:21:52 +00:00
Wayne Davison
8fe27e7631 Starting NEWS for 2.6.6. 2005-06-10 17:17:38 +00:00
Wayne Davison
a1c75ed05c Aged news from NEWS file. 2005-06-10 17:17:24 +00:00
Wayne Davison
e73ad2be54 Got rid of some potentially unhandled permissions differences. 2005-06-10 17:06:43 +00:00
Wayne Davison
59b0e7a82d Changed the "max verbosity" setting from global to per-module. 2005-06-10 16:57:43 +00:00
Wayne Davison
b4fc3987f2 Use the new NOBODY_USER and NOBODY_GROUP configure defines. 2005-06-10 16:50:09 +00:00
Wayne Davison
58418cb0c4 Added a simple check to see if the /etc/group file has the
group "nobody" or "nogroup".
2005-06-10 16:46:50 +00:00
Wayne Davison
5794112ad0 Test that our outputting of itemized messages (as well as
double-verbose output) is happening correctly.
2005-06-09 22:27:59 +00:00
Wayne Davison
f2b6fe44a6 - Fixed the overzealous outputting of unchanged hard-linked items
when verbose > 1.
- An unchanged hard-link with -i (log-format w/%i) now changes the
  trailing dots to spaces.
2005-06-09 22:27:22 +00:00
Wayne Davison
215b444cae Don't set ITEM_REPORT_TIME when a hard-linked file is already
linked up as it should be and --times was not enabled.
2005-06-09 21:57:45 +00:00
Wayne Davison
a45f581b2a - Never output the '"FOO" is a hard link' message when -i (%i)
output is enabled.
- Go back to outputting '"FOO" is a hard link' message when -i (%i)
  is not enabled and verbose > 1.
2005-06-09 21:56:11 +00:00
Wayne Davison
dfdd71ecff Updated version to 2.6.6cvs. 2005-06-09 21:18:26 +00:00
Wayne Davison
2dfe1c37ad Preparing for release of 2.6.5 2005-06-02 03:57:58 +00:00
Wayne Davison
b9949780f4 Improved a few of the items. 2005-06-02 03:54:00 +00:00
Wayne Davison
5fe857d4be One more configure item. 2005-06-01 16:21:41 +00:00
Wayne Davison
3d86c6b18f Mention HAVE_REMSH fix. 2005-05-31 06:09:42 +00:00
Wayne Davison
0f0b2e66b8 Simplified the last change a bit. 2005-05-27 18:15:18 +00:00
Wayne Davison
5d24ee71ad Test for various past problems with --relative. 2005-05-27 18:09:34 +00:00
Wayne Davison
3a05c5d3ce If we unduplicate '.', make sure we also copy FLAG_DEL_HERE (in
addition to FLAG_TOP_DIR), so that the unduplication of a real
dir and an implied dir (implied by --relative) works right.
2005-05-27 18:04:04 +00:00
Wayne Davison
89ec535af5 - Only define HAVE_REMSH if it is going to have a non-0 value.
- Got rid of ssh warning that was added for 2.6.0.
2005-05-27 16:41:19 +00:00
Wayne Davison
e96d7972c4 Improved the opening comment. 2005-05-26 18:00:09 +00:00
Wayne Davison
962a3f0b6e Mention the latest bug-fix. 2005-05-25 15:52:03 +00:00
Wayne Davison
cbb5fa4f07 Handle nested "." dirs (caused by --relative and a trailing slash or
a trailing "/.") in f_name_cmp() when dirname is not an identical
pointer.
2005-05-25 01:24:01 +00:00
Wayne Davison
b57907efb2 Mention the output change for a mount-dir when -x is used. 2005-05-22 20:53:18 +00:00
Wayne Davison
26beb7861f - Don't stop deleting in a dir if one item fails.
- Don't skip deleting in a dir if the initial rmdir fails
  (2.6.4 only continued if it was a non-empty error).
2005-05-22 20:52:32 +00:00
Wayne Davison
6e8b9f1341 Must check FLAG_MOUNT_POINT in delete_in_dir() to avoid starting a
descent into a mounted directory when -x is specified.
2005-05-22 17:19:16 +00:00
Wayne Davison
6efe94167f Improved the SYMBOLIC LINKS section, as suggested by John. 2005-05-20 17:57:31 +00:00
Wayne Davison
51cc96e469 Improved a --files-from example (as suggested by Paul). 2005-05-20 17:39:10 +00:00
Wayne Davison
bdedced84b Tweaked a sentence. 2005-05-19 22:16:50 +00:00
Wayne Davison
f497ad722d Preparing for release of 2.6.5pre2 2005-05-19 21:45:41 +00:00
Wayne Davison
339eb8943e Tweaked the opening comments. 2005-05-19 21:42:20 +00:00
Wayne Davison
c36864e40e Mentioned the improved keep-alive code. 2005-05-19 21:38:25 +00:00
Wayne Davison
af6155bb0e Clarifications related to --dirs. 2005-05-19 21:36:30 +00:00
Wayne Davison
605fed4b46 Periodically call maybe_send_keepalive() when timeouts are in effect
(this ensures that the receiver doesn't timeout when we're still
doing work reading data from the generator).
2005-05-19 08:52:24 +00:00
Wayne Davison
ac40b74788 The global allowed_lull is now already set, so just set lull_mod. 2005-05-19 08:52:22 +00:00
Wayne Davison
3e6ddb3738 - Call the new set_io_timeout() function to set the timeout value.
- If the user specified a shorter timeout than the config-file,
  don't override the shorter value.
2005-05-19 08:52:19 +00:00
Wayne Davison
9ac756c6ea - The variable allowed_lull is now our global.
- Tweaked the --timeout option handling to call set_io_timeout().
2005-05-19 08:52:17 +00:00
Wayne Davison
3b0a30eba8 - Added set_io_timeout(), which sets all the timeout-dependent
variables when the timeout value changes.
- Split last_io into last_io_in and last_io_out.
- Made select_timeout static.
2005-05-19 08:52:13 +00:00
Wayne Davison
bac7259081 The latest bug-fix. 2005-05-19 00:02:29 +00:00
Wayne Davison
4d474ad513 One place that was testing errno for ENOTEMPTY was failing to
also test for EEXIST (which is returned by some OSes).
2005-05-19 00:00:28 +00:00
Wayne Davison
e50e82ab40 Fixed a typo. 2005-05-18 23:59:12 +00:00
Wayne Davison
4922175589 Two more items. 2005-05-17 15:08:05 +00:00
Wayne Davison
a289f89fbe Treat a trailing ".." dir-name as if "../" had been specified so
that we don't use the name in the destination path and save files
into a higher destination directory.
2005-05-14 18:44:57 +00:00
Wayne Davison
ba64001df8 Mention the latest bug fix. 2005-05-13 23:03:00 +00:00
Wayne Davison
b225b089b8 Have do_delete_pass() immediately return if list_only is set. 2005-05-13 23:00:20 +00:00
Wayne Davison
557a35f55b If adding a trailing dot to a directory name overflows
MAXPATHLEN, die with an overflow error.
2005-05-13 22:02:24 +00:00
Wayne Davison
1848fd6fa1 An example filter script to maintain .cvsinclude files. 2005-05-13 18:37:11 +00:00
Wayne Davison
f2a4853c93 Improved the use of the "remaining" var in readfd_unbuffered() to
make certain that the static value is always set correctly anytime
we call out to another function.
2005-05-12 17:36:29 +00:00
Wayne Davison
e65154085c Got rid of some code from writefd_unbuffered() that was only needed
back when the generator had a writeable pipe to the receiver.
2005-05-12 07:45:21 +00:00
Wayne Davison
e4676bb59b Make the --stats output come out after any delete-after messages. 2005-05-12 07:43:14 +00:00
Wayne Davison
3b968014c9 Improved a few sentences. 2005-05-12 07:34:45 +00:00
Wayne Davison
21b9b93377 Fixed a typo. 2005-05-10 18:31:46 +00:00
Wayne Davison
c4d1b2983d Preparing for release of 2.6.5pre1 2005-05-10 17:28:34 +00:00
Wayne Davison
7d7a34aeb2 Added more missing NEWS items. 2005-05-10 17:27:39 +00:00
Wayne Davison
65c84700fc Mention two more changes. 2005-05-10 16:55:22 +00:00
Wayne Davison
5a727522f0 Refer to the rsync daemon as a "daemon", not a "server". This is
to avoid confusion with the server that rsync runs in a normal
remote-shell transfer.
2005-05-10 16:14:26 +00:00
Wayne Davison
1599754727 - Improved the GENERAL section.
- Improved the description of --list-only.
- Added a VERSION section, like the rsyncd.conf manpage.
2005-05-10 16:04:02 +00:00
Wayne Davison
d90338cec6 Refer to the rsync daemon as a "daemon", not a "server". This is
to avoid confusion with the server that rsync runs in a normal
remote-shell transfer.
2005-05-10 16:00:24 +00:00
Wayne Davison
d0e94abb40 Fixed one synopsis line to make the DEST arg optional. 2005-05-09 15:39:24 +00:00
Wayne Davison
d8c4d6de10 Use new MAX_SERVER_ARGS define instead of hard-wired "100". 2005-05-03 17:04:26 +00:00
Wayne Davison
74ba98a51b There was no reason to have MAX_BASIS_DIRS factored into the
length of the argstr[] array.
2005-05-03 17:01:59 +00:00
Wayne Davison
c296031d9f Added MAX_SERVER_ARGS. 2005-05-03 17:00:47 +00:00
Wayne Davison
81c453b16a A few minor doc tweaks. 2005-05-03 16:47:03 +00:00
Wayne Davison
4a34c6f176 - Moved the --version option in the help text.
- Tweaked the --log-format option's description.
- Added a comment.
2005-05-03 16:46:49 +00:00
Wayne Davison
9b3150bd2e Mention the change in error message and exit status when we pull an
empty file list.
2005-05-03 16:45:40 +00:00
Wayne Davison
6f2245c8fa Tweaked the checking of the "limit" in safe_fname(). 2005-05-03 16:44:47 +00:00
Wayne Davison
0f9941dc5a Fixed a typo. 2005-05-03 16:03:31 +00:00
Wayne Davison
060f31500b - Improved the comments on the backslash-escaped output, and moved it
to the top in an "OUTPUT CHANGES" section.
- Added a mention of the generator's new output-flushing optimization.
2005-05-03 15:59:24 +00:00
Wayne Davison
7c2a83c635 Improved a sentence. 2005-05-03 15:58:06 +00:00
Wayne Davison
97e3c50cd9 Mention the '?'-in-filenames change. 2005-05-02 18:04:32 +00:00
Wayne Davison
b2360dabf6 Fixed some misspellings. 2005-05-02 17:27:20 +00:00
Wayne Davison
723160280f Tweaked the description of --from0. 2005-05-02 17:23:08 +00:00
Wayne Davison
fa92818af3 Tweaked the doc for --from0. 2005-05-02 17:22:42 +00:00
Wayne Davison
289a32167c Moved the max-size checking code down so that it only checks
regular files.
2005-04-28 16:26:23 +00:00
Wayne Davison
95e107db96 Moved the size-parsing code for --max-size into its own function. 2005-04-28 16:11:32 +00:00
Wayne Davison
513fd04d21 Set ignore_timeout before starting the transfer, regardless of
what protocol level is in effect.  This guards against the
generator timing out when the output pipe is full and the input
pipe (to the receiver) is slow.
2005-04-27 22:58:06 +00:00
Wayne Davison
7a16e12207 If the user specified --relative and a source dir with a trailing
slash, make sure we strip of the trailing "/." from the dir's len
(in del_hier_name_len) so that its subdirs get marked with
FLAG_DEL_HERE.
2005-04-27 22:56:47 +00:00
Wayne Davison
de8252f67f Added a new test to check how we interact with --link-dest and
--copy-dest.
2005-04-26 16:25:01 +00:00
Wayne Davison
98e4741463 A slightly better fix than the last one (though it won't make any
difference in how the code behaves due to how it is called).
2005-04-26 16:09:03 +00:00
Wayne Davison
028245a57b Mention newest fix. 2005-04-26 15:25:43 +00:00
Wayne Davison
2765f2e4a7 Fixed problem with -C when we're the sender, the remote is using an
older protocol, and we're not sending the exclude list (i.e. the
user didn't specify --delete or they specified --delete-ignored).
2005-04-26 15:24:40 +00:00
Wayne Davison
79db59d1a7 Try to make rsync's behavior w/o "--perms" a little clearer. 2005-04-25 19:30:29 +00:00
Wayne Davison
c48cff9fbe Fixed two typos. 2005-04-25 19:23:43 +00:00
Wayne Davison
f4b8e829e9 Mention fix for --one-file-system. 2005-04-24 22:35:03 +00:00
Wayne Davison
468d766819 Simplified the last change a little using a fix derived from
Mike Castle's suggestion.
2005-04-24 22:34:20 +00:00
Wayne Davison
f3ab64d3a8 When deleting files, we need to take any local FLAG_MOUNT_POINT
flag-bit and put it into the regular flist's flags for that dir,
and delete_in_dir() now refuses to delete a directory that has
that bit set.
2005-04-24 22:11:26 +00:00
Wayne Davison
a234bca4ef Reject any --remove-* options when read-only, just in case there
are new ones added in the future.
2005-04-24 16:19:16 +00:00
Wayne Davison
42e9c7eb56 Mention the latest fixes. 2005-04-24 00:34:39 +00:00
Wayne Davison
9d19f8a5fe When rsync encountered an empty file list, it behaved differently
when pulling files than when pushing files:  pulling it output a
(mostly) unhelpful error message and then exited with a 0 status,
even when the remote side exited with an error code.  I changed this
to output the normal end summary (when verbose) and to exit with the
status intact (just like when pushing files).
2005-04-23 22:30:08 +00:00
Wayne Davison
24e61cffe3 For those rare individuals without web access, mention how to
send bug reports via email.
2005-04-23 22:17:10 +00:00
Wayne Davison
3556fe5d86 Fixed a problem where a --link-dest hard-link could cause us to
miss out on the hard_link_cluster() call.
2005-04-23 19:46:22 +00:00
Wayne Davison
ee887d98f6 Two more tests:
- Update the hard-linked cluster and copy over the old versions.
- Add a new hard-linked item down in a new subdir to make sure that
  the new file doesn't get handled before the subdir gets created.
2005-04-23 18:20:47 +00:00
Wayne Davison
5c7b1feb4c Added --no-whole-file option to one of the runs. 2005-04-23 18:17:25 +00:00
Wayne Davison
3cd5301f40 - Added a new function, maybe_hard_link(), which now holds the code
(moved from hard_link_cluster()) that checks the inode/dev of an
  existing file and either does nothing (when properly linked), or
  removes the existing file before calling hard_link_one().
- Changed hard_link_check() so that it checks if the master item is
  marked with FINISHED_LINK (in its hlindex int), and if so, it
  finishes the current file by calling maybe_hard_link() (and
  marking it as finished too).  Otherwise it marks the item as
  skipped by setting hlindex to SKIPPED_LINK.
- Fixed the outputting of an error in hard_link_one() so that the
  message is always output when the caller did not request "terse"
  processing.
- Changed hard_link_cluster() so that it marks the master item with
  FINISHED_LINK and then links only the skipped items (marking them
  with FINISHED_LINK too).
2005-04-23 17:48:34 +00:00
Wayne Davison
d8169e6f6b - Call hard_link_check() with its new args.
- Got rid of a duplicate error after the hard_link_one() call.
2005-04-23 17:48:31 +00:00
Wayne Davison
c4833b024e Mention how a module reference doesn't need a trailing slash
to copy its contents.
2005-04-22 17:17:18 +00:00
Wayne Davison
2a5d5a8cc4 If we're outputting a message about the remote file in a
single-file transfer, we need to make sure that the file's
name is the generic-transfer name and not a local name.
2005-04-22 16:45:33 +00:00
Wayne Davison
f7112154e9 Moved "port" and "address" into the global section where they
belong.
2005-04-22 15:19:10 +00:00
Wayne Davison
f83051b2e3 Updated FSF's address and some minor non-license tweaks taken
from the latest GPL file on the web.
2005-04-17 08:25:50 +00:00
Wayne Davison
2e42adb302 Simplified the newly added test so that it should stop sporadically
failing.
2005-04-16 07:34:49 +00:00
Wayne Davison
c09ebb8c04 Call rsync via $RSYNC. 2005-04-15 17:39:35 +00:00
Wayne Davison
042dc7360e Make sure that the $chkdir has the same mtime/etc. as the
$fromdir.
2005-04-15 17:26:27 +00:00
Wayne Davison
7a6e294f7b Added a test that copies a single file with -H specified. 2005-04-15 08:28:02 +00:00
Wayne Davison
97e786c331 - Fixed a potential crash/infinite-loop bug if -H was used
when sending a single file.
- Made a couple variable improvements in link_idev_data().
- Got rid of the non-NULL check of hlink_list in init_hard_links()
  because is enough to just check file->link_u.links these days.
2005-04-15 08:26:58 +00:00
Wayne Davison
8ee6adefe3 Call logfile_close() and logfile_reopen() (tweaked function names). 2005-04-14 16:08:12 +00:00
Wayne Davison
64c37826e4 - Changed log_open() into two functions, logfile_open() and
logfile_reopen().
- Changed log_close() into logfile_close().
- Improved the logic in logit().
2005-04-14 16:08:10 +00:00
Wayne Davison
2e8015e0da Mention that less data is sent over the wire when --only-write-batch
is used and we're pushing files to a remote system.
2005-04-14 01:47:47 +00:00
Wayne Davison
5b6281afcf Got rid of ITEM_DUMMY_BIT. 2005-04-14 01:46:08 +00:00
Wayne Davison
e732fb0c4f - Got rid of the iflag kluge for 2.6.4pre3.
- When we're handling --only-write-batch on the client side, we now
  send all index/header info to the receiver (not just to the batch
  file, like we do with the xfer data) so that the connection cannot
  timeout.
2005-04-14 01:45:47 +00:00
Wayne Davison
b10917a426 Support the reception of a file-transfer header without xfer data
when we're on the server side and --only-write-batch was specified.
2005-04-14 01:42:13 +00:00
Wayne Davison
7ae64260e0 Mention how the daemon handles a failure to open a user-specified
"log file".
2005-04-12 23:09:35 +00:00
Wayne Davison
f97f6bcd3a Mention how we now handle a log-file that the daemon can't open. 2005-04-12 23:06:45 +00:00
Wayne Davison
e86d98cbaa Got rid of RERR_LOG_FAILURE. 2005-04-12 23:04:10 +00:00
Wayne Davison
6afb90778b If we can't open the daemon's log file, fall-back to using
syslog (rather than trying to output an error on stderr,
which would usually be lost, and then exiting).
2005-04-12 23:03:49 +00:00
Wayne Davison
32c7f91a14 A couple improvements for the --only-write-batch section. 2005-04-12 03:55:56 +00:00
Wayne Davison
b28a27e9e9 Mention the latest bug-fix. 2005-04-10 20:08:00 +00:00
Wayne Davison
15164c0aa9 Paul's patch to improve the "not creating new ..." message
for directories.
2005-04-10 19:44:16 +00:00
Wayne Davison
bf011fedfc Made the code a little cleaner by having gen_challenge() return
the challenge string base64-encoded (instead of forcing the caller
to handle this).  Also improved a couple comments.
2005-04-10 17:09:10 +00:00
Wayne Davison
d7d11b7ebd Mention fix for SUPPORT{,_HARD}_LINKS defines. 2005-04-10 07:17:47 +00:00
Wayne Davison
9a929c8f68 - Don't define HAVE_READLINK unless HAVE_READLINK is defined.
- Don't define SUPPORT_HARD_LINKS unless HAVE_LINK is defined.
2005-04-10 06:24:14 +00:00
Wayne Davison
298d8c0a9b Mention the new --only-write-batch=FILE option. 2005-04-09 18:59:59 +00:00
Wayne Davison
a054570942 - Use the new do_xfers variable in place of some dry_run checks
(with appropriate negation).
- If write_batch is < 0, we write out the file-transfer data to
  just the batch file, not the socket.
2005-04-09 18:59:57 +00:00
Wayne Davison
a0009fc30d - Use the new do_xfers variable in place of some dry_run checks
(with appropriate negation).
- If we get a transfer when write_batch is < 0, discard it.
2005-04-09 18:59:55 +00:00
Wayne Davison
beb51aa09e Use the new do_xfers variable in place of some dry_run checks
(with appropriate negation).
2005-04-09 18:59:52 +00:00
Wayne Davison
e8a96e275e - Only do read-/write-batch processing if we're not the server (needed
now that write_batch is no longer forced to 0 for the server).
- If write_batch is < 0, force "dry_run = 1" (but only after we've
  finished any appropriate write-batch file creation).
2005-04-09 18:59:49 +00:00
Wayne Davison
11e758a430 - Added do_xfers variable.
- Handle the new --only-write-batch=FILE option.
2005-04-09 18:59:47 +00:00
Wayne Davison
d630f53e0d Also change --only-write-batch to --read-batch (in addition to
changing --write-batch).
2005-04-09 18:59:44 +00:00
Wayne Davison
5918daf8a4 We no longer force write_batch to 0 for the server. 2005-04-09 18:59:42 +00:00
Wayne Davison
326bb56e40 Document the new --only-write-batch=FILE option. 2005-04-09 18:59:40 +00:00
Wayne Davison
f96154f44c Mention the latest changes. 2005-04-09 18:15:22 +00:00
Wayne Davison
45c5b903eb - Call auth_server() with its new "host" arg.
- Don't log an auth-failed error -- auth_server() now handles that.
2005-04-09 18:11:25 +00:00
Wayne Davison
5037cf3adf - Use the MD4_SUM_LENGTH define in place of some hard-wired values.
- Pass the hostname in to auth_server().
- Generate a unique error for each failure type in auth_server() so
  that the log-file contains why the authorization failed.
- Don't use sscanf() to parse the client's auth-challenge response.
2005-04-09 18:11:23 +00:00
Wayne Davison
180443af42 The "@ERROR" handler in start_inband_exchange() was not returning
the right value.
2005-04-09 16:49:51 +00:00
Wayne Davison
4f3f97fbde Fixed one typo and improved another sentence. 2005-04-08 01:40:57 +00:00
Wayne Davison
664cf3278a Make sure that "- !" or "+ !" aren't interpreted as a list-clearing
token.
2005-04-07 18:06:06 +00:00
Wayne Davison
cd36049cd1 Combine one of the backup tests with --delete-after. 2005-04-07 09:09:17 +00:00
Wayne Davison
c2523a0541 Don't call maybe_flush_socket() quite so often. 2005-04-07 08:32:32 +00:00
Wayne Davison
92739a0aa7 Mention the latest changes. 2005-04-07 08:28:06 +00:00
Wayne Davison
cd908ef4ff Fix a bug with --delete-after combined with --backup. 2005-04-07 08:13:44 +00:00
Wayne Davison
ebd33e0cea Use the new HAVE_LSEEK64 define. 2005-04-06 02:08:21 +00:00
Wayne Davison
5f2c5bf110 Added skipping of mkstemp() on HP-UX. 2005-04-06 02:07:21 +00:00
Wayne Davison
417099fa20 Periodically call maybe_flush_socket(). 2005-04-05 20:08:51 +00:00
Wayne Davison
626bec8e84 - Added maybe_flush_socket() for use by the generator.
- Always maintain the last_io value for the generator.
2005-04-05 20:07:42 +00:00
Wayne Davison
a06e2b7cab When doing a delete pass with do_progress output, get rid of the
temporary output (it used to always be covered up by output in
older versions, but it might be followed by a newline in newer
versions).
2005-04-05 19:51:13 +00:00
Wayne Davison
3ae5367ff2 Document the use of --address in client mode. 2005-04-05 06:00:17 +00:00
Wayne Davison
b4ef0bca47 Allows --address to be used in client mode. 2005-04-05 05:59:49 +00:00
Wayne Davison
4313d6f9c0 Changed the bind_address local variables to be named bind_addr
in order to avoid confusion with the bind_address global.
2005-04-05 05:52:49 +00:00
Wayne Davison
2a0dd9bd70 Make sure that the line buffer in readfd_unbuffered() is large
enough to handle long-filename messages on a system that has a
really short MAXPATHLEN value.  Also, make it large enough to
be able to comment on a MAXPATHLEN filename.
2005-04-04 17:27:56 +00:00
Wayne Davison
3eeac9bc7e In writefd_unbuffered(), make sure that we don't look at the r_fds
variable when we're ignoring msg_fd_in.
2005-04-04 00:48:39 +00:00
Wayne Davison
67de72bd9b Mention fix for --compare-dest. 2005-04-01 18:18:17 +00:00
Wayne Davison
552a218468 Make a local-copy caused by a not-quite-up-to-date --compare-dest
or --link-dest file be output as a 'c' (local change) when itemizing
or as transfered file when not itemizing.
2005-04-01 18:12:22 +00:00
Wayne Davison
d940151496 - Conditionally include <locale.h>.
- Conditionally call setlocale(LC_CTYPE, "").
2005-04-01 17:25:37 +00:00
Wayne Davison
f5c7f4abe7 - Changed version to 2.6.5cvs.
- Look for setlocale(), locale.h, and honor --disable-locale.
2005-04-01 17:25:34 +00:00
Wayne Davison
3ae6c1875d Starting the 2.6.5 news. 2005-04-01 17:25:28 +00:00
Wayne Davison
1ad6a7f611 Moved the 2.6.4 news here. 2005-04-01 17:25:26 +00:00
Wayne Davison
89d26123ff Changed safe_fname() to output \### (octal) to escape non-printable
characters (not ?) and \\ to escape \ itself.
2005-04-01 16:48:54 +00:00
Wayne Davison
46bffd98cb Fix the setting of module_dirlen for a module path of "/".
This fixes a crash in the exclude code when chroot is off.
2005-04-01 00:18:40 +00:00
Wayne Davison
41b84ce012 Don't try to tweak read-only dest-dir permissions in list-only mode. 2005-03-31 23:30:03 +00:00
Wayne Davison
de392f1e5c Preparing for release of 2.6.4 2005-03-31 03:14:34 +00:00
Wayne Davison
0455cd933d - Made the handling of adjacent percents (e.g. "%%b") work like it
did in older versions.
- Added a comment for log_format_has().
2005-03-31 03:01:26 +00:00
Wayne Davison
d9c0051fae In log_formatted(), add the newline to the format string so
that we can call rwrite() instead of rprintf().
2005-03-31 01:09:18 +00:00
Wayne Davison
126e7affb7 Enabled width-sizing for %L. 2005-03-31 00:50:58 +00:00
Wayne Davison
624d6be2a5 Use new log_format_has() function instead of strstr(). 2005-03-31 00:21:15 +00:00
Wayne Davison
16f960feb5 Added log_format_has(). 2005-03-31 00:19:13 +00:00
Wayne Davison
e145d51ba6 Make sure that we can't scan past the end of the format string. 2005-03-30 23:39:00 +00:00
Wayne Davison
dcbae65444 Optimized '%f' a little more. 2005-03-30 20:41:11 +00:00
Wayne Davison
b4bf2b5a7e Allow %i to have a field width. 2005-03-30 20:18:48 +00:00
Wayne Davison
9baed7609c - Allow the infix field width to start with a '-'.
- Apply the field width to all escapes, not just numeric ones.
2005-03-30 19:44:29 +00:00
Wayne Davison
1c2efa1706 Mention the numeric field width now possible in the % escapes. 2005-03-30 19:41:51 +00:00
Wayne Davison
80a24d52d4 Mention that the % escapes can now have a numeric infix. 2005-03-30 19:39:11 +00:00
Wayne Davison
af9f56a09d dropped the "const" from the return value of safe_fname() because
some callers would like to manipulate the string in the buffer.
2005-03-30 19:34:20 +00:00
Wayne Davison
ddd74b67be Allow the escapes in the log-format string to contain a numeric
field width (e.g. %8l %07p).
2005-03-30 18:27:09 +00:00
Wayne Davison
7b558d7f8b Fixed a comment. 2005-03-30 17:31:35 +00:00
Wayne Davison
c87ae64a82 Moved a call to output_summary() up a line. 2005-03-30 16:55:11 +00:00
Wayne Davison
b9f0ca7274 Tweaked a couple sentences. 2005-03-30 16:51:33 +00:00
Wayne Davison
c1759b9fa2 Changed %i to output '>' for a local copy. 2005-03-30 16:35:01 +00:00
Wayne Davison
9c63d83d3d Got rid of a useless extern. 2005-03-30 16:33:41 +00:00
Wayne Davison
1ed91a04fe - Fixed a potential crash if the receiver couldn't open the basis file
and the sender (possibly via a batch) tells us to use basis data.
- Enhanced the batched-update skipping message to indicate what phase
  is being skipped.
2005-03-29 22:05:33 +00:00
Wayne Davison
154cdaaa40 - Warn about missing batched updates the generator wants but the
batch doesn't have.
- Tweaked the "skipping ..." message that is output for already-
  applied batched updates.
2005-03-29 19:49:40 +00:00
Wayne Davison
33c4b445ef Split report() into handle_stats() and output_report() so that (1)
the report happens after all --delete-after activity has ceased when
pulling, and (2) a batch-file created when pushing gets the stats
values written out prior to any end-of-run keep-alive packets.
2005-03-29 11:11:35 +00:00
Wayne Davison
53135fe89a Changed maybe_emit_filelist_progress() and emit_filelist_progress()
to take an integer count instead of a struct file_list so that we
can pass in a file-list-count offset for delete's separate calls
to send_directory().
2005-03-29 10:57:31 +00:00
Wayne Davison
083acd496d Turn off do_progress during the file-update phase so that
--delete-during and --fuzzy don't get any superfluous
" N files..." lines output in the middle of the processing.
2005-03-29 10:41:26 +00:00
124 changed files with 12767 additions and 6289 deletions

11
COPYING
View File

@@ -2,7 +2,7 @@
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -279,7 +279,7 @@ POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
Copyright (C) <year> <name of author>
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
@@ -305,14 +305,15 @@ the "copyright" line and a pointer to where the full notice is found.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.

23
INSTALL
View File

@@ -1,4 +1,4 @@
To build and install rsync
To build and install rsync:
$ ./configure
$ make
@@ -9,8 +9,15 @@ 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 release 1.5 is included in the rsync distribution,
cut-down copy of release 1.6.4 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.
@@ -18,7 +25,6 @@ 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.
RPM NOTES
---------
@@ -37,16 +43,15 @@ fails:
Install gcc or HP's "ANSI/C Compiler".
MAC OSX NOTES
-------------
Mac OS X (Darwin) seems to have an IPv6 stack, but it does not
completely implement the "New Sockets" API.
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 do not support
IPv6 yet. If your build fails, try again with --disable-ipv6.
<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
-------------

View File

@@ -28,13 +28,12 @@ VERSION=@VERSION@
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h lib/pool_alloc.h
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
lib/permstring.o lib/pool_alloc.o @LIBOBJS@
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
zlib/zutil.o zlib/adler32.o
ZLIBOBJ=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=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
main.o checksum.o match.o syscall.o log.o backup.o
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
fileio.o batch.o clientname.o
fileio.o batch.o clientname.o chmod.o
OBJS3=progress.o pipe.o
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 \
@@ -91,29 +90,14 @@ T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o t_stub.o lib/compat.o lib/snprintf.o
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
gen: $(srcdir)/configure $(srcdir)/config.h.in proto man
gen:
$(MAKE) -C $(srcdir) -f prepare-source.mak gen
man: $(srcdir)/rsync.1 $(srcdir)/rsyncd.conf.5
$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
cd $(srcdir); autoconf
$(srcdir)/config.h.in: $(srcdir)/configure.in $(srcdir)/aclocal.m4
cd $(srcdir); autoheader
$(srcdir)/rsync.1: $(srcdir)/rsync.yo
yodl2man -o $(srcdir)/rsync.1 $(srcdir)/rsync.yo
$(srcdir)/rsyncd.conf.5: $(srcdir)/rsyncd.conf.yo
yodl2man -o $(srcdir)/rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
man:
$(MAKE) -C $(srcdir) -f prepare-source.mak man
proto:
cat $(srcdir)/*.c $(srcdir)/lib/compat.c | awk -f $(srcdir)/mkproto.awk >$(srcdir)/proto.h.new
if diff $(srcdir)/proto.h $(srcdir)/proto.h.new >/dev/null; then \
rm $(srcdir)/proto.h.new; \
else \
mv $(srcdir)/proto.h.new $(srcdir)/proto.h; \
fi
$(MAKE) -C $(srcdir) -f prepare-source.mak proto.h
clean: cleantests
rm -f *~ $(OBJS) $(TLS_OBJ) $(CHECK_PROGS) $(CHECK_OBJS)
@@ -161,8 +145,8 @@ check: all $(CHECK_PROGS)
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin=`pwd`/rsync$(EXEEXT) srcdir="$(srcdir)" $(srcdir)/runtests.sh
wildtest.o: wildtest.c lib/wildmatch.c rsync.h
wildtest$(EXEEXT): wildtest.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o @BUILD_POPT@ $(LIBS)
wildtest$(EXEEXT): wildtest.o lib/compat.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o @BUILD_POPT@ $(LIBS)
# This does *not* depend on building or installing: you can use it to
# check a version installed from a binary or some other source tree,

533
NEWS
View File

@@ -1,381 +1,320 @@
NEWS for rsync 2.6.4 (30 March 2005)
Protocol: 29 (changed)
Changes since 2.6.3:
NEWS for rsync 2.6.7 (11 Mar 2006)
Protocol: 29 (unchanged)
Changes since 2.6.6:
OUTPUT CHANGES:
- When rsync deletes a directory and outputs a verbose message about
it, it now appends a trailing slash to the name instead of (only
sometimes) outputting a preceding "directory " string.
- The letter 'D' in the itemized output was being used for both devices
(character or block) as well as other special files (such as fifos and
named sockets). This has changed to separate non-device special files
under the 'S' designation (e.g. "cS+++++++ path/fifo"). See also the
"--specials" option, below.
- The --stats output will contain file-list time-statistics if both
sides are 2.6.4, or if the local side is 2.6.4 and the files are
being pushed (since the stats come from the sending side).
(Requires protocol 29 for a pull.)
- The way rsync escapes unreadable characters has changed. First, rsync
now has support for recognizing valid multibyte character sequences in
your current locale, allowing it to escape fewer characters than before
for a locale such as UTF-8. Second, it now uses an escape idiom of
"\#123", which is the literal string "\#" followed by exactly 3 octal
digits. Rsync no longer doubles a backslash character in a filename
(e.g. it used to output "foo\\bar" when copying "foo\bar") -- now it only
escapes a backslash that is followed by a hash-sign and 3 digits (0-9)
(e.g. it will output "foo\#134#789" when copying "foo\#789"). See also
the --8-bit-output (-8) option, mentioned below.
- The "%o" (operation) log-format escape now has a third value (besides
"send" and "recv"): "del." (with trailing dot to make it 4 chars).
This changes the way deletions are logged in the daemon's log file.
Script writers: the local rsync is the one that outputs escaped names,
so if you need to support unescaping of filenames for older rsyncs, I'd
suggest that you parse the output of "rsync --version" and only use the
old unescaping rules for 2.6.5 and 2.6.6.
- When the --log-format option is combined with --verbose, rsync now
avoids outputting the name of the file twice in most circumstances.
As long as the --log-format item does not refer to any post-transfer
items (such as %b or %c), the --log-format message is output prior to
the transfer, so --verbose is now the equivalent of a --log-format of
'%n%L' (which outputs the name and any link info). If the log output
must occur after the transfer to be complete, the only time the name
is also output prior to the transfer is when --progress was specified
(so that the name will precede the progress stats, and the full
--log-format output will come after).
BUG FIXES:
- Restore the list-clearing behavior of "!" in a .cvsignore file (2.6.3
was only treating it as a special token in an rsync include/exclude
file).
- Fixed a really old bug that caused --checksum (-c) to checksum all the
files encountered during the delete scan (ouch).
- The combination of --verbose and --dry-run now mentions the full list
of changes that would be output without --dry-run.
- Fixed a potential hang in a remote generator: when the receiver gets a
read-error on the socket, it now signals the generator about this so that
the generator does not try to send any of the terminating error messages
to the client (avoiding a potential hang in some setups).
- Avoid a mkdir warning when removing a directory in the destination
that already exists in the --backup-dir.
- Made hard-links work with symlinks and devices again.
- An OS that has a binary mode for its files (such as cygwin) needed
setmode(fd, O_BINARY) called on the temp-file we opened with
mkstemp(). (Fix derived from the cygwin's 2.6.3 rsync package.)
- If the sender gets an early EOF reading a source file, we propagate this
error to the receiver so that it can discard the file and try requesting
it again (which is the existing behavior for other kinds of read errors).
- Fixed a potential hang when verbosity is high, the client side is
the sender, and the file-list is large.
- If a device-file/special-file changes permissions, rsync now updates the
permissions without recreating the file.
- Fixed a potential protocol-corrupting bug where the generator could
merge a message from the receiver into the middle of a multiplexed
packet of data if only part of that data had been written out to the
socket when the message from the generator arrived.
- If the user specifies a remote-host for both the source and destination,
we now output a syntax error rather than trying to open the destination
hostspec as a filename.
- We now check if the OS doesn't support using mknod() for creating
FIFOs and sockets, and compile-in some compatibility code using
mkfifo() and socket() when necessary.
- When --inplace creates a new destination file, rsync now creates it with
permissions 0600 instead of 0000 -- this makes restarting possible when
the transfer gets interrupted in the middle of sending a new file.
- Fixed an off-by-one error in the handling of --max-delete=N. Also,
if the --max-delete limit is exceeded during a run, we now output a
warning about this at the end of the run and exit with a new error
code (25).
- Reject the combination of --inplace and --sparse since the sparse-output
algorithm doesn't work when overwriting existing data.
- One place in the code wasn't checking if fork() failed.
- Fixed the directory name in the error that is output when pop_dir()
fails.
- The "ignore nonreadable" daemon parameter used to erroneously affect
readable symlinks that pointed to a non-existent file.
- Really fixed the parsing of a "!" entry in .cvsignore files this time.
- If the OS does not have lchown() and a chown() of a symlink will
affect the referent of a symlink (as it should), we no longer try
to set the user and group of a symlink.
- If the generator gets a stat() error on a file, output it (this used to
require at least -vv for the error to be seen).
- The generator now properly runs the hard-link loop and the dir-time
rewriting loop after we're sure that the redo phase is complete.
- If waitpid() fails or the child rsync didn't exit cleanly, we now handle
the exit status properly and generate a better error.
- When --backup was specified with --partial-dir=DIR, where DIR is a
relative path, the backup code was erroneously trying to backup a
file that was put into the partial-dir.
- Fixed some glitches in the double-verbose output when using --copy-dest,
--link-dest, or --compare-dest. Also improved how the verbose output
handles hard-links (within the transfer) that had an up-to-date alternate
"dest" file, and copied files (via --copy-dest).
- If a file gets resent in a single transfer and the --backup option is
enabled along with --inplace, rsync no longer performs a duplicate
backup (it used to overwrite the first backup with the failed file).
- Fixed the matching of the dont-compress items (e.g. *.gz) against files
that have a path component containing a slash.
- One call to flush_write_file() was not being checked for an error.
- If code reading a filter/exclude file an EINTR error, rsync now clears
the error flag on the file handle so it can keep on reading.
- The --no-relative option was not being sent from the client to a
server sender.
- If --relative is active, the sending side cleans up trailing "/" or "/."
suffixes to avoid triggering a bug in older rsync versions. Also, we now
reject a ".." dir if it would be sent as a relative dir.
- If an rsync daemon specified "dont compress = ..." for a file and the
client tried to specify --compress, the libz code was not handling a
compression level of 0 properly. This could cause a transfer failure
if the block-size for a file was large enough (e.g. rsync might have
exited with an error for large files).
- If a non-directory is in the way of a directory and rsync is run with
--dry-run and --delete, rsync no longer complains about not being able
to opendir() the not-yet present directory.
- Fixed a bug that would sometimes surface when using --compress and
sending a file with a block-size larger than 64K (either manually
specified, or computed due to the file being really large). Prior
versions of rsync would sometimes fail to decompress the data
properly, and thus the transferred file would fail its verification.
- When --list-only is used and a non-existent local destination dir was
also specified as a destination, rsync no longer generates a warning
about being unable to create the missing directory.
- If a daemon can't open the specified log file (i.e. syslog is not
being used), die without crashing. We also output an error about
the failure on stderr (which will only be seen if --no-detach was
specified) and exit with a new error code (6).
- Fixed some problems with --relative --no-implied-dirs when the
destination directory did not yet exist: we can now create a symlink or
device when it is the first thing in the missing dir, and --fuzzy no
longer complains about being unable to open the missing dir.
- A local transfer no longer duplicates all its include/exclude options
(since the forked process already has a copy of the exclude list,
there's no need to send them a set of duplicates).
- Fixed a bug where the --copy-links option would not affect implied
directories without --copy-unsafe-links (see --relative).
- When --progress is specified, the output of items that the generator
is creating (e.g. dirs, symlinks) is now integrated into the progress
output without overlapping it. (Requires protocol 29.)
- Got rid of the need for --force to be used in some circumstances with
--delete-after (making it consistent with --delete-before/-during).
- When --timeout is specified, lulls that occur in the transfer while
the generator is doing work that does not generate socket traffic
(looking for changed files, deleting files, doing directory-time
touch-ups, etc.) will cause a new keep-alive packet to be sent that
should keep the transfer going as long as the generator continues to
make progress. (Requires protocol 29.)
- Rsync now ignores the SIGXFSZ signal, just in case your OS sends this
when a file is too large (rsync handles the write error).
- The stat size of a device is not added to the total file size of the
items in the transfer (the size might be undefined on some OSes).
- Fixed a bug in the Proxy-Authorization header's base64-encoded value: it
was not properly padded with trailing '=' chars. This only affects a
user that need to use a password-authenticated proxy for an outgoing
daemon-rsync connection.
- Fixed a problem with refused-option messages sometimes not making it
back to the client side when a remote --files-from was in effect and
the daemon was the receiver.
- If we're transferring an empty directory to a new name, rsync no longer
forces S_IWUSR if it wasn't already set, nor does it accidentally leave
it set.
- The --compare-dest option was not updating a file that differred in
(the preserved) attributes from the version in the compare-dest DIR.
- Fixed a bug in the debug output (-vvvvv) that could mention the wrong
checksum for the current file offset.
- When rsync is copying files into a write-protected directory, fixed
the change-report output for the directory so that we don't report
an identical directory as changed.
- Rsync no longer allows a single directory to be copied over a non-
directory destination arg.
ENHANCEMENTS:
- Rsync now supports popt's option aliases, which means that you can
use /etc/popt and/or ~/.popt to create your own option aliases.
- Added the --append option that makes rsync append data onto files that
are longer on the source than the destination (this includes new files).
- Added the --delete-during (--del) option which will delete files
from the receiving side incrementally as each directory in the
transfer is being processed. This makes it more efficient than the
default, before-the-transfer behavior, which is now also available as
--delete-before (and is still the default --delete-WHEN option that
will be chosen if --delete or --delete-excluded is specified without
a --delete-WHEN choice). All the --del* options infer --delete, so
an rsync daemon that refuses "delete" will still refuse to allow any
file-deleting options (including the new --remove-sent-files option).
- Added the --min-size=SIZE option to exclude small files from the
transfer.
- All the --delete-WHEN options are now more memory efficient:
Previously an duplicate set of file-list objects was created on the
receiving side for the entire destination hierarchy. The new
algorithm only creates one directory of objects at a time (for files
inside the transfer).
- Added the --compress-level option to allow you to set how aggressive
rsync's compression should be (this option implies --compress).
- Added the --copy-dest option, which works like --link-dest except
that it locally copies identical files instead of hard-linking them.
- Enhanced the parsing of the SIZE value for --min-size and --max-size to
allow easy entry of multiples of 1000 (instead of just multiples of 1024)
and off-by-one values too (e.g. --max-size=8mb-1).
- Added support for specifying multiple --compare-dest, --copy-dest, or
--link-dest options, but only of a single type. (Promoted from the
patches dir and enhanced.) (Requires protocol 29.)
- Added the --8-bit-output (-8) option, which tells rsync to avoid escaping
high-bit characters that it thinks are unreadable in the current locale.
- Added the --max-size option. (Promoted from the patches dir.)
- The new option --human-readable (-h) changes the output of --progress,
--stats, and the end-of-run summary to be easier to read. If repeated,
the units become powers of 1024 instead of powers of 1000. (The old
meaning of -h, as a shorthand for --help, still works as long as you
just use it on its own, as in "rsync -h".)
- The daemon-mode options are now separated from the normal rsync
options so that they can't be mixed together. This makes it
impossible to start a daemon that has improper default option values
(which could cause problems when a client connects, such as hanging
or crashing).
- If lutimes() and/or lchmod() are around, use them to allow the
preservation of attributes on symlinks.
- The --bwlimit option may now be used in combination with --daemon
to specify both a default value for the daemon side and a value
that cannot be exceeded by a user-specified --bwlimit option.
- The --link-dest option now affects symlinks and devices (when possible).
- Added the "port" parameter to the rsyncd.conf file. (Promoted from
the patches dir.) Also added "address". The command-line options
take precedence over a config-file option, as expected.
- Added two config items to the rsyncd.conf parsing: "pre-xfer exec" and
"post-xfer exec". These allow a command to be specified on a per-module
basis that will be run before and/or after a daemon-mode transfer. (See
the man page for a list of the environment variables that are set with
information about the transfer.)
- In _exit_cleanup(): when we are exiting with a partially-received
file, we now flush any data in the write-cache before closing the
partial file.
- When using the --relative option, you can now insert a dot dir in
the source path to indicate where the replication of the source dirs
should start. For example, if you specify a source path of
rsync://host/module/foo/bar/./baz/dir with -R, rsync will now only
replicate the "baz/dir" part of the source path (note: a trailing
dot dir is unaffected unless it also has a trailing slash).
- The --inplace support was enhanced to work with --compare-dest,
--link-dest, and (the new) --copy-dest options. (Requires protocol
29.)
- Added some new --no-FOO options that make it easier to override unwanted
implied or default options. For example, "-a --no-o" (aka "--archive
--no-owner") can be used to turn off the preservation of file ownership
that is implied by -a.
- Added the --dirs (-d) option for an easier way to copy directories
without recursion.
- Added the --chmod=MODE option that allows the destination permissions to
be changed from the source permissions. E.g. --chmod=g+w,o-rwx
- Added the --list-only option, which is mainly a way for the client to
put the server into listing mode without needing to resort to any
internal option kluges (e.g. the age-old use of "-r --exclude="/*/*"
for a non-recursive listing). This option is used automatically
(behind the scenes) when a modern rsync speaks to a modern daemon,
but may also be specified manually if you want to force the use of
the --list-only option over a remote-shell connection.
- Added the "incoming chmod" and "outgoing chmod" daemon options that allow
a module to specify what permissions changes should be applied to all
files copied to and from the daemon.
- Added the --omit-dir-times (-O) option, which will avoid updating
the modified time for directories when --times was specified. This
option will avoid an extra pass through the file-list at the end of
the transfer (to tweak all the directory times), which may provide
an appreciable speedup for a really large transfer. (Promoted from
the patches dir.)
- Allow the --temp-dir option to be specified when starting a daemon, which
sets the default temporary directory for incoming files.
- Added the --filter (-f) option and its helper option, -F. Filter
rules are an extension to the existing include/exclude handling
that also supports nested filter files as well as per-directory
filter files (like .cvsignore, but with full filter-rule parsing).
This new option was chosen in order to ensure that all existing
include/exclude processing remained 100% compatible with older
versions. Protocol 29 is needed for full filter-rule support, but
backward-compatible rules work with earlier protocol versions.
(Promoted from the patches dir and enhanced.)
- If --delete is combined with --dirs without --recursive, rsync will now
delete in any directory whose content is being synchronized.
- Added the --delay-updates option that puts all updated files into
a temporary directory (by default ".~tmp~", but settable via the
--partial-dir=DIR option) until the end of the transfer. This
makes the updates a little more atomic for a large transfer.
- If --backup is combined with --delete without --backup-dir (and without
--delete-excluded), we add a "protect" filter-rule to ensure that files
with the backup suffix are not deleted.
- If rsync is put into the background, any output from --progress is
reduced.
- The file-count stats that are output by --progress were improved to
better indicate what the numbers mean. For instance, the output:
"(xfer#5, to-check=8383/9999)" indicates that this was the fifth file
to be transferred, and we still need to check 8383 more files out of
a total of 9999.
- Documented the "max verbosity" setting for rsyncd.conf. (This
setting was added a couple releases ago, but left undocumented.)
- The include/exclude code now allows a dir/*** directive (with 3 trailing
stars) to match both the dir itself as well as all the content below the
dir (dir/** would not match the dir).
- The sender and the generator now double-check the file-list index
they are given, and refuse to try to do a file transfer on a
non-file index (since that would indicate that something had gone
very wrong).
- Added the --prune-empty-dirs (-m) option that makes the receiving rsync
discard empty chains of directories from the file-list. This makes it
easier to selectively copy files from a source hierarchy and end up with
just the directories needed to hold the resulting files.
- Added the --itemize-changes (-i) option, which is a way to output a
more detailed list of what files changed and in what way. The effect
is the same as specifying a --log-format of "%i %n%L" (see both the
rsync and rsyncd.conf manpages). Works with --dry-run too.
- If the --itemize-changes (-i) option is repeated, rsync now includes
unchanged files in the itemized output (similar to -vv, but without all
the other verbose messages that can get in the way). Of course, the
client must be version 2.6.7 for this to work, but the remote rsync only
needs to be 2.6.7 if you're pushing files.
- Added the --fuzzy (-y) option, which attempts to find a basis file
for a file that is being created from scratch. The current algorithm
only looks in the destination directory for the created file, but it
does attempt to find a match based on size/mod-time (in case the file
was renamed with no other changes) as well as based on a fuzzy
name-matching algorithm. This option requires protocol 29 because it
needs the new file-sorting order. (Promoted from patches dir and
enhanced.) (Requires protocol 29.)
- Added the --specials option to tell rsync to copy non-device special
files (which rsync now attempts even as a normal user). The --devices
option now requests the copying of just devices (character and block).
The -D option still requests both (e.g. --devices and --specials), -a
still implies -D, and non-root users still get a silent downgrade that
omits device copying.
- Added the --remove-sent-files option, which lets you move files
between systems.
- Added the --super option to make the receiver always attempt super-user
activities. This is useful for systems that allow things such as devices
to be created or ownership to be set without being UID 0, and is also
useful for someone who wants to ensure that errors will be output if the
receiving rsync isn't being run as root.
- The hostname in HOST:PATH or HOST::PATH may now be an IPv6 literal
enclosed in '[' and ']' (e.g. "[::1]"). (We already allowed IPv6
literals in the rsync://HOST:PORT/PATH format.)
- Added the --sockopts option for those few who want to customize the TCP
options used to contact a daemon rsync.
- When rsync recurses to build the file list, it no longer keeps open
one or more directory handles from the dir's parent dirs.
- Added a way for the --temp-dir option to be combined with a partial-dir
setting that lets rsync avoid non-atomic updates (for those times when
--temp-dir is not being used because space is tight).
- When building under windows, the default for --daemon is now to
avoid detaching, requiring the new --detach option to force rsync
to detach.
- A new support script, files-to-excludes, will transform a list of files
into a set of include/exclude directives that will copy those files.
- The --dry-run option can now be combined with either --write-batch or
--read-batch, allowing you to run a do-nothing test command to see
what would happen without --dry-run.
- A new option, --executability (-E) can be used to preserve just the
execute bit on files, for those times when using the --perms option is
not desired.
- The daemon's "read only" config item now sets an internal read_only
variable that makes extra sure that no write/delete calls on the
read-only side can succeed.
- The daemon now logs each connection and also each module-list request
that it receives.
- Improved the option descriptions in the --help text.
- New log-format options: %M (modtime), %U (uid), %G (gid), and %B
(permission bits, e.g. "rwxr-xrwt").
SUPPORT FILES:
- The --dry-run option no longer forces the enabling of --verbose.
- Added atomic-rsync to the support dir: a perl script that will
transfer some files using rsync, and then move the updated files into
place all at once at the end of the transfer. Only works when
pulling, and uses --link-dest and a parallel hierarchy of files to
effect its update.
- The --remove-sent-files option now does a better job of incrementally
removing the sent files on the sending side (older versions tended to
clump up all the removals at the end).
- Added mnt-excl to the support dir: a perl script that takes the
/proc/mounts file and translates it into a set of excludes that will
exclude all mount points (even mapped mounts to the same disk). The
excludes are made relative to the specified source dir and properly
anchored.
- A daemon now supersedes its minimal SIGCHLD handler with the standard
PID-remembering version after forking. This ensures that the generator
can get the child-exit status from the receiver.
- Added savetransfer.c to the support dir: a C program that can make
a copy of all the data that flows over the wire. This lets you test
for data corruption (by saving the data on both the sending side and
the receiving side) and provides one way to debug a protocol error.
- Use of the --bwlimit option no longer interferes with the remote rsync
sending error messages about invalid/refused options.
- Added rrsync to the support dir: this is an updated version of Joe
Smith's restricted rsync perl script. This helps to ensure that only
certain rsync commands can be run by an ssh invocation.
- Rsync no longer returns a usage error when used with one local source arg
and no destination: this now implies the --list-only option, just like
the comparable situation with a remote source arg.
- Added the --copy-dirlinks option, a more limited version of --copy-links.
- Various documentation improvements, including: a better synopsis, some
improved examples, a better discussion of the presence and absence of
--perms (including how it interacts with the new --executability and
--chmod options), an extended discussion of --temp-dir, an improved
discussion of --partial-dir, a better description of rsync's pattern
matching characters, an improved --no-implied-dirs section, and the
documenting of what the --stats option outputs.
- Various new and updated diffs in the patches dir, including: acls.diff,
xattrs.diff, atimes.diff, detect-renamed.diff, and slp.diff.
INTERNAL:
- Added better checking of the checksum-header values that come over
the socket.
- We now use sigaction() and sigprocmask() if possible, and fall back on
signal() if not. Using sigprocmask() ensures that rsync enables all the
signals that it needs, just in case it was started in a masked state.
- Merged a variety of file-deleting functions into a single function so
that it is easier to maintain.
- Some buffer sizes were expanded a bit, particularly on systems where
MAXPATHLEN is overly small (e.g. cygwin).
- Improved the type of some variables (particularly blocksize vars) for
consistency and proper size.
- If io_printf() tries to format more data than fits in the buffer, exit
with an error instead of transmitting a truncated buffer.
- Got rid of the uint64 type (which we didn't need).
- If a va_copy macro is defined, lib/snprintf.c will use it when defining
the VA_COPY macro.
- Use a slightly more compatible set of core #include directives.
- Reduced the amount of stack memory needed for each level of directory
recursion by nearly MAXPATHLEN bytes.
- Defined int32 in a way that ensures that the build dies if we can't
find a variable with at least 32 bits.
- The wildmatch function was extended to allow an array of strings to be
supplied as the string to match. This allows the exclude code to do less
string copying.
PROTOCOL DIFFERENCES FOR VERSION 29:
- Got rid of the safe_fname() function (and all the myriad calls) and
replaced it with a new function in the log.c code that filters all the
output going to the terminal.
- A 16-bit flag-word is transmitted after every file-list index. This
indicates what is changing between the sender and the receiver. The
generator now transmits an index and a flag-word to indicate when
dirs and symlinks have changed (instead of producing a message),
which makes the outputting of the information more consistent and
less prone to screen corruption (because the local receiver/sender is
now outputting all the file-change info messages).
- Unified the f_name() and the f_name_to() functions.
- If a file is being hard-linked, the ITEM_XNAME_FOLLOWS bit is enabled
in the flag-word and the name of the file that was linked immediately
follows in vstring format (see below).
- Improved the hash-table code the sender uses to handle checksums to make
it use slightly less memory and run just a little faster.
- If a file is being transferred with an alternate-basis file, the
ITEM_BASIS_TYPE_FOLLOWS bit is enabled in the flag-word and a single
byte follows, indicating what type of basis file was chosen. If that
indicates that a fuzzy-match was selected, the ITEM_XNAME_FOLLOWS bit
is set in the flag-word and the name of the match in vstring format
follows the basis byte. A vstring is a variable length string that
has its size written prior to the string, and no terminating null.
If the string is from 1-127 bytes, the length is a single byte. If
it is from 128-32767 bytes, the length is written as ((len >> 8) |
0x80) followed by (len % 0x100).
DEVELOPER RELATED:
- The sending of exclude names is done using filter-rule syntax. This
means that all names have a prefixed rule indicator, even excludes
(which used to be sent as a bare pattern, when possible). The -C
option will include the per-dir .cvsignore merge file in the list of
filter rules so it is positioned correctly (unlike in some older
transfer scenarios).
- The diffs in the patches dir now require "patch -p1 <DIFF" instead of
the previous -p0. Also, the version included in the release tar now
affect generated files (e.g. configure, rsync.1, proto.h, etc.), so
it is no longer necessary to run autoconf and/or yodl unless you're
applying a patch that was checked out from CVS.
- Rsync sorts the filename list in a different way: it sorts the subdir
names after the non-subdir names for each dir's contents, and it
always puts a dir's contents immediately after the dir's name in the
list. (Previously an item named "foo.txt" would sort in between
directory "foo/" and "foo/bar".)
- Several diffs in the patches dir now use the proper --enable-FOO
configure option instead of --with-FOO to turn on the inclusion of
the newly patched feature.
- When talking to a protocol 29 rsync daemon, a list-only request
is able to note this before the options are sent over the wire and
the new --list-only option is included in the options.
- There is a new script, "prepare-source" than can be used to update the
various generated files (proto.h, configure, etc.) even before configure
has created the Makefile (this is mainly useful when patching the source
with a patch that doesn't affect generated files).
- When the --stats bytes are sent over the wire (or stored in a batch),
they now include two elapsed-time values: one for how long it took to
build the file-list, and one for how long it took to send it over the
wire (each expressed in thousandths of a second).
- When --delete-excluded is specified with some filter rules (AKA
excludes), a client sender will now initiate a send of the rules to
the receiver (older protocols used to omit the sending of excludes in
this situation since there were no receiver-specific rules that
survived --delete-excluded back then). Note that, as with all the
filter-list sending, only items that are significant to the other
side will actually be sent over the wire, so the filter-rule list
that is sent in this scenario is often empty.
- An index equal to the file-list count is sent as a keep-alive packet
from the generator to the sender, which then forwards it on to the
receiver. This normally invalid index is only a valid keep-alive
packet if the 16-bit flag-word that follows it contains a single bit
(ITEM_IS_NEW, which is normally an illegal flag to appear alone).
- A protocol-29 batch file includes a bit for the setting of the --dirs
option and for the setting of the --compress option. Also, the shell
script created by --write-batch will use the --filter option instead
of --exclude-from to capture any filter rules.
BUILD CHANGES:
- Handle an operating system that use mkdev() in place of makedev().
- Improved configure to better handle cross-compiling.
- The testsuite now sets HOME so that it won't be affected by a file such
as ~/.popt.

649
OLDNEWS
View File

@@ -1,3 +1,647 @@
NEWS for rsync 2.6.6 (28 Jul 2005)
Protocol: 29 (unchanged)
Changes since 2.6.5:
SECURITY FIXES:
- The zlib code was upgraded to version 1.2.3 in order to make it more
secure. While the widely-publicized security problem in zlib 1.2.2 did
not affect rsync, another security problem surfaced that affects rsync's
zlib 1.1.4.
BUG FIXES:
- The setting of flist->high in clean_flist() was wrong for an empty list.
This could cause flist_find() to crash in certain rare circumstances
(e.g. if just the right directory setup was around when --fuzzy was
combined with --link-dest).
- The outputting of hard-linked files when verbosity was > 1 was not right:
(1) Without -i it would output the name of each hard-linked file as
though it had been changed; it now outputs a "is hard linked" message for
the file. (2) With -i it would output all dots for the unchanged
attributes of a hard-link; it now changes those dots to spaces, as is
done for other totally unchanged items.
- When backing up a changed symlink or device, get rid of any old backup
item so that we don't get an "already exists" error.
- A couple places that were comparing a local and a remote modification-
time were not honoring the --modify-window option.
- Fixed a bug where the 'p' (permissions) itemized-changes flag might get
set too often (if some non-significant mode bits differed).
- Fixed a really old, minor bug that could cause rsync to warn about being
unable to mkdir() a path that ends in "/." because it just created the
directory (required --relative, --no-implied-dirs, a source path that
ended in either a trailing slash or a trailing "/.", and a non-existing
destination dir to tickle the bug in a recent version).
ENHANCEMENTS:
- Made the "max verbosity" setting in the rsyncd.conf file settable on a
per-module basis (which now matches the documentation).
- The support/rrsync script has been upgraded to verify the args of options
that take args (instead of rejecting any such options). The script was
also changed to try to be more secure and to fix a problem in the parsing
of a pull operation that has multiple sources.
- Improved the documentation that explains the difference between a
normal daemon transfer and a daemon-over remote-shell transfer.
- Some of the diffs supplied in the patches dir were fixed and/or
improved.
BUILD CHANGES:
- Made configure define NOBODY_USER (currently hard-wired to "nobody") and
NOBODY_GROUP (set to either "nobody" or "nogroup" depending on what we
find in the /etc/group file).
- Added a test to the test suite, itemized.test, that tests the output of
-i (log-format w/%i) and some double-verbose messages.
NEWS for rsync 2.6.5 (1 Jun 2005)
Protocol: 29 (unchanged)
Changes since 2.6.4:
OUTPUT CHANGES:
- Non-printable chars in filenames are now output using backslash-
escaped characters rather than '?'s. Any non-printable character is
output using 3 digits of octal (e.g. "\n" -> "\012"), and a backslash
is now output as "\\". Rsync also uses your locale setting, which
can make it treat fewer high-bit characters as non-printable.
- If rsync received an empty file-list when pulling files, it would
output a "nothing to do" message and exit with a 0 (success) exit
status, even if the remote rsync returned an error (it did not do
this under the same conditions when pushing files). This was changed
to make the pulling behavior the same as the pushing behavior: we
now do the normal end-of-run outputting (depending on options) and
exit with the appropriate exit status.
BUG FIXES:
- A crash bug was fixed when a daemon had its "path" set to "/", did
not have chroot enabled, and used some anchored excludes in the
rsyncd.conf file.
- Fixed a bug in the transfer of a single file when -H is specified
(rsync would either infinite loop or perhaps crash).
- Fixed a case where the generator might try (and fail) to tweak the
write-permissions of a read-only directory in list-only mode (this
only caused an annoying warning message).
- If --compare-dest or --link-dest uses a locally-copied file as the
basis for an updated version, log this better when --verbose or -i
is in effect.
- Fixed the accidental disabling of --backup during the --delete-after
processing.
- Restored the ability to use the --address option in client mode (in
addition to its use in daemon mode).
- Make sure that some temporary progress information from the delete
processing does not get left on the screen when it is followed by a
newline.
- When --existing skips a directory with extra verbosity, refer to it
as a "directory", not a "file".
- When transferring a single file to a different-named file, any
generator messages that are source-file related no longer refer to
the file by the destination filename.
- Fixed a bug where hard-linking a group of files might fail if the
generator hasn't created a needed destination directory yet.
- Fixed a bug where a hard-linked group of files that is newly-linked
to a file in a --link-dest dir doesn't link the files from the rest
of the cluster.
- When deleting files with the --one-file-system (-x) option set, rsync
no longer tries to remove files from inside a mount-point on the
receiving side. Also, we don't complain about being unable to remove
the mount-point dir.
- Fixed a compatibility problem when using --cvs-ignore (-C) and
sending files to an older rsync without using --delete.
- Make sure that a "- !" or "+ !" include/exclude pattern does not
trigger the list-clearing action that is reserved for "!".
- Avoid a timeout in the generator when the sender/receiver aren't
handling the generator's checksum output quickly enough.
- Fixed the omission of some directories in the delete processing when
--relative (-R) was combined with a source path that had a trailing
slash.
- Fixed a case where rsync would erroneously delete some files and then
re-transfer them when the options --relative (-R) and --recursive
(-r) were both enabled (along with --delete) and a source path had a
trailing slash.
- Make sure that --max-size doesn't affect a device or a symlink.
- Make sure that a system with a really small MAXPATHLEN does not cause
the buffers in readfd_unbuffered() to be too small to receive normal
messages. (This mainly affected Cygwin.)
- If a source pathname ends with a filename of "..", treat it as if
"../" had been specified (so that we don't copy files to the parent
dir of the destination).
- If --delete is combined with a file-listing rsync command (i.e. no
transfer is happening), avoid outputting a warning that we couldn't
delete anything.
- If --stats is specified with --delete-after, ensure that all the
"deleting" messages are output before the statistics.
- Improved one "if" in the deletion code that was only checking errno
for ENOTEMPTY when it should have also been checking for EEXIST (for
compatibility with OS variations).
ENHANCEMENTS:
- Added the --only-write-batch=FILE option that may be used (instead
of --write-batch=FILE) to create a batch file without doing any
actual updating of the destination. This allows you to divert all
the file-updating data away from a slow data link (as long as you
are pushing the data to the remote server when creating the batch).
- When the generator is taking a long time to fill up its output buffer
(e.g. if the transferred files are few, small, or missing), it now
periodically flushes the output buffer so that the sender/receiver
can get started on the files sooner rather than later.
- Improved the keep-alive code to handle a long silence between the
sender and the receiver that can occur when the sender is receiving
the checksum data for a large file.
- Improved the auth-errors that are logged by the daemon to include
some information on why the authorization failed: wrong user,
password mismatch, etc. (The client-visible message is unchanged!)
- Improved the client's handling of an "@ERROR" from a daemon so that
it does not complain about an unexpectedly closed socket (since we
really did expect the socket to close).
- If the daemon can't open the log-file specified in rsyncd.conf, fall
back to using syslog and log an appropriate warning. This is better
than what was typically a totally silent (and fatal) failure (since a
daemon is not usually run with the --no-detach option that was
necessary to see the error on stderr).
- The man pages now consistently refer to an rsync daemon as a "daemon"
instead of a "server" (to distinguish it from the server process in a
non-daemon transfer).
- Made a small change to the rrsync script (restricted rsync -- in the
support dir) to make a read-only server reject all --remove-* options
when sending files (to future-proof it against the possibility of
other similar options being added at some point).
INTERNAL:
- Rsync now calls setlocale(LC_CTYPE, ""). This enables isprint() to
better discern which filename characters need to be escaped in
messages (which should result in fewer escaped characters in some
locales).
- Improved the naming of the log-file open/reopen/close functions.
- Removed some protocol-compatibility code that was only needed to help
someone running a pre-release of 2.6.4.
BUILD CHANGES:
- Added configure option "--disable-locale" to disable any use of
setlocale() in the binary.
- Fixed a bug in the SUPPORT{,_HARD}_LINKS #defines which prevented
rsync from being built without symlink or hard-link support.
- Only #define HAVE_REMSH if it is going to be set to 1.
- Configure now disables the use of mkstemp() under HP-UX (since they
refuse to fix its broken handling of large files).
- Configure now explicitly checks for the lseek64() function so that
the code can use HAVE_LSEEK64 instead of inferring lseek64()'s
presence based on the presence of the off64_t type.
- Configure no longer mentions the change in the default remote-shell
(from rsh to ssh) that occurred for the 2.6.0 release.
- Some minor enhancements to the test scripts.
- Added a few new *.diff files to the patches dir, including a patch
that enables the optional copying of extended attributes.
NEWS for rsync 2.6.4 (30 March 2005)
Protocol: 29 (changed)
Changes since 2.6.3:
OUTPUT CHANGES:
- When rsync deletes a directory and outputs a verbose message about
it, it now appends a trailing slash to the name instead of (only
sometimes) outputting a preceding "directory " string.
- The --stats output will contain file-list time-statistics if both
sides are 2.6.4, or if the local side is 2.6.4 and the files are
being pushed (since the stats come from the sending side).
(Requires protocol 29 for a pull.)
- The "%o" (operation) log-format escape now has a third value (besides
"send" and "recv"): "del." (with trailing dot to make it 4 chars).
This changes the way deletions are logged in the daemon's log file.
- When the --log-format option is combined with --verbose, rsync now
avoids outputting the name of the file twice in most circumstances.
As long as the --log-format item does not refer to any post-transfer
items (such as %b or %c), the --log-format message is output prior to
the transfer, so --verbose is now the equivalent of a --log-format of
'%n%L' (which outputs the name and any link info). If the log output
must occur after the transfer to be complete, the only time the name
is also output prior to the transfer is when --progress was specified
(so that the name will precede the progress stats, and the full
--log-format output will come after).
- Non-printable characters in filenames are replaced with a '?' to
avoid corrupting the screen or generating empty lines in the output.
BUG FIXES:
- Restore the list-clearing behavior of "!" in a .cvsignore file (2.6.3
was only treating it as a special token in an rsync include/exclude
file).
- The combination of --verbose and --dry-run now mentions the full list
of changes that would be output without --dry-run.
- Avoid a mkdir warning when removing a directory in the destination
that already exists in the --backup-dir.
- An OS that has a binary mode for its files (such as cygwin) needed
setmode(fd, O_BINARY) called on the temp-file we opened with
mkstemp(). (Fix derived from cygwin's 2.6.3 rsync package.)
- Fixed a potential hang when verbosity is high, the client side is
the sender, and the file-list is large.
- Fixed a potential protocol-corrupting bug where the generator could
merge a message from the receiver into the middle of a multiplexed
packet of data if only part of that data had been written out to the
socket when the message from the generator arrived.
- We now check if the OS doesn't support using mknod() for creating
FIFOs and sockets, and compile-in some compatibility code using
mkfifo() and socket() when necessary.
- Fixed an off-by-one error in the handling of --max-delete=N. Also,
if the --max-delete limit is exceeded during a run, we now output a
warning about this at the end of the run and exit with a new error
code (25).
- One place in the code wasn't checking if fork() failed.
- The "ignore nonreadable" daemon parameter used to erroneously affect
readable symlinks that pointed to a non-existent file.
- If the OS does not have lchown() and a chown() of a symlink will
affect the referent of a symlink (as it should), we no longer try
to set the user and group of a symlink.
- The generator now properly runs the hard-link loop and the dir-time
rewriting loop after we're sure that the redo phase is complete.
- When --backup was specified with --partial-dir=DIR, where DIR is a
relative path, the backup code was erroneously trying to backup a
file that was put into the partial-dir.
- If a file gets resent in a single transfer and the --backup option is
enabled along with --inplace, rsync no longer performs a duplicate
backup (it used to overwrite the first backup with the failed file).
- One call to flush_write_file() was not being checked for an error.
- The --no-relative option was not being sent from the client to a
server sender.
- If an rsync daemon specified "dont compress = ..." for a file and the
client tried to specify --compress, the libz code was not handling a
compression level of 0 properly. This could cause a transfer failure
if the block-size for a file was large enough (e.g. rsync might have
exited with an error for large files).
- Fixed a bug that would sometimes surface when using --compress and
sending a file with a block-size larger than 64K (either manually
specified, or computed due to the file being really large). Prior
versions of rsync would sometimes fail to decompress the data
properly, and thus the transferred file would fail its verification.
- If a daemon can't open the specified log file (i.e. syslog is not
being used), die without crashing. We also output an error about
the failure on stderr (which will only be seen if --no-detach was
specified) and exit with a new error code (6).
- A local transfer no longer duplicates all its include/exclude options
(since the forked process already has a copy of the exclude list,
there's no need to send them a set of duplicates).
- The output of the items that are being updated by the generator (dirs,
symlinks, devices) is now intermingled in the proper order with the
output from the items that the receiver is updating (regular files)
when pulling. This misordering was particularly bad when --progress
was specified. (Requires protocol 29.)
- When --timeout is specified, lulls that occur in the transfer while
the generator is doing work that does not generate socket traffic
(looking for changed files, deleting files, doing directory-time
touch-ups, etc.) will cause a new keep-alive packet to be sent that
should keep the transfer going as long as the generator continues to
make progress. (Requires protocol 29.)
- The stat size of a device is not added to the total file size of the
items in the transfer (the size might be undefined on some OSes).
- Fixed a problem with refused-option messages sometimes not making it
back to the client side when a remote --files-from was in effect and
the daemon was the receiver.
- The --compare-dest option was not updating a file that differed in
(the preserved) attributes from the version in the compare-dest DIR.
- When rsync is copying files into a write-protected directory, fixed
the change-report output for the directory so that we don't report
an identical directory as changed.
ENHANCEMENTS:
- Rsync now supports popt's option aliases, which means that you can
use /etc/popt and/or ~/.popt to create your own option aliases.
- Added the --delete-during (--del) option which will delete files
from the receiving side incrementally as each directory in the
transfer is being processed. This makes it more efficient than the
default, before-the-transfer behavior, which is now also available as
--delete-before (and is still the default --delete-WHEN option that
will be chosen if --delete or --delete-excluded is specified without
a --delete-WHEN choice). All the --del* options infer --delete, so
an rsync daemon that refuses "delete" will still refuse to allow any
file-deleting options (including the new --remove-sent-files option).
- All the --delete-WHEN options are now more memory efficient:
Previously an duplicate set of file-list objects was created on the
receiving side for the entire destination hierarchy. The new
algorithm only creates one directory of objects at a time (for files
inside the transfer).
- Added the --copy-dest option, which works like --link-dest except
that it locally copies identical files instead of hard-linking them.
- Added support for specifying multiple --compare-dest, --copy-dest, or
--link-dest options, but only of a single type. (Promoted from the
patches dir and enhanced.) (Requires protocol 29.)
- Added the --max-size option. (Promoted from the patches dir.)
- The daemon-mode options are now separated from the normal rsync
options so that they can't be mixed together. This makes it
impossible to start a daemon that has improper default option values
(which could cause problems when a client connects, such as hanging
or crashing).
- The --bwlimit option may now be used in combination with --daemon
to specify both a default value for the daemon side and a value
that cannot be exceeded by a user-specified --bwlimit option.
- Added the "port" parameter to the rsyncd.conf file. (Promoted from
the patches dir.) Also added "address". The command-line options
take precedence over a config-file option, as expected.
- In _exit_cleanup(): when we are exiting with a partially-received
file, we now flush any data in the write-cache before closing the
partial file.
- The --inplace support was enhanced to work with --compare-dest,
--link-dest, and (the new) --copy-dest options. (Requires protocol
29.)
- Added the --dirs (-d) option for an easier way to copy directories
without recursion. Any directories that are encountered are created
on the destination. Specifying a directory with a trailing slash
copies its immediate contents to the destination.
- The --files-from option now implies --dirs (-d).
- Added the --list-only option, which is mainly a way for the client to
put the server into listing mode without needing to resort to any
internal option kluges (e.g. the age-old use of "-r --exclude="/*/*"
for a non-recursive listing). This option is used automatically
(behind the scenes) when a modern rsync speaks to a modern daemon,
but may also be specified manually if you want to force the use of
the --list-only option over a remote-shell connection.
- Added the --omit-dir-times (-O) option, which will avoid updating
the modified time for directories when --times was specified. This
option will avoid an extra pass through the file-list at the end of
the transfer (to tweak all the directory times), which may provide
an appreciable speedup for a really large transfer. (Promoted from
the patches dir.)
- Added the --filter (-f) option and its helper option, -F. Filter
rules are an extension to the existing include/exclude handling
that also supports nested filter files as well as per-directory
filter files (like .cvsignore, but with full filter-rule parsing).
This new option was chosen in order to ensure that all existing
include/exclude processing remained 100% compatible with older
versions. Protocol 29 is needed for full filter-rule support, but
backward-compatible rules work with earlier protocol versions.
(Promoted from the patches dir and enhanced.)
- Added the --delay-updates option that puts all updated files into
a temporary directory (by default ".~tmp~", but settable via the
--partial-dir=DIR option) until the end of the transfer. This
makes the updates a little more atomic for a large transfer.
- If rsync is put into the background, any output from --progress is
reduced.
- Documented the "max verbosity" setting for rsyncd.conf. (This
setting was added a couple releases ago, but left undocumented.)
- The sender and the generator now double-check the file-list index
they are given, and refuse to try to do a file transfer on a
non-file index (since that would indicate that something had gone
very wrong).
- Added the --itemize-changes (-i) option, which is a way to output a
more detailed list of what files changed and in what way. The effect
is the same as specifying a --log-format of "%i %n%L" (see both the
rsync and rsyncd.conf manpages). Works with --dry-run too.
- Added the --fuzzy (-y) option, which attempts to find a basis file
for a file that is being created from scratch. The current algorithm
only looks in the destination directory for the created file, but it
does attempt to find a match based on size/mod-time (in case the file
was renamed with no other changes) as well as based on a fuzzy
name-matching algorithm. This option requires protocol 29 because it
needs the new file-sorting order. (Promoted from patches dir and
enhanced.) (Requires protocol 29.)
- Added the --remove-sent-files option, which lets you move files
between systems.
- The hostname in HOST:PATH or HOST::PATH may now be an IPv6 literal
enclosed in '[' and ']' (e.g. "[::1]"). (We already allowed IPv6
literals in the rsync://HOST:PORT/PATH format.)
- When rsync recurses to build the file list, it no longer keeps open
one or more directory handles from the dir's parent dirs.
- When building under windows, the default for --daemon is now to
avoid detaching, requiring the new --detach option to force rsync
to detach.
- The --dry-run option can now be combined with either --write-batch or
--read-batch, allowing you to run a do-nothing test command to see
what would happen without --dry-run.
- The daemon's "read only" config item now sets an internal read_only
variable that makes extra sure that no write/delete calls on the
read-only side can succeed.
- The log-format % escapes can now have a numeric field width in
between the % and the escape letter (e.g. "%-40n %08p").
- Improved the option descriptions in the --help text.
SUPPORT FILES:
- Added atomic-rsync to the support dir: a perl script that will
transfer some files using rsync, and then move the updated files into
place all at once at the end of the transfer. Only works when
pulling, and uses --link-dest and a parallel hierarchy of files to
effect its update.
- Added mnt-excl to the support dir: a perl script that takes the
/proc/mounts file and translates it into a set of excludes that will
exclude all mount points (even mapped mounts to the same disk). The
excludes are made relative to the specified source dir and properly
anchored.
- Added savetransfer.c to the support dir: a C program that can make
a copy of all the data that flows over the wire. This lets you test
for data corruption (by saving the data on both the sending side and
the receiving side) and provides one way to debug a protocol error.
- Added rrsync to the support dir: this is an updated version of Joe
Smith's restricted rsync perl script. This helps to ensure that only
certain rsync commands can be run by an ssh invocation.
INTERNAL:
- Added better checking of the checksum-header values that come over
the socket.
- Merged a variety of file-deleting functions into a single function so
that it is easier to maintain.
- Improved the type of some variables (particularly blocksize vars) for
consistency and proper size.
- Got rid of the uint64 type (which we didn't need).
- Use a slightly more compatible set of core #include directives.
- Defined int32 in a way that ensures that the build dies if we can't
find a variable with at least 32 bits.
PROTOCOL DIFFERENCES FOR VERSION 29:
- A 16-bit flag-word is transmitted after every file-list index. This
indicates what is changing between the sender and the receiver. The
generator now transmits an index and a flag-word to indicate when
dirs and symlinks have changed (instead of producing a message),
which makes the outputting of the information more consistent and
less prone to screen corruption (because the local receiver/sender is
now outputting all the file-change info messages).
- If a file is being hard-linked, the ITEM_XNAME_FOLLOWS bit is enabled
in the flag-word and the name of the file that was linked immediately
follows in vstring format (see below).
- If a file is being transferred with an alternate-basis file, the
ITEM_BASIS_TYPE_FOLLOWS bit is enabled in the flag-word and a single
byte follows, indicating what type of basis file was chosen. If that
indicates that a fuzzy-match was selected, the ITEM_XNAME_FOLLOWS bit
is set in the flag-word and the name of the match in vstring format
follows the basis byte. A vstring is a variable length string that
has its size written prior to the string, and no terminating null.
If the string is from 1-127 bytes, the length is a single byte. If
it is from 128-32767 bytes, the length is written as ((len >> 8) |
0x80) followed by (len % 0x100).
- The sending of exclude names is done using filter-rule syntax. This
means that all names have a prefixed rule indicator, even excludes
(which used to be sent as a bare pattern, when possible). The -C
option will include the per-dir .cvsignore merge file in the list of
filter rules so it is positioned correctly (unlike in some older
transfer scenarios).
- Rsync sorts the filename list in a different way: it sorts the subdir
names after the non-subdir names for each dir's contents, and it
always puts a dir's contents immediately after the dir's name in the
list. (Previously an item named "foo.txt" would sort in between
directory "foo/" and "foo/bar".)
- When talking to a protocol 29 rsync daemon, a list-only request
is able to note this before the options are sent over the wire and
the new --list-only option is included in the options.
- When the --stats bytes are sent over the wire (or stored in a batch),
they now include two elapsed-time values: one for how long it took to
build the file-list, and one for how long it took to send it over the
wire (each expressed in thousandths of a second).
- When --delete-excluded is specified with some filter rules (AKA
excludes), a client sender will now initiate a send of the rules to
the receiver (older protocols used to omit the sending of excludes in
this situation since there were no receiver-specific rules that
survived --delete-excluded back then). Note that, as with all the
filter-list sending, only items that are significant to the other
side will actually be sent over the wire, so the filter-rule list
that is sent in this scenario is often empty.
- An index equal to the file-list count is sent as a keep-alive packet
from the generator to the sender, which then forwards it on to the
receiver. This normally invalid index is only a valid keep-alive
packet if the 16-bit flag-word that follows it contains a single bit
(ITEM_IS_NEW, which is normally an illegal flag to appear alone).
- A protocol-29 batch file includes a bit for the setting of the --dirs
option and for the setting of the --compress option. Also, the shell
script created by --write-batch will use the --filter option instead
of --exclude-from to capture any filter rules.
BUILD CHANGES:
- Handle an operating system that use mkdev() in place of makedev().
- Improved configure to better handle cross-compiling.
NEWS for rsync 2.6.3 (30 Sep 2004)
Protocol: 28 (unchanged)
Changes since 2.6.2:
@@ -339,7 +983,7 @@ Changes since 2.6.0:
- We now reset the "new data has been sent" flag at the start of
each file we send. This makes sure that an interrupted transfer
with the --partial option set doesn't keep a shorter temp file
than the current basis file when no new data has been transfered
than the current basis file when no new data has been transferred
over the wire for that file.
- Fixed a byte-order problem in --batch-mode on big-endian machines.
@@ -1043,6 +1687,9 @@ Changes since 2.4.6:
Partial Protocol History
RELEASE DATE VER. DATE OF COMMIT* PROTOCOL
11 Mar 2006 2.6.7 29
28 Jul 2005 2.6.6 29
01 Jun 2005 2.6.5 29
30 Mar 2005 2.6.4 17 Jan 2005 29
30 Sep 2004 2.6.3 28
30 Apr 2004 2.6.2 28

3
README
View File

@@ -89,6 +89,9 @@ mailing list archives at
To send a bug report, follow the instructions on the bug-tracking
page of the web site.
If you don't have web access, email your bug report to
rsync@lists.samba.org.
CVS TREE
--------

120
TODO
View File

@@ -1,22 +1,17 @@
-*- indented-text -*-
BUGS ---------------------------------------------------------------
Do not rely on having a group called "nobody"
FEATURES ------------------------------------------------------------
Use chroot only if supported
Allow supplementary groups in rsyncd.conf 2002/04/09
Handling IPv6 on old machines
Other IPv6 stuff:
Other IPv6 stuff
Add ACL support 2001/12/02
Lazy directory creation
proxy authentication 2002/01/23
SOCKS 2002/01/23
FAT support
Allow forcing arbitrary permissions 2002/03/12
--diff david.e.sewell 2002/03/15
Add daemon --no-fork option
Create more granular verbosity jw 2003/05/15
Create more granular verbosity 2003/05/15
DOCUMENTATION --------------------------------------------------------
Keep list of open issues and todos on the web site
@@ -25,22 +20,19 @@ Perhaps redo manual as SGML
LOGGING --------------------------------------------------------------
Memory accounting
Improve error messages
Better statistics: Rasmus 2002/03/08
Better statistics Rasmus 2002/03/08
Perhaps flush stdout like syslog
Log deamon sessions that just list modules
Log child death on signal
Log errors with function that reports process of origin
verbose output David Stein 2001/12/20
internationalization
DEVELOPMENT --------------------------------------------------------
Handling duplicate names
Use generic zlib 2002/02/25
TDB: 2002/03/12
TDB 2002/03/12
Splint 2002/03/12
PERFORMANCE ----------------------------------------------------------
File list structure in memory
Traverse just one directory at a time
Allow skipping MD4 file_sum 2002/04/08
Accelerate MD4
@@ -52,8 +44,6 @@ Test on kernel source
Test large files
Create mutator program for testing
Create configure option to enable dangerous tests
If tests are skipped, say why.
Test daemon feature to disallow particular options.
Create pipe program for testing
Create test makefile target for some tests
@@ -66,17 +56,6 @@ reverse rsync over HTTP Range
BUGS ---------------------------------------------------------------
Do not rely on having a group called "nobody"
http://www.linuxbase.org/spec/refspecs/LSB_1.1.0/gLSB/usernames.html
On Debian it's "nogroup"
-- --
FEATURES ------------------------------------------------------------
@@ -133,7 +112,7 @@ Handling IPv6 on old machines
-- --
Other IPv6 stuff:
Other IPv6 stuff
Implement suggestions from http://www.kame.net/newsletter/19980604/
and ftp://ftp.iij.ad.jp/pub/RFC/rfc2553.txt
@@ -159,15 +138,6 @@ Add ACL support 2001/12/02
-- --
Lazy directory creation
With the current common --include '*/' --exclude '*' pattern, people
can end up with many empty directories. We might avoid this by
lazily creating such directories.
-- --
proxy authentication 2002/01/23
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
@@ -199,35 +169,6 @@ FAT support
-- --
Allow forcing arbitrary permissions 2002/03/12
On 12 Mar 2002, Dave Dykstra <dwd@bell-labs.com> wrote:
> If we would add an option to do that functionality, I
> would vote for one that was more general which could mask
> off any set of permission bits and possibly add any set of
> bits. Perhaps a chmod-like syntax if it could be
> implemented simply.
I think that would be good too. For example, people uploading files
to a web server might like to say
rsync -avzP --chmod a+rX ./ sourcefrog.net:/home/www/sourcefrog/
Ideally the patch would implement as many of the gnu chmod semantics
as possible. I think the mode parser should be a separate function
that passes back something like (mask,set) description to the rest
of the program. For bonus points there would be a test case for the
parser.
Possibly also --chown
(Debian #23628)
NOTE: there is a patch that implements this in the "patches" subdir.
-- --
--diff david.e.sewell 2002/03/15
Allow people to specify the diff command. (Might want to use wdiff,
@@ -252,7 +193,7 @@ Add daemon --no-fork option
-- --
Create more granular verbosity jw 2003/05/15
Create more granular verbosity 2003/05/15
Control output with the --report option.
@@ -322,14 +263,10 @@ Improve error messages
our load? (Debian #28416) Probably fixed now, but a test case would
be good.
When running as a daemon, some errors should both be returned to the
user and logged. This will make interacting with a daemon less
cryptic.
-- --
Better statistics: Rasmus 2002/03/08
Better statistics Rasmus 2002/03/08
<Rasmus>
hey, how about an rsync option that just gives you the
@@ -355,14 +292,6 @@ Perhaps flush stdout like syslog
-- --
Log deamon sessions that just list modules
At the connections that just get a list of modules are not logged,
but they should be.
-- --
Log child death on signal
If a child of the rsync daemon dies with a signal, we should notice
@@ -371,15 +300,6 @@ Log child death on signal
-- --
Log errors with function that reports process of origin
Use a separate function for reporting errors; prefix it with
"rsync:" or "rsync(remote)", or perhaps even "rsync(local
generator): ".
-- --
verbose output David Stein 2001/12/20
At end of transfer, show how many files were or were not transferred
@@ -445,7 +365,7 @@ Use generic zlib 2002/02/25
-- --
TDB: 2002/03/12
TDB 2002/03/12
Rather than storing the file list in memory, store it in a TDB.
@@ -472,20 +392,6 @@ Splint 2002/03/12
PERFORMANCE ----------------------------------------------------------
File list structure in memory
Rather than one big array, perhaps have a tree in memory mirroring
the directory tree.
This might make sorting much faster! (I'm not sure it's a big CPU
problem, mind you.)
It might also reduce memory use in storing repeated directory names
-- again I'm not sure this is a problem.
-- --
Traverse just one directory at a time
Traverse just one directory at a time. Tridge says it's possible.
@@ -586,16 +492,6 @@ Create configure option to enable dangerous tests
-- --
If tests are skipped, say why.
-- --
Test daemon feature to disallow particular options.
-- --
Create pipe program for testing
Create pipe program that makes slow/jerky connections for

View File

@@ -208,7 +208,7 @@ static int match_address(char *addr, char *tok)
ret = match_binary(a, t, mask, addrlen);
out:
out:
freeaddrinfo(resa);
freeaddrinfo(rest);
return ret;

View File

@@ -21,21 +21,18 @@
#include "rsync.h"
extern char *password_file;
extern int am_root;
/***************************************************************************
encode a buffer using base64 - simple and slow algorithm. null terminates
the result.
***************************************************************************/
void base64_encode(char *buf, int len, char *out)
void base64_encode(char *buf, int len, char *out, int pad)
{
char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int bit_offset, byte_offset, idx, i;
unsigned char *d = (unsigned char *)buf;
int bytes = (len*8 + 5)/6;
memset(out, 0, bytes+1);
for (i = 0; i < bytes; i++) {
byte_offset = (i*6)/8;
bit_offset = (i*6)%8;
@@ -49,12 +46,18 @@ void base64_encode(char *buf, int len, char *out)
}
out[i] = b64[idx];
}
while (pad && (i % 4))
out[i++] = '=';
out[i] = '\0';
}
/* create a 16 byte challenge buffer */
/* Generate a challenge buffer and return it base64-encoded. */
static void gen_challenge(char *addr, char *challenge)
{
char input[32];
char md4_out[MD4_SUM_LENGTH];
struct timeval tv;
memset(input, 0, sizeof input);
@@ -67,7 +70,9 @@ static void gen_challenge(char *addr, char *challenge)
sum_init(0);
sum_update(input, sizeof input);
sum_end(challenge);
sum_end(md4_out);
base64_encode(md4_out, MD4_SUM_LENGTH, challenge, 0);
}
@@ -87,13 +92,13 @@ static int get_secret(int module, char *user, char *secret, int len)
return 0;
if (do_stat(fname, &st) == -1) {
rsyserr(FLOG, errno, "stat(%s)", safe_fname(fname));
rsyserr(FLOG, errno, "stat(%s)", fname);
ok = 0;
} else if (lp_strict_modes(module)) {
if ((st.st_mode & 06) != 0) {
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
ok = 0;
} else if (am_root && (st.st_uid != 0)) {
} else if (MY_UID() == 0 && st.st_uid != 0) {
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
ok = 0;
}
@@ -157,19 +162,19 @@ static char *getpassf(char *filename)
if ((fd = open(filename,O_RDONLY)) < 0) {
rsyserr(FERROR, errno, "could not open password file \"%s\"",
safe_fname(filename));
filename);
if (envpw)
rprintf(FERROR, "falling back to RSYNC_PASSWORD environment variable.\n");
return NULL;
}
if (do_stat(filename, &st) == -1) {
rsyserr(FERROR, errno, "stat(%s)", safe_fname(filename));
rsyserr(FERROR, errno, "stat(%s)", filename);
ok = 0;
} else if ((st.st_mode & 06) != 0) {
rprintf(FERROR,"password file must not be other-accessible\n");
ok = 0;
} else if (am_root && st.st_uid != 0) {
} else if (MY_UID() == 0 && st.st_uid != 0) {
rprintf(FERROR,"password file must be owned by root when running as root\n");
ok = 0;
}
@@ -195,17 +200,18 @@ static char *getpassf(char *filename)
return NULL;
}
/* generate a 16 byte hash from a password and challenge */
/* Generate an MD4 hash created from the combination of the password
* and the challenge string and return it base64-encoded. */
static void generate_hash(char *in, char *challenge, char *out)
{
char buf[16];
char buf[MD4_SUM_LENGTH];
sum_init(0);
sum_update(in, strlen(in));
sum_update(challenge, strlen(challenge));
sum_end(buf);
base64_encode(buf, 16, out);
base64_encode(buf, MD4_SUM_LENGTH, out, 0);
}
/* Possibly negotiate authentication with the client. Use "leader" to
@@ -214,17 +220,15 @@ static void generate_hash(char *in, char *challenge, char *out)
* Return NULL if authentication failed. Return "" if anonymous access.
* Otherwise return username.
*/
char *auth_server(int f_in, int f_out, int module, char *addr, char *leader)
char *auth_server(int f_in, int f_out, int module, char *host, char *addr,
char *leader)
{
char *users = lp_auth_users(module);
char challenge[16];
char b64_challenge[30];
char line[MAXPATHLEN];
static char user[100];
char secret[100];
char pass[30];
char pass2[30];
char *tok;
char challenge[MD4_SUM_LENGTH*2];
char line[BIGPATHBUFLEN];
char secret[512];
char pass2[MD4_SUM_LENGTH*2];
char *tok, *pass;
/* if no auth list then allow anyone in! */
if (!users || !*users)
@@ -232,52 +236,60 @@ char *auth_server(int f_in, int f_out, int module, char *addr, char *leader)
gen_challenge(addr, challenge);
base64_encode(challenge, 16, b64_challenge);
io_printf(f_out, "%s%s\n", leader, challenge);
io_printf(f_out, "%s%s\n", leader, b64_challenge);
if (!read_line(f_in, line, sizeof line - 1))
if (!read_line(f_in, line, sizeof line - 1)
|| (pass = strchr(line, ' ')) == NULL) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"invalid challenge response\n",
lp_name(module), host, addr);
return NULL;
}
*pass++ = '\0';
memset(user, 0, sizeof user);
memset(pass, 0, sizeof pass);
if (!(users = strdup(users)))
out_of_memory("auth_server");
if (sscanf(line,"%99s %29s", user, pass) != 2)
return NULL;
users = strdup(users);
if (!users)
return NULL;
for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL," ,\t")) {
if (wildmatch(tok, user))
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
if (wildmatch(tok, line))
break;
}
free(users);
if (!tok)
return NULL;
memset(secret, 0, sizeof secret);
if (!get_secret(module, user, secret, sizeof secret - 1)) {
memset(secret, 0, sizeof secret);
if (!tok) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"unauthorized user\n",
lp_name(module), host, addr);
return NULL;
}
generate_hash(secret, b64_challenge, pass2);
memset(secret, 0, sizeof secret);
if (!get_secret(module, line, secret, sizeof secret - 1)) {
memset(secret, 0, sizeof secret);
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"missing secret for user \"%s\"\n",
lp_name(module), host, addr, line);
return NULL;
}
generate_hash(secret, challenge, pass2);
memset(secret, 0, sizeof secret);
if (strcmp(pass, pass2) == 0)
return user;
if (strcmp(pass, pass2) != 0) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"password mismatch\n",
lp_name(module), host, addr);
return NULL;
}
return NULL;
return strdup(line);
}
void auth_client(int fd, char *user, char *challenge)
{
char *pass;
char pass2[30];
char pass2[MD4_SUM_LENGTH*2];
if (!user || !*user)
user = "nobody";
@@ -302,5 +314,3 @@ void auth_client(int fd, char *user, char *challenge)
generate_hash(pass, challenge, pass2);
io_printf(fd, "%s %s\n", user, pass2);
}

View File

@@ -21,7 +21,6 @@
#include "rsync.h"
extern int verbose;
extern int backup_suffix_len;
extern int backup_dir_len;
extern unsigned int backup_dir_remainder;
extern char backup_dir_buf[MAXPATHLEN];
@@ -30,9 +29,8 @@ extern char *backup_dir;
extern int am_root;
extern int preserve_devices;
extern int preserve_specials;
extern int preserve_links;
extern int preserve_hard_links;
extern int orig_umask;
extern int safe_symlinks;
/* make a complete pathname for backup file */
@@ -65,8 +63,7 @@ static int make_simple_backup(char *fname)
if (do_rename(fname, fnamebak) == 0) {
if (verbose > 1) {
rprintf(FINFO, "backed up %s to %s\n",
safe_fname(fname),
safe_fname(fnamebak));
fname, fnamebak);
}
break;
}
@@ -81,7 +78,7 @@ static int make_simple_backup(char *fname)
continue;
rsyserr(FERROR, rename_errno, "rename %s to backup %s",
safe_fname(fname), safe_fname(fnamebak));
fname, fnamebak);
errno = rename_errno;
return 0;
}
@@ -112,7 +109,7 @@ static int make_bak_dir(char *fullpath)
}
if (*p == '/') {
*p = '\0';
if (do_mkdir(fullpath, 0777 & ~orig_umask) == 0)
if (mkdir_defmode(fullpath) == 0)
break;
if (errno != ENOENT) {
rsyserr(FERROR, errno,
@@ -141,7 +138,7 @@ static int make_bak_dir(char *fullpath)
p += strlen(p);
if (p == end)
break;
if (do_mkdir(fullpath, 0777 & ~orig_umask) < 0) {
if (mkdir_defmode(fullpath) < 0) {
rsyserr(FERROR, errno, "make_bak_dir mkdir %s failed",
full_fname(fullpath));
goto failure;
@@ -149,7 +146,7 @@ static int make_bak_dir(char *fullpath)
}
return 0;
failure:
failure:
while (p != end) {
*p = '/';
p += strlen(p);
@@ -160,8 +157,9 @@ failure:
/* robustly move a file, creating new directory structures if necessary */
static int robust_move(char *src, char *dst)
{
if (robust_rename(src, dst, 0755) < 0 && (errno != ENOENT
|| make_bak_dir(dst) < 0 || robust_rename(src, dst, 0755) < 0))
if (robust_rename(src, dst, NULL, 0755) < 0
&& (errno != ENOENT || make_bak_dir(dst) < 0
|| robust_rename(src, dst, NULL, 0755) < 0))
return -1;
return 0;
}
@@ -181,25 +179,24 @@ static int keep_backup(char *fname)
if (do_lstat(fname, &st) < 0)
return 1;
if (!(file = make_file(fname, NULL, NO_FILTERS)))
if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
return 1; /* the file could have disappeared */
if (!(buf = get_backup_name(fname)))
return 0;
/* Check to see if this is a device file, or link */
if (IS_DEVICE(file->mode)) {
if (am_root && preserve_devices) {
if (do_mknod(buf, file->mode, file->u.rdev) < 0
&& (errno != ENOENT || make_bak_dir(buf) < 0
|| do_mknod(buf, file->mode, file->u.rdev) < 0)) {
rsyserr(FERROR, errno, "mknod %s failed",
full_fname(buf));
} else if (verbose > 2) {
rprintf(FINFO,
"make_backup: DEVICE %s successful.\n",
safe_fname(fname));
}
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|| (preserve_specials && IS_SPECIAL(file->mode))) {
do_unlink(buf);
if (do_mknod(buf, file->mode, file->u.rdev) < 0
&& (errno != ENOENT || make_bak_dir(buf) < 0
|| do_mknod(buf, file->mode, file->u.rdev) < 0)) {
rsyserr(FERROR, errno, "mknod %s failed",
full_fname(buf));
} else if (verbose > 2) {
rprintf(FINFO, "make_backup: DEVICE %s successful.\n",
fname);
}
kept = 1;
do_unlink(fname);
@@ -230,21 +227,24 @@ static int keep_backup(char *fname)
full_fname(buf), file->u.link);
}
kept = 1;
} else {
do_unlink(buf);
if (do_symlink(file->u.link, buf) < 0
&& (errno != ENOENT || make_bak_dir(buf) < 0
|| do_symlink(file->u.link, buf) < 0)) {
rsyserr(FERROR, errno, "link %s -> \"%s\"",
full_fname(buf),
file->u.link);
}
do_unlink(fname);
kept = 1;
}
if (do_symlink(file->u.link, buf) < 0
&& (errno != ENOENT || make_bak_dir(buf) < 0
|| do_symlink(file->u.link, buf) < 0)) {
rsyserr(FERROR, errno, "link %s -> \"%s\"",
full_fname(buf), safe_fname(file->u.link));
}
do_unlink(fname);
kept = 1;
}
#endif
if (!kept && !S_ISREG(file->mode)) {
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
safe_fname(fname));
fname);
return 1;
}
@@ -252,19 +252,19 @@ static int keep_backup(char *fname)
if (!kept) {
if (robust_move(fname, buf) != 0) {
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
full_fname(fname), safe_fname(buf));
full_fname(fname), buf);
} else if (st.st_nlink > 1) {
/* If someone has hard-linked the file into the backup
* dir, rename() might return success but do nothing! */
robust_unlink(fname); /* Just in case... */
}
}
set_perms(buf, file, NULL, 0);
set_file_attrs(buf, file, NULL, 0);
free(file);
if (verbose > 1) {
rprintf(FINFO, "backed up %s to %s\n",
safe_fname(fname), safe_fname(buf));
fname, buf);
}
return 1;
}

68
batch.c
View File

@@ -6,9 +6,9 @@
*/
#include "rsync.h"
#include "zlib/zlib.h"
#include <time.h>
extern int am_sender;
extern int eol_nulls;
extern int recurse;
extern int xfer_dirs;
@@ -19,11 +19,14 @@ extern int preserve_uid;
extern int preserve_gid;
extern int always_checksum;
extern int do_compression;
extern int def_compress_level;
extern int protocol_version;
extern char *batch_name;
extern struct filter_list_struct filter_list;
static int tweaked_compress_level;
static int *flag_ptr[] = {
&recurse, /* 0 */
&preserve_uid, /* 1 */
@@ -33,7 +36,7 @@ static int *flag_ptr[] = {
&preserve_hard_links, /* 5 */
&always_checksum, /* 6 */
&xfer_dirs, /* 7 (protocol 29) */
&do_compression, /* 8 (protocol 29) */
&tweaked_compress_level,/* 8 (protocol 29) */
NULL
};
@@ -54,6 +57,12 @@ void write_stream_flags(int fd)
{
int i, flags;
#if Z_DEFAULT_COMPRESSION == -1
tweaked_compress_level = do_compression ? def_compress_level + 2 : 0;
#else
#error internal logic error! Fix def_compress_level logic above and below too!
#endif
/* Start the batch file with a bitmap of data-stream-affecting
* flags. */
if (protocol_version < 29)
@@ -88,6 +97,13 @@ void read_stream_flags(int fd)
else if (xfer_dirs < 2)
xfer_dirs = 0;
}
if (tweaked_compress_level == 0 || tweaked_compress_level == 2)
do_compression = 0;
else {
do_compression = 1;
def_compress_level = tweaked_compress_level - 2;
}
}
static void write_arg(int fd, char *arg)
@@ -139,7 +155,7 @@ static void write_filter_rules(int fd)
* (hopefully) work. */
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
{
int fd, i;
int fd, i, len;
char *p, filename[MAXPATHLEN];
stringjoin(filename, sizeof filename,
@@ -148,7 +164,7 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
S_IRUSR | S_IWUSR | S_IEXEC);
if (fd < 0) {
rsyserr(FERROR, errno, "Batch file %s open error",
safe_fname(filename));
filename);
exit_cleanup(1);
}
@@ -175,11 +191,12 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
continue;
}
write(fd, " ", 1);
if (strncmp(p, "--write-batch", 13) == 0) {
if (strncmp(p, "--write-batch", len = 13) == 0
|| strncmp(p, "--only-write-batch", len = 18) == 0) {
write(fd, "--read-batch", 12);
if (p[13] == '=') {
if (p[len] == '=') {
write(fd, "=", 1);
write_arg(fd, p + 14);
write_arg(fd, p + len + 1);
}
} else
write_arg(fd, p);
@@ -193,42 +210,7 @@ void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
write_filter_rules(fd);
if (write(fd, "\n", 1) != 1 || close(fd) < 0) {
rsyserr(FERROR, errno, "Batch file %s write error",
safe_fname(filename));
filename);
exit_cleanup(1);
}
}
void show_flist(int index, struct file_struct **fptr)
{
/* for debugging show_flist(flist->count, flist->files * */
int i;
for (i = 0; i < index; i++) {
rprintf(FINFO, "flist->flags=%#x\n", fptr[i]->flags);
rprintf(FINFO, "flist->modtime=%#lx\n",
(long unsigned) fptr[i]->modtime);
rprintf(FINFO, "flist->length=%.0f\n",
(double) fptr[i]->length);
rprintf(FINFO, "flist->mode=%#o\n", (int) fptr[i]->mode);
rprintf(FINFO, "flist->basename=%s\n",
safe_fname(fptr[i]->basename));
if (fptr[i]->dirname) {
rprintf(FINFO, "flist->dirname=%s\n",
safe_fname(fptr[i]->dirname));
}
if (am_sender && fptr[i]->dir.root) {
rprintf(FINFO, "flist->dir.root=%s\n",
safe_fname(fptr[i]->dir.root));
}
}
}
/* for debugging */
void show_argvs(int argc, char *argv[])
{
int i;
rprintf(FINFO, "BATCH.C:show_argvs,argc=%d\n", argc);
for (i = 0; i < argc; i++)
rprintf(FINFO, "i=%d,argv[i]=%s\n", i, safe_fname(argv[i]));
}

205
chmod.c Normal file
View File

@@ -0,0 +1,205 @@
#include "rsync.h"
extern mode_t orig_umask;
#define FLAG_X_KEEP (1<<0)
#define FLAG_DIRS_ONLY (1<<1)
#define FLAG_FILES_ONLY (1<<2)
struct chmod_mode_struct {
struct chmod_mode_struct *next;
int ModeAND, ModeOR;
char flags;
};
#define CHMOD_ADD 1
#define CHMOD_SUB 2
#define CHMOD_EQ 3
#define STATE_ERROR 0
#define STATE_1ST_HALF 1
#define STATE_2ND_HALF 2
/* 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
* (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)
{
int state = STATE_1ST_HALF;
int where = 0, what = 0, op = 0, topbits = 0, topoct = 0, flags = 0;
struct chmod_mode_struct *first_mode = NULL, *curr_mode = NULL,
*prev_mode = NULL;
while (state != STATE_ERROR) {
if (!*modestr || *modestr == ',') {
int bits;
if (!op) {
state = STATE_ERROR;
break;
}
prev_mode = curr_mode;
curr_mode = new_array(struct chmod_mode_struct, 1);
if (prev_mode)
prev_mode->next = curr_mode;
else
first_mode = curr_mode;
curr_mode->next = NULL;
if (where)
bits = where * what;
else {
where = 0111;
bits = (where * what) & ~orig_umask;
}
switch (op) {
case CHMOD_ADD:
curr_mode->ModeAND = CHMOD_BITS;
curr_mode->ModeOR = bits + topoct;
break;
case CHMOD_SUB:
curr_mode->ModeAND = CHMOD_BITS - bits - topoct;
curr_mode->ModeOR = 0;
break;
case CHMOD_EQ:
curr_mode->ModeAND = CHMOD_BITS - (where * 7) - (topoct ? topbits : 0);
curr_mode->ModeOR = bits + topoct;
break;
}
curr_mode->flags = flags;
if (!*modestr)
break;
modestr++;
state = STATE_1ST_HALF;
where = what = op = topoct = topbits = flags = 0;
}
if (state != STATE_2ND_HALF) {
switch (*modestr) {
case 'D':
if (flags & FLAG_FILES_ONLY)
state = STATE_ERROR;
flags |= FLAG_DIRS_ONLY;
break;
case 'F':
if (flags & FLAG_DIRS_ONLY)
state = STATE_ERROR;
flags |= FLAG_FILES_ONLY;
break;
case 'u':
where |= 0100;
topbits |= 04000;
break;
case 'g':
where |= 0010;
topbits |= 02000;
break;
case 'o':
where |= 0001;
break;
case 'a':
where |= 0111;
break;
case '+':
op = CHMOD_ADD;
state = STATE_2ND_HALF;
break;
case '-':
op = CHMOD_SUB;
state = STATE_2ND_HALF;
break;
case '=':
op = CHMOD_EQ;
state = STATE_2ND_HALF;
break;
default:
state = STATE_ERROR;
break;
}
} else {
switch (*modestr) {
case 'r':
what |= 4;
break;
case 'w':
what |= 2;
break;
case 'X':
flags |= FLAG_X_KEEP;
/* FALL THROUGH */
case 'x':
what |= 1;
break;
case 's':
if (topbits)
topoct |= topbits;
else
topoct = 04000;
break;
case 't':
topoct |= 01000;
break;
default:
state = STATE_ERROR;
break;
}
}
modestr++;
}
if (state == STATE_ERROR) {
free_chmod_mode(first_mode);
return NULL;
}
if (!(curr_mode = *root_mode_ptr))
*root_mode_ptr = first_mode;
else {
while (curr_mode->next)
curr_mode = curr_mode->next;
curr_mode->next = first_mode;
}
return first_mode;
}
/* Takes an existing file permission and a list of AND/OR changes, and
* create a new permissions. */
int tweak_mode(int mode, struct chmod_mode_struct *chmod_modes)
{
int IsX = mode & 0111;
int NonPerm = mode & ~CHMOD_BITS;
for ( ; chmod_modes; chmod_modes = chmod_modes->next) {
if ((chmod_modes->flags & FLAG_DIRS_ONLY) && !S_ISDIR(NonPerm))
continue;
if ((chmod_modes->flags & FLAG_FILES_ONLY) && S_ISDIR(NonPerm))
continue;
mode &= chmod_modes->ModeAND;
if ((chmod_modes->flags & FLAG_X_KEEP) && !IsX && !S_ISDIR(NonPerm))
mode |= chmod_modes->ModeOR & ~0111;
else
mode |= chmod_modes->ModeOR;
}
return mode | NonPerm;
}
/* Free the linked list created by parse_chmod. */
int free_chmod_mode(struct chmod_mode_struct *chmod_modes)
{
struct chmod_mode_struct *next;
while (chmod_modes) {
next = chmod_modes->next;
free(chmod_modes);
chmod_modes = next;
}
return 0;
}

View File

@@ -26,6 +26,10 @@ extern int keep_partial;
extern int log_got_error;
extern char *partial_dir;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
#endif
/**
* Close all open sockets and files, allowing a (somewhat) graceful
* shutdown() of socket connections. This eliminates the abortive
@@ -94,17 +98,18 @@ void _exit_cleanup(int code, const char *file, int line)
}
inside_cleanup++;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
SIGACTION(SIGUSR1, SIG_IGN);
SIGACTION(SIGUSR2, SIG_IGN);
if (verbose > 3) {
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
code, safe_fname(file), line);
code, file, line);
}
if (cleanup_child_pid != -1) {
int status;
if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
if (wait_process(cleanup_child_pid, &status, WNOHANG)
== cleanup_child_pid) {
status = WEXITSTATUS(status);
if (status > code)
code = status;
@@ -121,8 +126,8 @@ void _exit_cleanup(int code, const char *file, int line)
flush_write_file(cleanup_fd_w);
close(cleanup_fd_w);
}
finish_transfer(cleanup_new_fname, fname, cleanup_file, 0,
!partial_dir);
finish_transfer(cleanup_new_fname, fname, NULL,
cleanup_file, 0, !partial_dir);
}
io_flush(FULL_FLUSH);
if (cleanup_fname)
@@ -149,7 +154,7 @@ void _exit_cleanup(int code, const char *file, int line)
if (verbose > 2) {
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
ocode, safe_fname(file), line, code);
ocode, file, line, code);
}
close_all();
@@ -166,7 +171,7 @@ void cleanup_disable(void)
void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
int fd_r, int fd_w)
{
cleanup_fname = fnametmp;
cleanup_fname = fname ? fnametmp : NULL;
cleanup_new_fname = fname;
cleanup_file = file;
cleanup_fd_r = fd_r;

View File

@@ -34,7 +34,6 @@
#include "rsync.h"
static const char default_name[] = "UNKNOWN";
extern int am_daemon;
extern int am_server;
@@ -321,7 +320,6 @@ int check_name(int fd,
return error;
}
/* Given all these results, we expect that one of them will be
* the same as ss. The comparison is a bit complicated. */
for (res = res0; res; res = res->ai_next) {

View File

@@ -28,6 +28,7 @@
#include "rsync.h"
extern int verbose;
extern int quiet;
extern int list_only;
extern int am_sender;
extern int am_server;
@@ -41,24 +42,31 @@ extern int filesfrom_fd;
extern int remote_protocol;
extern int protocol_version;
extern int io_timeout;
extern int select_timeout;
extern int orig_umask;
extern int no_detach;
extern int default_af_hint;
extern mode_t orig_umask;
extern char *bind_address;
extern struct filter_list_struct server_filter_list;
extern char *sockopts;
extern char *config_file;
extern char *files_from;
extern char *tmpdir;
extern struct chmod_mode_struct *chmod_modes;
extern struct filter_list_struct server_filter_list;
char *auth_user;
int read_only = 0;
int daemon_log_format_has_i = 0;
int daemon_log_format_has_o_or_i = 0;
int module_id = -1;
struct chmod_mode_struct *daemon_chmod_modes;
/* Length of lp_path() string when in daemon mode & not chrooted, else 0. */
unsigned int module_dirlen = 0;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
#endif
/**
* Run a client connected to an rsyncd. The alternative to this
* function for remote-shell connections is do_cmd().
@@ -98,9 +106,11 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
if (fd == -1)
exit_cleanup(RERR_SOCKETIO);
set_socket_options(fd, sockopts);
ret = start_inband_exchange(user, path, fd, fd, argc);
return ret < 0? ret : client_run(fd, fd, -1, argc, argv);
return ret ? ret : client_run(fd, fd, -1, argc, argv);
}
int start_inband_exchange(char *user, char *path, int f_in, int f_out,
@@ -109,7 +119,7 @@ int start_inband_exchange(char *user, char *path, int f_in, int f_out,
int i;
char *sargs[MAX_ARGS];
int sargc = 0;
char line[MAXPATHLEN];
char line[BIGPATHBUFLEN];
char *p;
if (argc == 0 && !am_sender)
@@ -196,10 +206,10 @@ int start_inband_exchange(char *user, char *path, int f_in, int f_out,
rprintf(FERROR, "%s\n", line);
/* This is always fatal; the server will now
* close the socket. */
return RERR_STARTCLIENT;
} else {
rprintf(FINFO,"%s\n", line);
return -1;
}
rprintf(FINFO, "%s\n", line);
}
kluge_around_eof = 0;
@@ -216,24 +226,62 @@ int start_inband_exchange(char *user, char *path, int f_in, int f_out,
return 0;
}
static char *finish_pre_exec(pid_t pid, int fd, char *request,
int argc, char *argv[])
{
int j, status = -1;
if (request) {
write_buf(fd, request, strlen(request)+1);
for (j = 0; j < argc; j++)
write_buf(fd, argv[j], strlen(argv[j])+1);
}
static int rsync_module(int f_in, int f_out, int i)
write_byte(fd, 0);
close(fd);
if (wait_process(pid, &status, 0) < 0
|| !WIFEXITED(status) || WEXITSTATUS(status) != 0) {
char *e;
if (asprintf(&e, "pre-xfer exec returned failure (%d)\n", status) < 0)
out_of_memory("finish_pre_exec");
return e;
}
return NULL;
}
static int read_arg_from_pipe(int fd, char *buf, int limit)
{
char *bp = buf, *eob = buf + limit - 1;
while (1) {
if (read(fd, bp, 1) != 1)
return -1;
if (*bp == '\0')
break;
if (bp < eob)
bp++;
}
*bp = '\0';
return bp - buf;
}
static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
{
int argc = 0;
int maxargs;
char **argv;
char **argp;
char line[MAXPATHLEN];
char line[BIGPATHBUFLEN];
uid_t uid = (uid_t)-2; /* canonically "nobody" */
gid_t gid = (gid_t)-2;
char *p;
char *addr = client_addr(f_in);
char *host = client_name(f_in);
char *p, *err_msg = NULL;
char *name = lp_name(i);
int use_chroot = lp_use_chroot(i);
int start_glob = 0;
int ret;
int ret, pre_exec_fd = -1;
pid_t pre_exec_pid = 0;
char *request = NULL;
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
@@ -257,7 +305,7 @@ static int rsync_module(int f_in, int f_out, int i)
if (!claim_connection(lp_lock_file(i), lp_max_connections(i))) {
if (errno) {
rsyserr(FLOG, errno, "failed to open lock file %s",
safe_fname(lp_lock_file(i)));
lp_lock_file(i));
io_printf(f_out, "@ERROR: failed to open lock file\n");
} else {
rprintf(FLOG, "max connections (%d) reached\n",
@@ -268,11 +316,9 @@ static int rsync_module(int f_in, int f_out, int i)
return -1;
}
auth_user = auth_server(f_in, f_out, i, addr, "@RSYNCD: AUTHREQD ");
auth_user = auth_server(f_in, f_out, i, host, addr, "@RSYNCD: AUTHREQD ");
if (!auth_user) {
rprintf(FLOG, "auth failed on module %s from %s (%s)\n",
name, host, addr);
io_printf(f_out, "@ERROR: auth failed on module %s\n", name);
return -1;
}
@@ -283,10 +329,10 @@ static int rsync_module(int f_in, int f_out, int i)
read_only = 1;
if (lp_transfer_logging(i)) {
if (strstr(lp_log_format(i), "%i") != NULL)
if (log_format_has(lp_log_format(i), 'i'))
daemon_log_format_has_i = 1;
if (daemon_log_format_has_i
|| strstr(lp_log_format(i), "%o") != NULL)
|| log_format_has(lp_log_format(i), 'o'))
daemon_log_format_has_o_or_i = 1;
}
@@ -321,37 +367,126 @@ static int rsync_module(int f_in, int f_out, int i)
/* TODO: Perhaps take a list of gids, and make them into the
* supplementary groups. */
if (use_chroot) {
if (use_chroot || (module_dirlen = strlen(lp_path(i))) == 1) {
module_dirlen = 0;
set_filter_dir("/", 1);
} else {
module_dirlen = strlen(lp_path(i));
} else
set_filter_dir(lp_path(i), module_dirlen);
}
p = lp_filter(i);
parse_rule(&server_filter_list, p, MATCHFLG_WORD_SPLIT,
XFLG_ANCHORED2ABS);
XFLG_ABS_IF_SLASH);
p = lp_include_from(i);
parse_filter_file(&server_filter_list, p, MATCHFLG_INCLUDE,
XFLG_ANCHORED2ABS | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
p = lp_include(i);
parse_rule(&server_filter_list, p,
MATCHFLG_INCLUDE | MATCHFLG_WORD_SPLIT,
XFLG_ANCHORED2ABS | XFLG_OLD_PREFIXES);
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES);
p = lp_exclude_from(i);
parse_filter_file(&server_filter_list, p, 0,
XFLG_ANCHORED2ABS | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES | XFLG_FATAL_ERRORS);
p = lp_exclude(i);
parse_rule(&server_filter_list, p, MATCHFLG_WORD_SPLIT,
XFLG_ANCHORED2ABS | XFLG_OLD_PREFIXES);
XFLG_ABS_IF_SLASH | XFLG_OLD_PREFIXES);
log_init();
#ifdef HAVE_PUTENV
if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
char *modname, *modpath, *hostaddr, *hostname, *username;
int status;
if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
|| asprintf(&modpath, "RSYNC_MODULE_PATH=%s", lp_path(i)) < 0
|| asprintf(&hostaddr, "RSYNC_HOST_ADDR=%s", addr) < 0
|| asprintf(&hostname, "RSYNC_HOST_NAME=%s", host) < 0
|| asprintf(&username, "RSYNC_USER_NAME=%s", auth_user) < 0)
out_of_memory("rsync_module");
putenv(modname);
putenv(modpath);
putenv(hostaddr);
putenv(hostname);
putenv(username);
umask(orig_umask);
/* For post-xfer exec, fork a new process to run the rsync
* daemon while this process waits for the exit status and
* runs the indicated command at that point. */
if (*lp_postxfer_exec(i)) {
pid_t pid = fork();
if (pid < 0) {
rsyserr(FLOG, errno, "fork failed");
io_printf(f_out, "@ERROR: fork failed\n");
return -1;
}
if (pid) {
char *ret1, *ret2;
if (wait_process(pid, &status, 0) < 0)
status = -1;
if (asprintf(&ret1, "RSYNC_RAW_STATUS=%d", status) > 0)
putenv(ret1);
if (WIFEXITED(status))
status = WEXITSTATUS(status);
else
status = -1;
if (asprintf(&ret2, "RSYNC_EXIT_STATUS=%d", status) > 0)
putenv(ret2);
system(lp_postxfer_exec(i));
_exit(status);
}
}
/* For pre-xfer exec, fork a child process to run the indicated
* command, though it first waits for the parent process to
* send us the user's request via a pipe. */
if (*lp_prexfer_exec(i)) {
int fds[2];
if (pipe(fds) < 0 || (pre_exec_pid = fork()) < 0) {
rsyserr(FLOG, errno, "pre-xfer exec preparation failed");
io_printf(f_out, "@ERROR: pre-xfer exec preparation failed\n");
return -1;
}
if (pre_exec_pid == 0) {
char buf[BIGPATHBUFLEN];
int j, len;
close(fds[1]);
set_blocking(fds[0]);
len = read_arg_from_pipe(fds[0], buf, BIGPATHBUFLEN);
if (len <= 0)
_exit(1);
if (asprintf(&p, "RSYNC_REQUEST=%s", buf) < 0)
out_of_memory("rsync_module");
putenv(p);
for (j = 0; ; j++) {
len = read_arg_from_pipe(fds[0], buf,
BIGPATHBUFLEN);
if (len <= 0) {
if (!len)
break;
_exit(1);
}
if (asprintf(&p, "RSYNC_ARG%d=%s", j, buf) < 0)
out_of_memory("rsync_module");
putenv(p);
}
close(fds[0]);
close(STDIN_FILENO);
close(STDOUT_FILENO);
status = system(lp_prexfer_exec(i));
if (!WIFEXITED(status))
_exit(1);
_exit(WEXITSTATUS(status));
}
close(fds[0]);
set_blocking(fds[1]);
pre_exec_fd = fds[1];
}
umask(0);
}
#endif
if (use_chroot) {
/*
* XXX: The 'use chroot' flag is a fairly reliable
@@ -367,14 +502,14 @@ static int rsync_module(int f_in, int f_out, int i)
*/
if (chroot(lp_path(i))) {
rsyserr(FLOG, errno, "chroot %s failed",
safe_fname(lp_path(i)));
lp_path(i));
io_printf(f_out, "@ERROR: chroot failed\n");
return -1;
}
if (!push_dir("/")) {
rsyserr(FLOG, errno, "chdir %s failed\n",
safe_fname(lp_path(i)));
lp_path(i));
io_printf(f_out, "@ERROR: chdir failed\n");
return -1;
}
@@ -382,7 +517,7 @@ static int rsync_module(int f_in, int f_out, int i)
} else {
if (!push_dir(lp_path(i))) {
rsyserr(FLOG, errno, "chdir %s failed\n",
safe_fname(lp_path(i)));
lp_path(i));
io_printf(f_out, "@ERROR: chdir failed\n");
return -1;
}
@@ -424,6 +559,16 @@ static int rsync_module(int f_in, int f_out, int i)
am_root = (MY_UID() == 0);
}
if (lp_temp_dir(i) && *lp_temp_dir(i)) {
tmpdir = lp_temp_dir(i);
if (strlen(tmpdir) >= MAXPATHLEN - 10) {
rprintf(FLOG,
"the 'temp dir' value for %s is WAY too long -- ignoring.\n",
name);
tmpdir = NULL;
}
}
io_printf(f_out, "@RSYNCD: OK\n");
maxargs = MAX_ARGS;
@@ -448,22 +593,37 @@ static int rsync_module(int f_in, int f_out, int i)
if (!(argv[argc] = strdup(p)))
out_of_memory("rsync_module");
if (start_glob) {
if (start_glob == 1) {
request = strdup(p);
start_glob++;
}
glob_expand(name, &argv, &argc, &maxargs);
} else
switch (start_glob) {
case 0:
argc++;
if (strcmp(line, ".") == 0)
start_glob = 1;
break;
case 1:
if (pre_exec_pid) {
err_msg = finish_pre_exec(pre_exec_pid,
pre_exec_fd, p,
argc, argv);
pre_exec_pid = 0;
}
request = strdup(p);
start_glob = 2;
/* FALL THROUGH */
default:
if (!err_msg)
glob_expand(name, &argv, &argc, &maxargs);
break;
}
}
if (strcmp(line, ".") == 0)
start_glob = 1;
if (pre_exec_pid) {
err_msg = finish_pre_exec(pre_exec_pid, pre_exec_fd, request,
argc, argv);
}
verbose = 0; /* future verbosity is controlled by client options */
argp = argv;
ret = parse_arguments(&argc, (const char ***) &argp, 0);
ret = parse_arguments(&argc, (const char ***) &argv, 0);
quiet = 0; /* Don't let someone try to be tricky. */
if (filesfrom_fd == 0)
filesfrom_fd = f_in;
@@ -483,14 +643,14 @@ static int rsync_module(int f_in, int f_out, int i)
#ifndef DEBUG
/* don't allow the logs to be flooded too fast */
if (verbose > lp_max_verbosity())
verbose = lp_max_verbosity();
if (verbose > lp_max_verbosity(i))
verbose = lp_max_verbosity(i);
#endif
if (protocol_version < 23
&& (protocol_version == 22 || am_sender))
io_start_multiplex_out();
else if (!ret) {
else if (!ret || err_msg) {
/* We have to get I/O multiplexing started so that we can
* get the error back to the client. This means getting
* the protocol setup finished first in later versions. */
@@ -516,19 +676,32 @@ static int rsync_module(int f_in, int f_out, int i)
io_start_multiplex_out();
}
if (!ret) {
option_error();
if (!ret || err_msg) {
if (err_msg)
rprintf(FERROR, err_msg);
else
option_error();
msleep(400);
exit_cleanup(RERR_UNSUPPORTED);
}
if (lp_timeout(i)) {
io_timeout = lp_timeout(i);
if (io_timeout < select_timeout)
select_timeout = io_timeout;
if (lp_timeout(i) && lp_timeout(i) > io_timeout)
set_io_timeout(lp_timeout(i));
/* If we have some incoming/outgoing chmod changes, append them to
* any user-specified changes (making our changes have priority).
* We also get a pointer to just our changes so that a receiver
* process can use them separately if --perms wasn't specified. */
if (am_sender)
p = lp_outgoing_chmod(i);
else
p = lp_incoming_chmod(i);
if (*p && !(daemon_chmod_modes = parse_chmod(p, &chmod_modes))) {
rprintf(FLOG, "Invalid \"%sing chmod\" directive: %s\n",
am_sender ? "outgo" : "incom", p);
}
start_server(f_in, f_out, argc, argp);
start_server(f_in, f_out, argc, argv);
return 0;
}
@@ -554,10 +727,14 @@ static void send_listing(int fd)
here */
int start_daemon(int f_in, int f_out)
{
char line[200];
char line[1024];
char *motd;
char *addr = client_addr(f_in);
char *host = client_name(f_in);
int i;
rprintf(FLOG, "connect from %s (%s)\n", host, addr);
io_set_sock_fds(f_in, f_out);
if (!lp_load(config_file, 0))
@@ -567,7 +744,10 @@ int start_daemon(int f_in, int f_out)
if (!am_server) {
set_socket_options(f_in, "SO_KEEPALIVE");
set_socket_options(f_in, lp_socket_options());
if (sockopts)
set_socket_options(f_in, sockopts);
else
set_socket_options(f_in, lp_socket_options());
set_nonblocking(f_in);
}
@@ -603,6 +783,8 @@ int start_daemon(int f_in, int f_out)
return -1;
if (!*line || strcmp(line, "#list") == 0) {
rprintf(FLOG, "module-list request from %s (%s)\n",
host, addr);
send_listing(f_out);
return -1;
}
@@ -614,17 +796,19 @@ int start_daemon(int f_in, int f_out)
}
if ((i = lp_number(line)) < 0) {
char *addr = client_addr(f_in);
char *host = client_name(f_in);
rprintf(FLOG, "unknown module '%s' tried from %s (%s)\n",
line, host, addr);
io_printf(f_out, "@ERROR: Unknown module '%s'\n", line);
return -1;
}
return rsync_module(f_in, f_out, i);
}
#ifdef HAVE_SIGACTION
sigact.sa_flags = SA_NOCLDSTOP;
#endif
SIGACTION(SIGCHLD, remember_children);
return rsync_module(f_in, f_out, i, addr, host);
}
int daemon_main(void)
{
@@ -672,7 +856,7 @@ int daemon_main(void)
0666 & ~orig_umask)) == -1) {
cleanup_set_pid(0);
rsyserr(FLOG, errno, "failed to create pid file %s",
safe_fname(pid_file));
pid_file);
exit_cleanup(RERR_FILEIO);
}
snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);

View File

@@ -29,12 +29,12 @@ int remote_protocol = 0;
extern int verbose;
extern int am_server;
extern int am_sender;
extern int inplace;
extern int fuzzy_basis;
extern int read_batch;
extern int checksum_seed;
extern int basis_dir_cnt;
extern int prune_empty_dirs;
extern int protocol_version;
extern char *dest_option;
@@ -78,25 +78,38 @@ void setup_protocol(int f_out,int f_in)
exit_cleanup(RERR_PROTOCOL);
}
if (fuzzy_basis && protocol_version < 29) {
rprintf(FERROR,
"--fuzzy requires protocol 29 or higher (negotiated %d).\n",
protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
if (protocol_version < 29) {
if (fuzzy_basis) {
rprintf(FERROR,
"--fuzzy requires protocol 29 or higher"
" (negotiated %d).\n",
protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
if (basis_dir_cnt && inplace && protocol_version < 29) {
rprintf(FERROR,
"%s with --inplace requires protocol 29 or higher (negotiated %d).\n",
dest_option, 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);
exit_cleanup(RERR_PROTOCOL);
}
if (basis_dir_cnt > 1 && protocol_version < 29) {
rprintf(FERROR,
"Multiple %s options requires protocol 29 or higher (negotiated %d).\n",
dest_option, 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);
exit_cleanup(RERR_PROTOCOL);
}
if (prune_empty_dirs) {
rprintf(FERROR,
"--prune-empty-dirs requires protocol 29 or higher"
" (negotiated %d).\n",
protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
}
if (am_server) {

View File

@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.59)
RSYNC_VERSION=2.6.4pre4
RSYNC_VERSION=2.6.7
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -26,8 +26,7 @@ AC_SUBST(SHELL)
AC_DEFINE([_GNU_SOURCE], 1,
[Define _GNU_SOURCE so that we get all necessary prototypes])
if test "x$ac_cv_prog_cc_stdc" = xno
then
if test x"$ac_cv_prog_cc_stdc" = x"no"; then
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
fi
@@ -38,12 +37,10 @@ fi
AC_MSG_CHECKING([whether to include debugging symbols])
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug],
[including debugging symbols and features (default yes)]),
[], [])
AC_HELP_STRING([--disable-debug],
[turn off debugging symbols and features]))
if test x"$enable_debug" = x"no"
then
if test x"$enable_debug" = x"no"; then
AC_MSG_RESULT(no)
CFLAGS=${CFLAGS-"-O"}
else
@@ -54,14 +51,10 @@ else
fi
AC_ARG_ENABLE(profile,
AC_HELP_STRING([--enable-profile],
[turn on CPU profiling (default no)],
[], []))
if test x"$enable_profile" = xyes
then
[turn on CPU profiling]))
if test x"$enable_profile" = x"yes"; then
CFLAGS="$CFLAGS -pg"
fi
@@ -69,10 +62,8 @@ fi
# Specifically, this turns on panic_action handling.
AC_ARG_ENABLE(maintainer-mode,
AC_HELP_STRING([--enable-maintainer-mode],
[turn on extra debug features],
[], []))
if test x"$enable_maintainer_mode" = xyes
then
[turn on extra debug features]))
if test x"$enable_maintainer_mode" = x"yes"; then
CFLAGS="$CFLAGS -DMAINTAINER_MODE"
fi
@@ -82,16 +73,15 @@ fi
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
# If GCC, turn on warnings.
if test x"$GCC" = x"yes"
then
if test x"$GCC" = x"yes"; then
CFLAGS="$CFLAGS -Wall -W"
fi
AC_ARG_WITH(included-popt,
[ --with-included-popt use bundled popt library, not from system])
AC_HELP_STRING([--with-included-popt], [use bundled popt library, not from system]))
AC_ARG_WITH(rsync-path,
[ --with-rsync-path=PATH set default --rsync-path to PATH (default: rsync)],
AC_HELP_STRING([--with-rsync-path=PATH], [set default --rsync-path to PATH (default: rsync)]),
[ RSYNC_PATH="$with_rsync_path" ],
[ RSYNC_PATH="rsync" ])
@@ -122,18 +112,30 @@ AC_ARG_WITH(rsh,
AC_HELP_STRING([--with-rsh=CMD], [set remote shell command to CMD (default: ssh)]))
AC_CHECK_PROG(HAVE_REMSH, remsh, 1, 0)
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [remote shell is remsh not rsh])
if test x$HAVE_REMSH = x1; then
AC_DEFINE(HAVE_REMSH, 1, [Define to 1 if remote shell is remsh, not rsh])
fi
if test x"$with_rsh" != x
then
if test x"$with_rsh" != x; then
RSYNC_RSH="$with_rsh"
else
RSYNC_RSH="ssh"
fi
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
# arrgh. libc in the current debian stable screws up the largefile
AC_MSG_CHECKING([the group for user "nobody"])
if grep '^nobody:' /etc/group >/dev/null 2>&1; then
NOBODY_GROUP=nobody
elif grep '^nogroup:' /etc/group >/dev/null 2>&1; then
NOBODY_GROUP=nogroup
else
NOBODY_GROUP=nobody # test for others?
fi
AC_MSG_RESULT($NOBODY_GROUP)
AC_DEFINE_UNQUOTED(NOBODY_USER, "nobody", [unprivileged user--e.g. nobody])
AC_DEFINE_UNQUOTED(NOBODY_GROUP, "$NOBODY_GROUP", [unprivileged group for unprivileged user])
# arrgh. libc in some old debian version screwed up the largefile
# stuff, getting byte range locking wrong
AC_CACHE_CHECK([for broken largefile support],rsync_cv_HAVE_BROKEN_LARGEFILE,[
AC_TRY_RUN([
@@ -179,10 +181,9 @@ ipv6lib=none
ipv6trylibc=yes
AC_ARG_ENABLE(ipv6,
AC_HELP_STRING([--disable-ipv6], [don't even try to use IPv6]))
if test "x$enable_ipv6" != xno
then
AC_HELP_STRING([--disable-ipv6],
[don't even try to use IPv6]))
if test x"$enable_ipv6" != x"no"; then
AC_MSG_CHECKING([ipv6 stack type])
for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
case $i in
@@ -271,6 +272,16 @@ yes
AC_SEARCH_LIBS(getaddrinfo, inet6)
fi
dnl Do you want to disable use of locale functions
AC_ARG_ENABLE([locale],
AC_HELP_STRING([--disable-locale],
[turn off locale features]))
AH_TEMPLATE([CONFIG_LOCALE],
[Undefine if you don't want locale features. By default this is defined.])
if test x"$enable_locale" != x"no"; then
AC_DEFINE(CONFIG_LOCALE)
fi
AC_MSG_CHECKING([whether to call shutdown on all sockets])
case $host_os in
*cygwin* ) AC_MSG_RESULT(yes)
@@ -287,8 +298,8 @@ AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \
unistd.h utime.h grp.h compat.h sys/param.h ctype.h sys/wait.h \
sys/ioctl.h sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h \
sys/un.h glob.h mcheck.h arpa/inet.h arpa/nameser.h \
netdb.h malloc.h float.h)
sys/un.h glob.h mcheck.h arpa/inet.h arpa/nameser.h locale.h \
netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h)
AC_HEADER_MAJOR
AC_CHECK_SIZEOF(int)
@@ -355,7 +366,11 @@ if test x"$ac_cv_func_connect" = x"no"; then
fi
fi
AC_CHECK_LIB(resolv, inet_ntop)
AC_SEARCH_LIBS(inet_ntop, resolv)
# Solaris and HP-UX weirdness:
# Search for libiconv_open (not iconv_open) to discover if -liconv is needed!
AC_SEARCH_LIBS(libiconv_open, iconv)
dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
@@ -474,11 +489,13 @@ dnl AC_FUNC_MEMCMP
AC_FUNC_UTIME_NULL
AC_FUNC_ALLOCA
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod mkfifo \
fchmod fstat strchr readlink link utime utimes strftime mtrace ftruncate \
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
memmove lchown vsnprintf snprintf vasprintf asprintf setsid glob strpbrk \
strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
setmode open64 mkstemp64 va_copy __va_copy)
setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
strerror putenv iconv_open locale_charset nl_langinfo \
sigaction sigprocmask)
AC_CHECK_FUNCS(getpgrp tcgetpgrp)
if test $ac_cv_func_getpgrp = yes; then
@@ -519,14 +536,12 @@ if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
AC_DEFINE(HAVE_SOCKETPAIR, 1, [Define to 1 if you have the "socketpair" function])
fi
if test x"$with_included_popt" != x"yes"
then
if test x"$with_included_popt" != x"yes"; then
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
fi
AC_MSG_CHECKING([whether to use included libpopt])
if test x"$with_included_popt" = x"yes"
then
if test x"$with_included_popt" = x"yes"; then
AC_MSG_RESULT($srcdir/popt)
BUILD_POPT='$(popt_OBJS)'
CFLAGS="$CFLAGS -I$srcdir/popt"
@@ -621,7 +636,17 @@ rsync_cv_HAVE_SECURE_MKSTEMP=yes,
rsync_cv_HAVE_SECURE_MKSTEMP=no,
rsync_cv_HAVE_SECURE_MKSTEMP=cross)])
if test x"$rsync_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
AC_DEFINE(HAVE_SECURE_MKSTEMP, 1, [Define to 1 if mkstemp() is available and works right])
case $target_os in
hpux*)
dnl HP-UX has a broken mkstemp() implementation they refuse to fix,
dnl so we noisily skip using it. See HP change request JAGaf34426
dnl for details. (sbonds)
AC_MSG_WARN(Skipping broken HP-UX mkstemp() -- using mktemp() instead)
;;
*)
AC_DEFINE(HAVE_SECURE_MKSTEMP, 1, [Define to 1 if mkstemp() is available and works right])
;;
esac
fi
@@ -661,7 +686,7 @@ AC_TRY_RUN([
#include <errno.h>
main() { int rc, ec; char *fn = "fifo-test";
unlink(fn); rc = mknod(fn,S_IFIFO,0600); ec = errno; unlink(fn);
if (rc) {printf("%d %d\n",rc,ec); return ec;}
if (rc) {printf("(%d %d) ",rc,ec); return ec;}
return 0;}],
rsync_cv_MKNOD_CREATES_FIFOS=yes,rsync_cv_MKNOD_CREATES_FIFOS=no,rsync_cv_MKNOD_CREATES_FIFOS=cross)])
if test x"$rsync_cv_MKNOD_CREATES_FIFOS" = x"yes"; then
@@ -675,7 +700,7 @@ AC_TRY_RUN([
#include <errno.h>
main() { int rc, ec; char *fn = "sock-test";
unlink(fn); rc = mknod(fn,S_IFSOCK,0600); ec = errno; unlink(fn);
if (rc) {printf("%d %d\n",rc,ec); return ec;}
if (rc) {printf("(%d %d) ",rc,ec); return ec;}
return 0;}],
rsync_cv_MKNOD_CREATES_SOCKETS=yes,rsync_cv_MKNOD_CREATES_SOCKETS=no,rsync_cv_MKNOD_CREATES_SOCKETS=cross)])
if test x"$rsync_cv_MKNOD_CREATES_SOCKETS" = x"yes"; then
@@ -716,21 +741,6 @@ AC_SUBST(BUILD_POPT)
AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig])
AC_OUTPUT
if test x"$with_rsh" = x; then
if test x"$HAVE_REMSH" = x1; then
rmsh1='remsh:'
rmsh2='=remsh'
else
rmsh1='rsh: '
rmsh2='=rsh '
fi
AC_MSG_RESULT()
AC_MSG_RESULT([ **********************************************************************])
AC_MSG_RESULT([ * As of v2.6.0, the default remote shell is ssh instead of rsh!! *])
AC_MSG_RESULT([ * To use previous default of $rmsh1 ./configure --with-rsh$rmsh2 *])
AC_MSG_RESULT([ **********************************************************************])
fi
AC_MSG_RESULT()
AC_MSG_RESULT([ rsync ${RSYNC_VERSION} configuration successful])
AC_MSG_RESULT()

View File

@@ -28,15 +28,17 @@
#define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */
#define RERR_UNSUPPORTED 4 /* requested action not supported */
#define RERR_STARTCLIENT 5 /* error starting client-server protocol */
#define RERR_LOG_FAILURE 6 /* daemon unable to append to log-file */
#define RERR_SOCKETIO 10 /* error in socket IO */
#define RERR_FILEIO 11 /* error in file IO */
#define RERR_STREAMIO 12 /* error in rsync protocol data stream */
#define RERR_MESSAGEIO 13 /* errors with program diagnostics */
#define RERR_IPC 14 /* error in IPC code */
#define RERR_CRASHED 15 /* sibling crashed */
#define RERR_TERMINATED 16 /* sibling terminated abnormally */
#define RERR_SIGNAL 20 /* status returned when sent SIGUSR1, SIGINT */
#define RERR_SIGNAL1 19 /* status returned when sent SIGUSR1 */
#define RERR_SIGNAL 20 /* status returned when sent SIGINT, SIGTERM, SIGHUP */
#define RERR_WAITCHILD 21 /* some error returned by waitpid() */
#define RERR_MALLOC 22 /* error allocating core memory buffers */
#define RERR_PARTIAL 23 /* partial transfer */

168
exclude.c
View File

@@ -34,6 +34,9 @@ extern int list_only;
extern int recurse;
extern int io_error;
extern int local_server;
extern int saw_delete_opt;
extern int saw_delete_excluded_opt;
extern int prune_empty_dirs;
extern int delete_mode;
extern int delete_excluded;
extern int cvs_exclude;
@@ -46,8 +49,8 @@ extern unsigned int curr_dir_len;
extern unsigned int module_dirlen;
struct filter_list_struct filter_list = { 0, 0, "" };
struct filter_list_struct cvs_filter_list = { 0, 0, " [cvsignore]" };
struct filter_list_struct server_filter_list = { 0, 0, " [server]" };
struct filter_list_struct cvs_filter_list = { 0, 0, " [global CVS]" };
struct filter_list_struct server_filter_list = { 0, 0, " [daemon]" };
/* Need room enough for ":MODS " prefix plus some room to grow. */
#define MAX_RULE_PREFIX (16)
@@ -133,9 +136,9 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
listp->debug_type);
}
/* This flag also indicates that we're reading a list that
/* These flags also indicate that we're reading a list that
* needs to be filtered now, not post-filtered later. */
if (xflags & XFLG_ANCHORED2ABS) {
if (xflags & (XFLG_ANCHORED2ABS|XFLG_ABS_IF_SLASH)) {
uint32 mf = mflags & (MATCHFLG_RECEIVER_SIDE|MATCHFLG_SENDER_SIDE);
if (am_sender) {
if (mf == MATCHFLG_RECEIVER_SIDE)
@@ -150,10 +153,14 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
out_of_memory("add_rule");
memset(ret, 0, sizeof ret[0]);
if (xflags & XFLG_ANCHORED2ABS && *pat == '/'
&& !(mflags & (MATCHFLG_ABS_PATH | MATCHFLG_MERGE_FILE))) {
if (!(mflags & (MATCHFLG_ABS_PATH | MATCHFLG_MERGE_FILE))
&& ((xflags & (XFLG_ANCHORED2ABS|XFLG_ABS_IF_SLASH) && *pat == '/')
|| (xflags & XFLG_ABS_IF_SLASH && strchr(pat, '/') != NULL))) {
mflags |= MATCHFLG_ABS_PATH;
ex_len = dirbuf_len - module_dirlen - 1;
if (*pat == '/')
ex_len = dirbuf_len - module_dirlen - 1;
else
ex_len = 0;
} else
ex_len = 0;
if (!(ret->pattern = new_array(char, ex_len + pat_len + 1)))
@@ -170,6 +177,12 @@ static void add_rule(struct filter_list_struct *listp, const char *pat,
/* If the pattern starts with **, note that. */
if (cp == ret->pattern)
mflags |= MATCHFLG_WILD2_PREFIX;
/* If the pattern ends with ***, note that. */
if (pat_len >= 3
&& ret->pattern[pat_len-3] == '*'
&& ret->pattern[pat_len-2] == '*'
&& ret->pattern[pat_len-1] == '*')
mflags |= MATCHFLG_WILD3_SUFFIX;
}
}
@@ -292,7 +305,7 @@ static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr,
}
if (!sanitize_path(fn, merge_file, r, dirbuf_depth)) {
rprintf(FERROR, "merge-file name overflows: %s\n",
safe_fname(merge_file));
merge_file);
return NULL;
}
} else {
@@ -305,8 +318,7 @@ static char *parse_merge_name(const char *merge_file, unsigned int *len_ptr,
goto done;
if (dirbuf_len + fn_len >= MAXPATHLEN) {
rprintf(FERROR, "merge-file name overflows: %s\n",
safe_fname(fn));
rprintf(FERROR, "merge-file name overflows: %s\n", fn);
return NULL;
}
memcpy(buf, dirbuf + prefix_skip, dirbuf_len - prefix_skip);
@@ -488,70 +500,68 @@ void pop_local_filters(void *mem)
static int rule_matches(char *name, struct filter_struct *ex, int name_is_dir)
{
char *p, full_name[MAXPATHLEN];
int match_start = 0;
int slash_handling, str_cnt = 0, anchored_match = 0;
int ret_match = ex->match_flags & MATCHFLG_NEGATE ? 0 : 1;
char *pattern = ex->pattern;
char *p, *pattern = ex->pattern;
const char *strings[16]; /* more than enough */
if (!*name)
return 0;
/* If the pattern does not have any slashes AND it does not have
* a "**" (which could match a slash), then we just match the
* name portion of the path. */
if (!ex->u.slash_cnt && !(ex->match_flags & MATCHFLG_WILD2)) {
/* If the pattern does not have any slashes AND it does
* not have a "**" (which could match a slash), then we
* just match the name portion of the path. */
if ((p = strrchr(name,'/')) != NULL)
name = p+1;
}
else if (ex->match_flags & MATCHFLG_ABS_PATH && *name != '/'
} else if (ex->match_flags & MATCHFLG_ABS_PATH && *name != '/'
&& curr_dir_len > module_dirlen + 1) {
pathjoin(full_name, sizeof full_name,
curr_dir + module_dirlen + 1, name);
name = full_name;
/* If we're matching against an absolute-path pattern,
* we need to prepend our full path info. */
strings[str_cnt++] = curr_dir + module_dirlen + 1;
strings[str_cnt++] = "/";
} else if (ex->match_flags & MATCHFLG_WILD2_PREFIX && *name != '/') {
/* Allow "**"+"/" to match at the start of the string. */
strings[str_cnt++] = "/";
}
if (ex->match_flags & MATCHFLG_DIRECTORY && !name_is_dir)
strings[str_cnt++] = name;
if (name_is_dir) {
/* Allow a trailing "/"+"***" to match the directory. */
if (ex->match_flags & MATCHFLG_WILD3_SUFFIX)
strings[str_cnt++] = "/";
} else if (ex->match_flags & MATCHFLG_DIRECTORY)
return !ret_match;
strings[str_cnt] = NULL;
if (*pattern == '/') {
match_start = 1;
anchored_match = 1;
pattern++;
if (*name == '/')
name++;
if (strings[0][0] == '/')
strings[0]++;
}
if (!anchored_match && ex->u.slash_cnt
&& !(ex->match_flags & MATCHFLG_WILD2)) {
/* A non-anchored match with an infix slash and no "**"
* needs to match the last slash_cnt+1 name elements. */
slash_handling = ex->u.slash_cnt + 1;
} else if (!anchored_match && !(ex->match_flags & MATCHFLG_WILD2_PREFIX)
&& ex->match_flags & MATCHFLG_WILD2) {
/* A non-anchored match with an infix or trailing "**" (but not
* a prefixed "**") needs to try matching after every slash. */
slash_handling = -1;
} else {
/* The pattern matches only at the start of the path or name. */
slash_handling = 0;
}
if (ex->match_flags & MATCHFLG_WILD) {
/* A non-anchored match with an infix slash and no "**"
* needs to match the last slash_cnt+1 name elements. */
if (!match_start && ex->u.slash_cnt
&& !(ex->match_flags & MATCHFLG_WILD2)) {
int cnt = ex->u.slash_cnt + 1;
for (p = name + strlen(name) - 1; p >= name; p--) {
if (*p == '/' && !--cnt)
break;
}
name = p+1;
}
if (wildmatch(pattern, name))
if (wildmatch_array(pattern, strings, slash_handling))
return ret_match;
if (ex->match_flags & MATCHFLG_WILD2_PREFIX) {
/* If the **-prefixed pattern has a '/' as the next
* character, then try to match the rest of the
* pattern at the root. */
if (pattern[2] == '/' && wildmatch(pattern+3, name))
return ret_match;
}
else if (!match_start && ex->match_flags & MATCHFLG_WILD2) {
/* A non-anchored match with an infix or trailing "**"
* (but not a prefixed "**") needs to try matching
* after every slash. */
while ((name = strchr(name, '/')) != NULL) {
name++;
if (wildmatch(pattern, name))
return ret_match;
}
}
} else if (match_start) {
} else if (str_cnt > 1) {
if (litmatch_array(pattern, strings, slash_handling))
return ret_match;
} else if (anchored_match) {
if (strcmp(name,pattern) == 0)
return ret_match;
} else {
@@ -577,11 +587,13 @@ static void report_filter_result(char const *name,
* case we add it back in here. */
if (verbose >= 2) {
rprintf(FINFO, "[%s] %scluding %s %s because of pattern %s%s%s\n",
who_am_i(),
ent->match_flags & MATCHFLG_INCLUDE ? "in" : "ex",
name_is_dir ? "directory" : "file", name, ent->pattern,
ent->match_flags & MATCHFLG_DIRECTORY ? "/" : "", type);
static char *actions[2][2]
= { {"show", "hid"}, {"risk", "protect"} };
const char *w = who_am_i();
rprintf(FINFO, "[%s] %sing %s %s because of pattern %s%s%s\n",
w, actions[*w!='s'][!(ent->match_flags&MATCHFLG_INCLUDE)],
name_is_dir ? "directory" : "file", name, ent->pattern,
ent->match_flags & MATCHFLG_DIRECTORY ? "/" : "", type);
}
}
@@ -674,8 +686,7 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags,
} else if (*s == '+' && s[1] == ' ') {
new_mflags |= MATCHFLG_INCLUDE;
s += 2;
}
if (*s == '!')
} else if (*s == '!')
new_mflags |= MATCHFLG_CLEAR_LIST; /* Tentative! */
} else {
char ch = 0, *mods = "";
@@ -716,7 +727,6 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags,
if ((s = RULE_STRCMP(s, "show")) != NULL)
ch = 'S';
break;
default:
ch = *s;
if (s[1] == ',')
@@ -829,7 +839,8 @@ static const char *parse_rule_tok(const char *p, uint32 mflags, int xflags,
len = strlen((char*)s);
if (new_mflags & MATCHFLG_CLEAR_LIST) {
if (!(xflags & XFLG_OLD_PREFIXES) && len) {
if (!(mflags & MATCHFLG_NO_PREFIXES)
&& !(xflags & XFLG_OLD_PREFIXES) && len) {
rprintf(FERROR,
"'!' rule has trailing characters: %s\n", p);
exit_cleanup(RERR_SYNTAX);
@@ -956,7 +967,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
uint32 mflags, int xflags)
{
FILE *fp;
char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */
char line[BIGPATHBUFLEN];
char *eob = line + sizeof line - 1;
int word_split = mflags & MATCHFLG_WORD_SPLIT;
@@ -978,7 +989,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
if (verbose > 2) {
rprintf(FINFO, "[%s] parse_filter_file(%s,%x,%x)%s\n",
who_am_i(), safe_fname(fname), mflags, xflags,
who_am_i(), fname, mflags, xflags,
fp ? "" : " [not found]");
}
@@ -987,7 +998,7 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
rsyserr(FERROR, errno,
"failed to open %sclude file %s",
mflags & MATCHFLG_INCLUDE ? "in" : "ex",
safe_fname(fname));
fname);
exit_cleanup(RERR_FILEIO);
}
return;
@@ -999,8 +1010,10 @@ void parse_filter_file(struct filter_list_struct *listp, const char *fname,
int ch, overflow = 0;
while (1) {
if ((ch = getc(fp)) == EOF) {
if (ferror(fp) && errno == EINTR)
if (ferror(fp) && errno == EINTR) {
clearerr(fp);
continue;
}
break;
}
if (word_split && isspace(ch))
@@ -1107,9 +1120,9 @@ static void send_rules(int f_out, struct filter_list_struct *flp)
continue;
if (ent->match_flags & MATCHFLG_CVS_IGNORE
&& !(ent->match_flags & MATCHFLG_MERGE_FILE)) {
int f = am_sender || protocol_version < 29 ? f_out : -1;
int f = am_sender || protocol_version < 29 ? f_out : -2;
send_rules(f, &cvs_filter_list);
if (f >= 0)
if (f == f_out)
continue;
}
p = get_rule_prefix(ent->match_flags, ent->pattern, 1, &plen);
@@ -1137,8 +1150,8 @@ static void send_rules(int f_out, struct filter_list_struct *flp)
/* This is only called by the client. */
void send_filter_list(int f_out)
{
int receiver_wants_list = delete_mode
&& (!delete_excluded || protocol_version >= 29);
int receiver_wants_list = prune_empty_dirs
|| (delete_mode && (!delete_excluded || protocol_version >= 29));
if (local_server || (am_sender && !receiver_wants_list))
f_out = -1;
@@ -1169,16 +1182,17 @@ void send_filter_list(int f_out)
/* This is only called by the server. */
void recv_filter_list(int f_in)
{
char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */
char line[BIGPATHBUFLEN];
int xflags = protocol_version >= 29 ? 0 : XFLG_OLD_PREFIXES;
int receiver_wants_list = delete_mode
&& (!delete_excluded || protocol_version >= 29);
int receiver_wants_list = prune_empty_dirs
|| (saw_delete_opt
&& (!saw_delete_excluded_opt || protocol_version >= 29));
unsigned int len;
if (!local_server && (am_sender || receiver_wants_list)) {
while ((len = read_int(f_in)) != 0) {
if (len >= sizeof line)
overflow("recv_rules");
overflow_exit("recv_rules");
read_sbuf(f_in, line, len);
parse_rule(&filter_list, line, 0, xflags);
}

View File

@@ -22,6 +22,10 @@
*/
#include "rsync.h"
#ifndef ENODATA
#define ENODATA EAGAIN
#endif
extern int sparse_files;
static char last_byte;
@@ -217,34 +221,35 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
rprintf(FERROR, "invalid read_size of %ld in map_ptr\n",
(long)read_size);
exit_cleanup(RERR_FILEIO);
} else {
if (map->p_fd_offset != read_start) {
OFF_T ret = do_lseek(map->fd, read_start, SEEK_SET);
if (ret != read_start) {
rsyserr(FERROR, errno,
"lseek returned %.0f, not %.0f",
(double)ret, (double)read_start);
exit_cleanup(RERR_FILEIO);
}
map->p_fd_offset = read_start;
}
if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
if (nread < 0) {
nread = 0;
if (!map->status)
map->status = errno;
}
/* the best we can do is zero the buffer - the file
has changed mid transfer! */
memset(map->p+read_offset+nread, 0, read_size - nread);
}
map->p_fd_offset += nread;
}
if (map->p_fd_offset != read_start) {
OFF_T ret = do_lseek(map->fd, read_start, SEEK_SET);
if (ret != read_start) {
rsyserr(FERROR, errno, "lseek returned %.0f, not %.0f",
(double)ret, (double)read_start);
exit_cleanup(RERR_FILEIO);
}
map->p_fd_offset = read_start;
}
map->p_fd_offset += read_size;
map->p_offset = window_start;
map->p_len = window_size;
while (read_size > 0) {
nread = read(map->fd, map->p + read_offset, read_size);
if (nread <= 0) {
if (!map->status)
map->status = nread ? errno : ENODATA;
/* The best we can do is zero the buffer -- the file
* has changed mid transfer! */
memset(map->p + read_offset, 0, read_size);
break;
}
read_offset += nread;
read_size -= nread;
}
return map->p;
}

635
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

185
hlink.c
View File

@@ -20,13 +20,18 @@
#include "rsync.h"
extern int dry_run;
extern int verbose;
extern int link_dest;
extern int make_backups;
extern int log_format_has_i;
extern char *basis_dir[];
extern struct file_list *the_file_list;
#ifdef SUPPORT_HARD_LINKS
#define SKIPPED_LINK (-1)
#define FINISHED_LINK (-2)
#define FPTR(i) (the_file_list->files[i])
#define LINKED(p1,p2) (FPTR(p1)->F_DEV == FPTR(p2)->F_DEV \
&& FPTR(p1)->F_INODE == FPTR(p2)->F_INODE)
@@ -52,7 +57,7 @@ static int hlink_count;
* linked, and replace the dev+inode data with the hlindex+next linked list. */
static void link_idev_data(void)
{
int head, from, to, start;
int cur, from, to, start;
alloc_pool_t hlink_pool;
alloc_pool_t idev_pool = the_file_list->hlink_pool;
@@ -62,31 +67,31 @@ static void link_idev_data(void)
for (from = to = 0; from < hlink_count; from++) {
start = from;
head = hlink_list[start];
while (from < hlink_count-1
&& LINKED(hlink_list[from], hlink_list[from+1])) {
pool_free(idev_pool, 0, FPTR(hlink_list[from])->link_u.idev);
FPTR(hlink_list[from])->link_u.links = pool_talloc(hlink_pool,
while (1) {
cur = hlink_list[from];
if (from == hlink_count-1
|| !LINKED(cur, hlink_list[from+1]))
break;
pool_free(idev_pool, 0, FPTR(cur)->link_u.idev);
FPTR(cur)->link_u.links = pool_talloc(hlink_pool,
struct hlink, 1, "hlink_list");
FPTR(hlink_list[from])->F_HLINDEX = to;
FPTR(hlink_list[from])->F_NEXT = hlink_list[from+1];
from++;
FPTR(cur)->F_HLINDEX = to;
FPTR(cur)->F_NEXT = hlink_list[++from];
}
pool_free(idev_pool, 0, FPTR(cur)->link_u.idev);
if (from > start) {
pool_free(idev_pool, 0, FPTR(hlink_list[from])->link_u.idev);
FPTR(hlink_list[from])->link_u.links = pool_talloc(hlink_pool,
int head = hlink_list[start];
FPTR(cur)->link_u.links = pool_talloc(hlink_pool,
struct hlink, 1, "hlink_list");
FPTR(head)->flags |= FLAG_HLINK_TOL;
FPTR(hlink_list[from])->F_HLINDEX = to;
FPTR(hlink_list[from])->F_NEXT = head;
FPTR(hlink_list[from])->flags |= FLAG_HLINK_EOL;
FPTR(cur)->F_HLINDEX = to;
FPTR(cur)->F_NEXT = head;
FPTR(cur)->flags |= FLAG_HLINK_EOL;
hlink_list[to++] = head;
} else {
pool_free(idev_pool, 0, FPTR(head)->link_u.idev);
FPTR(head)->link_u.idev = NULL;
}
} else
FPTR(cur)->link_u.links = NULL;
}
if (!to) {
@@ -110,9 +115,6 @@ void init_hard_links(void)
#ifdef SUPPORT_HARD_LINKS
int i;
if (the_file_list->count < 2)
return;
if (hlink_list)
free(hlink_list);
@@ -136,18 +138,90 @@ void init_hard_links(void)
#endif
}
int hard_link_check(struct file_struct *file, int ndx, int skip)
#ifdef SUPPORT_HARD_LINKS
static int maybe_hard_link(struct file_struct *file, int ndx,
char *fname, int statret, STRUCT_STAT *st,
char *toname, STRUCT_STAT *to_st,
int itemizing, enum logcode code)
{
if (statret == 0) {
if (st->st_dev == to_st->st_dev
&& st->st_ino == to_st->st_ino) {
if (itemizing) {
itemize(file, ndx, statret, st,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
0, "");
}
return 0;
}
if (make_backups) {
if (!make_backup(fname))
return -1;
} else if (robust_unlink(fname)) {
rsyserr(FERROR, errno, "unlink %s failed",
full_fname(fname));
return -1;
}
}
return hard_link_one(file, ndx, fname, statret, st, toname,
0, itemizing, code);
}
#endif
int hard_link_check(struct file_struct *file, int ndx, char *fname,
int statret, STRUCT_STAT *st, int itemizing,
enum logcode code, int skip)
{
#ifdef SUPPORT_HARD_LINKS
if (!hlink_list || !file->link_u.links)
return 0;
int head;
if (skip && !(file->flags & FLAG_HLINK_EOL))
hlink_list[file->F_HLINDEX] = file->F_NEXT;
if (hlink_list[file->F_HLINDEX] != ndx) {
if (verbose > 2) {
head = hlink_list[file->F_HLINDEX] = file->F_NEXT;
else
head = hlink_list[file->F_HLINDEX];
if (ndx != head) {
struct file_struct *head_file = FPTR(head);
if (!log_format_has_i && verbose > 1) {
rprintf(FINFO, "\"%s\" is a hard link\n",
safe_fname(f_name(file)));
f_name(file, NULL));
}
if (head_file->F_HLINDEX == FINISHED_LINK) {
STRUCT_STAT st2, st3;
char *toname = f_name(head_file, NULL);
if (link_stat(toname, &st2, 0) < 0) {
rsyserr(FERROR, errno, "stat %s failed",
full_fname(toname));
return -1;
}
if (statret < 0 && basis_dir[0] != NULL) {
char cmpbuf[MAXPATHLEN];
int j = 0;
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
if (link_stat(cmpbuf, &st3, 0) < 0)
continue;
if (link_dest) {
if (st2.st_dev != st3.st_dev
|| st2.st_ino != st3.st_ino)
continue;
statret = 1;
st = &st3;
if (verbose < 2 || !log_format_has_i)
itemizing = code = 0;
break;
}
if (!unchanged_file(cmpbuf, file, &st3))
continue;
statret = 1;
st = &st3;
if (unchanged_attrs(file, &st3))
break;
} while (basis_dir[++j] != NULL);
}
maybe_hard_link(file, ndx, fname, statret, st,
toname, &st2, itemizing, code);
file->F_HLINDEX = FINISHED_LINK;
} else
file->F_HLINDEX = SKIPPED_LINK;
return 1;
}
#endif
@@ -160,10 +234,14 @@ int hard_link_one(struct file_struct *file, int ndx, char *fname,
int itemizing, enum logcode code)
{
if (do_link(toname, fname)) {
if (verbose) {
rsyserr(FERROR, errno, "link %s => %s failed",
full_fname(fname), safe_fname(toname));
}
if (terse) {
if (!verbose)
return -1;
code = FINFO;
} else
code = FERROR;
rsyserr(code, errno, "link %s => %s failed",
full_fname(fname), toname);
return -1;
}
@@ -172,10 +250,8 @@ int hard_link_one(struct file_struct *file, int ndx, char *fname,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
terse ? "" : toname);
}
if (code && verbose && !terse) {
rprintf(code, "%s => %s\n",
safe_fname(fname), safe_fname(toname));
}
if (code && verbose && !terse)
rprintf(code, "%s => %s\n", fname, toname);
return 0;
}
#endif
@@ -190,7 +266,8 @@ void hard_link_cluster(struct file_struct *file, int master, int itemizing,
STRUCT_STAT st1, st2;
int statret, ndx = master;
if (link_stat(f_name_to(file, hlink1), &st1, 0) < 0)
file->F_HLINDEX = FINISHED_LINK;
if (link_stat(f_name(file, hlink1), &st1, 0) < 0)
return;
if (!(file->flags & FLAG_HLINK_TOL)) {
while (!(file->flags & FLAG_HLINK_EOL)) {
@@ -201,33 +278,13 @@ void hard_link_cluster(struct file_struct *file, int master, int itemizing,
do {
ndx = file->F_NEXT;
file = FPTR(ndx);
if (ndx == master)
if (file->F_HLINDEX != SKIPPED_LINK)
continue;
hlink2 = f_name(file);
if ((statret = link_stat(hlink2, &st2, 0)) == 0) {
if (st2.st_dev == st1.st_dev
&& st2.st_ino == st1.st_ino) {
if (itemizing) {
itemize(file, ndx, statret, &st2,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
0, "");
}
continue;
}
if (make_backups) {
if (!make_backup(hlink2))
continue;
} else if (robust_unlink(hlink2)) {
if (verbose > 0) {
rsyserr(FINFO, errno,
"unlink %s failed",
full_fname(hlink2));
}
continue;
}
}
hard_link_one(file, ndx, hlink2, statret,
&st2, hlink1, 0, itemizing, code);
hlink2 = f_name(file, NULL);
statret = link_stat(hlink2, &st2, 0);
maybe_hard_link(file, ndx, hlink2, statret, &st2,
hlink1, &st1, itemizing, code);
file->F_HLINDEX = FINISHED_LINK;
} while (!(file->flags & FLAG_HLINK_EOL));
#endif
}

312
io.c
View File

@@ -41,7 +41,6 @@
extern int bwlimit;
extern size_t bwlimit_writemax;
extern int verbose;
extern int io_timeout;
extern int allowed_lull;
extern int am_server;
@@ -49,6 +48,7 @@ extern int am_daemon;
extern int am_sender;
extern int am_generator;
extern int eol_nulls;
extern int read_batch;
extern int csum_length;
extern int checksum_seed;
extern int protocol_version;
@@ -59,7 +59,6 @@ extern struct stats stats;
extern struct file_list *the_file_list;
const char phase_unknown[] = "unknown";
int select_timeout = SELECT_TIMEOUT;
int ignore_timeout = 0;
int batch_fd = -1;
int batch_gen_fd = -1;
@@ -90,7 +89,8 @@ int sock_f_out = -1;
static int io_multiplexing_out;
static int io_multiplexing_in;
static time_t last_io;
static time_t last_io_in;
static time_t last_io_out;
static int no_flush;
static int write_batch_monitor_in = -1;
@@ -103,6 +103,9 @@ static char *io_filesfrom_bp;
static char io_filesfrom_lastchar;
static int io_filesfrom_buflen;
static size_t contiguous_write_len = 0;
static int select_timeout = SELECT_TIMEOUT;
static int active_filecnt = 0;
static OFF_T active_bytecnt = 0;
static void read_loop(int fd, char *buf, size_t len);
@@ -117,14 +120,17 @@ struct flist_ndx_list {
static struct flist_ndx_list redo_list, hlink_list;
struct msg_list {
struct msg_list *next;
struct msg_list_item {
struct msg_list_item *next;
char *buf;
int len;
};
static struct msg_list *msg_list_head;
static struct msg_list *msg_list_tail;
struct msg_list {
struct msg_list_item *head, *tail;
};
static struct msg_list msg_list;
static void flist_ndx_push(struct flist_ndx_list *lp, int ndx)
{
@@ -166,17 +172,17 @@ static void check_timeout(void)
if (!io_timeout || ignore_timeout)
return;
if (!last_io) {
last_io = time(NULL);
if (!last_io_in) {
last_io_in = time(NULL);
return;
}
t = time(NULL);
if (t - last_io >= io_timeout) {
if (t - last_io_in >= io_timeout) {
if (!am_server && !am_daemon) {
rprintf(FERROR, "io timeout after %d seconds -- exiting\n",
(int)(t-last_io));
(int)(t-last_io_in));
}
exit_cleanup(RERR_TIMEOUT);
}
@@ -190,6 +196,18 @@ void io_set_sock_fds(int f_in, int f_out)
sock_f_out = f_out;
}
void set_io_timeout(int secs)
{
io_timeout = secs;
if (!io_timeout || io_timeout > SELECT_TIMEOUT)
select_timeout = SELECT_TIMEOUT;
else
select_timeout = io_timeout;
allowed_lull = read_batch ? 0 : (io_timeout + 1) / 2;
}
/* Setup the fd used to receive MSG_* messages. Only needed during the
* early stages of being a local sender (up through the sending of the
* file list) or when we're the generator (to fetch the messages from
@@ -210,9 +228,9 @@ void set_msg_fd_out(int fd)
/* Add a message to the pending MSG_* list. */
static void msg_list_add(int code, char *buf, int len)
{
struct msg_list *ml;
struct msg_list_item *ml;
if (!(ml = new(struct msg_list)))
if (!(ml = new(struct msg_list_item)))
out_of_memory("msg_list_add");
ml->next = NULL;
if (!(ml->buf = new_array(char, len+4)))
@@ -220,21 +238,11 @@ static void msg_list_add(int code, char *buf, int len)
SIVAL(ml->buf, 0, ((code+MPLEX_BASE)<<24) | len);
memcpy(ml->buf+4, buf, len);
ml->len = len+4;
if (msg_list_tail)
msg_list_tail->next = ml;
if (msg_list.tail)
msg_list.tail->next = ml;
else
msg_list_head = ml;
msg_list_tail = ml;
}
void send_msg(enum msgcode code, char *buf, int len)
{
if (msg_fd_out < 0) {
io_multiplex_write(code, buf, len);
return;
}
msg_list_add(code, buf, len);
msg_list_push(NORMAL_FLUSH);
msg_list.head = ml;
msg_list.tail = ml;
}
/* Read a message from the MSG_* fd and handle it. This is called either
@@ -272,6 +280,8 @@ static void read_msg_fd(void)
exit_cleanup(RERR_STREAMIO);
}
read_loop(fd, buf, 4);
if (remove_sent_files)
decrement_active_files(IVAL(buf,0));
flist_ndx_push(&redo_list, IVAL(buf,0));
break;
case MSG_DELETED:
@@ -288,11 +298,20 @@ static void read_msg_fd(void)
exit_cleanup(RERR_STREAMIO);
}
read_loop(fd, buf, len);
if (remove_sent_files)
if (remove_sent_files) {
decrement_active_files(IVAL(buf,0));
io_multiplex_write(MSG_SUCCESS, buf, len);
}
if (preserve_hard_links)
flist_ndx_push(&hlink_list, IVAL(buf,0));
break;
case MSG_SOCKERR:
if (!am_generator) {
rprintf(FERROR, "invalid message %d:%d\n", tag, len);
exit_cleanup(RERR_STREAMIO);
}
close_multiplexing_out();
/* FALL THROUGH */
case MSG_INFO:
case MSG_ERROR:
case MSG_LOG:
@@ -313,10 +332,32 @@ static void read_msg_fd(void)
msg_fd_in = fd;
}
/* This is used by the generator to limit how many file transfers can
* be active at once when --remove-sent-files is specified. Without
* this, sender-side deletions were mostly happening at the end. */
void increment_active_files(int ndx, int itemizing, enum logcode code)
{
/* TODO: tune these limits? */
while (active_filecnt >= (active_bytecnt >= 128*1024 ? 10 : 50)) {
if (hlink_list.head)
check_for_finished_hlinks(itemizing, code);
read_msg_fd();
}
active_filecnt++;
active_bytecnt += the_file_list->files[ndx]->length;
}
void decrement_active_files(int ndx)
{
active_filecnt--;
active_bytecnt -= the_file_list->files[ndx]->length;
}
/* Try to push messages off the list onto the wire. If we leave with more
* to do, return 0. On error, return -1. If everything flushed, return 1.
* This is only active in the receiver. */
int msg_list_push(int flush_it_all)
static int msg_list_flush(int flush_it_all)
{
static int written = 0;
struct timeval tv;
@@ -325,8 +366,8 @@ int msg_list_push(int flush_it_all)
if (msg_fd_out < 0)
return -1;
while (msg_list_head) {
struct msg_list *ml = msg_list_head;
while (msg_list.head) {
struct msg_list_item *ml = msg_list.head;
int n = write(msg_fd_out, ml->buf + written, ml->len - written);
if (n < 0) {
if (errno == EINTR)
@@ -343,9 +384,9 @@ int msg_list_push(int flush_it_all)
check_timeout();
} else if ((written += n) == ml->len) {
free(ml->buf);
msg_list_head = ml->next;
if (!msg_list_head)
msg_list_tail = NULL;
msg_list.head = ml->next;
if (!msg_list.head)
msg_list.tail = NULL;
free(ml);
written = 0;
}
@@ -353,6 +394,16 @@ int msg_list_push(int flush_it_all)
return 1;
}
void send_msg(enum msgcode code, char *buf, int len)
{
if (msg_fd_out < 0) {
io_multiplex_write(code, buf, len);
return;
}
msg_list_add(code, buf, len);
msg_list_flush(NORMAL_FLUSH);
}
int get_redo_num(int itemizing, enum logcode code)
{
while (1) {
@@ -420,7 +471,6 @@ static void whine_about_eof(int fd)
exit_cleanup(RERR_STREAMIO);
}
/**
* Read from a socket with I/O timeout. return the number of bytes
* read. If no bytes can be read then exit, never return a number <= 0.
@@ -434,11 +484,11 @@ static void whine_about_eof(int fd)
*/
static int read_timeout(int fd, char *buf, size_t len)
{
int n, ret = 0;
int n, cnt = 0;
io_flush(NORMAL_FLUSH);
while (ret == 0) {
while (cnt == 0) {
/* until we manage to read *something* */
fd_set r_fds, w_fds;
struct timeval tv;
@@ -448,7 +498,7 @@ static int read_timeout(int fd, char *buf, size_t len)
FD_ZERO(&r_fds);
FD_ZERO(&w_fds);
FD_SET(fd, &r_fds);
if (msg_list_head) {
if (msg_list.head) {
FD_SET(msg_fd_out, &w_fds);
if (msg_fd_out > maxfd)
maxfd = msg_fd_out;
@@ -485,8 +535,8 @@ static int read_timeout(int fd, char *buf, size_t len)
continue;
}
if (msg_list_head && FD_ISSET(msg_fd_out, &w_fds))
msg_list_push(NORMAL_FLUSH);
if (msg_list.head && FD_ISSET(msg_fd_out, &w_fds))
msg_list_flush(NORMAL_FLUSH);
if (io_filesfrom_f_out >= 0) {
if (io_filesfrom_buflen) {
@@ -564,21 +614,23 @@ static int read_timeout(int fd, char *buf, size_t len)
continue;
/* Don't write errors on a dead socket. */
if (fd == sock_f_in)
if (fd == sock_f_in) {
close_multiplexing_out();
rsyserr(FERROR, errno, "read error");
rsyserr(FSOCKERR, errno, "read error");
} else
rsyserr(FERROR, errno, "read error");
exit_cleanup(RERR_STREAMIO);
}
buf += n;
len -= n;
ret += n;
cnt += n;
if (io_timeout && fd == sock_f_in)
last_io = time(NULL);
if (fd == sock_f_in && io_timeout)
last_io_in = time(NULL);
}
return ret;
return cnt;
}
/**
@@ -628,7 +680,6 @@ int read_filesfrom_line(int fd, char *fname)
return s - fname;
}
static char *iobuf_out;
static int iobuf_out_cnt;
@@ -641,7 +692,6 @@ void io_start_buffering_out(void)
iobuf_out_cnt = 0;
}
static char *iobuf_in;
static size_t iobuf_in_siz;
@@ -654,7 +704,6 @@ void io_start_buffering_in(void)
out_of_memory("io_start_buffering_in");
}
void io_end_buffering(void)
{
io_flush(NORMAL_FLUSH);
@@ -664,10 +713,15 @@ void io_end_buffering(void)
}
}
void maybe_flush_socket(void)
{
if (iobuf_out && iobuf_out_cnt && time(NULL) - last_io_out >= 5)
io_flush(NORMAL_FLUSH);
}
void maybe_send_keepalive(void)
{
if (time(NULL) - last_io >= allowed_lull) {
if (time(NULL) - last_io_out >= allowed_lull) {
if (!iobuf_out || !iobuf_out_cnt) {
if (protocol_version < 29)
return; /* there's nothing we can do */
@@ -679,7 +733,6 @@ void maybe_send_keepalive(void)
}
}
/**
* Continue trying to read len bytes - don't return until len has been
* read.
@@ -694,7 +747,6 @@ static void read_loop(int fd, char *buf, size_t len)
}
}
/**
* Read from the file descriptor handling multiplexing - return number
* of bytes read.
@@ -705,8 +757,9 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
{
static size_t remaining;
static size_t iobuf_in_ndx;
int tag, ret = 0;
char line[MAXPATHLEN+1];
size_t msg_bytes;
int tag, cnt = 0;
char line[BIGPATHBUFLEN];
if (!iobuf_in || fd != sock_f_in)
return read_timeout(fd, buf, len);
@@ -716,69 +769,66 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
iobuf_in_ndx = 0;
}
while (ret == 0) {
while (cnt == 0) {
if (remaining) {
len = MIN(len, remaining);
memcpy(buf, iobuf_in + iobuf_in_ndx, len);
iobuf_in_ndx += len;
remaining -= len;
ret = len;
cnt = len;
break;
}
read_loop(fd, line, 4);
tag = IVAL(line, 0);
remaining = tag & 0xFFFFFF;
msg_bytes = tag & 0xFFFFFF;
tag = (tag >> 24) - MPLEX_BASE;
switch (tag) {
case MSG_DATA:
if (remaining > iobuf_in_siz) {
if (msg_bytes > iobuf_in_siz) {
if (!(iobuf_in = realloc_array(iobuf_in, char,
remaining)))
msg_bytes)))
out_of_memory("readfd_unbuffered");
iobuf_in_siz = remaining;
iobuf_in_siz = msg_bytes;
}
read_loop(fd, iobuf_in, remaining);
read_loop(fd, iobuf_in, msg_bytes);
remaining = msg_bytes;
iobuf_in_ndx = 0;
break;
case MSG_DELETED:
if (remaining >= sizeof line) {
rprintf(FERROR, "invalid multi-message %d:%ld\n",
tag, (long)remaining);
exit_cleanup(RERR_STREAMIO);
}
read_loop(fd, line, remaining);
line[remaining] = '\0';
if (msg_bytes >= sizeof line)
goto overflow;
read_loop(fd, line, msg_bytes);
/* A directory name was sent with the trailing null */
if (remaining > 0 && !line[remaining-1])
if (msg_bytes > 0 && !line[msg_bytes-1])
log_delete(line, S_IFDIR);
else
else {
line[msg_bytes] = '\0';
log_delete(line, S_IFREG);
remaining = 0;
}
break;
case MSG_SUCCESS:
if (remaining != 4) {
if (msg_bytes != 4) {
rprintf(FERROR, "invalid multi-message %d:%ld [%s]\n",
tag, (long)remaining, who_am_i());
tag, (long)msg_bytes, who_am_i());
exit_cleanup(RERR_STREAMIO);
}
read_loop(fd, line, remaining);
read_loop(fd, line, msg_bytes);
successful_send(IVAL(line, 0));
remaining = 0;
break;
case MSG_INFO:
case MSG_ERROR:
if (remaining >= sizeof line) {
if (msg_bytes >= sizeof line) {
overflow:
rprintf(FERROR,
"multiplexing overflow %d:%ld [%s]\n",
tag, (long)remaining, who_am_i());
tag, (long)msg_bytes, who_am_i());
exit_cleanup(RERR_STREAMIO);
}
read_loop(fd, line, remaining);
rwrite((enum logcode)tag, line, remaining);
remaining = 0;
read_loop(fd, line, msg_bytes);
rwrite((enum logcode)tag, line, msg_bytes);
break;
default:
rprintf(FERROR, "unexpected tag %d [%s]\n",
@@ -790,11 +840,9 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
if (remaining == 0)
io_flush(NORMAL_FLUSH);
return ret;
return cnt;
}
/**
* Do a buffered read from @p fd. Don't return until all @p n bytes
* have been read. If all @p n can't be read then exit with an
@@ -802,12 +850,12 @@ static int readfd_unbuffered(int fd, char *buf, size_t len)
**/
static void readfd(int fd, char *buffer, size_t N)
{
int ret;
int cnt;
size_t total = 0;
while (total < N) {
ret = readfd_unbuffered(fd, buffer + total, N-total);
total += ret;
cnt = readfd_unbuffered(fd, buffer + total, N-total);
total += cnt;
}
if (fd == write_batch_monitor_in) {
@@ -819,7 +867,6 @@ static void readfd(int fd, char *buffer, size_t N)
stats.total_read += total;
}
int read_shortint(int f)
{
uchar b[2];
@@ -827,37 +874,36 @@ int read_shortint(int f)
return (b[1] << 8) + b[0];
}
int32 read_int(int f)
{
char b[4];
int32 ret;
int32 num;
readfd(f,b,4);
ret = IVAL(b,0);
if (ret == (int32)0xffffffff)
num = IVAL(b,0);
if (num == (int32)0xffffffff)
return -1;
return ret;
return num;
}
int64 read_longint(int f)
{
int64 ret;
int64 num;
char b[8];
ret = read_int(f);
num = read_int(f);
if ((int32)ret != (int32)0xffffffff)
return ret;
if ((int32)num != (int32)0xffffffff)
return num;
#if SIZEOF_INT64 < 8
rprintf(FERROR, "Integer overflow: attempted 64-bit offset\n");
exit_cleanup(RERR_UNSUPPORTED);
#else
readfd(f,b,8);
ret = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
num = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
#endif
return ret;
return num;
}
void read_buf(int f,char *buf,size_t len)
@@ -902,6 +948,11 @@ int read_vstring(int f, char *buf, int bufsize)
void read_sum_head(int f, struct sum_struct *sum)
{
sum->count = read_int(f);
if (sum->count < 0) {
rprintf(FERROR, "Invalid checksum count %ld [%s]\n",
(long)sum->count, who_am_i());
exit_cleanup(RERR_PROTOCOL);
}
sum->blength = read_int(f);
if (sum->blength < 0 || sum->blength > MAX_BLOCK_SIZE) {
rprintf(FERROR, "Invalid block length %ld [%s]\n",
@@ -939,7 +990,6 @@ void write_sum_head(int f, struct sum_struct *sum)
write_int(f, sum->remainder);
}
/**
* Sleep after writing to limit I/O bandwidth usage.
*
@@ -965,7 +1015,7 @@ static void sleep_for_bwlimit(int bytes_written)
#define ONE_SEC 1000000L /* # of microseconds in a second */
if (!bwlimit)
if (!bwlimit_writemax)
return;
total_written += bytes_written;
@@ -995,9 +1045,8 @@ static void sleep_for_bwlimit(int bytes_written)
total_written = (sleep_usec - elapsed_usec) * bwlimit / (ONE_SEC/1024);
}
/* Write len bytes to the file descriptor fd, looping as necessary to get
* the job done and also (in certain circumstnces) reading any data on
* the job done and also (in certain circumstances) reading any data on
* msg_fd_in to avoid deadlock.
*
* This function underlies the multiplexing system. The body of the
@@ -1006,7 +1055,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
{
size_t n, total = 0;
fd_set w_fds, r_fds;
int maxfd, count, ret;
int maxfd, count, cnt, using_r_fds;
struct timeval tv;
no_flush++;
@@ -1021,18 +1070,15 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
FD_SET(msg_fd_in,&r_fds);
if (msg_fd_in > maxfd)
maxfd = msg_fd_in;
}
if (fd != sock_f_out && iobuf_out_cnt && no_flush == 1) {
FD_SET(sock_f_out, &w_fds);
if (sock_f_out > maxfd)
maxfd = sock_f_out;
}
using_r_fds = 1;
} else
using_r_fds = 0;
tv.tv_sec = select_timeout;
tv.tv_usec = 0;
errno = 0;
count = select(maxfd + 1, msg_fd_in >= 0 ? &r_fds : NULL,
count = select(maxfd + 1, using_r_fds ? &r_fds : NULL,
&w_fds, NULL, &tv);
if (count <= 0) {
@@ -1042,19 +1088,19 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
continue;
}
if (msg_fd_in >= 0 && FD_ISSET(msg_fd_in, &r_fds))
if (using_r_fds && FD_ISSET(msg_fd_in, &r_fds))
read_msg_fd();
if (!FD_ISSET(fd, &w_fds))
continue;
n = len - total;
if (bwlimit && n > bwlimit_writemax)
if (bwlimit_writemax && n > bwlimit_writemax)
n = bwlimit_writemax;
ret = write(fd, buf + total, n);
cnt = write(fd, buf + total, n);
if (ret <= 0) {
if (ret < 0) {
if (cnt <= 0) {
if (cnt < 0) {
if (errno == EINTR)
continue;
if (errno == EWOULDBLOCK || errno == EAGAIN) {
@@ -1072,7 +1118,7 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
/* If the other side is sending us error messages, try
* to grab any messages they sent before they died. */
while (fd == sock_f_out && io_multiplexing_in) {
io_timeout = select_timeout = 30;
set_io_timeout(30);
ignore_timeout = 0;
readfd_unbuffered(sock_f_in, io_filesfrom_buf,
sizeof io_filesfrom_buf);
@@ -1080,26 +1126,25 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
exit_cleanup(RERR_STREAMIO);
}
total += ret;
total += cnt;
if (fd == sock_f_out) {
if (io_timeout)
last_io = time(NULL);
sleep_for_bwlimit(ret);
if (io_timeout || am_generator)
last_io_out = time(NULL);
sleep_for_bwlimit(cnt);
}
}
no_flush--;
}
/**
* Write an message to a multiplexed stream. If this fails then rsync
* exits.
**/
static void mplex_write(enum msgcode code, char *buf, size_t len)
{
char buffer[4096];
char buffer[1024];
size_t n = len;
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
@@ -1112,9 +1157,10 @@ static void mplex_write(enum msgcode code, char *buf, size_t len)
contiguous_write_len = len + 4;
if (n > sizeof buffer - 4)
n = sizeof buffer - 4;
n = 0;
else
memcpy(buffer + 4, buf, n);
memcpy(&buffer[4], buf, n);
writefd_unbuffered(sock_f_out, buffer, n+4);
len -= n;
@@ -1127,10 +1173,9 @@ static void mplex_write(enum msgcode code, char *buf, size_t len)
contiguous_write_len = 0;
}
void io_flush(int flush_it_all)
{
msg_list_push(flush_it_all);
msg_list_flush(flush_it_all);
if (!iobuf_out_cnt || no_flush)
return;
@@ -1142,7 +1187,6 @@ void io_flush(int flush_it_all)
iobuf_out_cnt = 0;
}
static void writefd(int fd,char *buf,size_t len)
{
if (fd == msg_fd_out) {
@@ -1177,7 +1221,6 @@ static void writefd(int fd,char *buf,size_t len)
}
}
void write_shortint(int f, int x)
{
uchar b[2];
@@ -1186,7 +1229,6 @@ void write_shortint(int f, int x)
writefd(f, (char *)b, 2);
}
void write_int(int f,int32 x)
{
char b[4];
@@ -1194,7 +1236,6 @@ void write_int(int f,int32 x)
writefd(f,b,4);
}
void write_int_named(int f, int32 x, const char *phase)
{
io_write_phase = phase;
@@ -1202,7 +1243,6 @@ void write_int_named(int f, int32 x, const char *phase)
io_write_phase = phase_unknown;
}
/*
* Note: int64 may actually be a 32-bit type if ./configure couldn't find any
* 64-bit types on this platform.
@@ -1264,7 +1304,6 @@ void write_vstring(int f, char *str, int len)
writefd(f, str, len);
}
/**
* Read a line of up to @p maxlen characters into @p buf (not counting
* the trailing null). Strips the (required) trailing newline and all
@@ -1290,11 +1329,10 @@ int read_line(int f, char *buf, size_t maxlen)
return maxlen > 0;
}
void io_printf(int fd, const char *format, ...)
{
va_list ap;
char buf[1024];
char buf[BIGPATHBUFLEN];
int len;
va_start(ap, format);
@@ -1304,10 +1342,14 @@ void io_printf(int fd, const char *format, ...)
if (len < 0)
exit_cleanup(RERR_STREAMIO);
if (len > (int)sizeof buf) {
rprintf(FERROR, "io_printf() was too long for the buffer.\n");
exit_cleanup(RERR_STREAMIO);
}
write_sbuf(fd, buf);
}
/** Setup for multiplexing a MSG_* stream with the data stream. */
void io_start_multiplex_out(void)
{

View File

@@ -26,8 +26,7 @@
*
* @param buf buffer of at least 11 characters
**/
void permstring(char *perms,
int mode)
void permstring(char *perms, mode_t mode)
{
static const char *perm_map = "rwxrwxrwx";
int i;

View File

@@ -1,3 +1,3 @@
#define PERMSTRING_SIZE 11
void permstring(char *perms, int mode);
void permstring(char *perms, mode_t mode);

View File

@@ -56,8 +56,7 @@ pool_create(size_t size, size_t quantum,
pool->size = size /* round extent size to min alignment reqs */
? (size + MINALIGN - 1) & ~(MINALIGN - 1)
: POOL_DEF_EXTENT;
if (pool->flags & POOL_INTERN)
{
if (pool->flags & POOL_INTERN) {
pool->size -= sizeof (struct pool_extent);
flags |= POOL_APPEND;
}
@@ -77,15 +76,13 @@ pool_destroy(alloc_pool_t p)
if (!pool)
return;
if (pool->live)
{
if (pool->live) {
cur = pool->live;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
}
for (cur = pool->free; cur; cur = next)
{
for (cur = pool->free; cur; cur = next) {
next = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
@@ -109,16 +106,14 @@ pool_alloc(alloc_pool_t p, size_t len, char *bomb)
if (len > pool->size)
goto bomb;
if (!pool->live || len > pool->live->free)
{
if (!pool->live || len > pool->live->free) {
void *start;
size_t free;
size_t bound;
size_t sqew;
size_t asize;
if (pool->live)
{
if (pool->live) {
pool->live->next = pool->free;
pool->free = pool->live;
}
@@ -137,16 +132,11 @@ pool_alloc(alloc_pool_t p, size_t len, char *bomb)
memset(start, 0, pool->size);
if (pool->flags & POOL_APPEND)
{
pool->live = PTR_ADD(start, free);
}
else if (!(pool->live = (struct pool_extent *) malloc(sizeof (struct pool_extent))))
{
goto bomb;
}
if (pool->flags & POOL_QALIGN && pool->quantum > 1
&& (sqew = (size_t)PTR_ADD(start, free) % pool->quantum))
{
&& (sqew = (size_t)PTR_ADD(start, free) % pool->quantum)) {
bound += sqew;
free -= sqew;
}
@@ -186,8 +176,7 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
else if (pool->quantum > 1 && len % pool->quantum)
len += pool->quantum - len % pool->quantum;
if (!addr && pool->live)
{
if (!addr && pool->live) {
pool->live->next = pool->free;
pool->free = pool->live;
pool->live = NULL;
@@ -197,35 +186,28 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
pool->b_freed += len;
cur = pool->live;
if (cur
&& addr >= cur->start
&& addr < PTR_ADD(cur->start, pool->size))
{
if (addr == PTR_ADD(cur->start, cur->free))
{
if (cur && addr >= cur->start
&& addr < PTR_ADD(cur->start, pool->size)) {
if (addr == PTR_ADD(cur->start, cur->free)) {
if (pool->flags & POOL_CLEAR)
memset(addr, 0, len);
pool->b_freed += len;
} else {
} else
cur->bound += len;
}
if (cur->free + cur->bound >= pool->size)
{
if (cur->free + cur->bound >= pool->size) {
size_t sqew;
cur->free = pool->size;
cur->bound = 0;
if (pool->flags & POOL_QALIGN && pool->quantum > 1
&& (sqew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum))
{
&& (sqew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum)) {
cur->bound += sqew;
cur->free -= sqew;
}
}
return;
}
for (prev = NULL, cur = pool->free; cur; prev = cur, cur = cur->next)
{
for (prev = NULL, cur = pool->free; cur; prev = cur, cur = cur->next) {
if (addr >= cur->start
&& addr < PTR_ADD(cur->start, pool->size))
break;
@@ -233,16 +215,14 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
if (!cur)
return;
if (prev)
{
if (prev) {
prev->next = cur->next;
cur->next = pool->free;
pool->free = cur;
}
cur->bound += len;
if (cur->free + cur->bound >= pool->size)
{
if (cur->free + cur->bound >= pool->size) {
pool->free = cur->next;
free(cur->start);
@@ -254,11 +234,11 @@ pool_free(alloc_pool_t p, size_t len, void *addr)
}
#define FDPRINT(label, value) \
snprintf(buf, BUFSIZ, label, value), \
write(fd, buf, strlen(buf));
snprintf(buf, sizeof buf, label, value), \
write(fd, buf, strlen(buf))
#define FDEXTSTAT(ext) \
snprintf(buf, BUFSIZ, " %12ld %5ld\n", \
snprintf(buf, sizeof buf, " %12ld %5ld\n", \
(long) ext->free, \
(long) ext->bound), \
write(fd, buf, strlen(buf))
@@ -291,14 +271,10 @@ pool_stats(alloc_pool_t p, int fd, int summarize)
write(fd, "\n", 1);
if (pool->live)
{
FDEXTSTAT(pool->live);
}
strcpy(buf, " FREE BOUND\n");
write(fd, buf, strlen(buf));
for (cur = pool->free; cur; cur = cur->next)
{
FDEXTSTAT(cur);
}
}

View File

@@ -146,7 +146,7 @@
#endif
#ifndef VA_COPY
#ifdef HAVE_VA_COPY
#if defined HAVE_VA_COPY || defined va_copy
#define VA_COPY(dest, src) va_copy(dest, src)
#else
#ifdef HAVE___VA_COPY

View File

@@ -57,173 +57,312 @@
int wildmatch_iteration_count;
#endif
static int domatch(const uchar *p, const uchar *text)
static int force_lower_case = 0;
/* Match pattern "p" against the a virtually-joined string consisting
* of "text" and any strings in array "a". */
static int dowild(const uchar *p, const uchar *text, const uchar*const *a)
{
int matched, special;
uchar ch, prev;
uchar p_ch;
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count++;
#endif
for ( ; (ch = *p) != '\0'; text++, p++) {
if (*text == '\0' && ch != '*')
return FALSE;
switch (ch) {
for ( ; (p_ch = *p) != '\0'; text++, p++) {
int matched, special;
uchar t_ch, prev_ch;
while ((t_ch = *text) == '\0') {
if (*a == NULL) {
if (p_ch != '*')
return ABORT_ALL;
break;
}
text = *a++;
}
if (force_lower_case && ISUPPER(t_ch))
t_ch = tolower(t_ch);
switch (p_ch) {
case '\\':
/* Literal match with following character. Note that the test
* in "default" handles the p[1] == '\0' failure case. */
ch = *++p;
p_ch = *++p;
/* FALLTHROUGH */
default:
if (*text != ch)
if (t_ch != p_ch)
return FALSE;
continue;
case '?':
/* Match anything but '/'. */
if (*text == '/')
if (t_ch == '/')
return FALSE;
continue;
case '*':
if (*++p == '*') {
while (*++p == '*') {}
special = TRUE;
}
else
} else
special = FALSE;
if (*p == '\0') {
/* Trailing "**" matches everything. Trailing "*" matches
* only if there are no more slash characters. */
return special? TRUE : strchr((char*)text, '/') == NULL;
if (!special) {
do {
if (strchr((char*)text, '/') != NULL)
return FALSE;
} while ((text = *a++) != NULL);
}
return TRUE;
}
for ( ; *text; text++) {
if ((matched = domatch(p, text)) != FALSE) {
while (1) {
if (t_ch == '\0') {
if ((text = *a++) == NULL)
break;
t_ch = *text;
continue;
}
if ((matched = dowild(p, text, a)) != FALSE) {
if (!special || matched != ABORT_TO_STARSTAR)
return matched;
}
else if (!special && *text == '/')
} else if (!special && t_ch == '/')
return ABORT_TO_STARSTAR;
t_ch = *++text;
}
return ABORT_ALL;
case '[':
ch = *++p;
p_ch = *++p;
#ifdef NEGATE_CLASS2
if (ch == NEGATE_CLASS2)
ch = NEGATE_CLASS;
if (p_ch == NEGATE_CLASS2)
p_ch = NEGATE_CLASS;
#endif
/* Assign literal TRUE/FALSE because of "matched" comparison. */
special = ch == NEGATE_CLASS? TRUE : FALSE;
special = p_ch == NEGATE_CLASS? TRUE : FALSE;
if (special) {
/* Inverted character class. */
ch = *++p;
p_ch = *++p;
}
prev = 0;
prev_ch = 0;
matched = FALSE;
do {
if (!ch)
if (!p_ch)
return ABORT_ALL;
if (ch == '\\') {
ch = *++p;
if (!ch)
if (p_ch == '\\') {
p_ch = *++p;
if (!p_ch)
return ABORT_ALL;
if (*text == ch)
if (t_ch == p_ch)
matched = TRUE;
}
else if (ch == '-' && prev && p[1] && p[1] != ']') {
ch = *++p;
if (ch == '\\') {
ch = *++p;
if (!ch)
} else if (p_ch == '-' && prev_ch && p[1] && p[1] != ']') {
p_ch = *++p;
if (p_ch == '\\') {
p_ch = *++p;
if (!p_ch)
return ABORT_ALL;
}
if (*text <= ch && *text >= prev)
if (t_ch <= p_ch && t_ch >= prev_ch)
matched = TRUE;
ch = 0; /* This makes "prev" get set to 0. */
}
else if (ch == '[' && p[1] == ':') {
p_ch = 0; /* This makes "prev_ch" get set to 0. */
} else if (p_ch == '[' && p[1] == ':') {
const uchar *s;
int i;
for (s = p += 2; (ch = *p) && ch != ']'; p++) {}
if (!ch)
for (s = p += 2; (p_ch = *p) && p_ch != ']'; p++) {}
if (!p_ch)
return ABORT_ALL;
i = p - s - 1;
if (i < 0 || p[-1] != ':') {
/* Didn't find ":]", so treat like a normal set. */
p = s - 2;
ch = '[';
if (*text == ch)
p_ch = '[';
if (t_ch == p_ch)
matched = TRUE;
continue;
}
if (CC_EQ(s,i, "alnum")) {
if (ISALNUM(*text))
if (ISALNUM(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "alpha")) {
if (ISALPHA(*text))
} else if (CC_EQ(s,i, "alpha")) {
if (ISALPHA(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "blank")) {
if (ISBLANK(*text))
} else if (CC_EQ(s,i, "blank")) {
if (ISBLANK(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "cntrl")) {
if (ISCNTRL(*text))
} else if (CC_EQ(s,i, "cntrl")) {
if (ISCNTRL(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "digit")) {
if (ISDIGIT(*text))
} else if (CC_EQ(s,i, "digit")) {
if (ISDIGIT(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "graph")) {
if (ISGRAPH(*text))
} else if (CC_EQ(s,i, "graph")) {
if (ISGRAPH(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "lower")) {
if (ISLOWER(*text))
} else if (CC_EQ(s,i, "lower")) {
if (ISLOWER(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "print")) {
if (ISPRINT(*text))
} else if (CC_EQ(s,i, "print")) {
if (ISPRINT(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "punct")) {
if (ISPUNCT(*text))
} else if (CC_EQ(s,i, "punct")) {
if (ISPUNCT(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "space")) {
if (ISSPACE(*text))
} else if (CC_EQ(s,i, "space")) {
if (ISSPACE(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "upper")) {
if (ISUPPER(*text))
} else if (CC_EQ(s,i, "upper")) {
if (ISUPPER(t_ch))
matched = TRUE;
}
else if (CC_EQ(s,i, "xdigit")) {
if (ISXDIGIT(*text))
} else if (CC_EQ(s,i, "xdigit")) {
if (ISXDIGIT(t_ch))
matched = TRUE;
}
else /* malformed [:class:] string */
} else /* malformed [:class:] string */
return ABORT_ALL;
ch = 0; /* This makes "prev" get set to 0. */
}
else if (*text == ch)
p_ch = 0; /* This makes "prev_ch" get set to 0. */
} else if (t_ch == p_ch)
matched = TRUE;
} while (prev = ch, (ch = *++p) != ']');
if (matched == special || *text == '/')
} while (prev_ch = p_ch, (p_ch = *++p) != ']');
if (matched == special || t_ch == '/')
return FALSE;
continue;
}
}
return *text == '\0';
do {
if (*text)
return FALSE;
} while ((text = *a++) != NULL);
return TRUE;
}
/* Find the pattern (p) in the text string (t). */
int wildmatch(const char *p, const char *t)
/* Match literal string "s" against the a virtually-joined string consisting
* of "text" and any strings in array "a". */
static int doliteral(const uchar *s, const uchar *text, const uchar*const *a)
{
for ( ; *s != '\0'; text++, s++) {
while (*text == '\0') {
if ((text = *a++) == NULL)
return FALSE;
}
if (*text != *s)
return FALSE;
}
do {
if (*text)
return FALSE;
} while ((text = *a++) != NULL);
return TRUE;
}
/* Return the last "count" path elements from the concatenated string.
* We return a string pointer to the start of the string, and update the
* array pointer-pointer to point to any remaining string elements. */
static const uchar *trailing_N_elements(const uchar*const **a_ptr, int count)
{
const uchar*const *a = *a_ptr;
const uchar*const *first_a = a;
while (*a)
a++;
while (a != first_a) {
const uchar *s = *--a;
s += strlen((char*)s);
while (--s >= *a) {
if (*s == '/' && !--count) {
*a_ptr = a+1;
return s+1;
}
}
}
if (count == 1) {
*a_ptr = a+1;
return *a;
}
return NULL;
}
/* Match the "pattern" against the "text" string. */
int wildmatch(const char *pattern, const char *text)
{
static const uchar *nomore[1]; /* A NULL pointer. */
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count = 0;
#endif
return domatch((const uchar*)p, (const uchar*)t) == TRUE;
return dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;
}
/* Match the "pattern" against the forced-to-lower-case "text" string. */
int iwildmatch(const char *pattern, const char *text)
{
static const uchar *nomore[1]; /* A NULL pointer. */
int ret;
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count = 0;
#endif
force_lower_case = 1;
ret = dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;
force_lower_case = 0;
return ret;
}
/* Match pattern "p" against the a virtually-joined string consisting
* of all the pointers in array "texts" (which has a NULL pointer at the
* end). The int "where" can be 0 (normal matching), > 0 (match only
* the trailing N slash-separated filename components of "texts"), or < 0
* (match the "pattern" at the start or after any slash in "texts"). */
int wildmatch_array(const char *pattern, const char*const *texts, int where)
{
const uchar *p = (const uchar*)pattern;
const uchar*const *a = (const uchar*const*)texts;
const uchar *text;
int matched;
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count = 0;
#endif
if (where > 0)
text = trailing_N_elements(&a, where);
else
text = *a++;
if (!text)
return FALSE;
if ((matched = dowild(p, text, a)) != TRUE && where < 0
&& matched != ABORT_ALL) {
while (1) {
if (*text == '\0') {
if ((text = (uchar*)*a++) == NULL)
return FALSE;
continue;
}
if (*text++ == '/' && (matched = dowild(p, text, a)) != FALSE
&& matched != ABORT_TO_STARSTAR)
break;
}
}
return matched == TRUE;
}
/* Match literal string "s" against the a virtually-joined string consisting
* of all the pointers in array "texts" (which has a NULL pointer at the
* end). The int "where" can be 0 (normal matching), or > 0 (match
* only the trailing N slash-separated filename components of "texts"). */
int litmatch_array(const char *string, const char*const *texts, int where)
{
const uchar *s = (const uchar*)string;
const uchar*const *a = (const uchar* const*)texts;
const uchar *text;
if (where > 0)
text = trailing_N_elements(&a, where);
else
text = *a++;
if (!text)
return FALSE;
return doliteral(s, text, a) == TRUE;
}

View File

@@ -1,3 +1,6 @@
/* wildmatch.h */
int wildmatch(const char *p, const char *text);
int wildmatch(const char *pattern, const char *text);
int iwildmatch(const char *pattern, const char *text);
int wildmatch_array(const char *pattern, const char*const *texts, int where);
int litmatch_array(const char *string, const char*const *texts, int where);

View File

@@ -98,95 +98,107 @@ struct parm_struct
*/
typedef struct
{
char *motd_file;
char *bind_address;
char *log_file;
char *motd_file;
char *pid_file;
char *socket_options;
char *bind_address;
int syslog_facility;
int max_verbosity;
int rsync_port;
int syslog_facility;
} global;
static global Globals;
/*
* This structure describes a single service.
* This structure describes a single service. 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.)
*/
typedef struct
{
char *name;
char *path;
char *auth_users;
char *comment;
char *lock_file;
BOOL read_only;
BOOL write_only;
BOOL list;
BOOL use_chroot;
BOOL transfer_logging;
BOOL ignore_errors;
char *uid;
char *dont_compress;
char *exclude;
char *exclude_from;
char *filter;
char *gid;
char *hosts_allow;
char *hosts_deny;
char *auth_users;
char *secrets_file;
BOOL strict_modes;
char *filter;
char *exclude;
char *exclude_from;
char *include;
char *include_from;
char *incoming_chmod;
char *lock_file;
char *log_format;
char *name;
char *outgoing_chmod;
char *path;
char *postxfer_exec;
char *prexfer_exec;
char *refuse_options;
char *dont_compress;
int timeout;
char *secrets_file;
char *temp_dir;
char *uid;
int max_connections;
int max_verbosity;
int timeout;
BOOL ignore_errors;
BOOL ignore_nonreadable;
BOOL list;
BOOL read_only;
BOOL strict_modes;
BOOL transfer_logging;
BOOL use_chroot;
BOOL write_only;
} service;
/* This is a default service used to prime a services structure */
/* This is a default service used to prime a services structure. In order
* to make these easy to keep sorted in the same way as the variables
* above, use the variable name in the leading comment, including a
* trailing ';' (to avoid a sorting problem with trailing digits). */
static service sDefault =
{
NULL, /* name */
NULL, /* path */
NULL, /* comment */
DEFAULT_LOCK_FILE, /* lock file */
True, /* read only */
False, /* write only */
True, /* list */
True, /* use chroot */
False, /* transfer logging */
False, /* ignore errors */
"nobody",/* uid */
/* auth_users; */ NULL,
/* comment; */ NULL,
/* dont_compress; */ "*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz",
/* exclude; */ NULL,
/* exclude_from; */ NULL,
/* filter; */ NULL,
/* gid; */ NOBODY_GROUP,
/* hosts_allow; */ NULL,
/* hosts_deny; */ NULL,
/* include; */ NULL,
/* include_from; */ NULL,
/* incoming_chmod; */ NULL,
/* lock_file; */ DEFAULT_LOCK_FILE,
/* 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; */ NOBODY_USER,
/* TODO: This causes problems on Debian, where it is called
* "nogroup". Debian patch this in their version of the
* package, but it would be nice to be consistent. Possibly
* other systems are different again.
*
* What is the best behaviour? Perhaps always using (gid_t)
* -2? */
"nobody",/* gid */
/* max_connections; */ 0,
/* max_verbosity; */ 1,
/* timeout; */ 0,
NULL, /* hosts allow */
NULL, /* hosts deny */
NULL, /* auth users */
NULL, /* secrets file */
True, /* strict modes */
NULL, /* filter */
NULL, /* exclude */
NULL, /* exclude from */
NULL, /* include */
NULL, /* include from */
"%o %h [%a] %m (%u) %f %l", /* log format */
NULL, /* refuse options */
"*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */
0, /* timeout */
0, /* max connections */
False /* ignore nonreadable */
/* ignore_errors; */ False,
/* ignore_nonreadable; */ False,
/* list; */ True,
/* read_only; */ True,
/* strict_modes; */ True,
/* transfer_logging; */ False,
/* use_chroot; */ True,
/* write_only; */ False,
};
@@ -269,44 +281,51 @@ static struct enum_list enum_facilities[] = {
/* note that we do not initialise the defaults union - it is not allowed in ANSI C */
static struct parm_struct parm_table[] =
{
{"motd file", P_STRING, P_GLOBAL, &Globals.motd_file, NULL, 0},
{"syslog facility", P_ENUM, P_GLOBAL, &Globals.syslog_facility, enum_facilities,0},
{"socket options", P_STRING, P_GLOBAL, &Globals.socket_options,NULL, 0},
{"log file", P_STRING, P_GLOBAL, &Globals.log_file, NULL, 0},
{"pid file", P_STRING, P_GLOBAL, &Globals.pid_file, NULL, 0},
{"max verbosity", P_INTEGER, P_GLOBAL, &Globals.max_verbosity, NULL, 0},
{"port", P_INTEGER, P_GLOBAL, &Globals.rsync_port, NULL, 0},
{"address", P_STRING, P_GLOBAL, &Globals.bind_address, NULL, 0},
{"address", P_STRING, P_GLOBAL,&Globals.bind_address, NULL,0},
{"log file", P_STRING, P_GLOBAL,&Globals.log_file, NULL,0},
{"motd file", P_STRING, P_GLOBAL,&Globals.motd_file, NULL,0},
{"pid file", P_STRING, P_GLOBAL,&Globals.pid_file, NULL,0},
{"port", P_INTEGER,P_GLOBAL,&Globals.rsync_port, NULL,0},
{"socket options", P_STRING, P_GLOBAL,&Globals.socket_options, NULL,0},
{"syslog facility", P_ENUM, P_GLOBAL,&Globals.syslog_facility,enum_facilities,0},
{"timeout", P_INTEGER, P_LOCAL, &sDefault.timeout, NULL, 0},
{"max connections", P_INTEGER, P_LOCAL, &sDefault.max_connections,NULL, 0},
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL, 0},
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, 0},
{"lock file", P_STRING, P_LOCAL, &sDefault.lock_file, NULL, 0},
{"path", P_PATH, P_LOCAL, &sDefault.path, NULL, 0},
{"read only", P_BOOL, P_LOCAL, &sDefault.read_only, NULL, 0},
{"write only", P_BOOL, P_LOCAL, &sDefault.write_only, NULL, 0},
{"list", P_BOOL, P_LOCAL, &sDefault.list, NULL, 0},
{"use chroot", P_BOOL, P_LOCAL, &sDefault.use_chroot, NULL, 0},
{"ignore nonreadable",P_BOOL, P_LOCAL, &sDefault.ignore_nonreadable, NULL, 0},
{"uid", P_STRING, P_LOCAL, &sDefault.uid, NULL, 0},
{"gid", P_STRING, P_LOCAL, &sDefault.gid, NULL, 0},
{"hosts allow", P_STRING, P_LOCAL, &sDefault.hosts_allow, NULL, 0},
{"hosts deny", P_STRING, P_LOCAL, &sDefault.hosts_deny, NULL, 0},
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL, 0},
{"secrets file", P_STRING, P_LOCAL, &sDefault.secrets_file,NULL, 0},
{"strict modes", P_BOOL, P_LOCAL, &sDefault.strict_modes,NULL, 0},
{"filter", P_STRING, P_LOCAL, &sDefault.filter, NULL, 0},
{"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL, 0},
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from,NULL, 0},
{"include", P_STRING, P_LOCAL, &sDefault.include, NULL, 0},
{"include from", P_STRING, P_LOCAL, &sDefault.include_from,NULL, 0},
{"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging,NULL,0},
{"ignore errors", P_BOOL, P_LOCAL, &sDefault.ignore_errors,NULL,0},
{"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0},
{"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0},
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress,NULL, 0},
{NULL, P_BOOL, P_NONE, NULL, NULL, 0}
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL,0},
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL,0},
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress, NULL,0},
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from, NULL,0},
{"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL,0},
{"filter", P_STRING, P_LOCAL, &sDefault.filter, NULL,0},
{"gid", P_STRING, P_LOCAL, &sDefault.gid, NULL,0},
{"hosts allow", P_STRING, P_LOCAL, &sDefault.hosts_allow, NULL,0},
{"hosts deny", P_STRING, P_LOCAL, &sDefault.hosts_deny, NULL,0},
{"ignore errors", P_BOOL, P_LOCAL, &sDefault.ignore_errors, NULL,0},
{"ignore nonreadable",P_BOOL, P_LOCAL, &sDefault.ignore_nonreadable,NULL,0},
{"include from", P_STRING, P_LOCAL, &sDefault.include_from, NULL,0},
{"include", P_STRING, P_LOCAL, &sDefault.include, NULL,0},
{"incoming chmod", P_STRING, P_LOCAL, &sDefault.incoming_chmod, NULL,0},
{"list", P_BOOL, P_LOCAL, &sDefault.list, NULL,0},
{"lock file", P_STRING, P_LOCAL, &sDefault.lock_file, NULL,0},
{"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL,0},
{"max connections", P_INTEGER,P_LOCAL, &sDefault.max_connections, NULL,0},
{"max verbosity", P_INTEGER,P_LOCAL, &sDefault.max_verbosity, NULL,0},
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL,0},
{"outgoing chmod", P_STRING, P_LOCAL, &sDefault.outgoing_chmod, NULL,0},
{"path", P_PATH, P_LOCAL, &sDefault.path, NULL,0},
#ifdef HAVE_PUTENV
{"post-xfer exec", P_STRING, P_LOCAL, &sDefault.postxfer_exec, NULL,0},
{"pre-xfer exec", P_STRING, P_LOCAL, &sDefault.prexfer_exec, NULL,0},
#endif
{"read only", P_BOOL, P_LOCAL, &sDefault.read_only, NULL,0},
{"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options, NULL,0},
{"secrets file", P_STRING, P_LOCAL, &sDefault.secrets_file, NULL,0},
{"strict modes", P_BOOL, P_LOCAL, &sDefault.strict_modes, NULL,0},
{"temp dir", P_PATH, P_LOCAL, &sDefault.temp_dir, NULL,0},
{"timeout", P_INTEGER,P_LOCAL, &sDefault.timeout, NULL,0},
{"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging, NULL,0},
{"uid", P_STRING, P_LOCAL, &sDefault.uid, NULL,0},
{"use chroot", P_BOOL, P_LOCAL, &sDefault.use_chroot, NULL,0},
{"write only", P_BOOL, P_LOCAL, &sDefault.write_only, NULL,0},
{NULL, P_BOOL, P_NONE, NULL, NULL,0}
};
@@ -319,7 +338,6 @@ static void init_globals(void)
#ifdef LOG_DAEMON
Globals.syslog_facility = LOG_DAEMON;
#endif
Globals.max_verbosity = 1;
}
/***************************************************************************
@@ -354,43 +372,51 @@ static void init_locals(void)
int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
FN_GLOBAL_STRING(lp_bind_address, &Globals.bind_address)
FN_GLOBAL_STRING(lp_log_file, &Globals.log_file)
FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
FN_GLOBAL_STRING(lp_pid_file, &Globals.pid_file)
FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility)
FN_GLOBAL_INTEGER(lp_max_verbosity, &Globals.max_verbosity)
FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port)
FN_GLOBAL_STRING(lp_bind_address, &Globals.bind_address)
FN_LOCAL_STRING(lp_name, name)
FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port)
FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility)
FN_LOCAL_STRING(lp_auth_users, auth_users)
FN_LOCAL_STRING(lp_comment, comment)
FN_LOCAL_STRING(lp_path, path)
FN_LOCAL_STRING(lp_lock_file, lock_file)
FN_LOCAL_BOOL(lp_read_only, read_only)
FN_LOCAL_BOOL(lp_write_only, write_only)
FN_LOCAL_BOOL(lp_list, list)
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
FN_LOCAL_STRING(lp_uid, uid)
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_auth_users, auth_users)
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
FN_LOCAL_STRING(lp_filter, filter)
FN_LOCAL_STRING(lp_exclude, exclude)
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
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_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_dont_compress, dont_compress)
FN_LOCAL_INTEGER(lp_timeout, timeout)
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_timeout, timeout)
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_read_only, read_only)
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)
/* local prototypes */
static int strwicmp(char *psz1, char *psz2);

462
log.c
View File

@@ -26,23 +26,34 @@
<mbp@samba.org>, Oct 2000.
*/
#include "rsync.h"
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
#include <iconv.h>
#endif
extern int verbose;
extern int dry_run;
extern int am_daemon;
extern int am_server;
extern int am_sender;
extern int local_server;
extern int quiet;
extern int module_id;
extern int msg_fd_out;
extern int allow_8bit_chars;
extern int protocol_version;
extern int preserve_times;
extern int log_format_has_i;
extern int log_format_has_o_or_i;
extern int daemon_log_format_has_o_or_i;
extern mode_t orig_umask;
extern char *auth_user;
extern char *log_format;
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
extern iconv_t ic_chck;
#endif
static int log_initialised;
static int logfile_was_closed;
static char *logfname;
static FILE *logfile;
struct stats stats;
@@ -58,14 +69,16 @@ struct {
{ RERR_FILESELECT , "errors selecting input/output files, dirs" },
{ RERR_UNSUPPORTED, "requested action not supported" },
{ RERR_STARTCLIENT, "error starting client-server protocol" },
{ RERR_LOG_FAILURE, "daemon unable to append to log-file" },
{ RERR_SOCKETIO , "error in socket IO" },
{ RERR_FILEIO , "error in file IO" },
{ RERR_STREAMIO , "error in rsync protocol data stream" },
{ RERR_MESSAGEIO , "errors with program diagnostics" },
{ RERR_IPC , "error in IPC code" },
{ RERR_SIGNAL , "received SIGUSR1 or SIGINT" },
{ RERR_WAITCHILD , "some error returned by waitpid()" },
{ RERR_CRASHED , "sibling process crashed" },
{ RERR_TERMINATED , "sibling process terminated abnormally" },
{ RERR_SIGNAL1 , "received SIGUSR1" },
{ RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" },
{ RERR_WAITCHILD , "waitpid() failed" },
{ RERR_MALLOC , "error allocating core memory buffers" },
{ RERR_PARTIAL , "some files could not be transferred" },
{ RERR_VANISHED , "some files vanished before they could be transferred" },
@@ -79,7 +92,6 @@ struct {
};
/*
* Map from rsync error code to name, or return NULL.
*/
@@ -93,12 +105,11 @@ static char const *rerr_name(int code)
return NULL;
}
static void logit(int priority, char *buf)
{
if (logfname) {
if (!logfile)
log_open();
if (logfile_was_closed)
logfile_reopen();
if (logfile) {
fprintf(logfile,"%s [%d] %s",
timestring(time(NULL)), (int)getpid(), buf);
fflush(logfile);
@@ -107,9 +118,47 @@ static void logit(int priority, 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());
#else
openlog("rsyncd", options);
#endif
#ifndef LOG_NDELAY
logit(LOG_INFO, "rsyncd started\n");
#endif
}
static void logfile_open(void)
{
mode_t old_umask = umask(022 | orig_umask);
logfile = fopen(logfname, "a");
umask(old_umask);
if (!logfile) {
int fopen_errno = errno;
/* Rsync falls back to using syslog on failure. */
syslog_init();
rsyserr(FERROR, fopen_errno,
"failed to open log-file %s", logfname);
rprintf(FINFO, "Ignoring \"log file\" setting.\n");
}
}
void log_init(void)
{
int options = LOG_PID;
time_t t;
if (log_initialised)
@@ -124,66 +173,64 @@ void log_init(void)
/* optionally use a log file instead of syslog */
logfname = lp_log_file();
if (logfname) {
if (*logfname) {
log_open();
return;
}
logfname = NULL;
}
#ifdef LOG_NDELAY
options |= LOG_NDELAY;
#endif
#ifdef LOG_DAEMON
openlog("rsyncd", options, lp_syslog_facility());
#else
openlog("rsyncd", options);
#endif
#ifndef LOG_NDELAY
logit(LOG_INFO,"rsyncd started\n");
#endif
if (logfname && *logfname)
logfile_open();
else
syslog_init();
}
void log_open(void)
{
if (logfname && !logfile) {
extern int orig_umask;
int old_umask = umask(022 | orig_umask);
logfile = fopen(logfname, "a");
umask(old_umask);
if (!logfile) {
am_daemon = 0; /* avoid trying to log again */
rsyserr(FERROR, errno, "fopen() of log-file failed");
exit_cleanup(RERR_LOG_FAILURE);
}
}
}
void log_close(void)
void logfile_close(void)
{
if (logfile) {
logfile_was_closed = 1;
fclose(logfile);
logfile = NULL;
}
}
void logfile_reopen(void)
{
if (logfile_was_closed) {
logfile_was_closed = 0;
logfile_open();
}
}
static void filtered_fwrite(FILE *f, const char *buf, int len, int use_isprint)
{
const char *s, *end = buf + len;
for (s = buf; s < end; s++) {
if ((s < end - 4
&& *s == '\\' && s[1] == '#'
&& isdigit(*(uchar*)(s+2))
&& isdigit(*(uchar*)(s+3))
&& isdigit(*(uchar*)(s+4)))
|| (*s != '\t'
&& ((use_isprint && !isprint(*(uchar*)s))
|| *(uchar*)s < ' '))) {
if (s != buf && fwrite(buf, s - buf, 1, f) != 1)
exit_cleanup(RERR_MESSAGEIO);
fprintf(f, "\\#%03o", *(uchar*)s);
buf = s + 1;
}
}
if (buf != end && fwrite(buf, end - buf, 1, f) != 1)
exit_cleanup(RERR_MESSAGEIO);
}
/* this is the underlying (unformatted) rsync debugging function. Call
* it with FINFO, FERROR or FLOG */
* it with FINFO, FERROR or FLOG. Note: recursion can happen with
* certain fatal conditions. */
void rwrite(enum logcode code, char *buf, int len)
{
int trailing_CR_or_NL;
FILE *f = NULL;
/* recursion can happen with certain fatal conditions */
if (quiet && code == FINFO)
return;
if (len < 0)
exit_cleanup(RERR_MESSAGEIO);
buf[len] = 0;
if (quiet && code == FINFO)
return;
if (am_server && msg_fd_out >= 0) {
/* Pass the message to our sibling. */
@@ -191,6 +238,9 @@ void rwrite(enum logcode code, char *buf, int len)
return;
}
if (code == FSOCKERR) /* This gets simplified for a non-sibling. */
code = FERROR;
if (code == FCLIENT)
code = FINFO;
else if (am_daemon) {
@@ -222,31 +272,67 @@ void rwrite(enum logcode code, char *buf, int len)
}
}
if (code == FERROR) {
switch (code) {
case FERROR:
log_got_error = 1;
f = stderr;
goto pre_scan;
case FINFO:
f = am_server ? stderr : stdout;
pre_scan:
while (len > 1 && *buf == '\n') {
fputc(*buf, f);
buf++;
len--;
}
break;
case FNAME:
f = am_server ? stderr : stdout;
break;
default:
exit_cleanup(RERR_MESSAGEIO);
}
if (code == FINFO)
f = am_server ? stderr : stdout;
trailing_CR_or_NL = len && (buf[len-1] == '\n' || buf[len-1] == '\r')
? buf[--len] : 0;
if (!f)
exit_cleanup(RERR_MESSAGEIO);
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
if (ic_chck != (iconv_t)-1) {
char convbuf[1024];
char *in_buf = buf, *out_buf = convbuf;
size_t in_cnt = len, out_cnt = sizeof convbuf - 1;
if (fwrite(buf, len, 1, f) != 1)
exit_cleanup(RERR_MESSAGEIO);
iconv(ic_chck, NULL, 0, NULL, 0);
while (iconv(ic_chck, &in_buf,&in_cnt,
&out_buf,&out_cnt) == (size_t)-1) {
if (out_buf != convbuf) {
filtered_fwrite(f, convbuf, out_buf - convbuf, 0);
out_buf = convbuf;
out_cnt = sizeof convbuf - 1;
}
if (errno == E2BIG)
continue;
fprintf(f, "\\#%03o", *(uchar*)in_buf++);
in_cnt--;
}
if (out_buf != convbuf)
filtered_fwrite(f, convbuf, out_buf - convbuf, 0);
} else
#endif
filtered_fwrite(f, buf, len, !allow_8bit_chars);
if (buf[len-1] == '\r' || buf[len-1] == '\n')
if (trailing_CR_or_NL) {
fputc(trailing_CR_or_NL, f);
fflush(f);
}
}
/* This is the rsync debugging function. Call it with FINFO, FERROR or
* FLOG. */
void rprintf(enum logcode code, const char *format, ...)
{
va_list ap;
char buf[MAXPATHLEN+512];
char buf[BIGPATHBUFLEN];
size_t len;
va_start(ap, format);
@@ -257,7 +343,7 @@ void rprintf(enum logcode code, const char *format, ...)
* truncate the resulting string. (Note that configure ensures
* that we have a vsnprintf() that doesn't ever return -1.) */
if (len > sizeof buf - 1) {
const char ellipsis[] = "[...]";
static const char ellipsis[] = "[...]";
/* Reset length, and zero-terminate the end of our buffer */
len = sizeof buf - 1;
@@ -273,7 +359,7 @@ void rprintf(enum logcode code, const char *format, ...)
* If the input format string has a trailing newline,
* we copy it into that extra null; if it doesn't, well,
* all we lose is one byte. */
strncpy(buf+len-sizeof ellipsis, ellipsis, sizeof ellipsis);
memcpy(buf+len-sizeof ellipsis, ellipsis, sizeof ellipsis);
if (format[strlen(format)-1] == '\n') {
buf[len-1] = '\n';
}
@@ -282,7 +368,6 @@ void rprintf(enum logcode code, const char *format, ...)
rwrite(code, buf, len);
}
/* This is like rprintf, but it also tries to print some
* representation of the error code. Normally errcode = errno.
*
@@ -294,7 +379,7 @@ void rprintf(enum logcode code, const char *format, ...)
void rsyserr(enum logcode code, int errcode, const char *format, ...)
{
va_list ap;
char buf[MAXPATHLEN+512];
char buf[BIGPATHBUFLEN];
size_t len;
strcpy(buf, RSYNC_NAME ": ");
@@ -314,12 +399,10 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
rwrite(code, buf, len);
}
void rflush(enum logcode code)
{
FILE *f = NULL;
if (am_daemon) {
return;
}
@@ -343,74 +426,143 @@ void rflush(enum logcode code)
fflush(f);
}
/* a generic logging routine for send/recv, with parameter
* substitiution */
static void log_formatted(enum logcode code, char *format, char *op,
struct file_struct *file, struct stats *initial_stats,
int iflags, char *hlink)
{
char buf[MAXPATHLEN+1024];
char buf2[MAXPATHLEN];
char *p, *n;
char buf[MAXPATHLEN+1024], buf2[MAXPATHLEN], fmt[32];
char *p, *s, *n;
size_t len, total;
int64 b;
*fmt = '%';
/* We expand % codes one by one in place in buf. We don't
* copy in the terminating nul of the inserted strings, but
* rather keep going until we reach the nul of the format. */
* copy in the terminating null of the inserted strings, but
* rather keep going until we reach the null of the format. */
total = strlcpy(buf, format, sizeof buf);
for (p = buf; (p = strchr(p, '%')) != NULL && p[1]; ) {
if (total > MAXPATHLEN) {
rprintf(FERROR, "log-format string is WAY too long!\n");
exit_cleanup(RERR_MESSAGEIO);
}
buf[total++] = '\n';
buf[total] = '\0';
for (p = buf; (p = strchr(p, '%')) != NULL; ) {
s = p++;
n = fmt + 1;
if (*p == '-')
*n++ = *p++;
while (isdigit(*(uchar*)p) && n - fmt < (int)(sizeof fmt) - 8)
*n++ = *p++;
if (!*p)
break;
*n = '\0';
n = NULL;
switch (p[1]) {
case 'h': if (am_daemon) n = client_name(0); break;
case 'a': if (am_daemon) n = client_addr(0); break;
switch (*p) {
case 'h':
if (am_daemon)
n = client_name(0);
break;
case 'a':
if (am_daemon)
n = client_addr(0);
break;
case 'l':
snprintf(buf2, sizeof buf2, "%.0f",
strlcat(fmt, ".0f", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
(double)file->length);
n = buf2;
break;
case 'p':
snprintf(buf2, sizeof buf2, "%d",
(int)getpid());
case 'U':
strlcat(fmt, "ld", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
(long)file->uid);
n = buf2;
break;
case 'o': n = op; break;
case 'f':
pathjoin(buf2, sizeof buf2,
am_sender && file->dir.root ? file->dir.root : "",
safe_fname(f_name(file)));
clean_fname(buf2, 0);
case 'G':
if (file->gid == GID_NONE)
n = "DEFAULT";
else {
strlcat(fmt, "ld", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
(long)file->gid);
n = buf2;
}
break;
case 'p':
strlcat(fmt, "ld", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt,
(long)getpid());
n = buf2;
if (*n == '/') n++;
break;
case 'M':
n = timestring(file->modtime);
{
char *cp = n;
while ((cp = strchr(cp, ' ')) != NULL)
*cp = '-';
}
break;
case 'B':
n = buf2 + MAXPATHLEN - PERMSTRING_SIZE;
permstring(n - 1, file->mode); /* skip the type char */
break;
case 'o':
n = op;
break;
case 'f':
n = f_name(file, NULL);
if (am_sender && file->dir.root) {
pathjoin(buf2, sizeof buf2,
file->dir.root, n);
clean_fname(buf2, 0);
if (fmt[1])
strlcpy(n, buf2, MAXPATHLEN);
else
n = buf2;
} else
clean_fname(n, 0);
if (*n == '/')
n++;
break;
case 'n':
n = (char*)safe_fname(f_name(file));
if (S_ISDIR(file->mode)) {
/* The buffer from safe_fname() has more
* room than MAXPATHLEN, so this is safe. */
strcat(n, "/");
}
n = f_name(file, NULL);
if (S_ISDIR(file->mode))
strlcat(n, "/", MAXPATHLEN);
break;
case 'L':
if (hlink && *hlink) {
snprintf(buf2, sizeof buf2, " => %s",
safe_fname(hlink));
n = buf2;
n = hlink;
strcpy(buf2, " => ");
} else if (S_ISLNK(file->mode) && file->u.link) {
snprintf(buf2, sizeof buf2, " -> %s",
safe_fname(file->u.link));
n = buf2;
} else
n = file->u.link;
strcpy(buf2, " -> ");
} else {
n = "";
if (!fmt[1])
break;
strcpy(buf2, " ");
}
strlcat(fmt, "s", sizeof fmt);
snprintf(buf2 + 4, sizeof buf2 - 4, fmt, n);
n = buf2;
break;
case 'm':
n = lp_name(module_id);
break;
case 't':
n = timestring(time(NULL));
break;
case 'P':
n = lp_path(module_id);
break;
case 'u':
n = auth_user;
break;
case 'm': n = lp_name(module_id); break;
case 't': n = timestring(time(NULL)); break;
case 'P': n = lp_path(module_id); break;
case 'u': n = auth_user; break;
case 'b':
if (am_sender) {
b = stats.total_written -
@@ -419,7 +571,8 @@ static void log_formatted(enum logcode code, char *format, char *op,
b = stats.total_read -
initial_stats->total_read;
}
snprintf(buf2, sizeof buf2, "%.0f", (double)b);
strlcat(fmt, ".0f", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt, (double)b);
n = buf2;
break;
case 'c':
@@ -430,7 +583,8 @@ static void log_formatted(enum logcode code, char *format, char *op,
b = stats.total_read -
initial_stats->total_read;
}
snprintf(buf2, sizeof buf2, "%.0f", (double)b);
strlcat(fmt, ".0f", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt, (double)b);
n = buf2;
break;
case 'i':
@@ -438,23 +592,23 @@ static void log_formatted(enum logcode code, char *format, char *op,
n = "*deleting";
break;
}
n = buf2;
n = buf2 + MAXPATHLEN - 32;
n[0] = iflags & ITEM_LOCAL_CHANGE
? iflags & ITEM_XNAME_FOLLOWS ? 'h' : 'c'
: !(iflags & ITEM_TRANSFER) ? '.'
: *op == 's' ? '<' : '>';
: !local_server && *op == 's' ? '<' : '>';
n[1] = S_ISDIR(file->mode) ? 'd'
: IS_SPECIAL(file->mode) ? 'S'
: IS_DEVICE(file->mode) ? 'D'
: S_ISLNK(file->mode) ? 'L' : 'f';
n[2] = !(iflags & ITEM_REPORT_CHECKSUM) ? '.' : 'c';
n[3] = !(iflags & ITEM_REPORT_SIZE) ? '.' : 's';
n[4] = !(iflags & ITEM_REPORT_TIME) ? '.'
: !preserve_times || IS_DEVICE(file->mode)
|| S_ISLNK(file->mode) ? 'T' : 't';
: !preserve_times || S_ISLNK(file->mode) ? 'T' : 't';
n[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
n[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
n[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
n[8] = !(iflags & ITEM_REPORT_XATTRS) ? '.' : 'a';
n[8] = '.';
n[9] = '\0';
if (iflags & (ITEM_IS_NEW|ITEM_MISSING_DATA)) {
@@ -462,7 +616,8 @@ static void log_formatted(enum logcode code, char *format, char *op,
int i;
for (i = 2; n[i]; i++)
n[i] = ch;
} else if (!(iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE))) {
} else if (n[0] == '.' || n[0] == 'h'
|| (n[0] == 'c' && n[1] == 'f')) {
int i;
for (i = 2; n[i]; i++) {
if (n[i] != '.')
@@ -476,17 +631,20 @@ static void log_formatted(enum logcode code, char *format, char *op,
break;
}
/* n is the string to be inserted in place of this %
* code; len is its length not including the trailing
* NUL */
if (!n) {
p += 2;
/* "n" is the string to be inserted in place of this % code. */
if (!n)
continue;
if (n != buf2 && fmt[1]) {
strlcat(fmt, "s", sizeof fmt);
snprintf(buf2, sizeof buf2, fmt, n);
n = buf2;
}
len = strlen(n);
if (len + total - 2 >= sizeof buf) {
/* Subtract the length of the escape from the string's size. */
total -= p - s + 1;
if (len + total >= (size_t)sizeof buf) {
rprintf(FERROR,
"buffer overflow expanding %%%c -- exiting\n",
p[0]);
@@ -494,19 +652,41 @@ static void log_formatted(enum logcode code, char *format, char *op,
}
/* Shuffle the rest of the string along to make space for n */
if (len != 2)
memmove(p + len, p + 2, total - (p + 2 - buf) + 1);
total += len - 2;
if (len != (size_t)(p - s + 1))
memmove(s + len, p + 1, total - (s - buf) + 1);
total += len;
/* Insert the contents of string "n", but NOT its nul. */
/* Insert the contents of string "n", but NOT its null. */
if (len)
memcpy(p, n, len);
memcpy(s, n, len);
/* Skip over inserted string; continue looking */
p += len;
p = s + len;
}
rprintf(code, "%s\n", buf);
rwrite(code, buf, total);
}
/* Return 1 if the format escape is in the log-format string (e.g. look for
* the 'b' in the "%9b" format escape). */
int log_format_has(const char *format, char esc)
{
const char *p;
if (!format)
return 0;
for (p = format; (p = strchr(p, '%')) != NULL; ) {
if (*++p == '-')
p++;
while (isdigit(*(uchar*)p))
p++;
if (!*p)
break;
if (*p == esc)
return 1;
}
return 0;
}
/* log the transfer of a file */
@@ -519,7 +699,7 @@ void log_item(struct file_struct *file, struct stats *initial_stats,
log_formatted(FLOG, lp_log_format(module_id), s_or_r,
file, initial_stats, iflags, hlink);
} else if (log_format && !am_server) {
log_formatted(FINFO, log_format, s_or_r,
log_formatted(FNAME, log_format, s_or_r,
file, initial_stats, iflags, hlink);
}
}
@@ -527,12 +707,15 @@ void log_item(struct file_struct *file, struct stats *initial_stats,
void maybe_log_item(struct file_struct *file, int iflags, int itemizing,
char *buf)
{
int see_item = itemizing && (iflags || verbose > 1);
int significant_flags = iflags & SIGNIFICANT_ITEM_FLAGS;
int see_item = itemizing && (significant_flags || *buf
|| log_format_has_i > 1 || (verbose > 1 && log_format_has_i));
int local_change = iflags & ITEM_LOCAL_CHANGE && significant_flags;
if (am_server) {
if (am_daemon && !dry_run && see_item)
log_item(file, &stats, iflags, buf);
} else if (see_item || iflags & ITEM_LOCAL_CHANGE || *buf
|| (S_ISDIR(file->mode) && iflags & SIGNIFICANT_ITEM_FLAGS))
} else if (see_item || local_change || *buf
|| (S_ISDIR(file->mode) && significant_flags))
log_item(file, &stats, iflags, buf);
}
@@ -564,7 +747,6 @@ void log_delete(char *fname, int mode)
log_formatted(FLOG, fmt, "del.", &file, &stats, ITEM_DELETED, NULL);
}
/*
* Called when the transfer is interrupted for some reason.
*
@@ -587,11 +769,11 @@ void log_exit(int code, const char *file, int line)
/* VANISHED is not an error, only a warning */
if (code == RERR_VANISHED) {
rprintf(FINFO, "rsync warning: %s (code %d) at %s(%d)\n",
name, code, file, line);
rprintf(FINFO, "rsync warning: %s (code %d) at %s(%d) [%s]\n",
name, code, file, line, who_am_i());
} else {
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d)\n",
name, code, file, line);
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d) [%s]\n",
name, code, file, line, who_am_i());
}
}
}

478
main.c
View File

@@ -20,8 +20,9 @@
*/
#include "rsync.h"
time_t starttime = 0;
#if defined CONFIG_LOCALE && defined HAVE_LOCALE_H
#include <locale.h>
#endif
extern int verbose;
extern int dry_run;
@@ -39,17 +40,14 @@ extern int kluge_around_eof;
extern int do_stats;
extern int log_got_error;
extern int module_id;
extern int orig_umask;
extern int copy_links;
extern int copy_dirlinks;
extern int keep_dirlinks;
extern int preserve_hard_links;
extern int protocol_version;
extern int recurse;
extern int fuzzy_basis;
extern int relative_paths;
extern int rsync_port;
extern int inplace;
extern int make_backups;
extern int whole_file;
extern int read_batch;
extern int write_batch;
@@ -59,58 +57,89 @@ extern int filesfrom_fd;
extern pid_t cleanup_child_pid;
extern struct stats stats;
extern char *filesfrom_host;
extern char *partial_dir;
extern char *basis_dir[];
extern char *rsync_path;
extern char *shell_cmd;
extern char *batch_name;
int local_server = 0;
mode_t orig_umask = 0;
struct file_list *the_file_list;
/* There's probably never more than at most 2 outstanding child processes,
* but set it higher, just in case. */
#define MAXCHILDPROCS 5
#define MAXCHILDPROCS 7
#ifdef HAVE_SIGACTION
# ifdef HAVE_SIGPROCMASK
# define SIGACTMASK(n,h) SIGACTION(n,h), sigaddset(&sigmask,(n))
# else
# define SIGACTMASK(n,h) SIGACTION(n,h)
# endif
static struct sigaction sigact;
#endif
struct pid_status {
pid_t pid;
int status;
int status;
} pid_stat_table[MAXCHILDPROCS];
static time_t starttime, endtime;
static int64 total_read, total_written;
static void show_malloc_stats(void);
/****************************************************************************
wait for a process to exit, calling io_flush while waiting
****************************************************************************/
void wait_process(pid_t pid, int *status)
/* Works like waitpid(), but if we already harvested the child pid in our
* remember_children(), we succeed instead of returning an error. */
pid_t wait_process(pid_t pid, int *status_ptr, int flags)
{
pid_t waited_pid;
int cnt;
while ((waited_pid = waitpid(pid, status, WNOHANG)) == 0) {
msleep(20);
io_flush(FULL_FLUSH);
}
pid_t waited_pid = waitpid(pid, status_ptr, flags);
if (waited_pid == -1 && errno == ECHILD) {
/* status of requested child no longer available.
* check to see if it was processed by the sigchld_handler.
*/
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
/* Status of requested child no longer available: check to
* see if it was processed by remember_children(). */
int cnt;
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
if (pid == pid_stat_table[cnt].pid) {
*status = pid_stat_table[cnt].status;
*status_ptr = pid_stat_table[cnt].status;
pid_stat_table[cnt].pid = 0;
break;
return pid;
}
}
}
return waited_pid;
}
/* Wait for a process to exit, calling io_flush while waiting. */
static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
{
pid_t waited_pid;
int status;
while ((waited_pid = wait_process(pid, &status, WNOHANG)) == 0) {
msleep(20);
io_flush(FULL_FLUSH);
}
/* TODO: If the child exited on a signal, then log an
* appropriate error message. Perhaps we should also accept a
* message describing the purpose of the child. Also indicate
* this to the caller so that thhey know something went
* wrong. */
*status = WEXITSTATUS(*status);
* this to the caller so that they know something went wrong. */
if (waited_pid < 0) {
rsyserr(FERROR, errno, "waitpid");
*exit_code_ptr = RERR_WAITCHILD;
} else if (!WIFEXITED(status)) {
#ifdef WCOREDUMP
if (WCOREDUMP(status))
*exit_code_ptr = RERR_CRASHED;
else
#endif
if (WIFSIGNALED(status))
*exit_code_ptr = RERR_TERMINATED;
else
*exit_code_ptr = RERR_WAITCHILD;
} else
*exit_code_ptr = WEXITSTATUS(status);
}
/* This function gets called from all 3 processes. We want the client side
@@ -121,12 +150,13 @@ void wait_process(pid_t pid, int *status)
* the report. All processes might also generate a set of debug stats, if
* the verbose level is high enough (this is the only thing that the
* generator process and the server receiver ever do here). */
static void report(int f)
static void handle_stats(int f)
{
endtime = time(NULL);
/* Cache two stats because the read/write code can change it. */
int64 total_read = stats.total_read;
int64 total_written = stats.total_written;
time_t t = time(NULL);
total_read = stats.total_read;
total_written = stats.total_written;
if (do_stats && verbose > 1) {
/* These come out from every process */
@@ -158,7 +188,9 @@ static void report(int f)
/* this is the client */
if (!am_sender) {
if (f < 0 && !am_sender) /* e.g. when we got an empty file list. */
;
else if (!am_sender) {
/* Read the first two in opposite order because the meaning of
* read/write swaps when switching from sender to receiver. */
total_written = read_longint(f);
@@ -179,19 +211,22 @@ static void report(int f)
write_longint(batch_fd, stats.flist_xfertime);
}
}
}
static void output_summary(void)
{
if (do_stats) {
rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
rprintf(FINFO,"Number of files transferred: %d\n",
stats.num_transferred_files);
rprintf(FINFO,"Total file size: %.0f bytes\n",
(double)stats.total_size);
rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
(double)stats.total_transferred_size);
rprintf(FINFO,"Literal data: %.0f bytes\n",
(double)stats.literal_data);
rprintf(FINFO,"Matched data: %.0f bytes\n",
(double)stats.matched_data);
rprintf(FINFO,"Total file size: %s bytes\n",
human_num(stats.total_size));
rprintf(FINFO,"Total transferred file size: %s bytes\n",
human_num(stats.total_transferred_size));
rprintf(FINFO,"Literal data: %s bytes\n",
human_num(stats.literal_data));
rprintf(FINFO,"Matched data: %s bytes\n",
human_num(stats.matched_data));
rprintf(FINFO,"File list size: %d\n", stats.flist_size);
if (stats.flist_buildtime) {
rprintf(FINFO,
@@ -201,19 +236,19 @@ static void report(int f)
"File list transfer time: %.3f seconds\n",
(double)stats.flist_xfertime / 1000);
}
rprintf(FINFO,"Total bytes sent: %.0f\n",
(double)total_written);
rprintf(FINFO,"Total bytes received: %.0f\n",
(double)total_read);
rprintf(FINFO,"Total bytes sent: %s\n",
human_num(total_written));
rprintf(FINFO,"Total bytes received: %s\n",
human_num(total_read));
}
if (verbose || do_stats) {
rprintf(FINFO,
"\nsent %.0f bytes received %.0f bytes %.2f bytes/sec\n",
(double)total_written, (double)total_read,
(total_written + total_read)/(0.5 + (t - starttime)));
rprintf(FINFO, "total size is %.0f speedup is %.2f\n",
(double)stats.total_size,
"\nsent %s bytes received %s bytes %s bytes/sec\n",
human_num(total_written), human_num(total_read),
human_dnum((total_written + total_read)/(0.5 + (endtime - starttime)), 2));
rprintf(FINFO, "total size is %s speedup is %.2f\n",
human_num(stats.total_size),
(double)stats.total_size / (total_written+total_read));
}
@@ -268,10 +303,11 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
int i, argc = 0;
char *args[MAX_ARGS];
pid_t ret;
char *tok, *dir = NULL;
char *dir = NULL;
int dash_l_set = 0;
if (!read_batch && !local_server) {
char *t, *f, in_quote = '\0';
char *rsh_env = getenv(RSYNC_RSH_ENV);
if (!cmd)
cmd = rsh_env;
@@ -281,13 +317,39 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
if (!cmd)
goto oom;
for (tok = strtok(cmd, " "); tok; tok = strtok(NULL, " ")) {
for (t = f = cmd; *f; f++) {
if (*f == ' ')
continue;
/* Comparison leaves rooms for server_options(). */
if (argc >= MAX_ARGS - 100) {
if (argc >= MAX_ARGS - MAX_SERVER_ARGS) {
rprintf(FERROR, "internal: args[] overflowed in do_cmd()\n");
exit_cleanup(RERR_SYNTAX);
}
args[argc++] = tok;
args[argc++] = t;
while (*f != ' ' || in_quote) {
if (!*f) {
if (in_quote) {
rprintf(FERROR,
"Missing trailing-%c in remote-shell command.\n",
in_quote);
exit_cleanup(RERR_SYNTAX);
}
f--;
break;
}
if (*f == '\'' || *f == '"') {
if (!in_quote) {
in_quote = *f++;
continue;
}
if (*f == in_quote && *++f != in_quote) {
in_quote = '\0';
continue;
}
}
*t++ = *f++;
}
*t++ = '\0';
}
/* check to see if we've already been given '-l user' in
@@ -340,10 +402,9 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
args[argc] = NULL;
if (verbose > 3) {
rprintf(FINFO,"cmd=");
for (i = 0; i < argc; i++)
rprintf(FINFO, "%s ", safe_fname(args[i]));
rprintf(FINFO,"\n");
rprintf(FINFO, "cmd[%d]=%s ", i, args[i]);
rprintf(FINFO, "\n");
}
if (read_batch) {
@@ -370,62 +431,122 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char *path,
return ret;
oom:
oom:
out_of_memory("do_cmd");
return 0; /* not reached */
}
static char *get_local_name(struct file_list *flist,char *name)
/* The receiving side operates in one of two modes:
*
* 1. it receives any number of files into a destination directory,
* placing them according to their names in the file-list.
*
* 2. it receives a single file and saves it using the name in the
* destination path instead of its file-list name. This requires a
* "local name" for writing out the destination file.
*
* So, our task is to figure out what mode/local-name we need and return
* either a NULL for mode 1, or the local-name for mode 2. We also
* change directory if there are any path components in dest_path. */
static char *get_local_name(struct file_list *flist, char *dest_path)
{
STRUCT_STAT st;
int e;
char *cp;
if (verbose > 2)
rprintf(FINFO,"get_local_name count=%d %s\n",
flist->count, NS(name));
if (verbose > 2) {
rprintf(FINFO, "get_local_name count=%d %s\n",
flist->count, NS(dest_path));
}
if (!name)
if (!dest_path || list_only)
return NULL;
if (do_stat(name,&st) == 0) {
/* If the destination path refers to an existing directory, enter
* it and use mode 1. If there is something other than a directory
* at the destination path, we must be transferring one file
* (anything at the destination will be overwritten). */
if (do_stat(dest_path, &st) == 0) {
if (S_ISDIR(st.st_mode)) {
if (!push_dir(name)) {
if (!push_dir(dest_path)) {
rsyserr(FERROR, errno, "push_dir#1 %s failed",
full_fname(name));
full_fname(dest_path));
exit_cleanup(RERR_FILESELECT);
}
return NULL;
}
if (flist->count > 1) {
rprintf(FERROR,"ERROR: destination must be a directory when copying more than 1 file\n");
rprintf(FERROR,
"ERROR: destination must be a directory when"
" copying more than 1 file\n");
exit_cleanup(RERR_FILESELECT);
}
return name;
}
if (flist->count <= 1 && ((e = strlen(name)) <= 1 || name[e-1] != '/'))
return name;
if (do_mkdir(name,0777 & ~orig_umask) != 0) {
rsyserr(FERROR, errno, "mkdir %s failed", full_fname(name));
exit_cleanup(RERR_FILEIO);
}
if (verbose > 0)
rprintf(FINFO, "created directory %s\n", safe_fname(name));
if (dry_run) {
dry_run++;
return NULL;
}
if (!push_dir(name)) {
rsyserr(FERROR, errno, "push_dir#2 %s failed",
full_fname(name));
/* Caution: flist->count could be 0! */
if (flist->count == 1 && S_ISDIR(flist->files[0]->mode)) {
rprintf(FERROR,
"ERROR: cannot overwrite non-directory"
" with a directory\n");
exit_cleanup(RERR_FILESELECT);
}
} else if (errno != ENOENT) {
rsyserr(FERROR, errno, "cannot stat destination %s",
full_fname(dest_path));
exit_cleanup(RERR_FILESELECT);
}
return NULL;
cp = strrchr(dest_path, '/');
/* If the destination path ends in a slash or we are transferring
* multiple files, create a directory at the destination path,
* enter the new directory, and use mode 1. */
if (flist->count > 1 || (cp && !cp[1])) {
/* Lop off the final slash (if any). */
if (cp && !cp[1])
*cp = '\0';
if (mkdir_defmode(dest_path) != 0) {
rsyserr(FERROR, errno, "mkdir %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILEIO);
}
if (verbose)
rprintf(FINFO, "created directory %s\n", dest_path);
if (dry_run) {
/* Indicate that the destination directory doesn't
* really exist and return mode 1. */
dry_run++;
return NULL;
}
if (!push_dir(dest_path)) {
rsyserr(FERROR, errno, "push_dir#2 %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILESELECT);
}
return NULL;
}
/* Otherwise, we are writing a single file, possibly on top of an
* existing non-directory. Change to the item's parent directory
* (if it has a path component), return the basename of the
* destination file as the local name, and use mode 2. */
if (!cp)
return dest_path;
if (cp == dest_path)
dest_path = "/";
*cp = '\0';
if (!push_dir(dest_path)) {
rsyserr(FERROR, errno, "push_dir#3 %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILESELECT);
}
*cp = '/';
return cp + 1;
}
@@ -453,9 +574,8 @@ static void read_final_goodbye(int f_in, int f_out)
}
static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
{
int i;
struct file_list *flist;
char *dir = argv[0];
@@ -484,14 +604,6 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
argc--;
argv++;
if (strcmp(dir,".")) {
int l = strlen(dir);
if (strcmp(dir,"/") == 0)
l = 0;
for (i = 0; i < argc; i++)
argv[i] += l+1;
}
if (argc == 0 && (recurse || list_only)) {
argc = 1;
argv--;
@@ -509,7 +621,7 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
send_files(flist,f_out,f_in);
io_flush(FULL_FLUSH);
report(f_out);
handle_stats(f_out);
if (protocol_version >= 24)
read_final_goodbye(f_in, f_out);
io_flush(FULL_FLUSH);
@@ -520,12 +632,12 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
{
int pid;
int status = 0;
int exit_code = 0;
int error_pipe[2];
/* The receiving side mustn't obey this, or an existing symlink that
* points to an identical file won't be replaced by the referent. */
copy_links = 0;
copy_links = copy_dirlinks = 0;
if (preserve_hard_links)
init_hard_links();
@@ -555,7 +667,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
recv_files(f_in, flist, local_name);
io_flush(FULL_FLUSH);
report(f_in);
handle_stats(f_in);
send_msg(MSG_DONE, "", 0);
io_flush(FULL_FLUSH);
@@ -583,7 +695,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
am_generator = 1;
close_multiplexing_in();
if (write_batch)
if (write_batch && !am_server)
stop_write_batch();
close(error_pipe[1]);
@@ -596,7 +708,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
generate_files(f_out, flist, local_name);
report(-1);
handle_stats(-1);
io_flush(FULL_FLUSH);
if (protocol_version >= 24) {
/* send a final goodbye message */
@@ -606,14 +718,14 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
set_msg_fd_in(-1);
kill(pid, SIGUSR2);
wait_process(pid, &status);
return status;
wait_process_with_flush(pid, &exit_code);
return exit_code;
}
static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
{
int status;
int exit_code;
struct file_list *flist;
char *local_name = NULL;
char *dir = NULL;
@@ -636,7 +748,6 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
return;
}
if (argc > 0) {
dir = argv[0];
argc--;
@@ -669,17 +780,11 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
}
the_file_list = flist;
if (argc > 0) {
if (strcmp(dir,".")) {
argv[0] += strlen(dir);
if (argv[0][0] == '/')
argv[0]++;
}
if (argc > 0)
local_name = get_local_name(flist,argv[0]);
}
status = do_recv(f_in,f_out,flist,local_name);
exit_cleanup(status);
exit_code = do_recv(f_in,f_out,flist,local_name);
exit_cleanup(exit_code);
}
@@ -697,6 +802,9 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
io_set_sock_fds(f_in, f_out);
setup_protocol(f_out, f_in);
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
setup_iconv();
#endif
if (protocol_version >= 23)
io_start_multiplex_out();
@@ -722,7 +830,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
{
struct file_list *flist = NULL;
int status = 0, status2 = 0;
int exit_code = 0, exit_code2 = 0;
char *local_name = NULL;
cleanup_child_pid = pid;
@@ -733,6 +841,9 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
io_set_sock_fds(f_in, f_out);
setup_protocol(f_out,f_in);
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
setup_iconv();
#endif
if (protocol_version >= 23 && !read_batch)
io_start_multiplex_in();
@@ -756,7 +867,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
if (filesfrom_host)
filesfrom_fd = f_in;
if (write_batch)
if (write_batch && !am_server)
start_write_batch(f_out);
flist = send_file_list(f_out, argc, argv);
set_msg_fd_in(-1);
@@ -767,17 +878,18 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
io_flush(NORMAL_FLUSH);
send_files(flist,f_out,f_in);
io_flush(FULL_FLUSH);
handle_stats(-1);
if (protocol_version >= 24)
read_final_goodbye(f_in, f_out);
if (pid != -1) {
if (verbose > 3)
rprintf(FINFO,"client_run waiting on %d\n", (int) pid);
io_flush(FULL_FLUSH);
wait_process(pid, &status);
wait_process_with_flush(pid, &exit_code);
}
report(-1);
output_summary();
io_flush(FULL_FLUSH);
exit_cleanup(status);
exit_cleanup(exit_code);
}
if (need_messages_from_generator && !read_batch)
@@ -793,29 +905,28 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
filesfrom_fd = -1;
}
if (write_batch)
if (write_batch && !am_server)
start_write_batch(f_in);
flist = recv_file_list(f_in);
if (!flist || flist->count == 0) {
rprintf(FINFO, "client: nothing to do: "
"perhaps you need to specify some filenames or "
"the --recursive option?\n");
exit_cleanup(0);
}
the_file_list = flist;
local_name = get_local_name(flist,argv[0]);
if (flist && flist->count > 0) {
local_name = get_local_name(flist, argv[0]);
status2 = do_recv(f_in,f_out,flist,local_name);
exit_code2 = do_recv(f_in, f_out, flist, local_name);
} else {
handle_stats(-1);
output_summary();
}
if (pid != -1) {
if (verbose > 3)
rprintf(FINFO,"client_run2 waiting on %d\n", (int) pid);
io_flush(FULL_FLUSH);
wait_process(pid, &status);
wait_process_with_flush(pid, &exit_code);
}
return MAX(status, status2);
return MAX(exit_code, exit_code2);
}
static int copy_argv (char *argv[])
@@ -859,9 +970,16 @@ static int start_client(int argc, char *argv[])
return rc;
if (!read_batch) { /* for read_batch, NO source is specified */
argc--;
shell_path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
if (shell_path) { /* source is remote */
char *dummy1;
int dummy2;
if (--argc
&& check_for_hostspec(argv[argc], &dummy1, &dummy2)) {
rprintf(FERROR,
"The source and destination cannot both be remote.\n");
exit_cleanup(RERR_SYNTAX);
}
argv++;
if (filesfrom_host && *filesfrom_host
&& strcmp(filesfrom_host, shell_machine) != 0) {
@@ -882,12 +1000,14 @@ static int start_client(int argc, char *argv[])
} else { /* source is local, check dest arg */
am_sender = 1;
if (argc < 1) { /* destination required */
usage(FERROR);
exit_cleanup(RERR_SYNTAX);
if (argc > 1)
p = argv[--argc];
else {
p = ".";
list_only = 1;
}
shell_path = check_for_hostspec(argv[argc], &shell_machine, &rsync_port);
shell_path = check_for_hostspec(p, &shell_machine, &rsync_port);
if (shell_path && filesfrom_host && *filesfrom_host
&& strcmp(filesfrom_host, shell_machine) != 0) {
rprintf(FERROR,
@@ -902,7 +1022,7 @@ static int start_client(int argc, char *argv[])
exit_cleanup(RERR_SYNTAX);
}
shell_machine = NULL;
shell_path = argv[argc];
shell_path = p;
} else if (rsync_port) {
if (!shell_cmd) {
return start_socket_client(shell_machine,
@@ -932,10 +1052,10 @@ static int start_client(int argc, char *argv[])
if (verbose > 3) {
rprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
shell_cmd ? safe_fname(shell_cmd) : "",
shell_machine ? safe_fname(shell_machine) : "",
shell_user ? safe_fname(shell_user) : "",
shell_path ? safe_fname(shell_path) : "");
shell_cmd ? shell_cmd : "",
shell_machine ? shell_machine : "",
shell_user ? shell_user : "",
shell_path ? shell_path : "");
}
/* for remote source, only single dest arg can remain ... */
@@ -972,17 +1092,20 @@ static int start_client(int argc, char *argv[])
static RETSIGTYPE sigusr1_handler(UNUSED(int val))
{
exit_cleanup(RERR_SIGNAL);
exit_cleanup(RERR_SIGNAL1);
}
static RETSIGTYPE sigusr2_handler(UNUSED(int val))
{
if (!am_server)
output_summary();
close_all();
if (log_got_error) _exit(RERR_PARTIAL);
if (log_got_error)
_exit(RERR_PARTIAL);
_exit(0);
}
static RETSIGTYPE sigchld_handler(UNUSED(int val))
RETSIGTYPE remember_children(UNUSED(int val))
{
#ifdef WNOHANG
int cnt, status;
@@ -991,8 +1114,7 @@ static RETSIGTYPE sigchld_handler(UNUSED(int val))
* get him to explain why he put it in, so rather than taking it
* out we're instead saving the child exit statuses for later use.
* The waitpid() loop presumably eliminates all possibility of leaving
* zombie children, maybe that's why he did it.
*/
* zombie children, maybe that's why he did it. */
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
/* save the child's exit status */
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
@@ -1004,6 +1126,9 @@ static RETSIGTYPE sigchld_handler(UNUSED(int val))
}
}
#endif
#ifndef HAVE_SIGACTION
signal(SIGCHLD, remember_children);
#endif
}
@@ -1063,16 +1188,23 @@ int main(int argc,char *argv[])
int ret;
int orig_argc = argc;
char **orig_argv = argv;
#ifdef HAVE_SIGACTION
# ifdef HAVE_SIGPROCMASK
sigset_t sigmask;
signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler);
signal(SIGCHLD, sigchld_handler);
sigemptyset(&sigmask);
# endif
sigact.sa_flags = SA_NOCLDSTOP;
#endif
SIGACTMASK(SIGUSR1, sigusr1_handler);
SIGACTMASK(SIGUSR2, sigusr2_handler);
SIGACTMASK(SIGCHLD, remember_children);
#ifdef MAINTAINER_MODE
signal(SIGSEGV, rsync_panic_handler);
signal(SIGFPE, rsync_panic_handler);
signal(SIGABRT, rsync_panic_handler);
signal(SIGBUS, rsync_panic_handler);
#endif /* def MAINTAINER_MODE */
SIGACTMASK(SIGSEGV, rsync_panic_handler);
SIGACTMASK(SIGFPE, rsync_panic_handler);
SIGACTMASK(SIGABRT, rsync_panic_handler);
SIGACTMASK(SIGBUS, rsync_panic_handler);
#endif
starttime = time(NULL);
am_root = (MY_UID() == 0);
@@ -1086,7 +1218,11 @@ int main(int argc,char *argv[])
/* we set a 0 umask so that correct file permissions can be
* carried across */
orig_umask = (int)umask(0);
orig_umask = umask(0);
#if defined CONFIG_LOCALE && defined HAVE_SETLOCALE
setlocale(LC_CTYPE, "");
#endif
if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
/* FIXME: We ought to call the same error-handling
@@ -1095,13 +1231,19 @@ int main(int argc,char *argv[])
exit_cleanup(RERR_SYNTAX);
}
signal(SIGINT,SIGNAL_CAST sig_int);
signal(SIGHUP,SIGNAL_CAST sig_int);
signal(SIGTERM,SIGNAL_CAST sig_int);
SIGACTMASK(SIGINT, sig_int);
SIGACTMASK(SIGHUP, sig_int);
SIGACTMASK(SIGTERM, sig_int);
#if defined HAVE_SIGACTION && HAVE_SIGPROCMASK
sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
#endif
/* Ignore SIGPIPE; we consistently check error codes and will
* see the EPIPE. */
signal(SIGPIPE, SIG_IGN);
SIGACTION(SIGPIPE, SIG_IGN);
#ifdef SIGXFSZ
SIGACTION(SIGXFSZ, SIG_IGN);
#endif
/* Initialize push_dir here because on some old systems getcwd
* (implemented by forking "pwd" and reading its output) doesn't
@@ -1111,7 +1253,7 @@ int main(int argc,char *argv[])
init_flist();
if (write_batch || read_batch) {
if ((write_batch || read_batch) && !am_server) {
if (write_batch)
write_batch_shell_file(orig_argc, orig_argv, argc);
@@ -1130,6 +1272,8 @@ int main(int argc,char *argv[])
if (read_batch)
read_stream_flags(batch_fd);
}
if (write_batch < 0)
dry_run = 1;
if (am_daemon && !am_server)
return daemon_main();

132
match.c
View File

@@ -20,69 +20,47 @@
#include "rsync.h"
extern int verbose;
extern int am_server;
extern int do_progress;
extern int checksum_seed;
extern int append_mode;
int updating_basis_file;
typedef unsigned short tag;
#define TABLESIZE (1<<16)
#define NULL_TAG (-1)
static int false_alarms;
static int tag_hits;
static int hash_hits;
static int matches;
static int64 data_transfer;
static int total_false_alarms;
static int total_tag_hits;
static int total_hash_hits;
static int total_matches;
extern struct stats stats;
struct target {
tag t;
int32 i;
};
#define TABLESIZE (1<<16)
static struct target *targets;
static int32 *tag_table;
#define gettag2(s1,s2) (((s1) + (s2)) & 0xFFFF)
#define gettag(sum) gettag2((sum)&0xFFFF,(sum)>>16)
static int compare_targets(struct target *t1,struct target *t2)
{
return (int)t1->t - (int)t2->t;
}
static int32 *hash_table;
#define SUM2HASH2(s1,s2) (((s1) + (s2)) & 0xFFFF)
#define SUM2HASH(sum) SUM2HASH2((sum)&0xFFFF,(sum)>>16)
static void build_hash_table(struct sum_struct *s)
{
int32 i;
if (!tag_table)
tag_table = new_array(int32, TABLESIZE);
targets = new_array(struct target, s->count);
if (!tag_table || !targets)
out_of_memory("build_hash_table");
for (i = 0; i < s->count; i++) {
targets[i].i = i;
targets[i].t = gettag(s->sums[i].sum1);
if (!hash_table) {
hash_table = new_array(int32, TABLESIZE);
if (!hash_table)
out_of_memory("build_hash_table");
}
qsort(targets,s->count,sizeof(targets[0]),(int (*)())compare_targets);
memset(hash_table, 0xFF, TABLESIZE * sizeof hash_table[0]);
for (i = 0; i < TABLESIZE; i++)
tag_table[i] = NULL_TAG;
for (i = s->count; i-- > 0; )
tag_table[targets[i].t] = i;
for (i = 0; i < s->count; i++) {
uint32 t = SUM2HASH(s->sums[i].sum1);
s->sums[i].chain = hash_table[t];
hash_table[t] = i;
}
}
@@ -127,7 +105,6 @@ static void matched(int f, struct sum_struct *s, struct map_struct *buf,
sum_update(map_ptr(buf, last_match + j, n1), n1);
}
if (i >= 0)
last_match = offset + s->sums[i].len;
else
@@ -177,20 +154,22 @@ static void hash_search(int f,struct sum_struct *s,
}
do {
tag t = gettag2(s1,s2);
int done_csum2 = 0;
int32 j = tag_table[t];
int32 i;
if (verbose > 4)
rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
if (verbose > 4) {
rprintf(FINFO, "offset=%.0f sum=%04x%04x\n",
(double)offset, s2 & 0xFFFF, s1 & 0xFFFF);
}
if (j == NULL_TAG)
goto null_tag;
i = hash_table[SUM2HASH2(s1,s2)];
if (i < 0)
goto null_hash;
sum = (s1 & 0xffff) | (s2 << 16);
tag_hits++;
hash_hits++;
do {
int32 l, i = targets[j].i;
int32 l;
if (sum != s->sums[i].sum1)
continue;
@@ -206,9 +185,11 @@ static void hash_search(int f,struct sum_struct *s,
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET))
continue;
if (verbose > 3)
rprintf(FINFO,"potential match at %.0f target=%.0f %.0f sum=%08x\n",
(double)offset,(double)j,(double)i,sum);
if (verbose > 3) {
rprintf(FINFO,
"potential match at %.0f i=%ld sum=%08x\n",
(double)offset, (long)i, sum);
}
if (!done_csum2) {
map = (schar *)map_ptr(buf,offset,l);
@@ -225,8 +206,8 @@ static void hash_search(int f,struct sum_struct *s,
* one with an identical offset, so we prefer that over
* the following want_i optimization. */
if (updating_basis_file) {
do {
int32 i2 = targets[j].i;
int32 i2;
for (i2 = i; i2 >= 0; i2 = s->sums[i2].chain) {
if (s->sums[i2].offset != offset)
continue;
if (i2 != i) {
@@ -241,7 +222,7 @@ static void hash_search(int f,struct sum_struct *s,
* both the sender and the receiver. */
s->sums[i].flags |= SUMFLG_SAME_OFFSET;
goto set_want_i;
} while (++j < s->count && targets[j].t == t);
}
}
/* we've found a match, but now check to see
@@ -267,9 +248,9 @@ static void hash_search(int f,struct sum_struct *s,
s2 = sum >> 16;
matches++;
break;
} while (++j < s->count && targets[j].t == t);
} while ((i = s->sums[i].chain) >= 0);
null_tag:
null_hash:
backup = offset - last_match;
/* We sometimes read 1 byte prior to last_match... */
if (backup < 0)
@@ -324,12 +305,31 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
last_match = 0;
false_alarms = 0;
tag_hits = 0;
hash_hits = 0;
matches = 0;
data_transfer = 0;
sum_init(checksum_seed);
if (append_mode) {
OFF_T j = 0;
for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
if (buf && do_progress)
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
CHUNK_SIZE);
last_match = j;
}
if (last_match < s->flength) {
int32 len = s->flength - last_match;
if (buf && do_progress)
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, len), len);
last_match = s->flength;
}
s->count = 0;
}
if (len > 0 && s->count > 0) {
build_hash_table(s);
@@ -343,7 +343,7 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
} else {
OFF_T j;
/* by doing this in pieces we avoid too many seeks */
for (j = CHUNK_SIZE; j < len; j += CHUNK_SIZE)
for (j = last_match + CHUNK_SIZE; j < len; j += CHUNK_SIZE)
matched(f, s, buf, j, -2);
matched(f, s, buf, len, -1);
}
@@ -357,16 +357,11 @@ void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
rprintf(FINFO,"sending file_sum\n");
write_buf(f,file_sum,MD4_SUM_LENGTH);
if (targets) {
free(targets);
targets=NULL;
}
if (verbose > 2)
rprintf(FINFO, "false_alarms=%d tag_hits=%d matches=%d\n",
false_alarms, tag_hits, matches);
rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
false_alarms, hash_hits, matches);
total_tag_hits += tag_hits;
total_hash_hits += hash_hits;
total_false_alarms += false_alarms;
total_matches += matches;
stats.literal_data += data_transfer;
@@ -378,8 +373,7 @@ void match_report(void)
return;
rprintf(FINFO,
"total: matches=%d tag_hits=%d false_alarms=%d data=%.0f\n",
total_matches,total_tag_hits,
total_false_alarms,
"total: matches=%d hash_hits=%d false_alarms=%d data=%.0f\n",
total_matches, total_hash_hits, total_false_alarms,
(double)stats.literal_data);
}

View File

@@ -58,7 +58,7 @@ BEGIN {
next;
}
!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const/ {
!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^uchar|^short|^struct|^BOOL|^void|^time|^const|^RETSIGTYPE/ {
next;
}

686
options.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
Summary: A program for synchronizing files over a network.
Name: rsync
Version: 2.6.4pre4
Version: 2.6.7
Release: 1
Group: Applications/Internet
Source: ftp://rsync.samba.org/pub/rsync/rsync-%{version}.tar.gz

116
packaging/nightly-rsync Executable file
View File

@@ -0,0 +1,116 @@
#!/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
# pristine CVS checkout of rsync (don't use your normal rsync build dir
# unless you're 100% sure that there are not unchecked-in 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;
# Choose any dir where a pristine rsync has been checked out of CVS.
our $unpacked = $ENV{HOME} . '/release/nightly';
# Where the local copy of /home/ftp/pub/rsync/nightly should be updated.
our $nightly = $ENV{HOME} . '/samba-rsync-ftp/nightly';
our($cvs_update, $make_tar, $upload, $help_opt);
&Getopt::Long::Configure('bundling');
&usage if !&GetOptions(
'cvs-update|c' => \$cvs_update,
'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;
chdir($unpacked) or die $!;
if ($cvs_update) {
print "Updating from cvs...\n";
system 'cvs -q up' and die $!;
}
if ($make_tar) {
print "Generating list of active CVS files...\n";
my($dir, @files);
open(CVS, '-|', 'cvs status 2>&1') or die $!;
while (<CVS>) {
if (/^cvs status: Examining (.*)/) {
if ($1 eq '.') {
$dir = '';
} else {
push(@files, $1);
$dir = $1 . '/';
}
} elsif (/^File: (.*?)\s+Status: (.*)/ && $1 ne '.cvsignore') {
push(@files, $dir . $1);
if ($2 ne 'Up-to-date') {
print "*** Not up-to-date: $dir$1\n";
}
}
}
close CVS;
print "Creating $unpacked/$name.tar.gz\n";
chdir('..') or die $!;
rename($unpacked, $name) or die $!;
open(TAR, '|-', "fakeroot tar --files-from=- --no-recursion --mode=g-w -czf $nightly/$name.tar.gz $name") or die $!;
foreach (@files) {
print TAR "$name/$_\n";
}
close TAR;
rename($name, $unpacked) or die $!;
}
chdir($nightly) or die $!;
foreach my $fn (qw( rsync.yo rsyncd.conf.yo )) {
my $html_fn = $fn;
$html_fn =~ s/\.yo/.html/;
open(IN, '<', "$unpacked/$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, '>', $fn) or die $!;
print OUT $_;
close OUT;
system "yodl2html -o $html_fn $fn";
unlink($fn);
}
system "find . -name 'rsync-HEAD-*' -daystart -mtime +14 | xargs rm -f";
system 'ls -ltr';
if ($upload) {
$ENV{RSYNC_PARTIAL_DIR} = ''; # The rsync on samba.org is OLD.
system "rsync -aviHP --delete . samba.org:/home/ftp/pub/rsync/nightly";
}
exit;
sub usage
{
die <<EOT;
Usage: nightly-rsync [OPTIONS]
-c, --cvs-update update $unpacked via CVS.
-t, --make-tar create a new tar file in $nightly
-u, --upload upload the revised nightly dir to samba.org
-h, --help display this help
EOT
}

317
packaging/release-rsync Executable file
View File

@@ -0,0 +1,317 @@
#!/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. If it is run
# in test mode, it instead expects a dir named ~/tmp/samba-rsync-ftp
# (e.g. copy ~/samba-rsync-ftp into ~/tmp and you can do a trial-run of
# a release without affecting the files in the ~/samba-rsync-ftp dir).
#
# Run this as "release-rsync live" to affect ~/samba-rsync-ftp instead
# of ~/tmp/samba-rsync-ftp.
use Date::Format;
my $dest = $ENV{HOME} . '/samba-rsync-ftp';
my $releasedir = $ENV{HOME} . '/release';
my $cvsroot = $ENV{CVSROOT} = 'samba.org:/data/cvs';
my $ztoday = time2str('%d %b %Y', time);
my $today = $ztoday;
$today =~ s/^0//;
my $break = <<EOT;
==========================================================================
EOT
my $note = <<EOT;
== Note: type "-a u,n" if you want to auto-accept the U,N suggestions. ==
EOT
my $live = shift;
my $skipping = '';
print $break;
if ($live) {
print <<EOT;
== This will release a new version of rsync onto an unsuspecting world. ==
EOT
} else {
print <<EOT;
== **** TESTMODE **** (Add "live" arg to avoid this.) ==
EOT
$dest =~ s#([^/]+$)#tmp/$1#;
$skipping = ' ** SKIPPING **';
}
die "$dest does not exist\n" unless -d $dest;
print $break, "\nChecking out the latest rsync into $releasedir ...\n";
mkdir($releasedir, 0755) or die $! unless -d $releasedir;
chdir($releasedir) or die $!;
system 'rm -rf rsync';
my(%dirs, @files);
open(CVS, '-|', 'cvs checkout -P rsync') or die $!;
while (<CVS>) {
print $_;
next if /\.(cvs)?ignore$/;
if (m#^[UP] rsync/(.*)#) {
my $fn = $1;
my($dir) = $fn =~ m#^(.+)/#;
push(@files, $dir) if defined($dir) && !$dirs{$1}++;
push(@files, $fn);
}
}
chdir('rsync') or die $!;
my($version, $lastversion);
open(IN, 'configure.in') or die $!;
while (<IN>) {
if (/^RSYNC_VERSION=(.*)/) {
$version = $lastversion = $1;
last;
}
}
close IN;
$lastversion =~ s/(\d+)cvs$/ $1 - 1 /e;
$version =~ s/cvs/pre1/ || $version =~ s/pre(\d+)/ 'pre' . ($1 + 1) /e;
print $break, "\nPlease enter the version number of this release: [$version] ";
chomp($_ = <STDIN>);
if ($_ eq '.') {
$version =~ s/pre\d+//;
} elsif ($_ ne '') {
$version = $_;
}
$version =~ s/[-.]*pre[-.]*/pre/;
$lastversion =~ s/(\d+)pre\d+$/ $1 - 1 /e unless $version =~ /pre/;
my $cvstag = "release-$version";
$cvstag =~ s/[.]/-/g;
$cvstag =~ s/pre/-pre/;
print "Enter the previous version to produce a patch against: [$lastversion] ";
chomp($_ = <STDIN>);
$lastversion = $_ if $_ ne '';
$lastversion =~ s/[-.]*pre[-.]*/pre/;
my $release = 1;
print "Please enter the RPM release number of this release: [$release] ";
chomp($_ = <STDIN>);
$release = $_ if $_ ne '';
my $diffdir;
my $skipping2;
if ($lastversion =~ /pre/) {
if ($version !~ /pre/) {
die "You should not diff a release version against a pre-release version.\n";
}
$diffdir = "$dest/old-previews";
$skipping2 = ' ** SKIPPING **';
} elsif ($version =~ /pre/) {
$diffdir = $dest;
$skipping2 = ' ** SKIPPING **';
} else {
$diffdir = "$dest/old-versions";
$skipping2 = '';
}
print "\n", $break, <<EOT;
\$version is "$version"
\$lastversion is "$lastversion"
\$cvstag is "$cvstag"
\$dest is "$dest"
\$releasedir is "$releasedir"
\$diffdir is "$diffdir"
\$release is "$release"
About to:
- make sure that configure, config.h.in, and proto.h are updated
- tweak the version in configure.in, configure, and the spec files
- tweak NEWS and OLDNEWS to update the release date$skipping2
- tweak the date in the *.yo files and re-generate the man pages
- make sure that the patches dir has been updated
- page through the "cvs diff" output
EOT
print "<Press Enter to continue> ";
$_ = <STDIN>;
my $f_opt = /f/ ? ' -f' : '';
print $break;
system "./prepare-source && touch proto.h";
my @tweak_files = ( glob('packaging/*.spec'), glob('packaging/*/*.spec'),
glob('*.yo'), qw( configure.in configure ) );
if ($version !~ /pre/) {
push(@tweak_files, qw( NEWS OLDNEWS ));
}
foreach my $fn (@tweak_files) {
open(IN, '<', $fn) or die $!;
undef $/; $_ = <IN>; $/ = "\n";
close IN;
if ($fn =~ /configure/) {
s/^RSYNC_VERSION.*/RSYNC_VERSION=$version/m;
} elsif ($fn =~ /\.spec/) {
s/^(Version:) .*/$1 $version/m;
s/^(Release:) .*/$1 $release/m;
} elsif ($fn =~ /\.yo/) {
s/^(manpage\([^)]+\)\(\d+\)\()[^)]+(\).*)/$1$today$2/m;
s/^(This man ?page is current for version) \S+ (of rsync)/$1 $version $2/m;
} else {
s/^(NEWS for rsync \Q$version\E) \(UNRELEASED\)\s*$/$1 ($today)\n/m;
s/^\t\S\S\s\S\S\S\s\d\d\d\d(\t\Q$version\E)/\t$ztoday$1/m;
}
open(OUT, '>', $fn) or die $!;
print OUT $_;
close OUT;
}
system "yodl2man -o rsync.1 rsync.yo";
system "yodl2man -o rsyncd.conf.5 rsyncd.conf.yo";
#system "perl -pi -e \"s/\\\\\\'/\\\\&'/g\" rsync.1 rsyncd.conf.5";
mkdir('patches/tmp') or die $!;
system "rsync -a --exclude=patches/ --exclude-from=.cvsignore . patches/tmp/cvsdir/";
print "\n", $break, $note, $break;
system "patches/verify-patches -n -an$f_opt";
print $break;
system "cvs -q diff | egrep -v '^(===============|RCS file: |retrieving revision |Index: )' | less -p '^diff .*'";
print $break, <<EOT;
About to:
- "cvs commit" all changes$skipping
- "cvs tag" this release as $cvstag$skipping
- change the diffs in the patches dir to include generated files
EOT
print "<Press Enter to continue> ";
$_ = <STDIN>;
if ($live) {
system "cvs commit -m 'Preparing for release of $version'";
system "cvs tag -F $cvstag .";
}
if (!/skip/i) {
print "\n", $break, $note, $break;
system "patches/verify-patches -pun -an";
}
my $tar_file = "$dest/rsync-$version.tar.gz";
my $diff_file = "$dest/rsync-$lastversion-$version.diffs.gz";
print $break, <<EOT;
About to do the following in the samba-rsync-ftp dir:
- move the old tar/diff files into the appropriate old-* dirs
- hard-link moved tar/diff files to old files on samba.org$skipping
- create release tar, "$tar_file"
- create release diffs, "$diff_file"
- update README, *NEWS, TODO, and cvs.log
- update rsync*.html man pages
EOT
print "<Press Enter to continue> ";
$_ = <STDIN>;
chdir($releasedir) or die $!;
print $break;
system "rm -rf rsync-$version";
rename('rsync', "rsync-$version") or die $!;
# When creating a pre-release after a normal release, there's nothing to move.
if ($diffdir ne $dest) {
chdir($dest) or die $!;
print "Shuffling old files ...\n";
# We need to run this regardless of $lastversion's "pre"ness.
my @moved_files;
foreach my $fn (glob('rsync*pre*.tar.gz*'), glob('rsync*pre*-NEWS')) {
my $new_fn = "old-previews/$fn";
rename($fn, $new_fn) or die $!;
push(@moved_files, $new_fn);
}
if ($version !~ /pre/) {
foreach my $fn (glob('rsync*.tar.gz*'), glob('rsync*-NEWS')) {
next if $fn =~ /^rsync.*pre/;
my $new_fn = "old-versions/$fn";
rename($fn, $new_fn) or die $!;
push(@moved_files, $new_fn);
}
foreach my $fn (glob('rsync*.diffs.gz*')) {
next if $fn =~ /^rsync.*pre/;
my $new_fn = "old-patches/$fn";
rename($fn, $new_fn) or die $!;
push(@moved_files, $new_fn);
}
}
# Optimize our future upload (in the absence of --detect-renamed) by
# hard-linking the above moved files on the remote server.
if ($live) {
my $remote_cmd = '';
foreach (@moved_files) {
my($path, $fn) = m#(.*)/([^/]+)$#;
$remote_cmd .= "ln -f /home/ftp/pub/rsync/{$fn,$path};";
}
system "ssh samba.org '$remote_cmd'";
}
foreach (glob("rsync*pre*.diffs.gz*")) {
unlink($_);
}
chdir($releasedir) or die $!;
}
print "Creating $tar_file ...\n";
system "fakeroot tar czf $tar_file rsync-$version";
open(TAR, '|-', "fakeroot tar --files-from=- --no-recursion --mode=g+w -czf $tar_file rsync-$version") or die $!;
foreach (@files) {
print TAR "rsync-$version/$_\n";
}
close TAR;
print "Creating $diff_file ...\n";
system "rm -rf rsync-$version rsync-$lastversion";
system "tar xzf $tar_file; tar xzf $diffdir/rsync-$lastversion.tar.gz";
## TWEAK THE VERSIONS AS DESIRED HERE ##
#mkdir("rsync-$lastversion/support", 0755) or die $!;
#rename("rsync-$lastversion/rsyncstats", "rsync-$lastversion/support/rsyncstats");
unlink("rsync-$lastversion/.ignore");
## END ##
system "diff -urN --exclude=patches rsync-$lastversion rsync-$version| gzip -9 >$diff_file";
print "Updating the other files in $dest ...\n";
system "rsync -a rsync-$version/{README,NEWS,OLDNEWS,TODO} $dest";
unlink("$dest/rsync-$version-NEWS");
link("$dest/NEWS", "$dest/rsync-$version-NEWS");
system "rsync -a $cvsroot/CVSROOT/rsync.updates $dest/cvs.log";
system "yodl2html -o $dest/rsync.html rsync-$version/rsync.yo";
system "yodl2html -o $dest/rsyncd.conf.html rsync-$version/rsyncd.conf.yo";
system "rm -rf rsync-*";
if ($live) {
chdir($dest) or die $!;
system "gpg -ba rsync-$version.tar.gz";
system "gpg -ba rsync-$lastversion-$version.diffs.gz";
}
print $break, <<EOT;
All done. Remember to announce the release on *BOTH*
rsync-announce\@lists.samba.org and rsync\@lists.samba.org!
EOT

View File

@@ -492,7 +492,7 @@ static FILE *OpenConfFile( char *FileName )
if( NULL == OpenedFile )
{
rsyserr(FERROR, errno, "rsync: unable to open configuration file \"%s\"",
safe_fname(FileName));
FileName);
}
return( OpenedFile );

26
pipe.c
View File

@@ -24,12 +24,12 @@
extern int am_sender;
extern int am_server;
extern int blocking_io;
extern int orig_umask;
extern int write_batch;
extern int filesfrom_fd;
extern mode_t orig_umask;
extern struct chmod_mode_struct *chmod_modes;
/**
* Create a child connected to use on stdin/stdout.
* Create a child connected to us via its stdin/stdout.
*
* This is derived from CVS code
*
@@ -79,8 +79,7 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
if (blocking_io > 0)
set_blocking(STDOUT_FILENO);
execvp(command[0], command);
rsyserr(FERROR, errno, "Failed to exec %s",
safe_fname(command[0]));
rsyserr(FERROR, errno, "Failed to exec %s", command[0]);
exit_cleanup(RERR_IPC);
}
@@ -112,6 +111,9 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
int to_child_pipe[2];
int from_child_pipe[2];
/* The parent process is always the sender for a local rsync. */
assert(am_sender);
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rsyserr(FERROR, errno, "pipe");
@@ -125,15 +127,10 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
}
if (pid == 0) {
am_sender = !am_sender;
am_sender = 0;
am_server = 1;
/* The server side never writes the batch, even if it
* is local (it makes the logic easier elsewhere). */
write_batch = 0;
if (!am_sender)
filesfrom_fd = -1;
filesfrom_fd = -1;
chmod_modes = NULL; /* Let the sending side handle this. */
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
@@ -149,9 +146,6 @@ pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
child_main(argc, argv);
}
if (!am_sender)
filesfrom_fd = -1;
if (close(from_child_pipe[1]) < 0 ||
close(to_child_pipe[0]) < 0) {
rsyserr(FERROR, errno, "Failed to close");

13
prepare-source Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/sh
# Use autoconf, autoheader, yodl, etc. to ready the generated files
# in the release. This is typically used after applying a diff from
# "patches" directory in CVS.
#
# NOTE: if you use a diff from the "patches" directory in a release
# tar, this is not needed (but doesn't hurt anything).
dir=`dirname $0`
if test x"$dir" = x -o x"$dir" = x.; then
make -f prepare-source.mak
else
make -C "$dir" -f prepare-source.mak
fi

23
prepare-source.mak Normal file
View File

@@ -0,0 +1,23 @@
gen: configure config.h.in proto.h man
configure: configure.in aclocal.m4
autoconf
config.h.in: configure.in aclocal.m4
autoheader && touch config.h.in
proto.h: *.c lib/compat.c
cat *.c lib/compat.c | awk -f mkproto.awk >proto.h.new
if diff proto.h proto.h.new >/dev/null; then \
rm proto.h.new; \
else \
mv proto.h.new proto.h; \
fi
man: rsync.1 rsyncd.conf.5
rsync.1: rsync.yo
yodl2man -o rsync.1 rsync.yo
rsyncd.conf.5: rsyncd.conf.yo
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo

View File

@@ -97,15 +97,14 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
remain_h = (int) (remain / 3600.0);
if (is_last) {
snprintf(eol, sizeof eol, " (%d, %.1f%% of %d)\n",
snprintf(eol, sizeof eol, " (xfer#%d, to-check=%d/%d)\n",
stats.num_transferred_files,
(float)((stats.current_file_index+1) * 100)
/ stats.num_files,
stats.num_files - stats.current_file_index - 1,
stats.num_files);
} else
strcpy(eol, "\r");
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s",
(double) ofs, pct, rate, units,
rprintf(FINFO, "%12s %3d%% %7.2f%s %4d:%02d:%02d%s",
human_num(ofs), pct, rate, units,
remain_h, remain_m, remain_s, eol);
}

View File

@@ -21,7 +21,7 @@
#include "rsync.h"
extern int verbose;
extern int dry_run;
extern int do_xfers;
extern int am_daemon;
extern int am_server;
extern int do_progress;
@@ -30,20 +30,18 @@ extern int log_format_has_i;
extern int daemon_log_format_has_i;
extern int csum_length;
extern int read_batch;
extern int write_batch;
extern int batch_gen_fd;
extern int protocol_version;
extern int relative_paths;
extern int keep_dirlinks;
extern int preserve_hard_links;
extern int preserve_perms;
extern int io_error;
extern int basis_dir_cnt;
extern int make_backups;
extern int cleanup_got_literal;
extern int remove_sent_files;
extern int module_id;
extern int ignore_errors;
extern int orig_umask;
extern int append_mode;
extern int sparse_files;
extern int keep_partial;
extern int checksum_seed;
extern int inplace;
@@ -53,71 +51,11 @@ extern char *log_format;
extern char *tmpdir;
extern char *partial_dir;
extern char *basis_dir[];
extern struct file_list *the_file_list;
extern struct filter_list_struct server_filter_list;
#define SLOT_SIZE (16*1024) /* Desired size in bytes */
#define PER_SLOT_BITS (SLOT_SIZE * 8) /* Number of bits per slot */
#define PER_SLOT_INTS (SLOT_SIZE / 4) /* Number of int32s per slot */
static uint32 **delayed_bits = NULL;
static int delayed_slot_cnt = 0;
static void init_delayed_bits(int max_ndx)
{
delayed_slot_cnt = (max_ndx + PER_SLOT_BITS - 1) / PER_SLOT_BITS;
if (!(delayed_bits = (uint32**)calloc(delayed_slot_cnt, sizeof (uint32*))))
out_of_memory("set_delayed_bit");
}
static void set_delayed_bit(int ndx)
{
int slot = ndx / PER_SLOT_BITS;
ndx %= PER_SLOT_BITS;
if (!delayed_bits[slot]) {
if (!(delayed_bits[slot] = (uint32*)calloc(PER_SLOT_INTS, 4)))
out_of_memory("set_delayed_bit");
}
delayed_bits[slot][ndx/32] |= 1u << (ndx % 32);
}
/* Call this with -1 to start checking from 0. Returns -1 at the end. */
static int next_delayed_bit(int after)
{
uint32 bits, mask;
int i, ndx = after + 1;
int slot = ndx / PER_SLOT_BITS;
ndx %= PER_SLOT_BITS;
mask = (1u << (ndx % 32)) - 1;
for (i = ndx / 32; slot < delayed_slot_cnt; slot++, i = mask = 0) {
if (!delayed_bits[slot])
continue;
for ( ; i < PER_SLOT_INTS; i++, mask = 0) {
if (!(bits = delayed_bits[slot][i] & ~mask))
continue;
/* The xor magic figures out the lowest enabled bit in
* bits, and the switch quickly computes log2(bit). */
switch (bits ^ (bits & (bits-1))) {
#define LOG2(n) case 1u << n: return slot*PER_SLOT_BITS + i*32 + n
LOG2(0); LOG2(1); LOG2(2); LOG2(3);
LOG2(4); LOG2(5); LOG2(6); LOG2(7);
LOG2(8); LOG2(9); LOG2(10); LOG2(11);
LOG2(12); LOG2(13); LOG2(14); LOG2(15);
LOG2(16); LOG2(17); LOG2(18); LOG2(19);
LOG2(20); LOG2(21); LOG2(22); LOG2(23);
LOG2(24); LOG2(25); LOG2(26); LOG2(27);
LOG2(28); LOG2(29); LOG2(30); LOG2(31);
}
return -1; /* impossible... */
}
}
return -1;
}
static struct bitbag *delayed_bits = NULL;
static int phase = 0;
/*
@@ -169,8 +107,7 @@ static int get_tmpname(char *fnametmp, char *fname)
maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8);
if (maxname < 1) {
rprintf(FERROR, "temporary filename too long: %s\n",
safe_fname(fname));
rprintf(FERROR, "temporary filename too long: %s\n", fname);
fnametmp[0] = '\0';
return 0;
}
@@ -203,13 +140,39 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
mapbuf = map_file(fd_r, size_r, read_size, sum.blength);
if (verbose > 2) {
rprintf(FINFO, "recv mapped %s of size %.0f\n",
safe_fname(fname_r), (double)size_r);
fname_r, (double)size_r);
}
} else
mapbuf = NULL;
sum_init(checksum_seed);
if (append_mode) {
OFF_T j;
sum.flength = (OFF_T)sum.count * sum.blength;
if (sum.remainder)
sum.flength -= sum.blength - sum.remainder;
for (j = CHUNK_SIZE; j < sum.flength; j += CHUNK_SIZE) {
if (do_progress)
show_progress(offset, total_size);
sum_update(map_ptr(mapbuf, offset, CHUNK_SIZE),
CHUNK_SIZE);
offset = j;
}
if (offset < sum.flength) {
int32 len = sum.flength - offset;
if (do_progress)
show_progress(offset, total_size);
sum_update(map_ptr(mapbuf, offset, len), len);
offset = sum.flength;
}
if (fd != -1 && do_lseek(fd, offset, SEEK_SET) != offset) {
rsyserr(FERROR, errno, "lseek failed on %s",
full_fname(fname));
exit_cleanup(RERR_FILEIO);
}
}
while ((i = recv_token(f_in, &data)) != 0) {
if (do_progress)
show_progress(offset, total_size);
@@ -266,7 +229,7 @@ static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
continue;
}
}
if (fd != -1 && write_file(fd, map, len) != (int)len)
if (fd != -1 && map && write_file(fd, map, len) != (int)len)
goto report_write_error;
offset += len;
}
@@ -313,22 +276,22 @@ static void handle_delayed_updates(struct file_list *flist, char *local_name)
char *fname, *partialptr, numbuf[4];
int i;
for (i = -1; (i = next_delayed_bit(i)) >= 0; ) {
for (i = -1; (i = bitbag_next_bit(delayed_bits, i)) >= 0; ) {
struct file_struct *file = flist->files[i];
fname = local_name ? local_name : f_name(file);
fname = local_name ? local_name : f_name(file, NULL);
if ((partialptr = partial_dir_fname(fname)) != NULL) {
if (make_backups && !make_backup(fname))
continue;
if (verbose > 2) {
rprintf(FINFO, "renaming %s to %s\n",
safe_fname(partialptr),
safe_fname(fname));
partialptr, fname);
}
/* We don't use robust_rename() here because the
* partial-dir must be on the same drive. */
if (do_rename(partialptr, fname) < 0) {
rsyserr(FERROR, errno,
"rename failed for %s (from %s)",
full_fname(fname),
safe_fname(partialptr));
full_fname(fname), partialptr);
} else {
if (remove_sent_files
|| (preserve_hard_links
@@ -336,13 +299,28 @@ static void handle_delayed_updates(struct file_list *flist, char *local_name)
SIVAL(numbuf, 0, i);
send_msg(MSG_SUCCESS,numbuf,4);
}
handle_partial_dir(partialptr,
PDIR_DELETE);
handle_partial_dir(partialptr, PDIR_DELETE);
}
}
}
}
static int get_next_gen_i(int batch_gen_fd, int next_gen_i, int desired_i)
{
while (next_gen_i < desired_i) {
if (next_gen_i >= 0) {
rprintf(FINFO,
"(No batched update for%s \"%s\")\n",
phase ? " resend of" : "",
f_name(the_file_list->files[next_gen_i], NULL));
}
next_gen_i = read_int(batch_gen_fd);
if (next_gen_i == -1)
next_gen_i = the_file_list->count;
}
return next_gen_i;
}
/**
* main routine for receiver process.
@@ -365,7 +343,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
int save_make_backups = make_backups;
int itemizing = am_daemon ? daemon_log_format_has_i
: !am_server && log_format_has_i;
int phase = 0, max_phase = protocol_version >= 29 ? 2 : 1;
int max_phase = protocol_version >= 29 ? 2 : 1;
int i, recv_ok;
if (verbose > 2)
@@ -377,7 +355,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
}
if (delay_updates)
init_delayed_bits(flist->count);
delayed_bits = bitbag_create(flist->count);
while (1) {
cleanup_disable();
@@ -385,8 +363,8 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
i = read_int(f_in);
if (i == -1) {
if (read_batch) {
if (next_gen_i != flist->count)
while (read_int(batch_gen_fd) != -1) {}
get_next_gen_i(batch_gen_fd, next_gen_i,
flist->count);
next_gen_i = -1;
}
if (++phase > max_phase)
@@ -399,6 +377,10 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
send_msg(MSG_DONE, "", 0);
if (keep_partial && !partial_dir)
make_backups = 0; /* prevents double backup */
if (append_mode) {
append_mode = 0;
sparse_files = 0;
}
continue;
}
@@ -408,10 +390,10 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
continue;
file = flist->files[i];
fname = local_name ? local_name : f_name_to(file, fbuf);
fname = local_name ? local_name : f_name(file, fbuf);
if (verbose > 2)
rprintf(FINFO, "recv_files(%s)\n", safe_fname(fname));
rprintf(FINFO, "recv_files(%s)\n", fname);
if (!(iflags & ITEM_TRANSFER)) {
maybe_log_item(file, iflags, itemizing, xname);
@@ -435,23 +417,26 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
exit_cleanup(RERR_PROTOCOL);
}
if (dry_run) { /* log the transfer */
if (!do_xfers) { /* log the transfer */
if (!am_server && log_format)
log_item(file, &stats, iflags, NULL);
if (read_batch)
discard_receive_data(f_in, file->length);
continue;
}
if (write_batch < 0) {
log_item(file, &stats, iflags, NULL);
if (!am_server)
discard_receive_data(f_in, file->length);
continue;
}
if (read_batch) {
while (i > next_gen_i) {
next_gen_i = read_int(batch_gen_fd);
if (next_gen_i == -1)
next_gen_i = flist->count;
}
next_gen_i = get_next_gen_i(batch_gen_fd, next_gen_i, i);
if (i < next_gen_i) {
rprintf(FINFO, "skipping update for \"%s\"\n",
safe_fname(fname));
rprintf(FINFO,
"(Skipping batched update for \"%s\")\n",
fname);
discard_receive_data(f_in, file->length);
continue;
}
@@ -552,16 +537,16 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
fd1 = -1;
}
if (fd1 != -1 && !preserve_perms) {
/* if the file exists already and we aren't preserving
* permissions then act as though the remote end sent
* us the file permissions we already have */
file->mode = st.st_mode;
/* If we're not preserving permissions, change the file-list's
* mode based on the local permissions and some heuristics. */
if (!preserve_perms) {
int exists = fd1 != -1;
file->mode = dest_mode(file->mode, st.st_mode, exists);
}
/* We now check to see if we are writing file "inplace" */
if (inplace) {
fd2 = do_open(fname, O_WRONLY|O_CREAT, 0);
fd2 = do_open(fname, O_WRONLY|O_CREAT, 0600);
if (fd2 == -1) {
rsyserr(FERROR, errno, "open %s failed",
full_fname(fname));
@@ -590,7 +575,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
* because their information should have been previously
* transferred, but that may not be the case with -R */
if (fd2 == -1 && relative_paths && errno == ENOENT
&& create_directory_path(fnametmp, orig_umask) == 0) {
&& create_directory_path(fnametmp) == 0) {
/* Get back to name with XXXXXX in it. */
get_tmpname(fnametmp, fname);
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
@@ -604,7 +589,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
continue;
}
if (partialptr)
if (keep_partial)
cleanup_set(fnametmp, partialptr, file, fd1, fd2);
}
@@ -612,7 +597,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
if (log_before_transfer)
log_item(file, &initial_stats, iflags, NULL);
else if (!am_server && verbose && do_progress)
rprintf(FINFO, "%s\n", safe_fname(fname));
rprintf(FINFO, "%s\n", fname);
/* recv file data */
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
@@ -630,17 +615,20 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
}
if ((recv_ok && (!delay_updates || !partialptr)) || inplace) {
finish_transfer(fname, fnametmp, file, recv_ok, 1);
if (partialptr != fname && fnamecmp == partialptr) {
if (partialptr == fname || *partial_dir == '/')
partialptr = NULL;
finish_transfer(fname, fnametmp, partialptr,
file, recv_ok, 1);
if (fnamecmp == partialptr) {
do_unlink(partialptr);
handle_partial_dir(partialptr, PDIR_DELETE);
}
} else if (keep_partial && partialptr
&& handle_partial_dir(partialptr, PDIR_CREATE)) {
finish_transfer(partialptr, fnametmp, file, recv_ok,
!partial_dir);
finish_transfer(partialptr, fnametmp, NULL,
file, recv_ok, !partial_dir);
if (delay_updates && recv_ok) {
set_delayed_bit(i);
bitbag_set_bit(delayed_bits, i);
recv_ok = -1;
}
} else {
@@ -675,8 +663,7 @@ int recv_files(int f_in, struct file_list *flist, char *local_name)
}
rprintf(msgtype,
"%s: %s failed verification -- update %s%s.\n",
errstr, safe_fname(fname),
keptstr, redostr);
errstr, fname, keptstr, redostr);
}
if (!phase) {
SIVAL(numbuf, 0, i);

177
rsync.c
View File

@@ -21,10 +21,20 @@
process */
#include "rsync.h"
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
#include <iconv.h>
#endif
#if defined HAVE_LIBCHARSET_H && defined HAVE_LOCALE_CHARSET
#include <libcharset.h>
#elif defined HAVE_LANGINFO_H && defined HAVE_NL_LANGINFO
#include <langinfo.h>
#endif
extern int verbose;
extern int dry_run;
extern int daemon_log_format_has_i;
extern int preserve_perms;
extern int preserve_executability;
extern int preserve_times;
extern int omit_dir_times;
extern int am_root;
@@ -32,13 +42,53 @@ extern int am_server;
extern int am_sender;
extern int am_generator;
extern int am_starting_up;
extern int allow_8bit_chars;
extern int preserve_uid;
extern int preserve_gid;
extern int inplace;
extern int keep_dirlinks;
extern int make_backups;
extern mode_t orig_umask;
extern struct stats stats;
extern struct chmod_mode_struct *daemon_chmod_modes;
#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H
iconv_t ic_chck = (iconv_t)-1;
static const char *default_charset(void)
{
#if defined HAVE_LIBCHARSET_H && defined HAVE_LOCALE_CHARSET
return locale_charset();
#elif defined HAVE_LANGINFO_H && defined HAVE_NL_LANGINFO
return nl_langinfo(CODESET);
#else
return ""; /* Works with (at the very least) gnu iconv... */
#endif
}
void setup_iconv()
{
if (!am_server && !allow_8bit_chars) {
const char *defset = default_charset();
/* It's OK if this fails... */
ic_chck = iconv_open(defset, defset);
if (verbose > 3) {
if (ic_chck == (iconv_t)-1) {
rprintf(FINFO,
"note: iconv_open(\"%s\", \"%s\") failed (%d)"
" -- using isprint() instead of iconv().\n",
defset, defset, errno);
} else {
rprintf(FINFO,
"note: iconv_open(\"%s\", \"%s\") succeeded.\n",
defset, defset);
}
}
}
}
#endif
/*
free a sums struct
@@ -49,9 +99,31 @@ void free_sums(struct sum_struct *s)
free(s);
}
/* This is only called when we aren't preserving permissions. Figure out what
* the permissions should be and return them merged back into the mode. */
mode_t dest_mode(mode_t flist_mode, mode_t cur_mode, int exists)
{
/* If the file already exists, we'll return the local permissions,
* possibly tweaked by the --executability option. */
if (exists) {
if (preserve_executability && S_ISREG(flist_mode)) {
/* If the source file is executable, grant execute
* rights to everyone who can read, but ONLY if the
* file isn't already executable. */
if (!(flist_mode & 0111))
cur_mode &= ~0111;
else if (!(cur_mode & 0111))
cur_mode |= (cur_mode & 0444) >> 2;
}
} else
cur_mode = flist_mode & ACCESSPERMS & ~orig_umask;
if (daemon_chmod_modes && !S_ISLNK(flist_mode))
cur_mode = tweak_mode(cur_mode, daemon_chmod_modes);
return (flist_mode & ~CHMOD_BITS) | (cur_mode & CHMOD_BITS);
}
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
int flags)
int set_file_attrs(char *fname, struct file_struct *file, STRUCT_STAT *st,
int flags)
{
int updated = 0;
STRUCT_STAT st2;
@@ -66,19 +138,26 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
return 0;
}
st = &st2;
if (!preserve_perms && S_ISDIR(file->mode)
&& st->st_mode & S_ISGID) {
/* We just created this directory and its setgid
* bit is on, so make sure it stays on. */
file->mode |= S_ISGID;
}
}
if (!preserve_times || S_ISLNK(st->st_mode)
|| (S_ISDIR(st->st_mode) && omit_dir_times))
flags |= PERMS_SKIP_MTIME;
if (!(flags & PERMS_SKIP_MTIME)
&& cmp_modtime(st->st_mtime, file->modtime) != 0) {
if (set_modtime(fname,file->modtime) != 0) {
if (!preserve_times || (S_ISDIR(st->st_mode) && omit_dir_times))
flags |= ATTRS_SKIP_MTIME;
if (!(flags & ATTRS_SKIP_MTIME)
&& cmp_time(st->st_mtime, file->modtime) != 0) {
int ret = set_modtime(fname, file->modtime, st->st_mode);
if (ret < 0) {
rsyserr(FERROR, errno, "failed to set times on %s",
full_fname(fname));
return 0;
}
updated = 1;
if (ret == 0) /* ret == 1 if symlink could not be set */
updated = 1;
}
change_uid = am_root && preserve_uid && st->st_uid != file->uid;
@@ -94,13 +173,13 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
if (change_uid) {
rprintf(FINFO,
"set uid of %s from %ld to %ld\n",
safe_fname(fname),
fname,
(long)st->st_uid, (long)file->uid);
}
if (change_gid) {
rprintf(FINFO,
"set gid of %s from %ld to %ld\n",
safe_fname(fname),
fname,
(long)st->st_gid, (long)file->gid);
}
}
@@ -125,31 +204,31 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
}
#ifdef HAVE_CHMOD
if (!S_ISLNK(st->st_mode)) {
if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
updated = 1;
if (do_chmod(fname,(file->mode & CHMOD_BITS)) != 0) {
rsyserr(FERROR, errno, "failed to set permissions on %s",
full_fname(fname));
return 0;
}
if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
int ret = do_chmod(fname, file->mode);
if (ret < 0) {
rsyserr(FERROR, errno,
"failed to set permissions on %s",
full_fname(fname));
return 0;
}
if (ret == 0) /* ret == 1 if symlink could not be set */
updated = 1;
}
#endif
if (verbose > 1 && flags & PERMS_REPORT) {
if (verbose > 1 && flags & ATTRS_REPORT) {
enum logcode code = daemon_log_format_has_i || dry_run
? FCLIENT : FINFO;
if (updated)
rprintf(code, "%s\n", safe_fname(fname));
rprintf(code, "%s\n", fname);
else
rprintf(code, "%s is uptodate\n", safe_fname(fname));
rprintf(code, "%s is uptodate\n", fname);
}
return updated;
}
void sig_int(void)
RETSIGTYPE sig_int(UNUSED(int val))
{
/* KLUGE: if the user hits Ctrl-C while ssh is prompting
* for a password, then our cleanup's sending of a SIGUSR1
@@ -163,36 +242,39 @@ void sig_int(void)
exit_cleanup(RERR_SIGNAL);
}
/* finish off a file transfer, renaming the file and setting the permissions
and ownership */
void finish_transfer(char *fname, char *fnametmp, struct file_struct *file,
int ok_to_set_time, int overwriting_basis)
/* Finish off a file transfer: renaming the file and setting the file's
* attributes (e.g. permissions, ownership, etc.). If partialptr is not
* NULL and the robust_rename() call is forced to copy the temp file, we
* stage the file into the partial-dir and then rename it into place. */
void finish_transfer(char *fname, char *fnametmp, char *partialptr,
struct file_struct *file, int ok_to_set_time,
int overwriting_basis)
{
int ret;
if (inplace) {
if (verbose > 2)
rprintf(FINFO, "finishing %s\n", safe_fname(fname));
goto do_set_perms;
rprintf(FINFO, "finishing %s\n", fname);
fnametmp = fname;
goto do_set_file_attrs;
}
if (make_backups && overwriting_basis && !make_backup(fname))
return;
/* Change permissions before putting the file into place. */
set_perms(fnametmp, file, NULL, ok_to_set_time ? 0 : PERMS_SKIP_MTIME);
set_file_attrs(fnametmp, file, NULL,
ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
/* move tmp file over real file */
if (verbose > 2) {
rprintf(FINFO, "renaming %s to %s\n",
safe_fname(fnametmp), safe_fname(fname));
}
ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
if (verbose > 2)
rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
ret = robust_rename(fnametmp, fname, partialptr,
file->mode & INITACCESSPERMS);
if (ret < 0) {
rsyserr(FERROR, errno, "%s %s -> \"%s\"",
ret == -2 ? "copy" : "rename",
full_fname(fnametmp), safe_fname(fname));
ret == -2 ? "copy" : "rename",
full_fname(fnametmp), fname);
do_unlink(fnametmp);
return;
}
@@ -200,8 +282,21 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file,
/* The file was moved into place (not copied), so it's done. */
return;
}
do_set_perms:
set_perms(fname, file, NULL, ok_to_set_time ? 0 : PERMS_SKIP_MTIME);
/* The file was copied, so tweak the perms of the copied file. If it
* was copied to partialptr, move it into its final destination. */
fnametmp = partialptr ? partialptr : fname;
do_set_file_attrs:
set_file_attrs(fnametmp, file, NULL,
ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
if (partialptr) {
if (do_rename(fnametmp, fname) < 0) {
rsyserr(FERROR, errno, "rename %s -> \"%s\"",
full_fname(fnametmp), fname);
} else
handle_partial_dir(partialptr, PDIR_DELETE);
}
}
const char *who_am_i(void)

95
rsync.h
View File

@@ -58,12 +58,12 @@
/* These flags are used in the live flist data. */
#define FLAG_TOP_DIR (1<<0)
#define FLAG_SENT (1<<1) /* sender */
#define FLAG_HLINK_EOL (1<<1) /* receiver/generator */
#define FLAG_MOUNT_POINT (1<<2) /* sender */
#define FLAG_NO_FUZZY (1<<2) /* generator */
#define FLAG_MOUNT_POINT (1<<2) /* sender/generator */
#define FLAG_DEL_HERE (1<<3) /* receiver/generator */
#define FLAG_SENT (1<<3) /* sender */
#define FLAG_HLINK_TOL (1<<4) /* receiver/generator */
#define FLAG_NO_FUZZY (1<<5) /* generator */
/* update this if you make incompatible changes */
#define PROTOCOL_VERSION 29
@@ -103,8 +103,8 @@
#define IOERR_DEL_LIMIT (1<<2)
#define MAX_ARGS 1000
#define MAX_BASIS_DIRS 20
#define MAX_SERVER_ARGS (MAX_BASIS_DIRS*2 + 100)
#define MPLEX_BASE 7
@@ -115,9 +115,10 @@
#define XFLG_FATAL_ERRORS (1<<0)
#define XFLG_OLD_PREFIXES (1<<1)
#define XFLG_ANCHORED2ABS (1<<2)
#define XFLG_ABS_IF_SLASH (1<<3)
#define PERMS_REPORT (1<<0)
#define PERMS_SKIP_MTIME (1<<1)
#define ATTRS_REPORT (1<<0)
#define ATTRS_SKIP_MTIME (1<<1)
#define FULL_FLUSH 1
#define NORMAL_FLUSH 0
@@ -133,13 +134,7 @@
#define FNAMECMP_BACKUP 0x82
#define FNAMECMP_FUZZY 0x83
/* For calling delete_file() */
#define DEL_NO_RECURSE (1<<1)
#define DEL_FORCE_RECURSE (1<<2) /* recurse even w/o --force */
#define DEL_TERSE (1<<3)
/* For use by the itemize_changes code */
#define ITEM_DUMMY_BIT (1<<0)
#define ITEM_REPORT_CHECKSUM (1<<1)
#define ITEM_REPORT_SIZE (1<<2)
#define ITEM_REPORT_TIME (1<<3)
@@ -153,7 +148,6 @@
#define ITEM_LOCAL_CHANGE (1<<14)
#define ITEM_TRANSFER (1<<15)
/* These are outside the range of the transmitted flags. */
#define ITEM_NO_DEST_AND_NO_UPDATE (1<<16) /* used by itemize() */
#define ITEM_MISSING_DATA (1<<16) /* used by log_formatted() */
#define ITEM_DELETED (1<<17) /* used by log_formatted() */
@@ -161,16 +155,17 @@
ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE))
/* Log-message categories. FLOG and FCLIENT are only used on the daemon
* side for custom logging -- they don't get sent over the socket. */
enum logcode { FERROR=1, FINFO=2, FLOG=3, FCLIENT=4 };
/* Log-message categories. Only FERROR and FINFO get sent over the socket.
* FLOG and FCLIENT are only used on the daemon side for custom logging,
* while FNAME is only used on the client side. */
enum logcode { FERROR=1, FINFO=2, FLOG=3, FCLIENT=4, FNAME=5, FSOCKERR=6 };
/* Messages types that are sent over the message channel. The logcode
* values must all be present here with identical numbers. */
enum msgcode {
MSG_DATA=0, /* raw data on the multiplexed stream */
MSG_ERROR=FERROR, MSG_INFO=FINFO, /* remote logging */
MSG_LOG=FLOG, MSG_FCLIENT=FCLIENT, /* sibling logging */
MSG_LOG=FLOG, MSG_SOCKERR=FSOCKERR, /* sibling logging */
MSG_REDO=9, /* reprocess indicated flist index */
MSG_SUCCESS=100,/* successfully updated indicated flist index */
MSG_DELETED=101,/* successfully deleted a file on receiving side */
@@ -320,6 +315,10 @@ enum msgcode {
#include <compat.h>
#endif
#ifdef HAVE_LIMITS_H
# include <limits.h>
#endif
#include <assert.h>
#include "lib/pool_alloc.h"
@@ -464,6 +463,14 @@ struct idev {
#define MAXPATHLEN 1024
#endif
/* We want a roomy line buffer that can hold more than MAXPATHLEN,
* and significantly more than an overly short MAXPATHLEN. */
#if MAXPATHLEN < 4096
#define BIGPATHBUFLEN (4096+1024)
#else
#define BIGPATHBUFLEN (MAXPATHLEN+1024)
#endif
#ifndef NAME_MAX
#define NAME_MAX 255
#endif
@@ -553,6 +560,7 @@ struct sum_buf {
OFF_T offset; /**< offset in file of this chunk */
int32 len; /**< length of chunk of file */
uint32 sum1; /**< simple checksum */
int32 chain; /**< next hash-table collision */
short flags; /**< flag bits */
char sum2[SUM_LENGTH]; /**< checksum */
};
@@ -580,11 +588,11 @@ struct map_struct {
#define MATCHFLG_WILD (1<<0) /* pattern has '*', '[', and/or '?' */
#define MATCHFLG_WILD2 (1<<1) /* pattern has '**' */
#define MATCHFLG_WILD2_PREFIX (1<<2) /* pattern starts with '**' */
#define MATCHFLG_ABS_PATH (1<<3) /* path-match on absolute path */
#define MATCHFLG_INCLUDE (1<<4) /* this is an include, not an exclude */
#define MATCHFLG_DIRECTORY (1<<5) /* this matches only directories */
#define MATCHFLG_CLEAR_LIST (1<<6) /* this item is the "!" token */
#define MATCHFLG_WILD2_PREFIX (1<<2) /* pattern starts with "**" */
#define MATCHFLG_WILD3_SUFFIX (1<<3) /* pattern ends with "***" */
#define MATCHFLG_ABS_PATH (1<<4) /* path-match on absolute path */
#define MATCHFLG_INCLUDE (1<<5) /* this is an include, not an exclude */
#define MATCHFLG_DIRECTORY (1<<6) /* this matches only directories */
#define MATCHFLG_WORD_SPLIT (1<<7) /* split rules on whitespace */
#define MATCHFLG_NO_INHERIT (1<<8) /* don't inherit these rules */
#define MATCHFLG_NO_PREFIXES (1<<9) /* parse no prefixes from patterns */
@@ -596,6 +604,7 @@ struct map_struct {
#define MATCHFLG_CVS_IGNORE (1<<15)/* rule was -C or :C */
#define MATCHFLG_SENDER_SIDE (1<<16)/* rule applies to the sending side */
#define MATCHFLG_RECEIVER_SIDE (1<<17)/* rule applies to the receiving side */
#define MATCHFLG_CLEAR_LIST (1<<18)/* this item is the "!" token */
#define MATCHFLGS_FROM_CONTAINER (MATCHFLG_ABS_PATH | MATCHFLG_INCLUDE \
| MATCHFLG_DIRECTORY | MATCHFLG_SENDER_SIDE \
@@ -632,6 +641,7 @@ struct stats {
int current_file_index;
};
struct chmod_mode_struct;
#include "byteorder.h"
#include "lib/mdfour.h"
@@ -639,6 +649,15 @@ struct stats {
#include "lib/permstring.h"
#include "lib/addrinfo.h"
#if !defined __GNUC__ || defined __APPLE__
/* Apparently the OS X port of gcc gags on __attribute__.
*
* <http://www.opensource.apple.com/bugs/X/gcc/2512150.html> */
#define __attribute__(x)
#endif
#define UNUSED(x) x __attribute__((__unused__))
#include "proto.h"
/* We have replacement versions of these if they're missing. */
@@ -675,10 +694,19 @@ extern char *sys_errlist[];
extern int errno;
#endif
#define SUPPORT_LINKS HAVE_READLINK
#define SUPPORT_HARD_LINKS HAVE_LINK
#ifdef HAVE_READLINK
#define SUPPORT_LINKS 1
#endif
#ifdef HAVE_LINK
#define SUPPORT_HARD_LINKS 1
#endif
#define SIGNAL_CAST (RETSIGTYPE (*)())
#ifdef HAVE_SIGACTION
#define SIGACTION(n,h) sigact.sa_handler=(h), sigaction((n),&sigact,NULL)
#define signal(n,h) we_need_to_call_SIGACTION_not_signal(n,h)
#else
#define SIGACTION(n,h) signal(n,h)
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK EAGAIN
@@ -775,7 +803,8 @@ extern int errno;
#define INADDR_NONE 0xffffffff
#endif
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
#define IS_SPECIAL(mode) (S_ISSOCK(mode) || S_ISFIFO(mode))
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode))
/* Initial mask on permissions given to temporary files. Mask off setuid
bits and group access because of potential race-condition security
@@ -783,15 +812,7 @@ extern int errno;
#define INITACCESSPERMS 0700
/* handler for null strings in printf format */
#define NS(s) ((s)?safe_fname(s):"<NULL>")
#if !defined __GNUC__ || defined __APPLE__
/* Apparently the OS X port of gcc gags on __attribute__.
*
* <http://www.opensource.apple.com/bugs/X/gcc/2512150.html> */
#define __attribute__(x)
#endif
#define NS(s) ((s)?(s):"<NULL>")
/* Convenient wrappers for malloc and realloc. Use them. */
#define new(type) ((type *)malloc(sizeof(type)))
@@ -857,7 +878,3 @@ int inet_pton(int af, const char *src, void *dst);
#ifdef MAINTAINER_MODE
const char *get_panic_action(void);
#endif
#define UNUSED(x) x __attribute__((__unused__))
extern const char *io_write_phase, *io_read_phase;

1099
rsync.yo
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
mailto(rsync-bugs@samba.org)
manpage(rsyncd.conf)(5)(28 Mar 2005)()()
manpagename(rsyncd.conf)(configuration file for rsync server)
manpage(rsyncd.conf)(5)(11 Mar 2006)()()
manpagename(rsyncd.conf)(configuration file for rsync in daemon mode)
manpagesynopsis()
rsyncd.conf
@@ -8,7 +8,7 @@ rsyncd.conf
manpagedescription()
The rsyncd.conf file is the runtime configuration file for rsync when
run as an rsync server.
run as an rsync daemon.
The rsyncd.conf file controls authentication, access, logging and
available modules.
@@ -52,9 +52,6 @@ write the appropriate data, log, and lock files.
You can launch it either via inetd, as a stand-alone daemon, or from
an rsync client via a remote shell. If run as a stand-alone daemon then
just run the command "bf(rsync --daemon)" from a suitable startup script.
If run from an rsync client via a remote shell (by specifying both the
bf(--rsh) (bf(-e)) option and server mode with "::" or "rsync://"), the bf(--daemon)
option is automatically passed to the remote side.
When run via inetd you should add a line like this to /etc/services:
@@ -68,7 +65,7 @@ Replace "/usr/bin/rsync" with the path to where you have rsync installed on
your system. You will then need to send inetd a HUP signal to tell it to
reread its config file.
Note that you should not send the rsync server a HUP signal to force
Note that you should bf(not) send the rsync daemon a HUP signal to force
it to reread the tt(rsyncd.conf) file. The file is re-read on each client
connection.
@@ -90,25 +87,37 @@ is no motd file.
dit(bf(log file)) The "log file" option tells the rsync daemon to log
messages to that file rather than using syslog. This is particularly
useful on systems (such as AIX) where syslog() doesn't work for
chrooted programs.
chrooted programs. If the daemon fails to open to specified file, it
will fall back to using syslog and output an error about the failure.
(Note that a failure to open the specified log file used to be a fatal
error.)
dit(bf(pid file)) The "pid file" option tells the rsync daemon to write
its process ID to that file.
dit(bf(syslog facility)) The "syslog facility" option allows you to
specify the syslog facility name to use when logging messages from the
rsync server. You may use any standard syslog facility name which is
rsync daemon. You may use any standard syslog facility name which is
defined on your system. Common names are auth, authpriv, cron, daemon,
ftp, kern, lpr, mail, news, security, syslog, user, uucp, local0,
local1, local2, local3, local4, local5, local6 and local7. The default
is daemon.
dit(bf(port)) You can override the default port the daemon will listen on
by specifying this value (defaults to 873). This is ignored if the daemon
is being run by inetd, and is superseded by the bf(--port) command-line option.
dit(bf(address)) You can override the default IP address the daemon
will listen on by specifying this value. This is ignored if the daemon is
being run by inetd, and is superseded by the bf(--address) command-line option.
dit(bf(socket options)) This option can provide endless fun for people
who like to tune their systems to the utmost degree. You can set all
sorts of socket options which may make transfers faster (or
slower!). Read the man page for the setsockopt() system call for
details on some of the options you may be able to set. By default no
special socket options are set.
special socket options are set. These settings are superseded by the
bf(--sockopts) command-line option.
enddit()
@@ -126,11 +135,11 @@ dit(bf(comment)) The "comment" option specifies a description string
that is displayed next to the module name when clients obtain a list
of available modules. The default is no comment.
dit(bf(path)) The "path" option specifies the directory in the servers
dit(bf(path)) The "path" option specifies the directory in the daemon's
filesystem to make available in this module. You must specify this option
for each module in tt(rsyncd.conf).
dit(bf(use chroot)) If "use chroot" is true, the rsync server will chroot
dit(bf(use chroot)) If "use chroot" is true, the rsync daemon will chroot
to the "path" before starting the file transfer with the client. This has
the advantage of extra protection against possible implementation security
holes, but it has the disadvantages of requiring super-user privileges,
@@ -155,9 +164,9 @@ specified.
Note that you are free to setup user/group information in the chroot area
differently from your normal system. For example, you could abbreviate
the list of users and groups. Also, you can protect this information from
being downloaded/uploaded by adding an exclude rule to the rsync.conf file
being downloaded/uploaded by adding an exclude rule to the rsyncd.conf file
(e.g. "exclude = /etc/**"). Note that having the exclusion affect uploads
is a relatively new feature in rsync, so make sure your server is running
is a relatively new feature in rsync, so make sure your daemon is
at least 2.6.3 to effect this. Also note that it is safest to exclude a
directory and all its contents combining the rule "/some/dir/" with the
rule "/some/dir/**" just to be sure that rsync will not allow deeper
@@ -165,14 +174,6 @@ access to some of the excluded files inside the directory (rsync tries to
do this automatically, but you might as well specify both to be extra
sure).
dit(bf(port)) You can override the default port the daemon will listen on
by specifying this value (defaults to 873). This is ignored if the daemon
is being run by inetd, and is superseded by the bf(--port) command-line option.
dit(bf(address)) You can override the default IP address the daemon
will listen on by specifying this value. This is ignored if the daemon is
being run by inetd, and is superseded by the bf(--address) command-line option.
dit(bf(max connections)) The "max connections" option allows you to
specify the maximum number of simultaneous connections you will allow.
Any clients connecting when the maximum has been reached will receive a
@@ -185,7 +186,7 @@ generate (since the information goes into the log file). The default is 1,
which allows the client to request one level of verbosity.
dit(bf(lock file)) The "lock file" option specifies the file to use to
support the "max connections" option. The rsync server uses record
support the "max connections" option. The rsync daemon uses record
locking on this file to ensure that the max connections limit is not
exceeded for the modules sharing the lock file.
The default is tt(/var/run/rsyncd.lock).
@@ -193,13 +194,13 @@ The default is tt(/var/run/rsyncd.lock).
dit(bf(read only)) The "read only" option determines whether clients
will be able to upload files or not. If "read only" is true then any
attempted uploads will fail. If "read only" is false then uploads will
be possible if file permissions on the server allow them. The default
be possible if file permissions on the daemon side allow them. The default
is for all modules to be read only.
dit(bf(write only)) The "write only" option determines whether clients
will be able to download files or not. If "write only" is true then any
attempted downloads will fail. If "write only" is false then downloads
will be possible if file permissions on the server allow them. The
will be possible if file permissions on the daemon side allow them. The
default is for this option to be disabled.
dit(bf(list)) The "list" option determines if this module should be
@@ -219,30 +220,30 @@ was run as root. This complements the "uid" option. The default is gid -2,
which is normally the group "nobody".
dit(bf(filter)) The "filter" option allows you to specify a space-separated
list of filter rules that the server will not allow to be read or written.
list of filter rules that the daemon will not allow to be read or written.
This is only superficially equivalent to the client specifying these
patterns with the bf(--filter) option. Only one "filter" option may be
specified, but it may contain as many rules as you like, including
merge-file rules. Note that per-directory merge-file rules do not provide
as much protection as global rules, but they can be used to make bf(--delete)
work better when a client downloads the server's files (if the per-dir
work better when a client downloads the daemon's files (if the per-dir
merge files are included in the transfer).
dit(bf(exclude)) The "exclude" option allows you to specify a
space-separated list of patterns that the server will not allow to be read
space-separated list of patterns that the daemon will not allow to be read
or written. This is only superficially equivalent to the client
specifying these patterns with the bf(--exclude) option. Only one "exclude"
option may be specified, but you can use "-" and "+" before patterns to
specify exclude/include.
Because this exclude list is not passed to the client it only applies on
the server: that is, it excludes files received by a client when receiving
from a server and files deleted on a server when sending to a server, but
the daemon: that is, it excludes files received by a client when receiving
from a daemon and files deleted on a daemon when sending to a daemon, but
it doesn't exclude files from being deleted on a client when receiving
from a server.
from a daemon.
dit(bf(exclude from)) The "exclude from" option specifies a filename
on the server that contains exclude patterns, one per line.
on the daemon that contains exclude patterns, one per line.
This is only superficially equivalent
to the client specifying the bf(--exclude-from) option with an equivalent file.
See the "exclude" option above.
@@ -250,18 +251,37 @@ See the "exclude" option above.
dit(bf(include)) The "include" option allows you to specify a
space-separated list of patterns which rsync should not exclude. This is
only superficially equivalent to the client specifying these patterns with
the bf(--include) option because it applies only on the server. This is
the bf(--include) option because it applies only on the daemon. This is
useful as it allows you to build up quite complex exclude/include rules.
Only one "include" option may be specified, but you can use "+" and "-"
before patterns to switch include/exclude. See the "exclude" option
above.
dit(bf(include from)) The "include from" option specifies a filename
on the server that contains include patterns, one per line. This is
on the daemon that contains include patterns, one per line. This is
only superficially equivalent to the client specifying the
bf(--include-from) option with a equivalent file.
See the "exclude" option above.
dit(bf(incoming chmod)) This option allows you to specify a set of
comma-separated chmod strings that will affect the permissions of all
incoming files (files that are being received by the daemon). These
changes happen after all other permission calculations, and this will
even override destination-default and/or existing permissions when the
client does not specify bf(--perms).
See the description of the bf(--chmod) rsync option and the bf(chmod)(1)
manpage for information on the format of this string.
dit(bf(outgoing chmod)) This option allows you to specify a set of
comma-separated chmod strings that will affect the permissions of all
outgoing files (files that are being sent out from the daemon). These
changes happen first, making the sent permissions appear to be different
than those stored in the filesystem itself. For instance, you could
disable group write permissions on the server while having it appear to
be on to the clients.
See the description of the bf(--chmod) rsync option and the bf(chmod)(1)
manpage for information on the format of this string.
dit(bf(auth users)) The "auth users" option specifies a comma and
space-separated list of usernames that will be allowed to connect to
this module. The usernames do not need to exist on the local
@@ -269,14 +289,14 @@ system. The usernames may also contain shell wildcard characters. If
"auth users" is set then the client will be challenged to supply a
username and password to connect to the module. A challenge response
authentication protocol is used for this exchange. The plain text
usernames are passwords are stored in the file specified by the
usernames and passwords are stored in the file specified by the
"secrets file" option. The default is for all users to be able to
connect without a password (this is called "anonymous rsync").
See also the bf(CONNECTING TO AN RSYNC SERVER OVER A REMOTE SHELL
PROGRAM) section in rsync(1) for information on how handle an
See also the "CONNECTING TO AN RSYNC DAEMON OVER A REMOTE SHELL
PROGRAM" section in rsync(1) for information on how handle an
rsyncd.conf-level username that differs from the remote-shell-level
username when using a remote shell to connect to an rsync server.
username when using a remote shell to connect to an rsync daemon.
dit(bf(secrets file)) The "secrets file" option specifies the name of
a file that contains the username:password pairs used for
@@ -351,21 +371,21 @@ rejected. See the "hosts allow" option for more information.
The default is no "hosts deny" option, which means all hosts can connect.
dit(bf(ignore errors)) The "ignore errors" option tells rsyncd to
ignore I/O errors on the server when deciding whether to run the delete
ignore I/O errors on the daemon when deciding whether to run the delete
phase of the transfer. Normally rsync skips the bf(--delete) step if any
I/O errors have occurred in order to prevent disastrous deletion due
to a temporary resource shortage or other I/O error. In some cases this
test is counter productive so you can use this option to turn off this
behavior.
dit(bf(ignore nonreadable)) This tells the rsync server to completely
dit(bf(ignore nonreadable)) This tells the rsync daemon to completely
ignore files that are not readable by the user. This is useful for
public archives that may have some non-readable files among the
directories, and the sysadmin doesn't want those files to be seen at all.
dit(bf(transfer logging)) The "transfer logging" option enables per-file
logging of downloads and uploads in a format somewhat similar to that
used by ftp daemons. The server always logs the transfer at the end, so
used by ftp daemons. The daemon always logs the transfer at the end, so
if a transfer is aborted, no mention will be made in the log file.
If you want to customize the log lines, see the "log format" option.
@@ -373,7 +393,9 @@ If you want to customize the log lines, see the "log format" option.
dit(bf(log format)) The "log format" option allows you to specify the
format used for logging file transfers when transfer logging is enabled.
The format is a text string containing embedded single-character escape
sequences prefixed with a percent (%) character.
sequences prefixed with a percent (%) character. An optional numeric
field width may also be specified between the percent and the escape
letter (e.g. "%-50n %8l %07p").
The default log format is "%o %h [%a] %m (%u) %f %l", and a "%t [%p] "
is always prefixed when using the "log file" option.
@@ -384,43 +406,44 @@ rsyncstats.)
The single-character escapes that are understood are as follows:
quote(itemize(
it() %h for the remote host name
it() %a for the remote IP address
it() %l for the length of the file in bytes
it() %p for the process ID of this rsync session
it() %o for the operation, which is "send", "recv", or "del."
(the latter includes the trailing period)
it() %f for the filename (long form on sender; no trailing "/")
it() %n for the filename (short form; trailing "/" on dir)
it() %L either the string " -> SYMLINK", or " => HARDLINK" or an
empty string (where bf(SYMLINK) or bf(HARDLINK) is a filename)
it() %P for the module path
it() %m for the module name
it() %t for the current date time
it() %u for the authenticated username (or the null string)
it() %b for the number of bytes actually transferred
it() %c when sending files this gives the number of checksum bytes
received for this file
it() %a the remote IP address
it() %b the number of bytes actually transferred
it() %B the permission bits of the file (e.g. rwxrwxrwt)
it() %c the checksum bytes received for this file (only when sending)
it() %f the filename (long form on sender; no trailing "/")
it() %G the gid of the file (decimal) or "DEFAULT"
it() %h the remote host name
it() %i an itemized list of what is being updated
it() %l the length of the file in bytes
it() %L the string " -> SYMLINK", " => HARDLINK", or "" (where bf(SYMLINK) or bf(HARDLINK) is a filename)
it() %m the module name
it() %M the last-modified time of the file
it() %n the filename (short form; trailing "/" on dir)
it() %o the operation, which is "send", "recv", or "del." (the latter includes the trailing period)
it() %p the process ID of this rsync session
it() %P the module path
it() %t the current date time
it() %u the authenticated username or an empty string
it() %U the uid of the file (decimal)
))
For a list of what the characters mean that are output by "%i", see the
bf(--itemize-changes) option in the rsync manpage.
Note that some of the logged output changes when talking with older
rsync versions. For instance, deleted files were only logged as verbose
rsync versions. For instance, deleted files were only output as verbose
messages prior to rsync 2.6.4.
dit(bf(timeout)) The "timeout" option allows you to override the
clients choice for I/O timeout for this module. Using this option you
can ensure that rsync won't wait on a dead client forever. The timeout
is specified in seconds. A value of zero means no timeout and is the
default. A good choice for anonymous rsync servers may be 600 (giving
default. A good choice for anonymous rsync daemons may be 600 (giving
a 10 minute timeout).
dit(bf(refuse options)) The "refuse options" option allows you to
specify a space-separated list of rsync command line options that will
be refused by your rsync server.
be refused by your rsync daemon.
You may specify the full option name, its one-letter abbreviation, or a
wild-card string that matches multiple options.
For example, this would refuse bf(--checksum) (bf(-c)) and all the various
@@ -435,7 +458,7 @@ bf(remove-sent-files) when the daemon is the sender; if you want the latter
without the former, instead refuse "delete-*" -- that refuses all the
delete modes without affecting bf(--remove-sent-files).
When an option is refused, the server prints an error message and exits.
When an option is refused, the daemon prints an error message and exits.
To prevent all compression, you can use "dont compress = *" (see below)
instead of "refuse options = compress" to avoid returning an error to a
client that requests compression.
@@ -452,18 +475,47 @@ of the patterns will not be compressed during transfer.
The default setting is tt(*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz)
dit(bf(pre-xfer exec), bf(post-xfer exec)) You may specify a command to be run
before and/or after the transfer. If the bf(pre-xfer exec) command fails, the
transfer is aborted before it begins.
The following environment variables will be set, though some are
specific to the pre-xfer or the post-xfer environment:
quote(itemize(
it() bf(RSYNC_MODULE_NAME): The name of the module being accessed.
it() bf(RSYNC_MODULE_PATH): The path configured for the module.
it() bf(RSYNC_HOST_ADDR): The accessing host's IP address.
it() bf(RSYNC_HOST_NAME): The accessing host's name.
it() bf(RSYNC_USER_NAME): The accessing user's name (empty if no user).
it() bf(RSYNC_REQUEST): (pre-xfer only) The module/path info specified
by the user (note that the user can specify multiple source files,
so the request can be something like "mod/path1 mod/path2", etc.).
it() bf(RSYNC_ARG#): (pre-xfer only) The pre-request arguments are set
in these numbered values. RSYNC_ARG0 is always "rsyncd", and the last
value contains a single period.
it() bf(RSYNC_EXIT_STATUS): (post-xfer only) rsync's exit value. This will be 0 for a
successful run, a positive value for an error that rsync returned
(e.g. 23=partial xfer), or a -1 if rsync failed to exit properly.
it() bf(RSYNC_RAW_STATUS): (post-xfer only) the raw exit value from waitpid().
))
Even though the commands can be associated with a particular module, they
are run using the permissions of the user that started the daemon (not the
module's uid/gid setting) without any chroot restrictions.
enddit()
manpagesection(AUTHENTICATION STRENGTH)
The authentication protocol used in rsync is a 128 bit MD4 based
challenge response system. Although I believe that no one has ever
demonstrated a brute-force break of this sort of system you should
realize that this is not a "military strength" authentication system.
It should be good enough for most purposes but if you want really top
quality security then I recommend that you run rsync over ssh.
challenge response system. This is fairly weak protection, though (with
at least one brute-force hash-finding algorithm publicly available), so
if you want really top-quality security, then I recommend that you run
rsync over ssh. (Yes, a future version of rsync will switch over to a
stronger hashing method.)
Also note that the rsync server protocol does not currently provide any
Also note that the rsync daemon protocol does not currently provide any
encryption of the data that is transferred over the connection. Only
authentication is provided. Use ssh as the transport if you want
encryption.
@@ -471,32 +523,6 @@ encryption.
Future versions of rsync may support SSL for better authentication and
encryption, but that is still being investigated.
manpagesection(RUNNING AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM)
If rsync is run with both the bf(--daemon) and bf(--rsh) (bf(-e)) options, it will
spawn an rsync daemon using a remote shell connection. Several
configuration options will not be available unless the remote user is
root (e.g. chroot, setuid/setgid, etc.). There is no need to configure
inetd or the services map to include the rsync server port if you run an
rsync server only via a remote shell program.
ADVANCED: To run an rsync server out of a single-use ssh key, use the
"command=em(COMMAND)" syntax in the remote user's authorized_keys entry,
where command would be
quote(tt(rsync --server --daemon .))
NOTE: rsync's argument parsing expects the trailing ".", so make sure
that it's there. If you want to use an rsyncd.conf(5)-style
configuration file other than the default, you can added a
bf(--config) option to the em(command):
quote(tt(rsync --server --daemon --config=em(file) .))
Note that the "--server" here is the internal option that rsync uses to
run the remote version of rsync that it communicates with, and thus you
should not be using the bf(--server) option under normal circumstances.
manpagesection(EXAMPLES)
A simple rsyncd.conf file that allow anonymous rsync to a ftp area at
@@ -560,15 +586,12 @@ manpagediagnostics()
manpagebugs()
The rsync server does not send all types of error messages to the
client. this means a client may be mystified as to why a transfer
failed. The error will have been logged by syslog on the server.
Please report bugs! The rsync bug tracking system is online at
url(http://rsync.samba.org/)(http://rsync.samba.org/)
manpagesection(VERSION)
This man page is current for version 2.x of rsync.
This man page is current for version 2.6.7 of rsync.
manpagesection(CREDITS)
@@ -589,7 +612,7 @@ Gailly and Mark Adler.
manpagesection(THANKS)
Thanks to Warren Stanley for his original idea and patch for the rsync
server. Thanks to Karsten Thygesen for his many suggestions and
daemon. Thanks to Karsten Thygesen for his many suggestions and
documentation!
manpageauthor()

View File

@@ -85,7 +85,7 @@
# they're explicitly given on the command line.
# Also, we can't count on 'cp -a' or 'mkdir -p', although they're
# pretty handy.
# pretty handy (see function makepath for the latter).
# I think some of the GNU documentation suggests that we shouldn't
# rely on shell functions. However, the Bash manual seems to say that
@@ -100,6 +100,8 @@
# You cannot do "export VAR=VALUE" all on one line; the export must be
# separate from the assignment. (SCO SysV)
# Don't rely on grep -q, as that doesn't work everywhere -- just redirect
# stdout to /dev/null to keep it quiet.
# STILL TO DO:
@@ -124,6 +126,7 @@ set -e
. "./shconfig"
RUNSHFLAGS='-e'
export RUNSHFLAGS
# for Solaris
[ -d /usr/xpg4/bin ] && PATH="/usr/xpg4/bin/:$PATH"
@@ -160,6 +163,12 @@ else
echo " preserve_scratch=no"
fi
# We'll use setfacl if it's around and it supports the -k option.
if setfacl --help 2>/dev/null | grep ' -k,' >/dev/null; then
setfacl=setfacl
else
setfacl=true
fi
if [ ! -f "$rsync_bin" ]; then
echo "rsync_bin $rsync_bin is not a file" >&2
@@ -194,6 +203,9 @@ export scratchdir suitedir
prep_scratch() {
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
mkdir "$scratchdir"
# Get rid of default ACLs and dir-setgid to avoid confusing some tests.
$setfacl -k "$scratchdir"
chmod g-s "$scratchdir"
return 0
}

View File

@@ -20,20 +20,24 @@
#include "rsync.h"
extern int verbose;
extern int dry_run;
extern int do_xfers;
extern int am_server;
extern int am_daemon;
extern int log_before_transfer;
extern int log_format_has_i;
extern int daemon_log_format_has_i;
extern int csum_length;
extern int append_mode;
extern int io_error;
extern int allowed_lull;
extern int protocol_version;
extern int remove_sent_files;
extern int updating_basis_file;
extern int make_backups;
extern int do_progress;
extern int inplace;
extern int batch_fd;
extern int write_batch;
extern struct stats stats;
extern struct file_list *the_file_list;
extern char *log_format;
@@ -54,6 +58,7 @@ static struct sum_struct *receive_sums(int f)
{
struct sum_struct *s;
int32 i;
int lull_mod = allowed_lull * 5;
OFF_T offset = 0;
if (!(s = new(struct sum_struct)))
@@ -68,6 +73,13 @@ static struct sum_struct *receive_sums(int f)
(double)s->count, (long)s->blength, (long)s->remainder);
}
if (append_mode) {
s->flength = (OFF_T)s->count * s->blength;
if (s->remainder)
s->flength -= s->blength - s->remainder;
return s;
}
if (s->count == 0)
return(s);
@@ -87,6 +99,9 @@ static struct sum_struct *receive_sums(int f)
s->sums[i].len = s->blength;
offset += s->sums[i].len;
if (allowed_lull && !(i % lull_mod))
maybe_send_keepalive();
if (verbose > 3) {
rprintf(FINFO,
"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
@@ -118,11 +133,9 @@ void successful_send(int ndx)
file->dir.root, "/", NULL);
} else
offset = 0;
f_name_to(file, fname + offset);
if (remove_sent_files && do_unlink(fname) == 0 && verbose > 1) {
rprintf(FINFO, "sender removed %s\n",
safe_fname(fname + offset));
}
f_name(file, fname + offset);
if (remove_sent_files && do_unlink(fname) == 0 && verbose > 1)
rprintf(FINFO, "sender removed %s\n", fname + offset);
}
static void write_ndx_and_attrs(int f_out, int ndx, int iflags,
@@ -173,10 +186,6 @@ int read_item_attrs(int f_in, int f_out, int ndx, uchar *type_ptr,
}
*len_ptr = len;
/* Temporary handling of 2.6.4pre3 */
if (iflags & ITEM_DUMMY_BIT && iflags & (ITEM_LOCAL_CHANGE|ITEM_TRANSFER))
iflags &= ~ITEM_DUMMY_BIT;
if (iflags & ITEM_TRANSFER) {
if (!S_ISREG(the_file_list->files[ndx]->mode)) {
rprintf(FERROR,
@@ -208,6 +217,7 @@ void send_files(struct file_list *flist, int f_out, int f_in)
int save_make_backups = make_backups;
int itemizing = am_daemon ? daemon_log_format_has_i
: !am_server && log_format_has_i;
int f_xfer = write_batch < 0 ? batch_fd : f_out;
int i, j;
if (verbose > 2)
@@ -227,6 +237,7 @@ void send_files(struct file_list *flist, int f_out, int f_in)
/* For inplace: redo phase turns off the backup
* flag so that we do a regular inplace send. */
make_backups = 0;
append_mode = 0;
continue;
}
@@ -243,7 +254,7 @@ void send_files(struct file_list *flist, int f_out, int f_in)
fname[offset++] = '/';
} else
offset = 0;
fname2 = f_name_to(file, fname + offset);
fname2 = f_name(file, fname + offset);
if (verbose > 2)
rprintf(FINFO, "send_files(%d, %s)\n", i, fname);
@@ -266,7 +277,7 @@ void send_files(struct file_list *flist, int f_out, int f_in)
stats.num_transferred_files++;
stats.total_transferred_size += file->length;
if (dry_run) { /* log the transfer */
if (!do_xfers) { /* log the transfer */
if (!am_server && log_format)
log_item(file, &stats, iflags, NULL);
write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
@@ -318,26 +329,24 @@ void send_files(struct file_list *flist, int f_out, int f_in)
if (verbose > 2) {
rprintf(FINFO, "send_files mapped %s of size %.0f\n",
safe_fname(fname), (double)st.st_size);
fname, (double)st.st_size);
}
write_ndx_and_attrs(f_out, i, iflags, fnamecmp_type,
xname, xlen);
write_sum_head(f_out, s);
write_sum_head(f_xfer, s);
if (verbose > 2) {
rprintf(FINFO, "calling match_sums %s\n",
safe_fname(fname));
}
if (verbose > 2)
rprintf(FINFO, "calling match_sums %s\n", fname);
if (log_before_transfer)
log_item(file, &initial_stats, iflags, NULL);
else if (!am_server && verbose && do_progress)
rprintf(FINFO, "%s\n", safe_fname(fname2));
rprintf(FINFO, "%s\n", fname2);
set_compression(fname);
match_sums(f_out, s, mbuf, st.st_size);
match_sums(f_xfer, s, mbuf, st.st_size);
if (do_progress)
end_progress(st.st_size);
@@ -357,10 +366,8 @@ void send_files(struct file_list *flist, int f_out, int f_in)
free_sums(s);
if (verbose > 2) {
rprintf(FINFO, "sender finished %s\n",
safe_fname(fname));
}
if (verbose > 2)
rprintf(FINFO, "sender finished %s\n", fname);
/* Flag that we actually sent this entry. */
file->flags |= FLAG_SENT;

View File

@@ -36,6 +36,10 @@
extern char *bind_address;
extern int default_af_hint;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
#endif
/**
* Establish a proxy connection on an open socket to a web proxy by
* using the CONNECT method. If proxy_user and proxy_pass are not NULL,
@@ -54,13 +58,13 @@ static int establish_proxy_connection(int fd, char *host, int port,
proxy_user, ":", proxy_pass, NULL);
len = strlen(buffer);
if ((len*8 + 5) / 6 >= (int)sizeof authbuf) {
if ((len*8 + 5) / 6 >= (int)sizeof authbuf - 3) {
rprintf(FERROR,
"authentication information is too long\n");
return -1;
}
base64_encode(buffer, len, authbuf);
base64_encode(buffer, len, authbuf, 1);
authhdr = "\r\nProxy-Authorization: Basic ";
} else {
*authbuf = '\0';
@@ -127,7 +131,7 @@ static int establish_proxy_connection(int fd, char *host, int port,
* if this fails.
**/
int try_bind_local(int s, int ai_family, int ai_socktype,
const char *bind_address)
const char *bind_addr)
{
int error;
struct addrinfo bhints, *bres_all, *r;
@@ -136,9 +140,9 @@ int try_bind_local(int s, int ai_family, int ai_socktype,
bhints.ai_family = ai_family;
bhints.ai_socktype = ai_socktype;
bhints.ai_flags = AI_PASSIVE;
if ((error = getaddrinfo(bind_address, NULL, &bhints, &bres_all))) {
if ((error = getaddrinfo(bind_addr, NULL, &bhints, &bres_all))) {
rprintf(FERROR, RSYNC_NAME ": getaddrinfo %s: %s\n",
bind_address, gai_strerror(error));
bind_addr, gai_strerror(error));
return -1;
}
@@ -172,12 +176,12 @@ int try_bind_local(int s, int ai_family, int ai_socktype,
* reachable, perhaps because we can't e.g. route ipv6 to that network
* but we can get ip4 packets through.
*
* @param bind_address Local address to use. Normally NULL to bind
* @param bind_addr Local address to use. Normally NULL to bind
* the wildcard address.
*
* @param af_hint Address family, e.g. AF_INET or AF_INET6.
**/
int open_socket_out(char *host, int port, const char *bind_address,
int open_socket_out(char *host, int port, const char *bind_addr,
int af_hint)
{
int type = SOCK_STREAM;
@@ -253,9 +257,9 @@ int open_socket_out(char *host, int port, const char *bind_address,
if (s < 0)
continue;
if (bind_address
if (bind_addr
&& try_bind_local(s, res->ai_family, type,
bind_address) == -1) {
bind_addr) == -1) {
close(s);
s = -1;
continue;
@@ -293,9 +297,9 @@ int open_socket_out(char *host, int port, const char *bind_address,
*
* This is based on the Samba LIBSMB_PROG feature.
*
* @param bind_address Local address to use. Normally NULL to get the stack default.
* @param bind_addr Local address to use. Normally NULL to get the stack default.
**/
int open_socket_out_wrapped(char *host, int port, const char *bind_address,
int open_socket_out_wrapped(char *host, int port, const char *bind_addr,
int af_hint)
{
char *prog = getenv("RSYNC_CONNECT_PROG");
@@ -307,7 +311,7 @@ int open_socket_out_wrapped(char *host, int port, const char *bind_address,
}
if (prog)
return sock_exec(prog);
return open_socket_out(host, port, bind_address, af_hint);
return open_socket_out(host, port, bind_addr, af_hint);
}
@@ -322,10 +326,10 @@ int open_socket_out_wrapped(char *host, int port, const char *bind_address,
* We return an array of file-descriptors to the sockets, with a trailing
* -1 value to indicate the end of the list.
*
* @param bind_address Local address to bind, or NULL to allow it to
* @param bind_addr Local address to bind, or NULL to allow it to
* default.
**/
static int *open_socket_in(int type, int port, const char *bind_address,
static int *open_socket_in(int type, int port, const char *bind_addr,
int af_hint)
{
int one = 1;
@@ -339,10 +343,10 @@ static int *open_socket_in(int type, int port, const char *bind_address,
hints.ai_socktype = type;
hints.ai_flags = AI_PASSIVE;
snprintf(portbuf, sizeof portbuf, "%d", port);
error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
error = getaddrinfo(bind_addr, portbuf, &hints, &all_ai);
if (error) {
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
bind_address, gai_strerror(error));
bind_addr, gai_strerror(error));
return NULL;
}
@@ -433,7 +437,9 @@ static RETSIGTYPE sigchld_handler(UNUSED(int val))
#ifdef WNOHANG
while (waitpid(-1, NULL, WNOHANG) > 0) {}
#endif
#ifndef HAVE_SIGACTION
signal(SIGCHLD, sigchld_handler);
#endif
}
@@ -442,6 +448,10 @@ void start_accept_loop(int port, int (*fn)(int, int))
fd_set deffds;
int *sp, maxfd, i;
#ifdef HAVE_SIGACTION
sigact.sa_flags = SA_NOCLDSTOP;
#endif
/* open an incoming socket */
sp = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
if (sp == NULL)
@@ -465,7 +475,6 @@ void start_accept_loop(int port, int (*fn)(int, int))
maxfd = sp[i];
}
/* now accept incoming connections - forking a new process
* for each incoming connection */
while (1) {
@@ -478,7 +487,7 @@ void start_accept_loop(int port, int (*fn)(int, int))
/* close log file before the potentially very long select so
* file can be trimmed by another process instead of growing
* forever */
log_close();
logfile_close();
#ifdef FD_COPY
FD_COPY(&deffds, &fds);
@@ -500,15 +509,15 @@ void start_accept_loop(int port, int (*fn)(int, int))
if (fd < 0)
continue;
signal(SIGCHLD, sigchld_handler);
SIGACTION(SIGCHLD, sigchld_handler);
if ((pid = fork()) == 0) {
int ret;
for (i = 0; sp[i] >= 0; i++)
close(sp[i]);
/* Re-open log file in child before possibly giving
* up privileges (see log_close() above). */
log_open();
* up privileges (see logfile_close() above). */
logfile_reopen();
ret = fn(fd, fd);
close_all();
_exit(ret);

View File

@@ -1,9 +1,9 @@
#!/usr/bin/perl
#
# This script lets you update a hierarchy of files in an atomic way by
# first creating a new hierarchy using --link-dest to rsync, and then
# swapping the hierarchy into place. See the usage message for more
# details and some important caveats!
# first creating a new hierarchy using rsync's --link-dest option, and
# then swapping the hierarchy into place. **See the usage message for
# more details and some important caveats!**
use strict;
use Cwd 'abs_path';

64
support/cull_options Executable file
View File

@@ -0,0 +1,64 @@
#!/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, %short_with_num, %long_opt);
our $last_long_opt;
open(IN, '../options.c') or die "Unable to open ../options.c: $!\n";
while (<IN>) {
if (/\Qargstr[x++]\E = '(.)'/) {
$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;
} 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 = '';
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-/;
$val = 3 if $opt eq 'files-from';
$val = '$ro ? -1 : ' . $val if $opt =~ /^remove-/;
print " '$opt' => $val,\n";
}
print ");\n\n";

42
support/cvs2includes Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/perl
#
# This script finds all CVS/Entries files in the current directory and below
# and creates a local .cvsinclude file with non-inherited rules including each
# checked-in file. Then, use this option whenever using --cvs-exclude (-C):
#
# -f ': .cvsinclude'
#
# That ensures that all checked-in files/dirs are included in the transfer.
# (You could alternately put ": .cvsinclude" into an .rsync-filter file and
# use the -F option, which is easier to type.)
#
# The downside is that you need to remember to re-run cvs2includes whenever
# You add a new file to the project.
use strict;
open(FIND, 'find . -name CVS -type d |') or die $!;
while (<FIND>) {
chomp;
s#^\./##;
my $entries = "$_/Entries";
s/CVS$/.cvsinclude/;
my $filter = $_;
open(ENTRIES, $entries) or die "Unable to open $entries: $!\n";
my @includes;
while (<ENTRIES>) {
push(@includes, $1) if m#/(.+?)/#;
}
close ENTRIES;
if (@includes) {
open(FILTER, ">$filter") or die "Unable to write $filter: $!\n";
print FILTER '+ /', join("\n+ /", @includes), "\n";
close FILTER;
print "Updated $filter\n";
} elsif (-f $filter) {
unlink($filter);
print "Removed $filter\n";
}
}
close FIND;

27
support/files-to-excludes Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/perl
# This script takes an input of filenames and outputs a set of
# include/exclude directives that can be used by rsync to copy
# just the indicated files using an --exclude-from=FILE option.
use strict;
my %hash;
while (<>) {
chomp;
s#^/+##;
my $path = '/';
while (m#([^/]+/)/*#g) {
$path .= $1;
print "+ $path\n" unless $hash{$path}++;
}
if (m#([^/]+)$#) {
print "+ $path$1\n";
} else {
delete $hash{$path};
}
}
foreach (sort keys %hash) {
print "- $_*\n";
}
print "- /*\n";

34
support/logfilter Executable file
View File

@@ -0,0 +1,34 @@
#!/usr/bin/perl
# Filter the rsync daemon log messages by module name. The log file can be
# in either syslog format or rsync's own log-file format. Note that the
# MODULE_NAME parameter is used in a regular-expression match in order to
# allow regex wildcards to be used. You can also limit the output by
# directory hierarchy in a module. Examples:
#
# logfilter foo /var/log/rsyncd.log # output lines for module foo
# logfilter foo/dir /var/log/syslog # limit lines to those in dir of foo
use strict;
my $match = shift;
die "Usage: logfilter MODULE_NAME [LOGFILE ...]\n" unless defined $match;
my $syslog_prefix = '\w\w\w +\d+ \d\d:\d\d:\d\d \S+ rsyncd';
my $rsyncd_prefix = '\d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d ';
my %pids;
while (<>) {
my($pid,$msg) = /^(?:$syslog_prefix|$rsyncd_prefix)\[(\d+)\]:? (.*)/o;
next unless defined $pid;
my($mod_spec) = $msg =~ /^rsync (?:on|to) (\S+) from /;
if (defined $mod_spec) {
if ($mod_spec =~ /^$match(\/\S*)?$/o) {
$pids{$pid} = 1;
} else {
delete $pids{$pid};
}
}
next unless $pids{$pid};
print $_;
}

View File

@@ -20,7 +20,7 @@
# ADDENDUM: The addition of the --filter option (which has support for
# absolute-anchored excludes) has made this script less useful than it
# was. Beginning with 2.6.4, you can achieve the effect of this script
# though this command:
# through this command:
#
# awk '{print $2}' /proc/mounts | rsync -f 'merge,/- -' host:/dir /dest/

View File

@@ -2,18 +2,28 @@
# Name: /usr/local/bin/rrsync (should also have a symlink in /usr/bin)
# Purpose: Restricts rsync to subdirectory declared in .ssh/authorized_keys
# Author: Joe Smith <js-cgi@inwap.com> 30-Sep-2004
# Modified by Wayne Davison <wayned@samba.org> 12-Jan-2005
# Modified by: Wayne Davison <wayned@samba.org>
use strict;
use Socket;
use Cwd 'abs_path';
use File::Glob ':glob';
# You may configure these values to your liking. See also the section
# of options if you want to disable any options that rsync accepts.
use constant RSYNC => '/usr/bin/rsync';
use constant LOGFILE => 'rrsync.log';
my $Usage = <<EOM;
Use 'command="$0 [-ro] SUBDIR"'
in front of lines in $ENV{HOME}/.ssh/authorized_keys
EOM
my $ro = (@ARGV and $ARGV[0] eq '-ro') ? shift : ''; # -ro = Read-Only
my $subdir = shift;
die "No subdirectory specified\n$Usage" unless defined $subdir;
our $ro = (@ARGV && $ARGV[0] eq '-ro') ? shift : ''; # -ro = Read-Only
our $subdir = shift;
die "$0: No subdirectory specified\n$Usage" unless defined $subdir;
$subdir = abs_path($subdir);
die "$0: Restricted directory does not exist!\n" if $subdir ne '/' && !-d $subdir;
# The client uses "rsync -av -e ssh src/ server:dir/", and sshd on the server
# executes this program when .ssh/authorized_keys has 'command="..."'.
@@ -22,53 +32,166 @@ die "No subdirectory specified\n$Usage" unless defined $subdir;
# command="rrsync -ro results" ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAmkHG1WCjC...
#
# Format of the envrionment variables set by sshd:
# SSH_ORIGINAL_COMMAND=rsync --server -vlogDtpr --partial . dir # push
# SSH_ORIGINAL_COMMAND=rsync --server --sender -vlogDtpr --partial . dir # pull
# SSH_ORIGINAL_COMMAND=rsync --server -vlogDtpr --partial . ARG # push
# SSH_ORIGINAL_COMMAND=rsync --server --sender -vlogDtpr --partial . ARGS # pull
# SSH_CONNECTION=client_addr client_port server_port
my $command = $ENV{SSH_ORIGINAL_COMMAND};
die "Not invoked via sshd\n$Usage" unless defined $command;
die "SSH_ORIGINAL_COMMAND='$command' is not rsync\n" unless $command =~ /^rsync\s/;
die "$0 -ro: sending to read-only server not allowed\n"
if $ro and $command !~ /^rsync --server --sender /;
die "$0 -ro: use of --remove-sent-files with read-only server not allowed\n"
if $ro and $command =~ /\s--remove-sent-files/;
die "$0: Not invoked via sshd\n$Usage" unless defined $command;
die "$0: SSH_ORIGINAL_COMMAND='$command' is not rsync\n" unless $command =~ s/^rsync\s+//;
our $am_sender = $command =~ /^--server\s+--sender\s/; # Restrictive on purpose!
die "$0 -ro: sending to read-only server not allowed\n" if $ro && !$am_sender;
my ($cmd,$dir) = $command =~ /^(rsync\s+(?:-[-a-zA-Z]+\s+)+\.) ?("[^"]*"|[^\s"]*)$/;
die "$0: invalid rsync-command syntax or options\n" if !defined $cmd;
### START of options data produced by the cull_options script. ###
# Enforce default of $subdir instead of the normal $HOME default.
my $orig = $dir;
my @dirs;
$dir =~ s/^"(.*?)"$/$1/;
$dir =~ s/^\s+//;
$dir =~ s/\s+$//;
foreach (split(/(?<!\\)\s+/, $dir)) {
s/\\(\s)/$1/g; # Unescape any escaped whitespace
if ($subdir eq '/') { # Less checking for '/' access
$dir = '/' if $dir eq '';
} else {
s#^/##; # Don't allow absolute paths
$_ = "$subdir/$_" unless m#^\Q$subdir\E(/|$)#;
1 while s#/\.\.(/|$)#/__/#g; # Don't allow foo/../../etc
}
tr#-_/a-zA-Z0-9.,+@^%: #_#c; # Don't allow '"&;|!=()[]{}<>*?#\$
s/(\s)/\\$1/g; # Re-escape whitespace
push(@dirs, $_);
# 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 = '';
our $short_no_arg = 'CDHIKLORSWbcdglnoprtuvxz'; # DO NOT REMOVE ANY
our $short_with_num = 'B'; # 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 = (
'backup-dir' => 2,
'bwlimit' => 1,
'checksum-seed' => 1,
'compare-dest' => 2,
'copy-dest' => 2,
'copy-unsafe-links' => 0,
'daemon' => 0,
'delay-updates' => 0,
'delete' => 0,
'delete-after' => 0,
'delete-before' => 0,
'delete-during' => 0,
'delete-excluded' => 0,
'existing' => 0,
'files-from' => 3,
'force' => 0,
'from0' => 0,
'fuzzy' => 0,
'ignore-errors' => 0,
'ignore-existing' => 0,
'inplace' => 0,
'link-dest' => 2,
'list-only' => 0,
'log-format' => 1,
'max-delete' => 1,
'max-size' => 1,
'modify-window' => 1,
'no-implied-dirs' => 0,
'no-relative' => 0,
'numeric-ids' => 0,
'only-write-batch' => 1,
'partial' => 0,
'partial-dir' => 2,
'remove-sent-files' => $ro ? -1 : 0,
'safe-links' => 0,
'sender' => 0,
'server' => 0,
'size-only' => 0,
'suffix' => 1,
'temp-dir' => 2,
'timeout' => 1,
);
### END of options data produced by the cull_options script. ###
if ($short_disabled ne '') {
$short_no_arg =~ s/[$short_disabled]//go;
$short_with_num =~ s/[$short_disabled]//go;
}
push(@dirs, $subdir) unless @dirs;
$dir = join(' ', @dirs);
$short_no_arg = "[$short_no_arg]" if length($short_no_arg) > 1;
$short_with_num = "[$short_with_num]" if length($short_with_num) > 1;
if (-f LOGFILE and open LOG,'>>',LOGFILE) {
my $write_log = -f LOGFILE && open(LOG, '>>', LOGFILE);
chdir($subdir) or die "$0: Unable to chdir to restricted dir: $!\n";
my(@opts, @args);
my $in_options = 1;
my $last_opt = '';
my $check_type;
while ($command =~ /((?:[^\s\\]+|\\.[^\s\\]*)+)/g) {
$_ = $1;
if ($check_type) {
push(@opts, check_arg($last_opt, $_, $check_type));
$check_type = 0;
} elsif ($in_options) {
push(@opts, $_);
if ($_ eq '.') {
$in_options = 0;
} else {
next if /^-$short_no_arg+$/o || /^-$short_with_num\d+$/o;
my($opt,$arg) = /^--([^=]+)(?:=(.*))?$/;
my $disabled;
if (defined $opt) {
my $ct = $long_opt{$opt};
last unless defined $ct;
next if $ct == 0;
if ($ct > 0) {
if (!defined $arg) {
$check_type = $ct;
$last_opt = $opt;
next;
}
$arg = check_arg($opt, $arg, $ct);
$opts[-1] =~ s/=.*/=$arg/;
next;
}
$disabled = 1;
$opt = "--$opt";
} elsif ($short_disabled ne '') {
$disabled = /^-$short_no_arg*([$short_disabled])/o;
$opt = "-$1";
}
last unless $disabled; # Generate generic failure
die "$0: option $opt has been disabled on this server.\n";
}
} else {
if ($subdir ne '/') {
# Validate args to ensure they don't try to leave our restricted dir.
s#//+#/#g;
s#^/##;
s#^$#.#;
die "Do not use .. in any path!\n" if m#(^|/)\\?\.\\?\.(\\?/|$)#;
}
push(@args, bsd_glob($_, GLOB_LIMIT|GLOB_NOCHECK|GLOB_BRACE|GLOB_QUOTE));
}
}
die "$0: invalid rsync-command syntax or options\n" if $in_options;
@args = ( '.' ) if !@args;
if ($write_log) {
my ($mm,$hh) = (localtime)[1,2];
my $host = $ENV{SSH_CONNECTION} || 'unknown';
$host =~ s/ .*//; # Keep only the client's IP addr
$host =~ s/ .*//; # Keep only the client's IP addr
$host =~ s/^::ffff://;
$host = gethostbyaddr(inet_aton($host),AF_INET) || $host;
my $dir_result = $dir eq $orig ? " OK" : "> \"$dir\"";
printf LOG "%02d:%02d %-13s [%s] =%s\n", $hh, $mm, $host, $command, $dir_result;
printf LOG "%02d:%02d %-13s [%s]\n", $hh, $mm, $host, "@opts @args";
close LOG;
}
exec "$cmd \"$dir\"" or die "exec($cmd \"$dir\") failed: $? $!";
# Note: This assumes that the rsync protocol will not be maliciously hijacked.
exec(RSYNC, @opts, @args) or die "exec(rsync @opts @args) failed: $? $!";
sub check_arg
{
my($opt, $arg, $type) = @_;
$arg =~ s/\\(.)/$1/g;
if ($subdir ne '/' && ($type == 3 || ($type == 2 && !$am_sender))) {
$arg =~ s#//#/#g;
die "Do not use .. in --$opt; anchor the path at the root of your restricted dir.\n"
if $arg =~ m#(^|/)\.\.(/|$)#;
$arg =~ s#^/#$subdir/#;
}
$arg;
}

View File

@@ -12,7 +12,7 @@
use Getopt::Long;
# You may wish to edit the next line to customize for your default log file.
$usage_file = "/var/adm/rsyncd.log";
$usage_file = "/var/log/rsyncd.log";
# Edit the following lines for default report settings.
# Entries defined here will be over-ridden by the command line.

View File

@@ -7,20 +7,13 @@
* -o Save the output coming from PROGRAM to the OUTPUT_FILE
*
* If you want to capture the flow of data for an rsync command, use one of
* the following commands (the first two are push commands, the last two are
* pull commands):
* the following commands (the resulting files should be identical):
*
* rsync -av --rsh="savetransfer -i /tmp/from.sender ssh"
* --rsync-path="savetransfer -i /tmp/to.receiver rsync" FILES HOST:DEST
* rsync -av --rsh="savetransfer -i /tmp/to.server ssh"
* --rsync-path="savetransfer -i /tmp/from.client rsync" SOURCE DEST
*
* rsync -av --rsh="savetransfer -o /tmp/to.sender ssh"
* --rsync-path="savetransfer -o /tmp/from.generator rsync" FILES HOST:DEST
*
* rsync -av --rsh="savetransfer -i /tmp/from.generator ssh"
* --rsync-path="savetransfer -i /tmp/to.sender rsync" HOST:FILES DEST
*
* rsync -av --rsh="savetransfer -o /tmp/to.receiver ssh"
* --rsync-path="savetransfer -o /tmp/from.sender rsync" HOST:FILES DEST
* rsync -av --rsh="savetransfer -o /tmp/from.server ssh"
* --rsync-path="savetransfer -o /tmp/to.client rsync" SOURCE DEST
*
* Note that this program aborts after 30 seconds of inactivity, so you'll need
* to change it if that is not enough dead time for your transfer. Also, some

View File

@@ -45,14 +45,14 @@ extern int preserve_perms;
#define RETURN_ERROR_IF_RO_OR_LO RETURN_ERROR_IF(read_only || list_only, EROFS)
int do_unlink(char *fname)
int do_unlink(const char *fname)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
return unlink(fname);
}
int do_symlink(char *fname1, char *fname2)
int do_symlink(const char *fname1, const char *fname2)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
@@ -60,7 +60,7 @@ int do_symlink(char *fname1, char *fname2)
}
#ifdef HAVE_LINK
int do_link(char *fname1, char *fname2)
int do_link(const char *fname1, const char *fname2)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
@@ -104,7 +104,11 @@ int do_mknod(char *pathname, mode_t mode, dev_t dev)
|| (bind(sock, (struct sockaddr*)&saddr, sizeof saddr)) < 0)
return -1;
close(sock);
#ifdef HAVE_CHMOD
return do_chmod(pathname, mode);
#else
return 0;
#endif
}
#endif
#ifdef HAVE_MKNOD
@@ -114,14 +118,14 @@ int do_mknod(char *pathname, mode_t mode, dev_t dev)
#endif
}
int do_rmdir(char *pathname)
int do_rmdir(const char *pathname)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
return rmdir(pathname);
}
int do_open(char *pathname, int flags, mode_t mode)
int do_open(const char *pathname, int flags, mode_t mode)
{
if (flags != O_RDONLY) {
RETURN_ERROR_IF(dry_run, 0);
@@ -137,21 +141,27 @@ int do_chmod(const char *path, mode_t mode)
int code;
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
code = chmod(path, mode);
if (S_ISLNK(mode)) {
#ifdef HAVE_LCHMOD
code = lchmod(path, mode & CHMOD_BITS);
#else
code = 1;
#endif
} else
code = chmod(path, mode & CHMOD_BITS);
if (code != 0 && preserve_perms)
return code;
return 0;
}
#endif
int do_rename(char *fname1, char *fname2)
int do_rename(const char *fname1, const char *fname2)
{
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
return rename(fname1, fname2);
}
void trim_trailing_slashes(char *name)
{
int l;
@@ -170,7 +180,6 @@ void trim_trailing_slashes(char *name)
}
}
int do_mkdir(char *fname, mode_t mode)
{
if (dry_run) return 0;
@@ -179,7 +188,6 @@ int do_mkdir(char *fname, mode_t mode)
return mkdir(fname, mode);
}
/* like mkstemp but forces permissions */
int do_mkstemp(char *template, mode_t perms)
{
@@ -243,8 +251,12 @@ int do_fstat(int fd, STRUCT_STAT *st)
OFF_T do_lseek(int fd, OFF_T offset, int whence)
{
#if SIZEOF_OFF64_T
#ifdef HAVE_LSEEK64
#if !SIZEOF_OFF64_T
OFF_T lseek64();
#else
off64_t lseek64();
#endif
return lseek64(fd, offset, whence);
#else
return lseek(fd, offset, whence);

View File

@@ -28,6 +28,9 @@
int modify_window = 0;
int module_id = -1;
int relative_paths = 0;
int human_readable = 0;
mode_t orig_umask = 002;
char *partial_dir;
struct filter_list_struct server_filter_list;

View File

@@ -17,14 +17,14 @@ name2="$fromdir/name2"
outfile="$scratchdir/rsync.out"
cat $srcdir/[gr]*.[ch] > "$name1"
cat $srcdir/[et]*.[ch] > "$name2"
cat "$srcdir"/[gr]*.[ch] > "$name1"
cat "$srcdir"/[et]*.[ch] > "$name2"
checkit "$RSYNC -avv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
checkit "$RSYNC -avv \"$fromdir/\" \"$chkdir/\"" "$fromdir" "$chkdir"
cat $srcdir/[fgpr]*.[ch] > "$name1"
cat $srcdir/[etw]*.[ch] > "$name2"
cat "$srcdir"/[fgpr]*.[ch] > "$name1"
cat "$srcdir"/[etw]*.[ch] > "$name2"
$RSYNC -avv --no-whole-file --backup "$fromdir/" "$todir/" \
| tee "$outfile"
@@ -35,17 +35,22 @@ for fn in name1 name2; do
mv "$todir/$fn~" "$todir/$fn"
done
checkit "$RSYNC -avv --no-whole-file --backup --backup-dir=\"$bakdir\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
echo deleted-file >"$todir/dname"
cp -p "$todir/dname" "$chkdir"
checkit "$RSYNC -avv --no-whole-file --delete-after \
--backup --backup-dir=\"$bakdir\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
| tee "$outfile"
for fn in name1 name2; do
grep "backed up $fn to .*/$fn$" "$outfile" >/dev/null || test_fail "no backup message output for $fn"
done
diff -r $diffopt "$chkdir" "$bakdir" || test_fail "backup dir contents are bogus"
rm "$bakdir/dname"
checkit "$RSYNC -avv \"$fromdir/\" \"$chkdir/\"" "$fromdir" "$chkdir"
cat $srcdir/[efgr]*.[ch] > "$name1"
cat $srcdir/[ew]*.[ch] > "$name2"
checkit "$RSYNC -avv --del \"$fromdir/\" \"$chkdir/\"" "$fromdir" "$chkdir"
cat "$srcdir"/[efgr]*.[ch] > "$name1"
cat "$srcdir"/[ew]*.[ch] > "$name2"
checkit "$RSYNC -avv --inplace --no-whole-file --backup --backup-dir=\"$bakdir\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
| tee "$outfile"

View File

@@ -9,8 +9,6 @@
. "$suitedir/rsync.fns"
set -x
hands_setup
cd "$tmpdir"

View File

@@ -11,8 +11,6 @@
. "$suitedir/rsync.fns"
set -x
# Build some hardlinks
mygrps="`rsync_getgroups`" || fail "Can't get groups"

View File

@@ -0,0 +1,42 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that the --chmod option functions correctly.
. $srcdir/testsuite/rsync.fns
# Build some files
fromdir="$scratchdir/from"
todir="$scratchdir/to"
checkdir="$scratchdir/check"
mkdir "$fromdir"
name1="$fromdir/name1"
name2="$fromdir/name2"
dir1="$fromdir/dir1"
dir2="$fromdir/dir2"
echo "This is the file" > "$name1"
echo "This is the other file" > "$name2"
mkdir "$dir1" "$dir2"
chmod 4700 "$name1" || test_skipped "Can't chmod"
chmod 700 "$dir1"
chmod 770 "$dir2"
# Copy the files we've created over to another directory
checkit "$RSYNC -avv \"$fromdir/\" \"$checkdir/\"" "$fromdir" "$checkdir"
# And then manually make the changes which should occur
umask 002
chmod ug-s,a+rX "$checkdir"/*
chmod +w "$checkdir" "$checkdir"/dir*
checkit "$RSYNC -avv --chmod ug-s,a+rX,D+w \"$fromdir/\" \"$todir/\"" "$checkdir" "$todir"
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -2,7 +2,7 @@
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL see
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that various read-only and set[ug]id permissions work properly,
@@ -11,8 +11,6 @@
. "$suitedir/rsync.fns"
set -x
hands_setup
tmpdir2=/tmp

View File

@@ -2,7 +2,7 @@
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL see
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that various read-only and set[ug]id permissions work properly,
@@ -11,8 +11,6 @@
. "$suitedir/rsync.fns"
set -x
hands_setup
chmod 440 "$fromdir/text"

View File

@@ -13,8 +13,6 @@
. "$suitedir/rsync.fns"
set -x
case `id -u` in
'') ;; # If "id" failed, try to continue...
0) ;;

View File

@@ -2,7 +2,7 @@
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL see
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync handling of the --compare-dest option.
@@ -14,8 +14,6 @@ alt2dir="$tmpdir/alt2"
# Build some files/dirs/links to copy
set -x
hands_setup
# Setup the alt and chk dirs

View File

@@ -26,8 +26,6 @@ build_rsyncd_conf
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
export RSYNC_CONNECT_PROG
set -x
hands_setup
# Build chkdir with a normal rsync and an --exclude.

View File

@@ -20,8 +20,6 @@ build_rsyncd_conf
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
export RSYNC_CONNECT_PROG
set -x
hands_setup
# Build chkdir with a normal rsync and an --exclude.

View File

@@ -2,15 +2,13 @@
# Copyright (C) 2005 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL see
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync handling of various delete directives.
. "$suitedir/rsync.fns"
set -x
hands_setup
makepath "$chkdir"

View File

@@ -9,6 +9,9 @@
. "$suitedir/rsync.fns"
chkfile="$scratchdir/rsync.chk"
outfile="$scratchdir/rsync.out"
# Build some hardlinks
case `id -u` in
@@ -16,7 +19,7 @@ case `id -u` in
0) ;;
*) if [ -f /usr/bin/fakeroot ]; then
echo "Let's try re-running the script under fakeroot..."
exec /usr/bin/fakeroot /bin/sh "$0"
exec /usr/bin/fakeroot /bin/sh $RUNSHFLAGS "$0"
fi
test_skipped "Rsync won't copy devices unless we're root"
;;
@@ -25,15 +28,66 @@ esac
# TODO: Need to test whether hardlinks are possible on this OS/filesystem
mkdir "$fromdir"
mkdir "$todir"
mknod "$fromdir/char" c 41 67 || test_skipped "Can't create char device node unless root"
mknod "$fromdir/char2" c 42 68 || test_skipped "Can't create char device node unless root"
mknod "$fromdir/char3" c 42 69 || test_skipped "Can't create char device node unless root"
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node unless root"
mknod "$fromdir/block2" b 42 73 || test_skipped "Can't create block device node unless root"
mknod "$fromdir/block3" b 105 73 || test_skipped "Can't create block device node unless root"
ln "$fromdir/block3" "$fromdir/block2.5" || echo "Skipping hard-linked device test..."
mkfifo "$fromdir/fifo" || test_skipped "Can't run mkfifo"
touch -r "$fromdir/block" "$fromdir/block2"
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" skip_file_diff
$RSYNC -ai "$fromdir/block" "$todir/block2" \
| tee "$outfile"
cat <<EOT >"$chkfile"
cD+++++++ block
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
$RSYNC -ai "$fromdir/block2" "$todir/block" \
| tee "$outfile"
cat <<EOT >"$chkfile"
cD+++++++ block2
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
sleep 1
$RSYNC -Di "$fromdir/block3" "$todir/block" \
| tee "$outfile"
cat <<EOT >"$chkfile"
cD..T.... block3
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
$RSYNC -aiHvv "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
.d..t.... ./
cD..t.... block
cD....... block2
cD+++++++ block3
hD+++++++ block2.5 => block3
cD+++++++ char
cD+++++++ char2
cD+++++++ char3
cS+++++++ fifo
EOT
if test ! -b "$fromdir/block2.5"; then
sed -e '/block2\.5/d' \
<"$chkfile" >"$chkfile.new"
mv "$chkfile.new" "$chkfile"
fi
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
echo "check how the directory listings compare with diff:"
echo ""
( cd "$fromdir" && rsync_ls_lR . ) > "$tmpdir/ls-from"
( cd "$todir" && rsync_ls_lR . ) > "$tmpdir/ls-to"
diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to"
# The script would have aborted on error, so getting here means we've won.
exit 0

41
testsuite/dir-sgid.test Normal file
View File

@@ -0,0 +1,41 @@
#! /bin/sh
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that rsync obeys directory setgid. -- Matt McCutchen
. $srcdir/testsuite/rsync.fns
umask 077
# Call as: testit <dirname> <dirperms> <file-expected> <program-expected> <dir-expected>
testit() {
todir="$scratchdir/$1"
mkdir "$todir"
chmod $2 "$todir"
# Make sure we obey directory setgid when creating a directory to hold multiple transferred files,
# even though the directory itself is outside the transfer
$RSYNC -rvv "$scratchdir/dir" "$scratchdir/file" "$scratchdir/program" "$todir/to/"
check_perms "$todir/to" $5 "Target $1"
check_perms "$todir/to/dir" $5 "Target $1"
check_perms "$todir/to/file" $3 "Target $1"
check_perms "$todir/to/program" $4 "Target $1"
}
echo "File!" >"$scratchdir/file"
echo "#!/bin/sh" >"$scratchdir/program"
mkdir "$scratchdir/dir"
chmod 2764 "$scratchdir/dir" || test_skipped "Can't chmod"
chmod 664 "$scratchdir/file"
chmod 775 "$scratchdir/program"
[ -g "$scratchdir/dir" ] || test_skipped "The directory setgid bit vanished!"
mkdir "$scratchdir/dir/blah"
[ -g "$scratchdir/dir/blah" ] || test_skipped "Your filesystem doesn't use directory setgid; maybe it's BSD."
# Test some target directories
testit setgid-off 700 rw------- rwx------ rwx------
testit setgid-on 2700 rw------- rwx------ rwx--S---
# Hooray
exit 0

View File

@@ -2,7 +2,7 @@
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL see
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync handling of duplicate filenames.
@@ -21,8 +21,6 @@
. "$suitedir/rsync.fns"
set -x
# Build some hardlinks
mkdir "$fromdir"

View File

@@ -2,7 +2,7 @@
# Copyright (C) 2003, 2004, 2005 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL see
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync handling of exclude/include directives.
@@ -12,18 +12,18 @@
. "$suitedir/rsync.fns"
HOME="$scratchdir"
CVSIGNORE='*.junk'
export HOME CVSIGNORE
set -x
export CVSIGNORE
# Build some files/dirs/links to copy
makepath "$fromdir/foo/down/to/you"
makepath "$fromdir/foo/sub"
makepath "$fromdir/bar/down/to/foo/too"
makepath "$fromdir/bar/down/to/bar/baz"
makepath "$fromdir/mid/for/foo/and/that/is/who"
makepath "$fromdir/new/keep/this"
makepath "$fromdir/new/lose/this"
cat >"$fromdir/.filt" <<EOF
exclude down
: .filt-temp
@@ -32,13 +32,14 @@ clear
- *.bak
- *.old
EOF
echo kept >"$fromdir/foo/file1"
echo filtered-1 >"$fromdir/foo/file1"
echo removed >"$fromdir/foo/file2"
echo cvsout >"$fromdir/foo/file2.old"
cat >"$fromdir/foo/.filt" <<EOF
include .filt
- file1
- /file1
EOF
echo not-filtered-1 >"$fromdir/foo/sub/file1"
cat >"$fromdir/bar/.filt" <<EOF
- home-cvs-exclude
dir-merge .filt2
@@ -87,8 +88,12 @@ cat >"$excl" <<EOF
- /bar
# This should match against the whole path, not just the name.
+ foo**too
# This should float at the end of the path.
# These should float at the end of the path.
+ foo/s?b/
- foo/*/
# Test how /** differs from /***
- new/keep/**
- new/lose/***
# Test some normal excludes. Competing lines are paired.
+ t[o]/
- to
@@ -109,6 +114,8 @@ sleep 1 # Ensures that the rm commands will tweak the directory times.
rm -r "$chkdir"/foo/down
rm -r "$chkdir"/mid/for/foo/and
rm -r "$chkdir"/new/keep/this
rm -r "$chkdir"/new/lose
rm "$chkdir"/foo/file[235-9]
rm "$chkdir"/bar/down/to/foo/to "$chkdir"/bar/down/to/foo/file[235-9]
rm "$chkdir"/mid/for/foo/extra

View File

@@ -0,0 +1,47 @@
#! /bin/sh
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test the --executability or -E option. -- Matt McCutchen
. $srcdir/testsuite/rsync.fns
# Put some files in the From directory
mkdir "$fromdir"
cat <<EOF >"$fromdir/1"
#!/bin/sh
echo 'Program One!'
EOF
cat <<EOF >"$fromdir/2"
#!/bin/sh
echo 'Program Two!'
EOF
chmod 1700 "$fromdir/1" || test_skipped "Can't chmod"
chmod 600 "$fromdir/2"
$RSYNC -rvv "$fromdir/" "$todir/"
check_perms "$todir/1" rwx------ 1
check_perms "$todir/2" rw------- 1
# Mix up the permissions a bit
chmod 600 "$fromdir/1"
chmod 601 "$fromdir/2"
chmod 604 "$todir/2"
$RSYNC -rvv "$fromdir/" "$todir/"
# No -E, so nothing should have changed
check_perms "$todir/1" rwx------ 2
check_perms "$todir/2" rw----r-- 2
$RSYNC -rvvE "$fromdir/" "$todir/"
# Now things should have happened!
check_perms "$todir/1" rw------- 3
check_perms "$todir/2" rwx---r-x 3
# Hooray
exit 0

View File

@@ -2,15 +2,13 @@
# Copyright (C) 2005 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL see
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync handling of the --fuzzy option.
. "$suitedir/rsync.fns"
set -x
mkdir "$fromdir"
mkdir "$todir"

View File

@@ -20,7 +20,7 @@ rm "$todir/text"
runtest "one file" 'checkit "$RSYNC -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
echo "extra line" >> "$todir/text"
runtest "extra data" 'checkit "$RSYNC -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
runtest "extra data" 'checkit "$RSYNC -avH --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'
cp "$fromdir/text" "$todir/ThisShouldGo"
runtest " --delete" 'checkit "$RSYNC --delete -avH \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"'

View File

@@ -12,8 +12,6 @@
. "$suitedir/rsync.fns"
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
@@ -30,8 +28,34 @@ echo "This is the file" > "$name1"
ln "$name1" "$name2" || fail "Can't create hardlink"
ln "$name2" "$name3" || fail "Can't create hardlink"
cp "$name2" "$name4" || fail "Can't copy file"
cat $srcdir/*.c >"$fromdir/text"
checkit "$RSYNC -aHivv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
echo "extra extra" >>"$todir/name1"
checkit "$RSYNC -aHivv --no-whole-file \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
# Add a new link in a new subdirectory to test that we don't try to link
# the files before the directory gets created.
mkdir "$fromdir/subdir"
ln "$name1" "$fromdir/subdir/new-file"
rm "$todir/text"
checkit "$RSYNC -aHivv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
# Do some duplicate copies using --link-dest and --copy-dest to test that
# we hard-link all locally-inherited items.
checkit "$RSYNC -aHivv --link-dest=\"$todir\" \"$fromdir/\" \"$chkdir/\"" "$todir" "$chkdir"
rm -rf "$chkdir"
checkit "$RSYNC -aHivv --copy-dest=\"$todir\" \"$fromdir/\" \"$chkdir/\"" "$fromdir" "$chkdir"
# Make sure there's nothing wrong with sending a single file with -H
# enabled (this has broken twice so far, so we need this test).
rm -rf "$todir"
$RSYNC -aHivv "$name1" "$todir/"
diff $diffopt "$name1" "$todir" || test_fail "solo copy of name1 failed"
# The script would have aborted on error, so getting here means we've won.
exit 0

271
testsuite/itemize.test Normal file
View File

@@ -0,0 +1,271 @@
#! /bin/sh
# Copyright (C) 2005 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test the output of various copy commands to ensure itemized output
# and double-verbose output is correct.
. "$suitedir/rsync.fns"
lddir="$tmpdir/ld"
chkfile="$scratchdir/rsync.chk"
outfile="$scratchdir/rsync.out"
makepath "$fromdir/foo"
makepath "$fromdir/bar/baz"
cp -p "$srcdir/configure.in" "$fromdir/foo/config1"
cp -p "$srcdir/config.h.in" "$fromdir/foo/config2"
cp -p "$srcdir/rsync.h" "$fromdir/bar/baz/rsync"
chmod 600 "$fromdir"/foo/config? "$fromdir/bar/baz/rsync"
umask 0
ln -s ../bar/baz/rsync "$fromdir/foo/sym"
umask 022
ln "$fromdir/foo/config1" "$fromdir/foo/extra"
$RSYNC -iplr "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
cd+++++++ bar/
cd+++++++ bar/baz/
>f+++++++ bar/baz/rsync
cd+++++++ foo/
>f+++++++ foo/config1
>f+++++++ foo/config2
>f+++++++ foo/extra
cL+++++++ foo/sym -> ../bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed"
# Ensure there are no accidental directory-time problems.
$RSYNC -a -f '-! */' "$fromdir/" "$todir"
cp -p "$srcdir/configure.in" "$fromdir/foo/config2"
chmod 601 "$fromdir/foo/config2"
$RSYNC -iplrH "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
>f..T.... bar/baz/rsync
>f..T.... foo/config1
>f.sTp... foo/config2
hf..T.... foo/extra => foo/config1
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed"
$RSYNC -a -f '-! */' "$fromdir/" "$todir"
sleep 1 # For directory mod below to ensure time difference
rm "$todir/foo/sym"
umask 0
ln -s ../bar/baz "$todir/foo/sym"
umask 022
cp -p "$srcdir/config.h.in" "$fromdir/foo/config2"
chmod 600 "$fromdir/foo/config2"
chmod 777 "$todir/bar/baz/rsync"
$RSYNC -iplrtc "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
.f..tp... bar/baz/rsync
.d..t.... foo/
.f..t.... foo/config1
>fcstp... foo/config2
cL..T.... foo/sym -> ../bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed"
cp -p "$srcdir/configure.in" "$fromdir/foo/config2"
chmod 600 "$fromdir/foo/config2"
# Lack of -t is for unchanged hard-link stress-test!
$RSYNC -vvplrH "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
bar/baz/rsync is uptodate
foo/config1 is uptodate
foo/config2
"foo/extra" is a hard link
foo/sym is uptodate
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed"
chmod 747 "$todir/bar/baz/rsync"
$RSYNC -a -f '-! */' "$fromdir/" "$todir"
$RSYNC -ivvplrtH "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
.d ./
.d bar/
.d bar/baz/
.f...p... bar/baz/rsync
.d foo/
.f foo/config1
>f..t.... foo/config2
hf foo/extra
.L foo/sym -> ../bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed"
chmod 757 "$todir/foo/config1"
touch "$todir/foo/config2"
$RSYNC -vplrtH "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
foo/config2
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 6 failed"
chmod 757 "$todir/foo/config1"
touch "$todir/foo/config2"
$RSYNC -iplrtH "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
.f...p... foo/config1
>f..t.... foo/config2
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 7 failed"
mv "$todir" "$lddir"
$RSYNC -ivvplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
.d..t.... ./
cd+++++++ bar/
cd+++++++ bar/baz/
cf bar/baz/rsync
cd+++++++ foo/
cf foo/config1
cf foo/config2
hf foo/extra => foo/config1
cL..T.... foo/sym -> ../bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 8 failed"
rm -rf "$todir"
$RSYNC -iplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
.d..t.... ./
cd+++++++ bar/
cd+++++++ bar/baz/
cd+++++++ foo/
hf foo/extra => foo/config1
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 9 failed"
rm -rf "$todir"
$RSYNC -vvplrtH --copy-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
./
bar/
bar/baz/
bar/baz/rsync is uptodate
foo/
foo/config1 is uptodate
foo/config2 is uptodate
"foo/extra" is a hard link
foo/extra => foo/config1
foo/sym is uptodate
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 10 failed"
rm -rf "$todir"
$RSYNC -ivvplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
.d..t.... ./
cd+++++++ bar/
cd+++++++ bar/baz/
hf bar/baz/rsync
cd+++++++ foo/
hf foo/config1
hf foo/config2
hf foo/extra => foo/config1
hL foo/sym -> ../bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 11 failed"
rm -rf "$todir"
$RSYNC -iplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
.d..t.... ./
cd+++++++ bar/
cd+++++++ bar/baz/
cd+++++++ foo/
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 12 failed"
rm -rf "$todir"
$RSYNC -vvplrtH --link-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
./
bar/
bar/baz/
bar/baz/rsync is uptodate
foo/
foo/config1 is uptodate
foo/config2 is uptodate
"foo/extra" is a hard link
foo/sym is uptodate
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 13 failed"
rm -rf "$todir"
$RSYNC -ivvplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
# TODO fix really-old problem when combining -H with --compare-dest:
# missing output for foo/extra hard-link (and it might not be updated)!
cat <<EOT >"$chkfile"
.d..t.... ./
cd+++++++ bar/
cd+++++++ bar/baz/
.f bar/baz/rsync
cd+++++++ foo/
.f foo/config1
.f foo/config2
.L foo/sym -> ../bar/baz/rsync
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 14 failed"
rm -rf "$todir"
$RSYNC -iplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
cat <<EOT >"$chkfile"
.d..t.... ./
cd+++++++ bar/
cd+++++++ bar/baz/
cd+++++++ foo/
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 15 failed"
rm -rf "$todir"
$RSYNC -vvplrtH --compare-dest="$lddir" "$fromdir/" "$todir/" \
| tee "$outfile"
filter_outfile
cat <<EOT >"$chkfile"
./
bar/
bar/baz/
bar/baz/rsync is uptodate
foo/
foo/config1 is uptodate
foo/config2 is uptodate
"foo/extra" is a hard link
foo/sym is uptodate
EOT
diff $diffopt "$chkfile" "$outfile" || test_fail "test 16 failed"
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -7,8 +7,6 @@
. "$suitedir/rsync.fns"
set -x
hands_setup
longname=This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job

View File

@@ -9,8 +9,6 @@
. "$suitedir/rsync.fns"
set -x
# Build some files/dirs/links to copy
from1dir="${fromdir}1"

39
testsuite/relative.test Normal file
View File

@@ -0,0 +1,39 @@
#!/bin/sh
# Copyright (C) 2005 by Wayne Davison <wayned@samba.org>
#
# This program is distributable under the terms of the GNU GPL (see COPYING)
. "$suitedir/rsync.fns"
deepstr='down/3/deep'
deepdir="$fromdir/$deepstr"
mkdir -p "$deepdir"
fromdir="$deepdir"
hands_setup
fromdir="$tmpdir/from"
outfile="$scratchdir/rsync.out"
cd "$fromdir"
# Main script starts here
echo "$fromdir"
runtest "basic relative" 'checkit "$RSYNC -avR ./$deepstr \"$todir\"" "$fromdir/" "$todir"'
ln "$deepdir/filelist" "$deepdir/dir"
runtest "hard links" 'checkit "$RSYNC -avHR ./$deepstr/ \"$todir\"" "$fromdir/" "$todir"'
cp "$deepdir/text" "$todir/$deepstr/ThisShouldGo"
cp "$deepdir/text" "$todir/$deepstr/dir/ThisShouldGoToo"
runtest "deletion" 'checkit "$RSYNC -avHR --delete ./$deepstr/ \"$todir\"" "$fromdir/" "$todir"'
runtest "non-deletion" 'checkit "$RSYNC -aiHR --delete ./$deepstr/ \"$todir\"" "$fromdir/" "$todir"' \
| tee "$outfile"
# Make sure no files were deleted
grep 'deleting ' "$outfile" && test_fail "Erroneous deletions occurred!"
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -32,6 +32,9 @@ else
diffopt="-c"
fi
HOME="$scratchdir"
export HOME
runtest() {
echo $ECHO_N "Test $1: $ECHO_C"
if eval "$2"
@@ -44,15 +47,38 @@ runtest() {
fi
}
# Call this if you want to filter out verbose messages (-v or -vv) from
# the output of an rsync run (whittling the output down to just the file
# messages). This isn't needed if you use -i without -v.
filter_outfile() {
sed -e '/^building file list /d' \
-e '/^created directory /d' \
-e '/^done$/d' \
-e '/ --whole-file$/d' \
-e '/^total: /d' \
-e '/^$/,$d' \
<"$outfile" >"$outfile.new"
mv "$outfile.new" "$outfile"
}
printmsg() {
echo "$1"
}
rsync_ls_lR() {
find "$@" -print | sort | sed 's/ /\\ /g' | xargs "$TOOLDIR/tls"
}
check_perms() {
perms=`"$TOOLDIR/tls" "$1" | sed 's/^[-d]\(.........\).*/\1/'`
if test $perms = $2; then
return 0
fi
echo "permissions: $perms on $1"
echo "should be: $2"
test_fail "failed test $3"
}
rsync_getgroups() {
"$TOOLDIR/getgroups"
}
@@ -92,7 +118,7 @@ hands_setup() {
ln -s nolf "$fromdir/nolf-symlink"
umask 022
cat $srcdir/*.c > "$fromdir/text"
cat "$srcdir"/*.c > "$fromdir/text"
mkdir "$fromdir/dir"
cp "$fromdir/text" "$fromdir/dir"
mkdir "$fromdir/dir/subdir"
@@ -118,7 +144,7 @@ hands_setup() {
####################
# Many machines do not have "mkdir -p", so we have to build up long paths.
# How boring.
makepath () {
makepath() {
echo " makepath $1"
p="$1"
(

View File

@@ -10,8 +10,6 @@
. "$suitedir/rsync.fns"
set -x
build_symlinks || test_fail "failed to build symlinks"
# Copy recursively, but without -l or -L or -a, and all the symlinks

View File

@@ -9,8 +9,6 @@
. "$suitedir/rsync.fns"
set -x
"$TOOLDIR/trimslash" "/usr/local/bin" "/usr/local/bin/" "/usr/local/bin///" \
"//a//" "////" \
"/Users/Wierd Macintosh Name/// Ooh, translucent plastic/" \

View File

@@ -32,8 +32,6 @@ ln -s ../files/file1 "from/safe/links/"
ln -s ../files/file2 "from/safe/links/"
ln -s ../../unsafe/unsafefile "from/safe/links/"
set -x
echo "rsync with relative path and just -a";
$RSYNC -avv from/safe/ to
test_symlink to/links/file1

View File

@@ -9,12 +9,15 @@
. "$suitedir/rsync.fns"
set -x
"$TOOLDIR/wildtest" "$srcdir/wildtest.txt" >"$scratchdir/wild.out"
diff $diffopt "$scratchdir/wild.out" - <<EOF
# This test exercises the wildmatch() function (with no options) and the
# wildmatch_join() function (using -x and/or -e).
for opts in "" -x1 "-x1 -e1" "-x1 -e1se" -x2 "-x2 -ese" -x3 "-x3 -e1" -x4 "-x4 -e2e" -x5 "-x5 -es"; do
echo Running wildtest with "$opts"
"$TOOLDIR/wildtest" $opts "$srcdir/wildtest.txt" >"$scratchdir/wild.out"
diff $diffopt "$scratchdir/wild.out" - <<EOF
No wildmatch errors found.
EOF
done
# The script would have aborted on error, so getting here means we've won.
exit 0

12
tls.c
View File

@@ -100,12 +100,12 @@ static void list_file(const char *fname)
mt = gmtime(&buf.st_mtime);
sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
mt->tm_year + 1900,
mt->tm_mon + 1,
mt->tm_mday,
mt->tm_hour,
mt->tm_min,
mt->tm_sec);
(int)mt->tm_year + 1900,
(int)mt->tm_mon + 1,
(int)mt->tm_mday,
(int)mt->tm_hour,
(int)mt->tm_min,
(int)mt->tm_sec);
} else {
strcpy(datebuf, " ");
}

58
token.c
View File

@@ -22,46 +22,60 @@
extern int do_compression;
extern int module_id;
extern int def_compress_level;
static int compression_level = Z_DEFAULT_COMPRESSION;
static int compression_level, per_file_default_level;
/* determine the compression level based on a wildcard filename list */
void set_compression(char *fname)
{
char *dont;
char *tok;
static char *match_list;
char *s;
if (!do_compression)
return;
compression_level = Z_DEFAULT_COMPRESSION;
dont = lp_dont_compress(module_id);
if (!dont || !*dont)
return;
if (dont[0] == '*' && !dont[1]) {
/* an optimization to skip the rest of this routine */
compression_level = 0;
return;
if (!match_list) {
char *t, *f = lp_dont_compress(module_id);
int len = strlen(f);
if (!(match_list = t = new_array(char, len + 2)))
out_of_memory("set_compression");
while (*f) {
if (*f == ' ') {
f++;
continue;
}
do {
if (isupper(*(unsigned char *)f))
*t++ = tolower(*(unsigned char *)f);
else
*t++ = *f;
} while (*++f != ' ' && *f);
*t++ = '\0';
}
/* Optimize a match-string of "*". */
if (t - match_list == 2 && match_list[0] == '*') {
t = match_list;
per_file_default_level = 0;
} else
per_file_default_level = def_compress_level;
*t++ = '\0';
}
dont = strdup(dont);
fname = strdup(fname);
if (!dont || !fname)
compression_level = per_file_default_level;
if (!*match_list)
return;
strlower(dont);
strlower(fname);
if ((s = strrchr(fname, '/')) != NULL)
fname = s + 1;
for (tok = strtok(dont, " "); tok; tok = strtok(NULL, " ")) {
if (wildmatch(tok, fname)) {
for (s = match_list; *s; s += strlen(s) + 1) {
if (iwildmatch(s, fname)) {
compression_level = 0;
break;
}
}
free(dont);
free(fname);
}
/* non-compressing recv token */

View File

@@ -324,7 +324,6 @@ void recv_uid_list(int f, struct file_list *flist)
}
}
if (preserve_gid && !numeric_ids) {
/* read the gid list */
while ((id = read_int(f)) != 0) {
@@ -337,8 +336,7 @@ void recv_uid_list(int f, struct file_list *flist)
}
}
/* now convert the uid/gid of all files in the list to the mapped
* uid/gid */
/* Now convert all the uids/gids from sender values to our values. */
if (am_root && preserve_uid && !numeric_ids) {
for (i = 0; i < flist->count; i++)
flist->files[i]->uid = match_uid(flist->files[i]->uid);

332
util.c
View File

@@ -31,6 +31,9 @@ extern int verbose;
extern int dry_run;
extern int module_id;
extern int modify_window;
extern int relative_paths;
extern int human_readable;
extern mode_t orig_umask;
extern char *partial_dir;
extern struct filter_list_struct server_filter_list;
@@ -68,7 +71,6 @@ void set_blocking(int fd)
}
}
/**
* Create a file descriptor pair - like pipe() but use socketpair if
* possible (because of blocking issues on pipes).
@@ -93,7 +95,6 @@ int fd_pair(int fd[2])
return ret;
}
void print_child_argv(char **cmd)
{
rprintf(FINFO, "opening connection using ");
@@ -105,34 +106,36 @@ void print_child_argv(char **cmd)
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789"
",.-_=+@/") != strlen(*cmd)) {
rprintf(FINFO, "\"%s\" ", safe_fname(*cmd));
rprintf(FINFO, "\"%s\" ", *cmd);
} else {
rprintf(FINFO, "%s ", safe_fname(*cmd));
rprintf(FINFO, "%s ", *cmd);
}
}
rprintf(FINFO, "\n");
}
void out_of_memory(char *str)
{
rprintf(FERROR, "ERROR: out of memory in %s\n", str);
exit_cleanup(RERR_MALLOC);
}
void overflow(char *str)
void overflow_exit(char *str)
{
rprintf(FERROR, "ERROR: buffer overflow in %s\n", str);
exit_cleanup(RERR_MALLOC);
}
int set_modtime(char *fname, time_t modtime)
int set_modtime(char *fname, time_t modtime, mode_t mode)
{
#if !defined HAVE_LUTIMES || !defined HAVE_UTIMES
if (S_ISLNK(mode))
return 1;
#endif
if (verbose > 2) {
rprintf(FINFO, "set modtime of %s to (%ld) %s",
safe_fname(fname), (long)modtime,
fname, (long)modtime,
asctime(localtime(&modtime)));
}
@@ -140,7 +143,18 @@ int set_modtime(char *fname, time_t modtime)
return 0;
{
#ifdef HAVE_UTIMBUF
#ifdef HAVE_UTIMES
struct timeval t[2];
t[0].tv_sec = time(NULL);
t[0].tv_usec = 0;
t[1].tv_sec = modtime;
t[1].tv_usec = 0;
# ifdef HAVE_LUTIMES
if (S_ISLNK(mode))
return lutimes(fname, t);
# endif
return utimes(fname, t);
#elif defined HAVE_UTIMBUF
struct utimbuf tbuf;
tbuf.actime = time(NULL);
tbuf.modtime = modtime;
@@ -151,41 +165,49 @@ int set_modtime(char *fname, time_t modtime)
t[1] = modtime;
return utime(fname,t);
#else
struct timeval t[2];
t[0].tv_sec = time(NULL);
t[0].tv_usec = 0;
t[1].tv_sec = modtime;
t[1].tv_usec = 0;
return utimes(fname,t);
#error No file-time-modification routine found!
#endif
}
}
/* This creates a new directory with default permissions. Since there
* might be some directory-default permissions affecting this, we can't
* force the permissions directly using the original umask and mkdir(). */
int mkdir_defmode(char *fname)
{
int ret;
/**
Create any necessary directories in fname. Unfortunately we don't know
what perms to give the directory when this is called so we need to rely
on the umask
**/
int create_directory_path(char *fname, int base_umask)
umask(orig_umask);
ret = do_mkdir(fname, ACCESSPERMS);
umask(0);
return ret;
}
/* Create any necessary directories in fname. Any missing directories are
* created with default permissions. */
int create_directory_path(char *fname)
{
char *p;
int ret = 0;
while (*fname == '/')
fname++;
while (strncmp(fname, "./", 2) == 0)
fname += 2;
umask(orig_umask);
p = fname;
while ((p = strchr(p,'/')) != NULL) {
*p = 0;
do_mkdir(fname, 0777 & ~base_umask);
*p = '/';
p++;
*p = '\0';
if (do_mkdir(fname, ACCESSPERMS) < 0 && errno != EEXIST)
ret = -1;
*p++ = '/';
}
return 0;
}
umask(0);
return ret;
}
/**
* Write @p len bytes at @p ptr to descriptor @p desc, retrying if
@@ -216,7 +238,6 @@ int full_write(int desc, char *ptr, size_t len)
return total_written;
}
/**
* Read @p len bytes at @p ptr from descriptor @p desc, retrying if
* interrupted.
@@ -242,12 +263,11 @@ static int safe_read(int desc, char *ptr, size_t len)
return n_chars;
}
/** Copy a file.
*
* This is used in conjunction with the --temp-dir, --backup, and
* --copy-dest options. */
int copy_file(char *source, char *dest, mode_t mode)
int copy_file(const char *source, const char *dest, mode_t mode)
{
int ifd;
int ofd;
@@ -316,7 +336,7 @@ int copy_file(char *source, char *dest, mode_t mode)
* --delete trying to remove old .rsyncNNN files, hence it renames it
* each time.
**/
int robust_unlink(char *fname)
int robust_unlink(const char *fname)
{
#ifndef ETXTBSY
return do_unlink(fname);
@@ -351,7 +371,7 @@ int robust_unlink(char *fname)
if (verbose > 0) {
rprintf(FINFO,"renaming %s to %s because of text busy\n",
safe_fname(fname), safe_fname(path));
fname, path);
}
/* maybe we should return rename()'s exit status? Nah. */
@@ -364,8 +384,11 @@ int robust_unlink(char *fname)
}
/* Returns 0 on successful rename, 1 if we successfully copied the file
* across filesystems, -2 if copy_file() failed, and -1 on other errors. */
int robust_rename(char *from, char *to, int mode)
* across filesystems, -2 if copy_file() failed, and -1 on other errors.
* If partialptr is not NULL and we need to do a copy, copy the file into
* the active partial-dir instead of over the destination file. */
int robust_rename(char *from, char *to, char *partialptr,
int mode)
{
int tries = 4;
@@ -381,6 +404,11 @@ int robust_rename(char *from, char *to, int mode)
break;
#endif
case EXDEV:
if (partialptr) {
if (!handle_partial_dir(partialptr,PDIR_CREATE))
return -1;
to = partialptr;
}
if (copy_file(from, to, mode) != 0)
return -2;
do_unlink(from);
@@ -392,7 +420,6 @@ int robust_rename(char *from, char *to, int mode)
return -1;
}
static pid_t all_pids[10];
static int num_pids;
@@ -436,7 +463,6 @@ void kill_all(int sig)
}
}
/** Turn a user name into a uid */
int name_to_uid(char *name, uid_t *uid)
{
@@ -465,7 +491,6 @@ int name_to_gid(char *name, gid_t *gid)
return 0;
}
/** Lock a byte range in a open file */
int lock_range(int fd, int offset, int len)
{
@@ -517,7 +542,6 @@ static void glob_expand_one(char *s, char ***argv_ptr, int *argc_ptr,
filter_server_path(s);
#else
glob_t globbuf;
int i;
if (maxargs <= argc)
return;
@@ -542,9 +566,9 @@ static void glob_expand_one(char *s, char ***argv_ptr, int *argc_ptr,
if (globbuf.gl_pathc == 0)
argv[argc++] = s;
else {
int j = globbuf.gl_pathc;
int i;
free(s);
for (i = 0; i < j; i++) {
for (i = 0; i < (int)globbuf.gl_pathc; i++) {
if (!(argv[argc++] = strdup(globbuf.gl_pathv[i])))
out_of_memory("glob_expand_one");
}
@@ -745,7 +769,7 @@ unsigned int clean_fname(char *name, BOOL collapse_dot_dot)
char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
{
char *start, *sanp;
int rlen = 0;
int rlen = 0, leave_one_dotdir = relative_paths;
if (dest != p) {
int plen = strlen(p);
@@ -780,9 +804,13 @@ char *sanitize_path(char *dest, const char *p, const char *rootdir, int depth)
* always be left pointing after a slash
*/
if (*p == '.' && (p[1] == '/' || p[1] == '\0')) {
/* skip "." component */
p++;
continue;
if (leave_one_dotdir && p[1])
leave_one_dotdir = 0;
else {
/* skip "." component */
p++;
continue;
}
}
if (*p == '.' && p[1] == '.' && (p[2] == '/' || p[2] == '\0')) {
/* ".." component followed by slash or end */
@@ -877,33 +905,6 @@ int pop_dir(char *dir)
return 1;
}
/* Return the filename, turning any non-printable characters into '?'s.
* This ensures that outputting it on a line of its own cannot generate an
* empty line. This function can return only MAX_SAFE_NAMES values at a
* time! The returned value can be longer than MAXPATHLEN (because we
* may be trying to output an error about a too-long filename)! */
const char *safe_fname(const char *fname)
{
#define MAX_SAFE_NAMES 4
static char fbuf[MAX_SAFE_NAMES][MAXPATHLEN*2];
static int ndx = 0;
int limit = sizeof fbuf / MAX_SAFE_NAMES - 1;
char *t;
ndx = (ndx + 1) % MAX_SAFE_NAMES;
for (t = fbuf[ndx]; *fname; fname++) {
if (!isprint(*(uchar*)fname))
*t++ = '?';
else
*t++ = *fname;
if (--limit == 0)
break;
}
*t = '\0';
return fbuf[ndx];
}
/**
* Return a quoted string with the full pathname of the indicated filename.
* The string " (in MODNAME)" may also be appended. The returned pointer
@@ -918,7 +919,6 @@ char *full_fname(const char *fn)
if (result)
free(result);
fn = safe_fname(fn);
if (*fn == '/')
p1 = p2 = "";
else {
@@ -1013,22 +1013,6 @@ int handle_partial_dir(const char *fname, int create)
return 1;
}
/** We need to supply our own strcmp function for file list comparisons
to ensure that signed/unsigned usage is consistent between machines. */
int u_strcmp(const char *cs1, const char *cs2)
{
const uchar *s1 = (const uchar *)cs1;
const uchar *s2 = (const uchar *)cs2;
while (*s1 && *s2 && (*s1 == *s2)) {
s1++; s2++;
}
return (int)*s1 - (int)*s2;
}
/**
* Determine if a symlink points outside the current directory tree.
* This is considered "unsafe" because e.g. when mirroring somebody
@@ -1093,6 +1077,63 @@ int unsafe_symlink(const char *dest, const char *src)
return (depth < 0);
}
/* Return the int64 number as a string. If the --human-readable option was
* specified, we may output the number in K, M, or G units. We can return
* up to 4 buffers at a time. */
char *human_num(int64 num)
{
static char bufs[4][128]; /* more than enough room */
static unsigned int n;
char *s;
n = (n + 1) % (sizeof bufs / sizeof bufs[0]);
if (human_readable) {
char units = '\0';
int mult = human_readable == 1 ? 1000 : 1024;
double dnum = 0;
if (num > mult*mult*mult) {
dnum = (double)num / (mult*mult*mult);
units = 'G';
} else if (num > mult*mult) {
dnum = (double)num / (mult*mult);
units = 'M';
} else if (num > mult) {
dnum = (double)num / mult;
units = 'K';
}
if (units) {
sprintf(bufs[n], "%.2f%c", dnum, units);
return bufs[n];
}
}
s = bufs[n] + sizeof bufs[0] - 1;
*s = '\0';
if (!num)
*--s = '0';
while (num) {
*--s = (num % 10) + '0';
num /= 10;
}
return s;
}
/* Return the double number as a string. If the --human-readable option was
* specified, we may output the number in K, M, or G units. We use a buffer
* from human_num() to return our result. */
char *human_dnum(double dnum, int decimal_digits)
{
char *buf = human_num(dnum);
int len = strlen(buf);
if (isdigit(*(uchar*)(buf+len-1))) {
/* There's extra room in buf prior to the start of the num. */
buf -= decimal_digits + 1;
snprintf(buf, len + decimal_digits + 2, "%.*f", decimal_digits, dnum);
}
return buf;
}
/**
* Return the date and time as a string
@@ -1101,6 +1142,7 @@ char *timestring(time_t t)
{
static char TimeBuf[200];
struct tm *tm = localtime(&t);
char *p;
#ifdef HAVE_STRFTIME
strftime(TimeBuf, sizeof TimeBuf - 1, "%Y/%m/%d %H:%M:%S", tm);
@@ -1108,14 +1150,12 @@ char *timestring(time_t t)
strlcpy(TimeBuf, asctime(tm), sizeof TimeBuf);
#endif
if (TimeBuf[strlen(TimeBuf)-1] == '\n') {
TimeBuf[strlen(TimeBuf)-1] = 0;
}
if ((p = strchr(TimeBuf, '\n')) != NULL)
*p = '\0';
return(TimeBuf);
return TimeBuf;
}
/**
* Sleep for a specified number of milliseconds.
*
@@ -1144,11 +1184,8 @@ int msleep(int t)
return True;
}
/**
* Determine if two file modification times are equivalent (either
* exact or in the modification timestamp window established by
* --modify-window).
/* Determine if two time_t values are equivalent (either exact, or in
* the modification timestamp window established by --modify-window).
*
* @retval 0 if the times should be treated as the same
*
@@ -1156,7 +1193,7 @@ int msleep(int t)
*
* @retval -1 if the 2nd is later
**/
int cmp_modtime(time_t file1, time_t file2)
int cmp_time(time_t file1, time_t file2)
{
if (file2 > file1) {
if (file2 - file1 <= modify_window)
@@ -1202,7 +1239,6 @@ int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
}
#endif
#define MALLOC_MAX 0x40000000
void *_new_array(unsigned int size, unsigned long num)
@@ -1328,3 +1364,95 @@ uint32 fuzzy_distance(const char *s1, int len1, const char *s2, int len2)
return a[len2-1];
}
#define BB_SLOT_SIZE (16*1024) /* Desired size in bytes */
#define BB_PER_SLOT_BITS (BB_SLOT_SIZE * 8) /* Number of bits per slot */
#define BB_PER_SLOT_INTS (BB_SLOT_SIZE / 4) /* Number of int32s per slot */
struct bitbag {
uint32 **bits;
int slot_cnt;
};
struct bitbag *bitbag_create(int max_ndx)
{
struct bitbag *bb = new(struct bitbag);
bb->slot_cnt = (max_ndx + BB_PER_SLOT_BITS - 1) / BB_PER_SLOT_BITS;
if (!(bb->bits = (uint32**)calloc(bb->slot_cnt, sizeof (uint32*))))
out_of_memory("bitbag_create");
return bb;
}
void bitbag_set_bit(struct bitbag *bb, int ndx)
{
int slot = ndx / BB_PER_SLOT_BITS;
ndx %= BB_PER_SLOT_BITS;
if (!bb->bits[slot]) {
if (!(bb->bits[slot] = (uint32*)calloc(BB_PER_SLOT_INTS, 4)))
out_of_memory("bitbag_set_bit");
}
bb->bits[slot][ndx/32] |= 1u << (ndx % 32);
}
#if 0 /* not needed yet */
void bitbag_clear_bit(struct bitbag *bb, int ndx)
{
int slot = ndx / BB_PER_SLOT_BITS;
ndx %= BB_PER_SLOT_BITS;
if (!bb->bits[slot])
return;
bb->bits[slot][ndx/32] &= ~(1u << (ndx % 32));
}
int bitbag_check_bit(struct bitbag *bb, int ndx)
{
int slot = ndx / BB_PER_SLOT_BITS;
ndx %= BB_PER_SLOT_BITS;
if (!bb->bits[slot])
return 0;
return bb->bits[slot][ndx/32] & (1u << (ndx % 32)) ? 1 : 0;
}
#endif
/* Call this with -1 to start checking from 0. Returns -1 at the end. */
int bitbag_next_bit(struct bitbag *bb, int after)
{
uint32 bits, mask;
int i, ndx = after + 1;
int slot = ndx / BB_PER_SLOT_BITS;
ndx %= BB_PER_SLOT_BITS;
mask = (1u << (ndx % 32)) - 1;
for (i = ndx / 32; slot < bb->slot_cnt; slot++, i = mask = 0) {
if (!bb->bits[slot])
continue;
for ( ; i < BB_PER_SLOT_INTS; i++, mask = 0) {
if (!(bits = bb->bits[slot][i] & ~mask))
continue;
/* The xor magic figures out the lowest enabled bit in
* bits, and the switch quickly computes log2(bit). */
switch (bits ^ (bits & (bits-1))) {
#define LOG2(n) case 1u << n: return slot*BB_PER_SLOT_BITS + i*32 + n
LOG2(0); LOG2(1); LOG2(2); LOG2(3);
LOG2(4); LOG2(5); LOG2(6); LOG2(7);
LOG2(8); LOG2(9); LOG2(10); LOG2(11);
LOG2(12); LOG2(13); LOG2(14); LOG2(15);
LOG2(16); LOG2(17); LOG2(18); LOG2(19);
LOG2(20); LOG2(21); LOG2(22); LOG2(23);
LOG2(24); LOG2(25); LOG2(26); LOG2(27);
LOG2(28); LOG2(29); LOG2(30); LOG2(31);
}
return -1; /* impossible... */
}
}
return -1;
}

View File

@@ -7,7 +7,7 @@
#define WILD_TEST_ITERATIONS
#include "lib/wildmatch.c"
#include "popt.h"
#include <popt.h>
#ifdef COMPARE_WITH_FNMATCH
#include <fnmatch.h>
@@ -20,10 +20,16 @@ int wildmatch_errors = 0;
typedef char bool;
int output_iterations = 0;
int explode_mod = 0;
int empties_mod = 0;
int empty_at_start = 0;
int empty_at_end = 0;
static struct poptOption long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
{"iterations", 'i', POPT_ARG_NONE, &output_iterations, 0, 0, 0},
{"empties", 'e', POPT_ARG_STRING, 0, 'e', 0, 0},
{"explode", 'x', POPT_ARG_INT, &explode_mod, 0, 0, 0},
{0,0,0,0, 0, 0, 0}
};
@@ -40,7 +46,28 @@ run_test(int line, bool matches, bool same_as_fnmatch,
same_as_fnmatch = 0; /* Get rid of unused-variable compiler warning. */
#endif
matched = wildmatch(pattern, text);
if (explode_mod) {
char buf[MAXPATHLEN*2], *texts[MAXPATHLEN];
int pos = 0, cnt = 0, ndx = 0, len = strlen(text);
if (empty_at_start)
texts[ndx++] = "";
/* An empty string must turn into at least one empty array item. */
while (1) {
texts[ndx] = buf + ndx * (explode_mod + 1);
strlcpy(texts[ndx++], text + pos, explode_mod + 1);
if (pos + explode_mod >= len)
break;
pos += explode_mod;
if (!(++cnt % empties_mod))
texts[ndx++] = "";
}
if (empty_at_end)
texts[ndx++] = "";
texts[ndx] = NULL;
matched = wildmatch_array(pattern, (const char**)texts, 0);
} else
matched = wildmatch(pattern, text);
#ifdef COMPARE_WITH_FNMATCH
fn_matched = !fnmatch(pattern, text, flags);
#endif
@@ -66,6 +93,7 @@ int
main(int argc, char **argv)
{
char buf[2048], *s, *string[2], *end[2];
const char *arg;
FILE *fp;
int opt, line, i, flag[2];
poptContext pc = poptGetContext("wildtest", argc, (const char**)argv,
@@ -73,6 +101,16 @@ main(int argc, char **argv)
while ((opt = poptGetNextOpt(pc)) != -1) {
switch (opt) {
case 'e':
arg = poptGetOptArg(pc);
empties_mod = atoi(arg);
if (strchr(arg, 's'))
empty_at_start = 1;
if (strchr(arg, 'e'))
empty_at_end = 1;
if (!explode_mod)
explode_mod = 1024;
break;
default:
fprintf(stderr, "%s: %s\n",
poptBadOption(pc, POPT_BADOPTION_NOALIAS),
@@ -81,9 +119,12 @@ main(int argc, char **argv)
}
}
if (explode_mod && !empties_mod)
empties_mod = 1024;
argv = (char**)poptGetArgs(pc);
if (!argv || argv[1]) {
fprintf(stderr, "Usage: wildtest TESTFILE\n");
fprintf(stderr, "Usage: wildtest [OPTIONS] TESTFILE\n");
exit(1);
}

View File

@@ -50,6 +50,10 @@
0 1 bar/baz/foo */foo
0 0 foo/bar/baz **/bar*
1 1 deep/foo/bar/baz **/bar/*
0 1 deep/foo/bar/baz/ **/bar/*
1 1 deep/foo/bar/baz/ **/bar/**
0 1 deep/foo/bar **/bar/*
1 1 deep/foo/bar/ **/bar/**
1 1 foo/bar/baz **/bar**
1 1 foo/bar/baz/x */bar/**
0 0 deep/foo/bar/baz/x */bar/**

View File

@@ -1,5 +1,379 @@
ChangeLog file for zlib
ChangeLog file for zlib
Changes in 1.2.3 (18 July 2005)
- Apply security vulnerability fixes to contrib/infback9 as well
- Clean up some text files (carriage returns, trailing space)
- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
Changes in 1.2.2.4 (11 July 2005)
- Add inflatePrime() function for starting inflation at bit boundary
- Avoid some Visual C warnings in deflate.c
- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
compile
- Fix some spelling errors in comments [Betts]
- Correct inflateInit2() error return documentation in zlib.h
- Added zran.c example of compressed data random access to examples
directory, shows use of inflatePrime()
- Fix cast for assignments to strm->state in inflate.c and infback.c
- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
- Add cast in trees.c t avoid a warning [Oberhumer]
- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
- Update make_vms.com [Zinser]
- Initialize state->write in inflateReset() since copied in inflate_fast()
- Be more strict on incomplete code sets in inflate_table() and increase
ENOUGH and MAXD -- this repairs a possible security vulnerability for
invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for
discovering the vulnerability and providing test cases.
- Add ia64 support to configure for HP-UX [Smith]
- Add error return to gzread() for format or i/o error [Levin]
- Use malloc.h for OS/2 [Necasek]
Changes in 1.2.2.3 (27 May 2005)
- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
- Typecast fread() return values in gzio.c [Vollant]
- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
- Fix crc check bug in gzread() after gzungetc() [Heiner]
- Add the deflateTune() function to adjust internal compression parameters
- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
- Remove an incorrect assertion in examples/zpipe.c
- Add C++ wrapper in infback9.h [Donais]
- Fix bug in inflateCopy() when decoding fixed codes
- Note in zlib.h how much deflateSetDictionary() actually uses
- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
- Add gzdirect() function to indicate transparent reads
- Update contrib/minizip [Vollant]
- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
- Add casts in crc32.c to avoid warnings [Oberhumer]
- Add contrib/masmx64 [Vollant]
- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
Changes in 1.2.2.2 (30 December 2004)
- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
avoid implicit memcpy calls (portability for no-library compilation)
- Increase sprintf() buffer size in gzdopen() to allow for large numbers
- Add INFLATE_STRICT to check distances against zlib header
- Improve WinCE errno handling and comments [Chang]
- Remove comment about no gzip header processing in FAQ
- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
- Add updated make_vms.com [Coghlan], update README
- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
- Add FAQ entry and comments in deflate.c on uninitialized memory access
- Add Solaris 9 make options in configure [Gilbert]
- Allow strerror() usage in gzio.c for STDC
- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
- Use z_off_t for adler32_combine() and crc32_combine() lengths
- Make adler32() much faster for small len
- Use OS_CODE in deflate() default gzip header
Changes in 1.2.2.1 (31 October 2004)
- Allow inflateSetDictionary() call for raw inflate
- Fix inflate header crc check bug for file names and comments
- Add deflateSetHeader() and gz_header structure for custom gzip headers
- Add inflateGetheader() to retrieve gzip headers
- Add crc32_combine() and adler32_combine() functions
- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
- Use zstreamp consistently in zlib.h (inflate_back functions)
- Remove GUNZIP condition from definition of inflate_mode in inflate.h
and in contrib/inflate86/inffast.S [Truta, Anderson]
- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
- Update projects/README.projects and projects/visualc6 [Truta]
- Update win32/DLL_FAQ.txt [Truta]
- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
- Use a new algorithm for setting strm->data_type in trees.c [Truta]
- Do not define an exit() prototype in zutil.c unless DEBUG defined
- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
- Fix Darwin build version identification [Peterson]
Changes in 1.2.2 (3 October 2004)
- Update zlib.h comments on gzip in-memory processing
- Set adler to 1 in inflateReset() to support Java test suite [Walles]
- Add contrib/dotzlib [Ravn]
- Update win32/DLL_FAQ.txt [Truta]
- Update contrib/minizip [Vollant]
- Move contrib/visual-basic.txt to old/ [Truta]
- Fix assembler builds in projects/visualc6/ [Truta]
Changes in 1.2.1.2 (9 September 2004)
- Update INDEX file
- Fix trees.c to update strm->data_type (no one ever noticed!)
- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
- Add limited multitasking protection to DYNAMIC_CRC_TABLE
- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
- Don't declare strerror() under VMS [Mozilla]
- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
- Update contrib/ada [Anisimkov]
- Update contrib/minizip [Vollant]
- Fix configure to not hardcode directories for Darwin [Peterson]
- Fix gzio.c to not return error on empty files [Brown]
- Fix indentation; update version in contrib/delphi/ZLib.pas and
contrib/pascal/zlibpas.pas [Truta]
- Update mkasm.bat in contrib/masmx86 [Truta]
- Update contrib/untgz [Truta]
- Add projects/README.projects [Truta]
- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
- Update win32/DLL_FAQ.txt [Truta]
- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
- Remove an unnecessary assignment to curr in inftrees.c [Truta]
- Add OS/2 to exe builds in configure [Poltorak]
- Remove err dummy parameter in zlib.h [Kientzle]
Changes in 1.2.1.1 (9 January 2004)
- Update email address in README
- Several FAQ updates
- Fix a big fat bug in inftrees.c that prevented decoding valid
dynamic blocks with only literals and no distance codes --
Thanks to "Hot Emu" for the bug report and sample file
- Add a note to puff.c on no distance codes case.
Changes in 1.2.1 (17 November 2003)
- Remove a tab in contrib/gzappend/gzappend.c
- Update some interfaces in contrib for new zlib functions
- Update zlib version number in some contrib entries
- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
- Support shared libraries on Hurd and KFreeBSD [Brown]
- Fix error in NO_DIVIDE option of adler32.c
Changes in 1.2.0.8 (4 November 2003)
- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
- Add experimental NO_DIVIDE #define in adler32.c
- Possibly faster on some processors (let me know if it is)
- Correct Z_BLOCK to not return on first inflate call if no wrap
- Fix strm->data_type on inflate() return to correctly indicate EOB
- Add deflatePrime() function for appending in the middle of a byte
- Add contrib/gzappend for an example of appending to a stream
- Update win32/DLL_FAQ.txt [Truta]
- Delete Turbo C comment in README [Truta]
- Improve some indentation in zconf.h [Truta]
- Fix infinite loop on bad input in configure script [Church]
- Fix gzeof() for concatenated gzip files [Johnson]
- Add example to contrib/visual-basic.txt [Michael B.]
- Add -p to mkdir's in Makefile.in [vda]
- Fix configure to properly detect presence or lack of printf functions
- Add AS400 support [Monnerat]
- Add a little Cygwin support [Wilson]
Changes in 1.2.0.7 (21 September 2003)
- Correct some debug formats in contrib/infback9
- Cast a type in a debug statement in trees.c
- Change search and replace delimiter in configure from % to # [Beebe]
- Update contrib/untgz to 0.2 with various fixes [Truta]
- Add build support for Amiga [Nikl]
- Remove some directories in old that have been updated to 1.2
- Add dylib building for Mac OS X in configure and Makefile.in
- Remove old distribution stuff from Makefile
- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
- Update links in README
Changes in 1.2.0.6 (13 September 2003)
- Minor FAQ updates
- Update contrib/minizip to 1.00 [Vollant]
- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
- Update POSTINC comment for 68060 [Nikl]
- Add contrib/infback9 with deflate64 decoding (unsupported)
- For MVS define NO_vsnprintf and undefine FAR [van Burik]
- Add pragma for fdopen on MVS [van Burik]
Changes in 1.2.0.5 (8 September 2003)
- Add OF to inflateBackEnd() declaration in zlib.h
- Remember start when using gzdopen in the middle of a file
- Use internal off_t counters in gz* functions to properly handle seeks
- Perform more rigorous check for distance-too-far in inffast.c
- Add Z_BLOCK flush option to return from inflate at block boundary
- Set strm->data_type on return from inflate
- Indicate bits unused, if at block boundary, and if in last block
- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
- Add condition so old NO_DEFLATE define still works for compatibility
- FAQ update regarding the Windows DLL [Truta]
- INDEX update: add qnx entry, remove aix entry [Truta]
- Install zlib.3 into mandir [Wilson]
- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
- Adapt the zlib interface to the new DLL convention guidelines [Truta]
- Introduce ZLIB_WINAPI macro to allow the export of functions using
the WINAPI calling convention, for Visual Basic [Vollant, Truta]
- Update msdos and win32 scripts and makefiles [Truta]
- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
- Add contrib/ada [Anisimkov]
- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
- Add contrib/masm686 [Truta]
- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
[Truta, Vollant]
- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
- Remove contrib/delphi2; add a new contrib/delphi [Truta]
- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
and fix some method prototypes [Truta]
- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
[Truta]
- Avoid the use of backslash (\) in contrib/minizip [Vollant]
- Fix file time handling in contrib/untgz; update makefiles [Truta]
- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
[Vollant]
- Remove contrib/vstudio/vc15_16 [Vollant]
- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
- Update README.contrib [Truta]
- Invert the assignment order of match_head and s->prev[...] in
INSERT_STRING [Truta]
- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
[Truta]
- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
- Fix prototype of syncsearch in inflate.c [Truta]
- Introduce ASMINF macro to be enabled when using an ASM implementation
of inflate_fast [Truta]
- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
- Modify test_gzio in example.c to take a single file name as a
parameter [Truta]
- Exit the example.c program if gzopen fails [Truta]
- Add type casts around strlen in example.c [Truta]
- Remove casting to sizeof in minigzip.c; give a proper type
to the variable compared with SUFFIX_LEN [Truta]
- Update definitions of STDC and STDC99 in zconf.h [Truta]
- Synchronize zconf.h with the new Windows DLL interface [Truta]
- Use SYS16BIT instead of __32BIT__ to distinguish between
16- and 32-bit platforms [Truta]
- Use far memory allocators in small 16-bit memory models for
Turbo C [Truta]
- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
zlibCompileFlags [Truta]
- Cygwin has vsnprintf [Wilson]
- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
Changes in 1.2.0.4 (10 August 2003)
- Minor FAQ updates
- Be more strict when checking inflateInit2's windowBits parameter
- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
- Add gzip wrapper option to deflateInit2 using windowBits
- Add updated QNX rule in configure and qnx directory [Bonnefoy]
- Make inflate distance-too-far checks more rigorous
- Clean up FAR usage in inflate
- Add casting to sizeof() in gzio.c and minigzip.c
Changes in 1.2.0.3 (19 July 2003)
- Fix silly error in gzungetc() implementation [Vollant]
- Update contrib/minizip and contrib/vstudio [Vollant]
- Fix printf format in example.c
- Correct cdecl support in zconf.in.h [Anisimkov]
- Minor FAQ updates
Changes in 1.2.0.2 (13 July 2003)
- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
- Attempt to avoid warnings in crc32.c for pointer-int conversion
- Add AIX to configure, remove aix directory [Bakker]
- Add some casts to minigzip.c
- Improve checking after insecure sprintf() or vsprintf() calls
- Remove #elif's from crc32.c
- Change leave label to inf_leave in inflate.c and infback.c to avoid
library conflicts
- Remove inflate gzip decoding by default--only enable gzip decoding by
special request for stricter backward compatibility
- Add zlibCompileFlags() function to return compilation information
- More typecasting in deflate.c to avoid warnings
- Remove leading underscore from _Capital #defines [Truta]
- Fix configure to link shared library when testing
- Add some Windows CE target adjustments [Mai]
- Remove #define ZLIB_DLL in zconf.h [Vollant]
- Add zlib.3 [Rodgers]
- Update RFC URL in deflate.c and algorithm.txt [Mai]
- Add zlib_dll_FAQ.txt to contrib [Truta]
- Add UL to some constants [Truta]
- Update minizip and vstudio [Vollant]
- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
- Expand use of NO_DUMMY_DECL to avoid all dummy structures
- Added iostream3 to contrib [Schwardt]
- Replace rewind() with fseek() for WinCE [Truta]
- Improve setting of zlib format compression level flags
- Report 0 for huffman and rle strategies and for level == 0 or 1
- Report 2 only for level == 6
- Only deal with 64K limit when necessary at compile time [Truta]
- Allow TOO_FAR check to be turned off at compile time [Truta]
- Add gzclearerr() function [Souza]
- Add gzungetc() function
Changes in 1.2.0.1 (17 March 2003)
- Add Z_RLE strategy for run-length encoding [Truta]
- When Z_RLE requested, restrict matches to distance one
- Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
- Correct FASTEST compilation to allow level == 0
- Clean up what gets compiled for FASTEST
- Incorporate changes to zconf.in.h [Vollant]
- Refine detection of Turbo C need for dummy returns
- Refine ZLIB_DLL compilation
- Include additional header file on VMS for off_t typedef
- Try to use _vsnprintf where it supplants vsprintf [Vollant]
- Add some casts in inffast.c
- Enchance comments in zlib.h on what happens if gzprintf() tries to
write more than 4095 bytes before compression
- Remove unused state from inflateBackEnd()
- Remove exit(0) from minigzip.c, example.c
- Get rid of all those darn tabs
- Add "check" target to Makefile.in that does the same thing as "test"
- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
- Update contrib/inflate86 [Anderson]
- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
- Add msdos and win32 directories with makefiles [Truta]
- More additions and improvements to the FAQ
Changes in 1.2.0 (9 March 2003)
- New and improved inflate code
- About 20% faster
- Does not allocate 32K window unless and until needed
- Automatically detects and decompresses gzip streams
- Raw inflate no longer needs an extra dummy byte at end
- Added inflateBack functions using a callback interface--even faster
than inflate, useful for file utilities (gzip, zip)
- Added inflateCopy() function to record state for random access on
externally generated deflate streams (e.g. in gzip files)
- More readable code (I hope)
- New and improved crc32()
- About 50% faster, thanks to suggestions from Rodney Brown
- Add deflateBound() and compressBound() functions
- Fix memory leak in deflateInit2()
- Permit setting dictionary for raw deflate (for parallel deflate)
- Fix const declaration for gzwrite()
- Check for some malloc() failures in gzio.c
- Fix bug in gzopen() on single-byte file 0x1f
- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
and next buffer doesn't start with 0x8b
- Fix uncompress() to return Z_DATA_ERROR on truncated input
- Free memory at end of example.c
- Remove MAX #define in trees.c (conflicted with some libraries)
- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
- Declare malloc() and free() in gzio.c if STDC not defined
- Use malloc() instead of calloc() in zutil.c if int big enough
- Define STDC for AIX
- Add aix/ with approach for compiling shared library on AIX
- Add HP-UX support for shared libraries in configure
- Add OpenUNIX support for shared libraries in configure
- Use $cc instead of gcc to build shared library
- Make prefix directory if needed when installing
- Correct Macintosh avoidance of typedef Byte in zconf.h
- Correct Turbo C memory allocation when under Linux
- Use libz.a instead of -lz in Makefile (assure use of compiled library)
- Update configure to check for snprintf or vsnprintf functions and their
return value, warn during make if using an insecure function
- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
is lost when library is used--resolution is to build new zconf.h
- Documentation improvements (in zlib.h):
- Document raw deflate and inflate
- Update RFCs URL
- Point out that zlib and gzip formats are different
- Note that Z_BUF_ERROR is not fatal
- Document string limit for gzprintf() and possible buffer overflow
- Note requirement on avail_out when flushing
- Note permitted values of flush parameter of inflate()
- Add some FAQs (and even answers) to the FAQ
- Add contrib/inflate86/ for x86 faster inflate
- Add contrib/blast/ for PKWare Data Compression Library decompression
- Add contrib/puff/ simple inflate for deflate format description
Changes in 1.1.4 (11 March 2002)
- ZFREE was repeated on same allocation on some error conditions.
@@ -10,7 +384,7 @@ Changes in 1.1.4 (11 March 2002)
less than 32K.
- force windowBits > 8 to avoid a bug in the encoder for a window size
of 256 bytes. (A complete fix will be available in 1.1.5).
Changes in 1.1.3 (9 July 1998)
- fix "an inflate input buffer bug that shows up on rare but persistent
occasions" (Mark)
@@ -166,7 +540,7 @@ Changes in 1.0.7 (20 Jan 1998)
Changes in 1.0.6 (19 Jan 1998)
- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
- Fix a deflate bug occuring only with compression level 0 (thanks to
- Fix a deflate bug occurring only with compression level 0 (thanks to
Andy Buckler for finding this one).
- In minigzip, pass transparently also the first byte for .Z files.
- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
@@ -184,13 +558,13 @@ Changes in 1.0.6 (19 Jan 1998)
- added Makefile.nt (thanks to Stephen Williams)
- added the unsupported "contrib" directory:
contrib/asm386/ by Gilles Vollant <info@winimage.com>
386 asm code replacing longest_match().
386 asm code replacing longest_match().
contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
A C++ I/O streams interface to the zlib gz* functions
contrib/iostream2/ by Tyge L<>vset <Tyge.Lovset@cmr.no>
Another C++ I/O streams interface
Another C++ I/O streams interface
contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
A very simple tar.gz file extractor using zlib
A very simple tar.gz file extractor using zlib
contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
How to use compress(), uncompress() and the gz* functions from VB.
- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
@@ -217,7 +591,7 @@ Changes in 1.0.6 (19 Jan 1998)
- add NEED_DUMMY_RETURN for Borland
- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
- allow compilation with CC
- defined STDC for OS/2 (David Charlap)
- defined STDC for OS/2 (David Charlap)
- limit external names to 8 chars for MVS (Thomas Lund)
- in minigzip.c, use static buffers only for 16-bit systems
- fix suffix check for "minigzip -d foo.gz"
@@ -242,7 +616,7 @@ Changes in 1.0.5 (3 Jan 98)
- Eliminate memory leaks on error conditions in inflate
- Removed some vestigial code in inflate
- Update web address in README
Changes in 1.0.4 (24 Jul 96)
- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
bit, so the decompressor could decompress all the correct data but went

View File

@@ -1,175 +0,0 @@
# Makefile for zlib
# Copyright (C) 1995-2002 Jean-loup Gailly.
# For conditions of distribution and use, see copyright notice in zlib.h
# To compile and test, type:
# ./configure; make test
# The call of configure is optional if you don't have special requirements
# If you wish to build zlib as a shared library, use: ./configure -s
# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
# make install
# To install in $HOME instead of /usr/local, use:
# make install prefix=$HOME
CC=cc
CFLAGS=-O
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-g -DDEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
# -Wstrict-prototypes -Wmissing-prototypes
LDFLAGS=-L. -lz
LDSHARED=$(CC)
CPP=$(CC) -E
VER=1.1.4
LIBS=libz.a
SHAREDLIB=libz.so
AR=ar rc
RANLIB=ranlib
TAR=tar
SHELL=/bin/sh
prefix = /usr/local
exec_prefix = ${prefix}
libdir = ${exec_prefix}/lib
includedir = ${prefix}/include
OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
OBJA =
# to use the asm code: make OBJA=match.o
TEST_OBJS = example.o minigzip.o
DISTFILES = README FAQ INDEX ChangeLog configure Make*[a-z0-9] *.[ch] *.mms \
algorithm.txt zlib.3 zlib.html \
msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
nt/Make*[a-z0-9] nt/zlib.dnt amiga/Make*.??? os2/M*.os2 os2/zlib.def \
contrib/RE*.contrib contrib/*.txt contrib/asm386/*.asm contrib/asm386/*.c \
contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/asm[56]86/*.?86 \
contrib/asm[56]86/*.S contrib/iostream/*.cpp \
contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \
contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 \
contrib/minizip/[CM]*[pe] contrib/minizip/*.[ch] contrib/minizip/*.[td]?? \
contrib/delphi*/*.???
all: example minigzip
test: all
@LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
echo hello world | ./minigzip | ./minigzip -d || \
echo ' *** minigzip test FAILED ***' ; \
if ./example; then \
echo ' *** zlib test OK ***'; \
else \
echo ' *** zlib test FAILED ***'; \
fi
libz.a: $(OBJS) $(OBJA)
$(AR) $@ $(OBJS) $(OBJA)
-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
match.o: match.S
$(CPP) match.S > _match.s
$(CC) -c _match.s
mv _match.o match.o
rm -f _match.s
$(SHAREDLIB).$(VER): $(OBJS)
$(LDSHARED) -o $@ $(OBJS)
rm -f $(SHAREDLIB) $(SHAREDLIB).1
ln -s $@ $(SHAREDLIB)
ln -s $@ $(SHAREDLIB).1
example: example.o $(LIBS)
$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
minigzip: minigzip.o $(LIBS)
$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
install: $(LIBS)
-@if [ ! -d $(includedir) ]; then mkdir $(includedir); fi
-@if [ ! -d $(libdir) ]; then mkdir $(libdir); fi
cp zlib.h zconf.h $(includedir)
chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
cp $(LIBS) $(libdir)
cd $(libdir); chmod 755 $(LIBS)
-@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
cd $(libdir); if test -f $(SHAREDLIB).$(VER); then \
rm -f $(SHAREDLIB) $(SHAREDLIB).1; \
ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB); \
ln -s $(SHAREDLIB).$(VER) $(SHAREDLIB).1; \
(ldconfig || true) >/dev/null 2>&1; \
fi
# The ranlib in install is needed on NeXTSTEP which checks file times
# ldconfig is for Linux
uninstall:
cd $(includedir); \
v=$(VER); \
if test -f zlib.h; then \
v=`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`; \
rm -f zlib.h zconf.h; \
fi; \
cd $(libdir); rm -f libz.a; \
if test -f $(SHAREDLIB).$$v; then \
rm -f $(SHAREDLIB).$$v $(SHAREDLIB) $(SHAREDLIB).1; \
fi
clean:
rm -f *.o *~ example minigzip libz.a libz.so* foo.gz so_locations \
_match.s maketree
distclean: clean
zip:
mv Makefile Makefile~; cp -p Makefile.in Makefile
rm -f test.c ztest*.c contrib/minizip/test.zip
v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
zip -ul9 zlib$$v $(DISTFILES)
mv Makefile~ Makefile
dist:
mv Makefile Makefile~; cp -p Makefile.in Makefile
rm -f test.c ztest*.c contrib/minizip/test.zip
d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
rm -f $$d.tar.gz; \
if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
files=""; \
for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
cd ..; \
GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
if test ! -d $$d; then rm -f $$d; fi
mv Makefile~ Makefile
tags:
etags *.[ch]
depend:
makedepend -- $(CFLAGS) -- *.[ch]
# DO NOT DELETE THIS LINE -- make depend depends on it.
adler32.o: zlib.h zconf.h
compress.o: zlib.h zconf.h
crc32.o: zlib.h zconf.h
deflate.o: deflate.h zutil.h zlib.h zconf.h
example.o: zlib.h zconf.h
gzio.o: zutil.h zlib.h zconf.h
infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
infcodes.o: zutil.h zlib.h zconf.h
infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
inffast.o: zutil.h zlib.h zconf.h inftrees.h
inffast.o: infblock.h infcodes.h infutil.h inffast.h
inflate.o: zutil.h zlib.h zconf.h infblock.h
inftrees.o: zutil.h zlib.h zconf.h inftrees.h
infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
minigzip.o: zlib.h zconf.h
trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
uncompr.o: zlib.h zconf.h
zutil.o: zutil.h zlib.h zconf.h

View File

@@ -1,110 +1,86 @@
zlib 1.1.4 is a general purpose data compression library. All the code
is thread safe. The data format used by the zlib library
is described by RFCs (Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
format) and rfc1952.txt (gzip format). These documents are also available in
other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
ZLIB DATA COMPRESSION LIBRARY
zlib 1.2.3 is a general purpose data compression library. All the code is
thread safe. The data format used by the zlib library is described by RFCs
(Request for Comments) 1950 to 1952 in the files
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
and rfc1952.txt (gzip format). These documents are also available in other
formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
All functions of the compression library are documented in the file zlib.h
(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
example of the library is given in the file example.c which also tests that
the library is working correctly. Another example is given in the file
minigzip.c. The compression library itself is composed of all source files
except example.c and minigzip.c.
(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
of the library is given in the file example.c which also tests that the library
is working correctly. Another example is given in the file minigzip.c. The
compression library itself is composed of all source files except example.c and
minigzip.c.
To compile all files and run the test program, follow the instructions
given at the top of Makefile. In short "make test; make install"
should work for most machines. For Unix: "./configure; make test; make install"
For MSDOS, use one of the special makefiles such as Makefile.msc.
For VMS, use Make_vms.com or descrip.mms.
To compile all files and run the test program, follow the instructions given at
the top of Makefile. In short "make test; make install" should work for most
machines. For Unix: "./configure; make test; make install". For MSDOS, use one
of the special makefiles such as Makefile.msc. For VMS, use make_vms.com.
Questions about zlib should be sent to <zlib@gzip.org>, or to
Gilles Vollant <info@winimage.com> for the Windows DLL version.
The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
Before reporting a problem, please check this site to verify that
you have the latest version of zlib; otherwise get the latest version and
check whether the problem still exists or not.
Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
<info@winimage.com> for the Windows DLL version. The zlib home page is
http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
please check this site to verify that you have the latest version of zlib;
otherwise get the latest version and check whether the problem still exists or
not.
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
before asking for help.
PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
for help.
Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
issue of Dr. Dobb's Journal; a copy of the article is available in
http://dogma.net/markn/articles/zlibtool/zlibtool.htm
The changes made in version 1.1.4 are documented in the file ChangeLog.
The only changes made since 1.1.3 are bug corrections:
- ZFREE was repeated on same allocation on some error conditions.
This creates a security problem described in
http://www.zlib.org/advisory-2002-03-11.txt
- Returned incorrect error (Z_MEM_ERROR) on some invalid data
- Avoid accesses before window for invalid distances with inflate window
less than 32K.
- force windowBits > 8 to avoid a bug in the encoder for a window size
of 256 bytes. (A complete fix will be available in 1.1.5).
The beta version 1.1.5beta includes many more changes. A new official
version 1.1.5 will be released as soon as extensive testing has been
completed on it.
The changes made in version 1.2.3 are documented in the file ChangeLog.
Unsupported third party contributions are provided in directory "contrib".
A Java implementation of zlib is available in the Java Development Kit
http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
See the zlib home page http://www.zlib.org for details.
A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
is in the CPAN (Comprehensive Perl Archive Network) sites
A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
CPAN (Comprehensive Perl Archive Network) sites
http://www.cpan.org/modules/by-module/Compress/
A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
is available in Python 1.5 and later versions, see
A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
available in Python 1.5 and later versions, see
http://www.python.org/doc/lib/module-zlib.html
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
An experimental package to read and write files in .zip format,
written on top of zlib by Gilles Vollant <info@winimage.com>, is
available at http://www.winimage.com/zLibDll/unzip.html
and also in the contrib/minizip directory of zlib.
An experimental package to read and write files in .zip format, written on top
of zlib by Gilles Vollant <info@winimage.com>, is available in the
contrib/minizip directory of zlib.
Notes for some targets:
- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
The zlib DLL support was initially done by Alessandro Iacopetti and is
now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
home page at http://www.winimage.com/zLibDll
- For Windows DLL versions, please see win32/DLL_FAQ.txt
From Visual Basic, you can call the DLL functions which do not take
a structure as argument: compress, uncompress and all gz* functions.
See contrib/visual-basic.txt for more information, or get
http://www.tcfb.com/dowseware/cmp-z-it.zip
- For 64-bit Irix, deflate.c must be compiled without any optimization. With
-O, one libpng test fails. The test works in 32 bit mode (with the -n32
compiler flag). The compiler bug has been reported to SGI.
- For 64-bit Irix, deflate.c must be compiled without any optimization.
With -O, one libpng test fails. The test works in 32 bit mode (with
the -n32 compiler flag). The compiler bug has been reported to SGI.
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
when compiled with cc.
- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
it works when compiled with cc.
- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
necessary to get gzprintf working correctly. This is done by configure.
- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
is necessary to get gzprintf working correctly. This is done by configure.
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
with other compilers. Use "make test" to check your compiler.
- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
other compilers. Use "make test" to check your compiler.
- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
- For Turbo C the small model is supported only with reduced performance to
avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
- For PalmOs, see http://palmzlib.sourceforge.net/
- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
Per Harald Myrvang <perm@stud.cs.uit.no>
- When building a shared, i.e. dynamic library on Mac OS X, the library must be
installed before testing (do "make install" before "make test"), since the
library location is specified in the library.
Acknowledgments:
@@ -116,7 +92,7 @@ Acknowledgments:
Copyright notice:
(C) 1995-2002 Jean-loup Gailly and Mark Adler
(C) 1995-2004 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -144,4 +120,6 @@ entirely written by Jean-loup Gailly and Mark Adler; it does not
include third-party code.
If you redistribute modified sources, we would appreciate that you include
in the file ChangeLog history information documenting your changes.
in the file ChangeLog history information documenting your changes. Please
read the FAQ for more information on the distribution of modified source
versions.

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