Compare commits

..

1418 Commits

Author SHA1 Message Date
Wayne Davison
42afed9c1a Preparing for release of 2.6.3pre2 2004-09-21 16:10:35 +00:00
Wayne Davison
37c36e2692 Mention the daemon-socket-connection change. 2004-09-21 15:47:20 +00:00
Wayne Davison
7fbc7031f4 Mentioned a couple more changes. 2004-09-21 15:31:33 +00:00
Wayne Davison
9f004a9ea9 The delete_one() function no longer needs to handle the case where
it thinks it is removing a directory and it is really removing a
symlink.
2004-09-21 09:24:06 +00:00
Wayne Davison
23f4587f2b - Turned readlink_stat() into a static function.
- Made readlink_stat() no longer honor keep_dirlinks.
- The make_file() function now checks keep_dirlinks late in the
  function so that it only transforms a symlink to a local dir
  into a directory if the receiver also has a directory by that
  name.  This makes the use of --delete with --keep-dirlinks
  work much better.
2004-09-21 09:24:02 +00:00
Wayne Davison
4d8f5b0ae7 - Fixed a problem with the $bakdir value.
- Made the files have better contents to copy.
- Also test --backup without --backup-dir.
2004-09-20 19:50:04 +00:00
Wayne Davison
89389a29ef Output a backup message when verbose > 1 and we did a copy prior
to an --inplace update.
2004-09-20 19:47:59 +00:00
Wayne Davison
29fe3961ab Output the same backup-message prefix when verbose > 1 regardless of
the setting of --backup-dir.
2004-09-20 19:46:45 +00:00
Wayne Davison
4e8a085ac9 Use $diffopt instead of -u. 2004-09-20 05:17:57 +00:00
Wayne Davison
fb22c2774d Got rid of a superfluous static buffer. 2004-09-20 05:01:38 +00:00
Wayne Davison
7d059d4c37 A simple test of the backup functionality. 2004-09-20 04:59:01 +00:00
Wayne Davison
9715c5899a Improved a comment. 2004-09-20 04:17:42 +00:00
Wayne Davison
cc07f21211 Mention the new RSYNC_PARTIAL_DIR environment variable. 2004-09-18 17:37:54 +00:00
Wayne Davison
b4d1e854ef Document the new RSYNC_PARTIAL_DIR environment variable. 2004-09-18 17:35:20 +00:00
Wayne Davison
075aa18fd4 Look for the RSYNC_PARTIAL_DIR environment variable when --partial
was specified (and --partial-dir was not).
2004-09-18 17:34:56 +00:00
Wayne Davison
e0204f5621 Mention that older rsync versions had a problem with --link-dest and
how to work around it.
2004-09-18 01:49:19 +00:00
Wayne Davison
a9ac4411e5 Mention the latest changes. 2004-09-17 16:53:51 +00:00
Wayne Davison
50b31539c2 - Added the ability to parse a literal IPv6 address in an "rsync:" URL
(e.g. rsync://[2001:638:500:101::21]:873/module/dir).
- Improved a couple --files-from error messages.
2004-09-17 16:50:53 +00:00
Wayne Davison
56194bcd95 When outputting the flist info (in a debug-level of verbosity) we
now mention the UID of the file when we are the sender (as well as
when we are root).
2004-09-17 16:39:34 +00:00
Wayne Davison
eb8ffa9040 Actually, since the close calls shouldn't fail (now that listener
is properly set to -1 on close), we don't really need to play the
save-errno game after all.
2004-09-16 17:22:31 +00:00
Wayne Davison
a7a1cc2c75 Make sure that /etc and /bin actually are readable before we try
to list them.
2004-09-16 17:16:36 +00:00
Wayne Davison
ab217f7ffa - Set "listener" to -1 after we close it so that the error-handler
doesn't try to re-close it.
- Set blocking I/O before the second (final) connect() call.
2004-09-16 17:09:46 +00:00
Wayne Davison
a20c9893e4 Don't try to optimize-away the sending of the --delete option if
--delete-after was specified (since we don't know what the protocol
version will be yet).
2004-09-08 07:33:06 +00:00
Wayne Davison
3bb400ca14 If --backup was used with --inplace, we don't limit the basis-file
matches (as we normally would) because the receiver is using the
backup-file as the basis-file.
2004-09-07 21:45:19 +00:00
Wayne Davison
cd6aa5b5c0 When --backup is used with --inplace, we make a copy of the destination
file into its backup spot while generating the checksums.
2004-09-07 21:44:02 +00:00
Wayne Davison
dc55d7bdab If we're making backups with --inplace, use the backup file as the
basis file while still updating the real destination file inplace.
2004-09-07 21:34:26 +00:00
Wayne Davison
8b115ac8dc Turn off make_backups during the redo phase, just like the receiver. 2004-09-07 21:32:36 +00:00
Wayne Davison
c94e4afbfa Moved the code that determines the backup filename into a new function
named get_backup_name().
2004-09-07 21:29:26 +00:00
Wayne Davison
6566d205e2 Made full_write() non-static. 2004-09-07 21:26:26 +00:00
Wayne Davison
e484f0cc04 W mustn't backup an inplace file in finish_transfer(). 2004-09-07 20:37:36 +00:00
Wayne Davison
bd397b8cba Reject the use of --compare-dest or --link-dest with --inplace
(it will take extra code to suppor this).
2004-09-07 20:36:36 +00:00
Wayne Davison
f8c8ef9eac When we say we're skipping a non-regular file, actually skip it. 2004-09-07 19:49:09 +00:00
Wayne Davison
72c19bb3de A minor optimization to the partial-dir code. 2004-09-07 17:03:51 +00:00
Wayne Davison
89f7eff382 Fix the case where a partial-dir file exists but the destination
file does not.
2004-09-07 16:50:07 +00:00
Wayne Davison
b90a6d9ff6 Mention that --whole-file interferes with the reuse of a --partial-dir
file.
2004-09-07 16:49:10 +00:00
Wayne Davison
584ba4ebae Fixed a typo Paul pointed out. 2004-09-05 21:30:00 +00:00
Wayne Davison
ba3db4795e Allow the use of the --exclude*/--include* options to a server
process again, but make sure that the user didn't specify a
server-excluded file for one of the --*-from options.
2004-08-26 17:39:48 +00:00
Wayne Davison
59d73bf3d2 Some fixes & clarifications for the BATCH MODE section. 2004-08-18 07:50:36 +00:00
Wayne Davison
919ca3a3cc Few few more minor improvements to the existing change items. 2004-08-18 07:49:03 +00:00
Wayne Davison
5886edfac2 Corrected/enhanced a comment. 2004-08-18 07:00:17 +00:00
Wayne Davison
d414962af4 One more NEWS tweak. 2004-08-12 21:02:13 +00:00
Wayne Davison
8fb7db245a Mention the security fix. 2004-08-12 20:58:33 +00:00
Wayne Davison
6f0fc27e33 Got rid of one item. 2004-08-12 20:48:05 +00:00
Wayne Davison
9c54ad58f8 Preparing for release of 2.6.3pre1 2004-08-12 20:06:57 +00:00
Wayne Davison
f55c2dfc03 One last minor tweak to clean_fname(). 2004-08-12 20:04:47 +00:00
Wayne Davison
675ef1aa3a Tweaked the USAGE section a tad and added an ADVANCED USAGE section
that discusses how to request multiple names from a remote rsync.
2004-08-12 19:31:23 +00:00
Wayne Davison
ef57235623 Improved the build rule for getfsdev and added getfsdev.o to the
files we cleanup.
2004-08-12 18:59:03 +00:00
Wayne Davison
d66d07e883 If system won't let us set chmod bits, fall back to testing without
them set.
2004-08-12 18:51:35 +00:00
Wayne Davison
b92693daba - Made clean_flist()'s collapsing of ".." dirs optional by adding
a "BOOL collapse_dot_dot" arg.
- Improved some comments.
2004-08-12 18:20:14 +00:00
Wayne Davison
58b1999e08 Call clean_flist() with its new "collapse_dot_dot" arg. 2004-08-12 18:20:07 +00:00
Wayne Davison
8e5f029e02 One (hopefully) last change to the sanitize_path() code. 2004-08-12 10:13:45 +00:00
Wayne Davison
2d41264e9e Simplified sanitize_path() logic a little. 2004-08-12 09:32:16 +00:00
Wayne Davison
82c6be7edf More improvements and a couple missing items. 2004-08-12 01:27:26 +00:00
Wayne Davison
0219d4dfba Improved a comment. 2004-08-12 00:58:01 +00:00
Wayne Davison
391516da51 Got rid of a comment that became inapplicable. 2004-08-12 00:52:58 +00:00
Wayne Davison
1d6b8f9ad2 - Call sanitize_path() with updated args.
- Added count_dir_elements() function.
- Changed the args for sanitize_path() so that the caller can request
  the value for the rootdir and so that the caller tells us the current
  subdir depth instead of sending us a string that we have to figure it
  out from.
- Make sure that sanitize_path() doesn't mis-parse multiple adjacent
  slashes.
2004-08-11 23:41:06 +00:00
Wayne Davison
10796f4b6e Call sanitize_path() with updated args. 2004-08-11 23:41:03 +00:00
Wayne Davison
33ffd7c37d - Set the var lastdir_depth when setting lastdir.
- Call sanitize_path() with updated args.
2004-08-11 23:41:00 +00:00
Wayne Davison
21d1e929a0 Ignore new getfsdev executable. 2004-08-11 17:33:52 +00:00
Wayne Davison
d0bc3520de Make the text of the --times (-t) option more correct on what
happens if it is omitted.
2004-08-11 17:24:37 +00:00
Wayne Davison
9f18657889 A minor improvement in check_one_exclude(). 2004-08-10 18:15:33 +00:00
Wayne Davison
c16d69b292 Mention the early-chmod change. 2004-08-09 20:58:26 +00:00
Wayne Davison
ebeacb36fb Set each file's permissions and modtime before it gets renamed. 2004-08-09 20:57:10 +00:00
Wayne Davison
6558854dbe Do some simple tests with various read-only and set[ug]id files. 2004-08-09 20:52:35 +00:00
Wayne Davison
7d9d5d9478 Added a rule for building getfsdev and for requiring it to run "test". 2004-08-09 20:51:44 +00:00
Wayne Davison
630f548ff4 Made robust_rename() return a 1 if it had to copy the file. 2004-08-09 20:48:38 +00:00
Wayne Davison
100b62bb69 Output a device string for each file given on the command-line. 2004-08-09 20:46:54 +00:00
Wayne Davison
e012b94f21 Fixed a bug in clean_fname() that could sometimes leave a "dir/.."
sequence uncollapsed.
2004-08-07 20:56:41 +00:00
Wayne Davison
3104620cf0 Made clean_fname() return the length of the string. 2004-08-06 22:36:55 +00:00
Wayne Davison
ebdd24d6d0 An improved clean_fname() routine that is more efficient and will also
collapse ".." dirs that aren't at the start of the path.  Care was taken
to ensure that the cleaning of a name that goes over the socket is done
in the same way as the old code (because both sides call clean_fname()
on those file-list names).  This ensures compatibility with older rsync
versions.
2004-08-06 21:24:14 +00:00
Wayne Davison
7cd72c79ec Set "eob" correctly in add_exclude_file(). 2004-08-05 22:58:17 +00:00
Wayne Davison
84a6379565 Merged alloc_sanitize_path() into sanitize_path(), adding an extra arg
that indicates the destination dir for the resulting path (if the dest
is NULL, a buffer will be allocated) and having it return a value.
2004-08-05 21:57:11 +00:00
Wayne Davison
0a5f12720e Use the new sanitize_path() calling syntax. 2004-08-05 21:57:09 +00:00
Wayne Davison
73f7af0e88 If dry_run is > 1 then the destination directory was missing, so we
set stat_errno to ENOENT and statret to -1 without calling stat().
2004-08-05 18:18:36 +00:00
Wayne Davison
e5a96f0f54 In get_local_name(), if we would have created the destination dir but
were prevented by dry_run being set, increment dry_run so that the
generator knows that all the files are missing.
2004-08-05 18:17:44 +00:00
Wayne Davison
d73e7f6edd In set_refuse_options(): make sure we scan the whole list of options
and avoid complaining about a wild-card spec that actually matches
one or more options.
2004-08-04 21:20:34 +00:00
Wayne Davison
61542c41de Decided that we don't need to limit the block size after all now
that the map_file() code handles large block sizes better.
2004-08-03 15:41:16 +00:00
Wayne Davison
bd1a581bee Use MAX_MAP_SIZE in the args to map_file(). 2004-08-03 15:37:54 +00:00
Wayne Davison
6e8a1782ab - Changed the calling syntax for map_file() so that it takes both
a (possibly approximate) window size and an optional block size
  (which is used to round-up the window size if it is non-zero).
- Don't set window_start behind the supplied offset in map_ptr().
2004-08-03 08:05:29 +00:00
Wayne Davison
96d910c770 Call map_file() with its new args, including a suggested window
size.
2004-08-03 08:05:27 +00:00
Wayne Davison
7560c17adc We call map_ptr() with a data range than includes any unmatched data
(which we might need to reference again) in addition to the current
rolling-checksum block (this prevents the unmatched data from being
lost when we slide the buffer and read more data).
2004-08-03 08:05:23 +00:00
Wayne Davison
9cd339eb39 - Changed the description for --block-size in the --help text.
- Use the new MAX_BLOCK_SIZE to limit the block_size value.
2004-08-03 08:05:20 +00:00
Wayne Davison
f310029387 - Added define for MAX_BLOCK_SIZE.
- Increased the MAX_MAP_SIZE.
2004-08-03 08:05:17 +00:00
Wayne Davison
3ed8eb3f9c Updated the description of the --block-size option. 2004-08-03 07:58:48 +00:00
Wayne Davison
007351494d Mention the open64()/mkstemp64() configure change. 2004-08-02 22:06:17 +00:00
Wayne Davison
6dcb93208d Don't use mkstemp() if the OS has open64() but not mkstemp64(). 2004-08-02 21:56:07 +00:00
Wayne Davison
84e1a698bf Test for functions open64() and mkstemp64(). 2004-08-02 21:54:49 +00:00
Wayne Davison
0d7638eafd Got rid of trailing whitespace. 2004-08-02 16:49:20 +00:00
Wayne Davison
86e2f445f7 Mention the "refuse options" change. 2004-08-02 07:41:04 +00:00
Wayne Davison
093e816c37 Allow better wildcard matching against the short-option letters in
the "refuse options" handling.
2004-08-02 07:40:34 +00:00
Wayne Davison
1cb0a3edc6 Document the improved "refuse options" syntax. 2004-08-02 05:01:36 +00:00
Wayne Davison
06a5054273 - Extended the "refuse options" daemon setting to allow wildcards
and to allow single-letter option names.
- No need to send the various --delete* options or the --force option
  from the receiver to the sender.
2004-08-02 05:00:30 +00:00
Wayne Davison
acd0299243 Got rid of unused externs. 2004-08-02 04:50:33 +00:00
Wayne Davison
dca68b0aad - Changed "read so far" to "received so far".
- Output the who_am_i() information in the socket read/write errors to
  make it a little clearer who is complaining about what (for those
  familiar with rsync, at least -- e.g. it will help when users report
  errors).
2004-08-02 02:43:54 +00:00
Wayne Davison
c3ea09906d - Changed all the errors in parse_arguments() to use the err_buf so
that a client talking to a daemon server actually gets the error.
- If a daemon has a list of exclusions, apply that list to various
  options to ensure that an excluded file can't be affected.
- Fixed an arg-checking problem when --files-from got passed to a
  daemon.
2004-07-31 20:09:54 +00:00
Wayne Davison
bf4679e8a0 If we need to return an error during the startup phase and the other
side is expecting us to send them a files-from list, send the list
terminator before sending the error.
2004-07-31 19:55:42 +00:00
Wayne Davison
c4054610c8 Don't allow a --partial-dir setting to overwrite a server-excluded
file (affects a daemon receiver only).
2004-07-31 18:13:20 +00:00
Wayne Davison
f6c0d3d70b - Document the change to --copy-links.
- Improved the "OUTPUT CHANGES" section.
2004-07-31 16:20:28 +00:00
Wayne Davison
ef855d198e Document the old side-effect to --copy-links and that it no longer
happens in a modern rsync w/o --keep-dirlinks.
2004-07-31 16:19:14 +00:00
Wayne Davison
81b07870c8 One call to link_stat() (in set_perms()) needed to honor the setting
of keep_dirlinks if the current item is a directory.
2004-07-31 16:15:41 +00:00
Wayne Davison
bb6721dce6 Reset copy_links in the receiver. 2004-07-31 16:14:27 +00:00
Wayne Davison
446a2987cd Prominently mention the changes to the text that gets output. 2004-07-31 03:33:05 +00:00
Wayne Davison
4de2a17409 Changed "wrote"/"written" to "sent" and "read" to "received" in
the text that is output.
2004-07-31 03:32:42 +00:00
Wayne Davison
99d24f77ed - Mention the "list = no" change in error handling.
- Improved a few of the NEWS items.
2004-07-30 22:46:07 +00:00
Wayne Davison
c0422cea9f If someone is denied access to a "list = no" module, lie and tell them
that the module is "Unknown" (so the user can't probe to find unlisted
modules).
2004-07-30 20:07:52 +00:00
Wayne Davison
8b6ad0193d Don't ignore case in lp_number() because the rest of the daemon code
can't handle the case where the module name doesn't exactly match the
string the user provided.
2004-07-30 20:05:37 +00:00
Wayne Davison
33eff8bfd6 If we reject a name due to a server-exclude, someone is trying to hack
rsync (because the generator would not have included this file).  Respond
with an exit.
2004-07-30 07:02:37 +00:00
Wayne Davison
65af3dab03 Document the latest changes. 2004-07-29 18:08:16 +00:00
Wayne Davison
065a605270 Got rid of bogus compare_dest scan in skip_file() -- it must checksum
the same file that we used for the stat() (in the parent routine).
2004-07-29 16:45:48 +00:00
Wayne Davison
a7260c4037 Added the new --partial-dir option. 2004-07-29 16:06:38 +00:00
Wayne Davison
44cad59f2b Document the new --partial-dir option. 2004-07-29 16:06:34 +00:00
Wayne Davison
c52461f911 Check the error return of flush_write_file(). 2004-07-29 07:37:27 +00:00
Wayne Davison
7f459268d9 Added close_multiplexing_in() and renamed io_multiplexing_close()
to close_multiplexing_out().
2004-07-29 07:24:45 +00:00
Wayne Davison
9eeb3b9c88 Call the new close_multiplexing_in() function in the generator. 2004-07-29 07:24:00 +00:00
Wayne Davison
d1b31da71e If we fail writing to the socket and we're receiving error messages
from the other side via a multiplexed input, read the socket to see
if we get some errors that would explain why they went away.
2004-07-29 07:09:46 +00:00
Wayne Davison
89e540e638 One more inplace code tweak. 2004-07-29 06:59:30 +00:00
Wayne Davison
fab65a5bc2 Some minor fixes and improvements for the inplace code. 2004-07-29 06:40:26 +00:00
Wayne Davison
e7d13fe532 - Explicitly save the stat()'s errno so that we can be sure we're
testing the right thing lower down (and so that future code doesn't
  always have to remember to save it off and restore it).
- Improved a chunk of link_dest code.
- Handle the removal of a non-regular file without so much duplicated
  code.
2004-07-28 10:04:06 +00:00
Wayne Davison
ecc81fce17 Use the new safe_fname() function. 2004-07-26 16:36:59 +00:00
Wayne Davison
b4afd23c30 Allow safe_fname() to tweak up to two name at a time. 2004-07-26 16:34:36 +00:00
Wayne Davison
af1a3f9b6e Use safe_fname() in full_fname(). 2004-07-26 15:59:51 +00:00
Wayne Davison
820b6c9aa0 Added safe_fname() that converts any newlines in a name into '?'s. 2004-07-26 15:52:25 +00:00
Wayne Davison
3cb22c204c Made a comment better. 2004-07-26 05:38:02 +00:00
Wayne Davison
7432ccf4ed Some batch-mode changes. 2004-07-24 16:51:58 +00:00
Wayne Davison
6a48e792c1 Made the new option-twiddling message only output when verbose. 2004-07-24 16:51:16 +00:00
Wayne Davison
9459290ae7 Call read_stream_flags() as soon as we open the batch file for
reading.
2004-07-24 16:40:41 +00:00
Wayne Davison
741d654495 Call write_stream_flags() from start_write_batch(). 2004-07-24 16:39:53 +00:00
Wayne Davison
d3e182af09 Added write_stream_flags() to write the state of certain flags into
the batchfile and read_stream_flags() to read and twiddle the same
flags.  This ensures that the batchfile reading doesn't get confused
about what data to expect from the socket.
2004-07-24 16:38:49 +00:00
Wayne Davison
d9b4d267c7 Tweaked a compound line. 2004-07-23 16:59:38 +00:00
Wayne Davison
58c5c24555 Added a comment. 2004-07-23 16:59:22 +00:00
Wayne Davison
341c9a137f Some basic batch-mode tests. 2004-07-23 02:13:34 +00:00
Wayne Davison
871446fc98 Chris added a missing "not" to a comment. 2004-07-23 01:40:22 +00:00
Wayne Davison
0abda1b176 Fixed the opening comments. 2004-07-23 01:39:19 +00:00
Wayne Davison
394bcdb5e3 If we sucessfully renamed a file that has multiple links to it, unlink()
it to ensure that rename() didn't lie to us (which it does if you try to
rename() a file over another link to the same file).
2004-07-22 22:52:39 +00:00
Wayne Davison
28deecca55 Changed NO_INT64 to INT64_IS_OFF_T because off_t might actually be
64 bits.  The code now only complains if int64 is really too short.
2004-07-22 19:28:45 +00:00
Wayne Davison
4db88e5b8f Some --help text fixes. 2004-07-22 15:43:28 +00:00
Wayne Davison
75b243a51d Some more --inplace improvements. 2004-07-22 15:41:09 +00:00
Wayne Davison
9bccfc429c Should always call finish_transfer() for inplace handling, just like
for keep_partial handling.
2004-07-22 15:31:06 +00:00
Wayne Davison
077e59b769 The inplace handling in finish_transfer() now passes PERMS_SKIP_MTIME
to set_perms() if ok_to_set_time wasn't specified.
2004-07-22 15:30:04 +00:00
Wayne Davison
007e3c0e9a Need to output the "failed verification" error before sending the
MSG_REDO so that the output comes out in the right order.
2004-07-22 08:16:35 +00:00
Wayne Davison
e2bc412669 Added a warning message when a file fails to verify, letting the user
know if we retained it or discarded it.  Especially useful for batch-
reading mode where the old code could look like it did the update when
it really silently failed.
2004-07-22 04:15:18 +00:00
Wayne Davison
e344209582 Added even more double-quoting. 2004-07-22 03:23:04 +00:00
Wayne Davison
e76ca1458c No need to check both delete_after and delete_mode since the former
implies the latter.
2004-07-22 02:52:57 +00:00
Wayne Davison
16cc9ca2c9 In read_batch mode, we read ints from the new batch_gen_fd pipe and
only process the updates from the batch file when the generator has
indicated that it is ready (which ensures that all the necessary
dirs have been created).
2004-07-21 23:59:37 +00:00
Wayne Davison
8c90957ff5 Got rid of read_batch special case. 2004-07-21 23:59:33 +00:00
Wayne Davison
c0d8e84c9d Setup for read_batch mode a little differently:
- Avoid calling local_child().
- Create a pipe that lets the generator send us index values.
- Set batch_gen_fd for the receiver to read the pipe.
2004-07-21 23:59:31 +00:00
Wayne Davison
b0ad542928 Added batch_gen_fd. 2004-07-21 23:59:28 +00:00
Wayne Davison
727b35f665 In read_batch mode, we now let the code write out the index value
to the f_out pipe before we return from recv_generator().  This gives
the receiver something to sync with so that it doesn't rush ahead of
us (which could be bad if we didn't have a chance to create the
destination dirs yet).
2004-07-21 23:59:25 +00:00
Wayne Davison
aa4343211f Don't write out the protocol_version number in read_batch mode. 2004-07-21 23:59:22 +00:00
Wayne Davison
3611989355 Complain if the user combines --read-batch with --files-from. 2004-07-21 22:50:11 +00:00
Wayne Davison
3381b77d71 Improved the test a little. 2004-07-21 21:06:13 +00:00
Wayne Davison
dce70db374 Adding a test for the --compare-dest option. 2004-07-21 20:58:32 +00:00
Wayne Davison
2adbcdc7ea A couple am_sender checks (one negated) were not needed. 2004-07-21 20:17:02 +00:00
Wayne Davison
7e5fa372cf Call map_file() with the new block_size arg (had to delay the
call to map_file() until the block size was known).
2004-07-20 21:35:58 +00:00
Wayne Davison
6e45e1dd86 - Call map_file() with the new block_size arg (had to delay the
call to map_file() until the block size was known).
- Got rid of the setting of max_map_size.
2004-07-20 21:35:55 +00:00
Wayne Davison
7f290d5c82 - Added a new block_size arg to map_file(). Use it to set the
new def_window_size member variable.
- Got rid of max_map_size global (we use def_window_size now).
2004-07-20 21:35:52 +00:00
Wayne Davison
b6609cafae - Got rid of cleanup_buf (map-file cleanup is not needed).
- Renamed the cleanup_fd* vars.
2004-07-20 21:35:49 +00:00
Wayne Davison
efa95a1842 Call map_file() with its new block_size arg. 2004-07-20 21:35:46 +00:00
Wayne Davison
51bd4f0f3a Tweaked an error message. 2004-07-20 21:10:20 +00:00
Wayne Davison
562b61695e Added a def_window_size variable to struct map_struct. 2004-07-20 21:08:33 +00:00
Wayne Davison
98f51bfb56 - More batch-file improvements.
- A few spelling fixes.
2004-07-20 18:12:50 +00:00
Wayne Davison
73f0ce69e7 We now append the exclude list as a "here" document to the end of
the BATCH.sh file.
2004-07-20 17:07:55 +00:00
Wayne Davison
cf338ab1be Made write_sbuf() non-static. 2004-07-20 16:57:18 +00:00
Wayne Davison
66a9dc9639 Changed write_batch_argvs_file() to new write_batch_shell_file()
call (with extra arg).
2004-07-19 17:11:41 +00:00
Wayne Davison
8ed9d849dc Added new function discard_receive_data(). 2004-07-19 17:05:01 +00:00
Wayne Davison
5ebab6c10c - Don't allow some crafty user to try to force us to update a
server-excluded file.
- If get_tmpname() fails we need to discard the update using
  receive_data().
2004-07-19 16:37:30 +00:00
Wayne Davison
e7a69008e6 Do a better job of writing out the BATCH.sh file (i.e. quote special
characters and spaces in args, omit all the source args, omit the
include/exclude args if we can).
2004-07-19 08:27:17 +00:00
Wayne Davison
73e015683c Changed batch.rsync_argvs to batch.sh. 2004-07-19 03:59:35 +00:00
Wayne Davison
b462781fd0 Fixed the argv munging to work properly regardless of whether the
user specified a trailing '=VALUE' or put the value in a separate
arg.
2004-07-19 00:53:49 +00:00
Wayne Davison
93095cbe99 A very minor optimization was made to read_sbuf(), read_byte(),
write_sbuf(), and write_byte().
2004-07-17 21:17:34 +00:00
Wayne Davison
399371e7b5 - Improved the warning about --inplace.
- Fixed the sentence describing how to read standard input with
  --read-batch.
2004-07-17 16:44:16 +00:00
Wayne Davison
d7142e2328 Moved the read_batch abort check below the code that handles the
symlinks and devices.
2004-07-17 16:29:10 +00:00
Wayne Davison
1f75bb1066 Revamped some of the io variables and calls to make the various I/O
functions seemlessly work on fds that aren't for the main socket. This
involved changing some fd-variable names (to make them clearer), adding
io_set_sock_fds(), and making input buffering have a better enabled
flag (via an allocated buffer, just like the output buffering).  I also
got rid of the fd arg to some functions where the fd arg could only
specify the input or output fd for the socket (which we already know).
2004-07-17 15:20:00 +00:00
Wayne Davison
088adfacc1 Got rid of the arg to io_start_multiplex_out(). 2004-07-17 15:19:57 +00:00
Wayne Davison
da3478b2a7 - Got rid of the arg to the io_start_multiplex_{in,out}() calls.
- Call io_set_sock_fds().
2004-07-17 15:19:54 +00:00
Wayne Davison
5126ed1ef0 Changed a MIN() to a MAX() when setting max_map_size. 2004-07-17 10:59:14 +00:00
Wayne Davison
61fb21ad28 Mention the new --inplace option. 2004-07-17 00:00:27 +00:00
Wayne Davison
a3221d2ac1 My version of Mark Curtis's --inplace option. 2004-07-16 20:06:24 +00:00
Wayne Davison
2c713fcdfa Added a check for ftruncate. 2004-07-16 20:04:20 +00:00
Wayne Davison
afd8bdb907 Avoid some useless memory copying. 2004-07-16 18:08:52 +00:00
Wayne Davison
efd5ee5786 - Limit the maximum block size we compute for a file.
- Set max_map_size based on the current file's block size (so that
  map_ptr() is more efficient with large blocks).
2004-07-16 18:04:23 +00:00
Wayne Davison
510b4cd4d5 Added a max_map_size variable, initialized to MAX_MAP_SIZE. 2004-07-16 18:02:30 +00:00
Wayne Davison
de584c658c Limit the block-size that the user can specify. 2004-07-16 18:01:30 +00:00
Wayne Davison
6eb770bbcc Improved a sentence about --whole-file. 2004-07-16 17:14:55 +00:00
Wayne Davison
c7e11bfdc0 Make wf_writeBufSize based on a multiple of WRITE_SIZE instead
of the unrelated MAX_MAP_SIZE.
2004-07-16 01:32:02 +00:00
Wayne Davison
94327ff0c2 - Complain and die if --dry-run is used with a batch option.
- Improved the warning if a batch option gets sent to the server.
2004-07-15 19:06:32 +00:00
Wayne Davison
4602eafa87 Changed the batch examples to show how to do a remote read-batch
without first transferring the batch file.
2004-07-15 19:04:54 +00:00
Wayne Davison
bb3edc3b47 Expanded the comment on the new batch code. 2004-07-15 19:03:50 +00:00
Wayne Davison
c769702fe5 Mention that "-" can be used with --read-batch for reading from stdin. 2004-07-15 17:56:11 +00:00
Wayne Davison
dbbab0c4d2 Allow --read-batch=- to indicate stdin. 2004-07-15 17:01:51 +00:00
Wayne Davison
9b3318b0df We no longer refer to a batch "prefix". 2004-07-15 16:27:02 +00:00
Wayne Davison
0fac7fe8b8 Mention new batch-mode changes. 2004-07-15 03:13:09 +00:00
Wayne Davison
b9f592fbf5 My modified version of Chris Shoemaker's improved batch-file handling. 2004-07-15 02:20:08 +00:00
Wayne Davison
c7b1a56b3d Mention recent changes. 2004-07-14 17:11:53 +00:00
Wayne Davison
3896bca4d8 Tweaked some single-line ifs. 2004-07-14 16:41:10 +00:00
Wayne Davison
9774cc3344 The "len" to generate_and_send_sums() is supposed to be an OFF_T. 2004-07-14 16:40:08 +00:00
Wayne Davison
d3979b025d Committed a space-tweak from Chris Shoemaker. 2004-07-14 16:39:08 +00:00
Wayne Davison
01966df4f7 Improved the write_batch_argvs_file() routine so that it doesn't
need the character buffers and so that it properly removes the
hostname from the destination arg.
2004-07-14 07:20:18 +00:00
Wayne Davison
f38bd4a072 Got rid of the disable_deltas_p() function (the whole_file value
is now fully set before the generator forks).
2004-07-13 01:45:51 +00:00
Wayne Davison
b1df18d76f We now conditionally turn on whole_file in do_cmd() right before
calling local_child().
2004-07-13 01:44:03 +00:00
Wayne Davison
7daccb8e72 In generate_files(), changed arg "f" to "f_out", as Chris Shoemaker
suggested.
2004-07-12 20:42:48 +00:00
Wayne Davison
bb91a624f1 Made hard_link_check() compile when SUPPORT_HARD_LINKS isn't enabled. 2004-07-12 07:03:28 +00:00
Wayne Davison
a04d77bcbc Use want_i instead of last_i+1. 2004-07-07 08:38:40 +00:00
Wayne Davison
25bd99451c Make the GID_NONE define a little safer. 2004-07-07 08:25:13 +00:00
Wayne Davison
ed43d0a76d Added some missing $(srcdir) references. 2004-07-04 08:56:31 +00:00
Wayne Davison
066a844c4e Changed a "for" loop into a "do ... while" loop. 2004-07-04 08:07:23 +00:00
Wayne Davison
5e252dea4b Optimized away a loop in hash_search(). 2004-07-02 23:35:30 +00:00
Wayne Davison
d2a918b454 Some formatting tweaks. 2004-07-02 18:23:57 +00:00
Wayne Davison
da38e779ea Moved the verbose message about renaming the finished file down into
finish_transfer() so that it only gets output when we're actually going
to rename the file.
2004-07-02 18:13:53 +00:00
Wayne Davison
8186ae6bc0 Tweaked some formatting. 2004-07-02 18:12:24 +00:00
Wayne Davison
e1f67417d7 Some simple whitespace tweaks. 2004-06-30 07:27:30 +00:00
Wayne Davison
fd322eef82 Made recv_generator static. 2004-06-29 19:19:00 +00:00
Wayne Davison
d3a4375f78 Optimized away a call to cmp_modtime() for a compare-dest file. 2004-06-29 16:22:54 +00:00
Wayne Davison
78112d305b Mention the extended argv-overflow checking. 2004-06-29 15:13:18 +00:00
Wayne Davison
f7c3ee9932 Tweaked an overly-long line. 2004-06-29 15:12:01 +00:00
Wayne Davison
e7a392c77c A few more improvements to the anti-overflow args[] checking. 2004-06-28 17:45:40 +00:00
Wayne Davison
887e553f05 Make sure that do_cmd() doesn't overflow its arg-pointer array
(which was also made larger).
2004-06-28 17:25:14 +00:00
Wayne Davison
beb227ddf1 Got rid of a couple unneeded assignments. 2004-06-24 04:46:02 +00:00
Wayne Davison
84acca07ae Restoring correct skip_file() return semantics. 2004-06-23 21:21:19 +00:00
Wayne Davison
cc1e997dcd Thought skip_file() wasn't returning 1 for "skip" and 0 or "keep"
so I reversed the return.
2004-06-23 16:51:21 +00:00
Wayne Davison
a7026ba90a Fixed a newly-introduced problem in read_timeout() where FD_ZERO(&w_fds)
wasn't always called before w_fds was used.
2004-06-23 01:13:09 +00:00
Wayne Davison
3a69fad0f6 Some trivial format tweaks. 2004-06-20 21:48:06 +00:00
Wayne Davison
40564811ee Mentioned the latest socket change and fixed a few typos. 2004-06-20 20:37:06 +00:00
Wayne Davison
dcd08dc51c Restored the code in the IPV6_V6ONLY section that checks the
return value from setsockopt() with one improvement:  if the
user has used --ipv6 (-6) we don't discard the IPv6 socket.
This should help people using older Linux kernels that don't
implement IPv6 support quite right.
2004-06-20 19:51:19 +00:00
Wayne Davison
fdf57ede8c Tweaked a comment. 2004-06-20 19:47:05 +00:00
Wayne Davison
bd717af8ab Must not call check_timeout() before checking the errno value. 2004-06-19 07:09:57 +00:00
Wayne Davison
c54f5170bf Added some missing changes. 2004-06-19 06:55:58 +00:00
Wayne Davison
eae4e1f9f0 Some minor improved sentences. 2004-06-19 05:52:45 +00:00
Wayne Davison
9c513d678d Tweaked some comments. 2004-06-18 16:55:12 +00:00
Wayne Davison
d16c245fc4 Some helpful comments from Chris Shoemaker. 2004-06-18 16:50:20 +00:00
Wayne Davison
ec8290c897 Fixed some typos in a comment, moved an extern, and made a few
minor format tweaks.
2004-06-18 16:30:24 +00:00
Wayne Davison
b293a7f62c Improved a comment. 2004-06-18 16:29:21 +00:00
Wayne Davison
d67c8bdfc3 Moved the externs to the top and made a few trivial format tweaks. 2004-06-18 16:22:14 +00:00
Wayne Davison
e2ccd3578c Got rid of some trailing whitespace. 2004-06-18 16:00:33 +00:00
Wayne Davison
4e834af140 If --partial was specified, make sure that make_backup is turned
off during the second (retry) phase of the transfer to avoid
making a second backup of a file (which would lose the original).
2004-06-14 15:09:36 +00:00
Wayne Davison
7e5614383d Added a short msleep() after option_error() before we exit. This
ensures that the remote client has time to read our error message
while it is trying to write data to us before it gets a socket
error.
2004-06-13 14:18:48 +00:00
Wayne Davison
eb84a83b47 Changed the new code in delete_one() so that some compilers
don't complain about returning a value from a void function.
2004-06-12 21:30:07 +00:00
Wayne Davison
2c2898a388 Mention the bugfix in option-parsing error-reporting from a daemon. 2004-06-12 18:27:04 +00:00
Wayne Davison
1732b6c037 - Changed some FERROR log calls to FLOG.
- Improved the option-error-reporting to actually get the error back
  to the user (by getting I/O multiplexing started).
2004-06-12 18:22:39 +00:00
Wayne Davison
314f459161 - Made readlink_stat() and link_stat() optionally follow a symlink
to a dir.  This fixes deletions inside "kept" symlinked dirs.
- Call link_stat() with its new arg (for --keep-dirlinks support).
2004-06-11 07:40:57 +00:00
Wayne Davison
83926d3cae Make sure that keep_dirlinks is turned off for the sender. 2004-06-11 07:40:54 +00:00
Wayne Davison
6218c7bf42 - Moved --keep-dirlinks code over to flist.c.
- Call link_stat() with its new arg (for --keep-dirlinks support).
2004-06-11 07:40:51 +00:00
Wayne Davison
566fce3237 Made delete_one() handle a failed rmdir on a symlink when
--keep-dirlinks was specified.
2004-06-11 07:40:48 +00:00
Wayne Davison
373ef16010 Call link_stat() with its new arg (for --keep-dirlinks support). 2004-06-11 07:40:45 +00:00
Wayne Davison
ea76e76104 In set_filesystem(), call do_stat(), not link_stat() to ensure
that we get the directory behind it all.
2004-06-11 05:02:59 +00:00
Wayne Davison
9fd62d1588 The mkdir code should be using do_stat(), not do_lstat() to copy
each existing dir's mode & owner info.
2004-06-10 16:43:52 +00:00
Wayne Davison
b7061c82b4 Allow the argv list the daemon uses for globbing its args to grow. 2004-06-09 21:51:07 +00:00
Wayne Davison
6fb812f747 Removed some excessive parens. 2004-06-09 21:43:28 +00:00
Wayne Davison
40e8d11e64 Mentioned a couple more bugfixes. 2004-06-09 21:42:33 +00:00
Wayne Davison
73042aae5b Restore UNUSED() macro (the prior problems that prompted me to remove
it appear to have been a build-farm bug).
2004-06-09 21:41:21 +00:00
Wayne Davison
e5ce3bcf2c Needed to enclose the new symlink-warning code in an
"#if SUPPORT_LINKS" conditional.
2004-06-09 19:23:56 +00:00
Wayne Davison
c399d22a19 Renamed read_unbuffered() to readfd_unbuffered() so that it matches
writefd_unbuffered().
2004-06-09 03:07:50 +00:00
Wayne Davison
1ea087a794 - Made the maximum-fd computation prior to a select() use the same idiom
in both the read and write code (also use a better variable name).
- Made the bytes-available code at the end of the select() loop use the
  same flow of control in the read and the write code.
2004-06-08 22:18:04 +00:00
Wayne Davison
00bdf89977 Improved a comment in read_msg_fd() and made the byte-reading code
in read_timeout() a little better.
2004-06-08 16:23:54 +00:00
Wayne Davison
0bb4d17634 Improved rwrite() in two ways:
- We no longer assume that the buffer is null terminated (daemon
  mode would ignore the len when logging a message).
- Errors in daemon mode are now sent to both the log and the user.
2004-06-07 22:51:14 +00:00
Wayne Davison
f9c6b3e7d6 Increase the size of the message-receving buffer for error
messages sent from the receiver to the generator.
2004-06-07 22:47:01 +00:00
Wayne Davison
9e5a5ddb4c Changed a few FINFO messages to FLOG. 2004-06-07 22:33:01 +00:00
Wayne Davison
8c0d6a8432 Got rid of some am_daemon games in option_error(). 2004-06-07 22:05:22 +00:00
Wayne Davison
553f93758a Updated some exclude information that has changed. 2004-06-07 21:40:11 +00:00
Wayne Davison
a4a7e64c19 Don't report a "file vanished" error if a symlink points to nowhere
and -L was specified.
2004-06-07 19:59:20 +00:00
Wayne Davison
22832c30a0 Updated a couple things. 2004-06-06 20:41:01 +00:00
Wayne Davison
1a21666286 Tell folks to go to the bug-tracking page to report bugs. 2004-06-06 20:36:56 +00:00
Wayne Davison
4033b80b51 - Got rid of some useless calls to msg_list_push().
- Added a couple checks to ensure that the receiver doesn't mix two
  clashing kinds of writes on the msg_fd_out pipe.
- Made sure that the read code in the receiver flushes the msg_fd_out
  pipe, if needed.
2004-06-06 19:15:58 +00:00
Wayne Davison
99218d821b If the user specifies a small io_timeout value, lower select_timeout. 2004-06-06 19:02:40 +00:00
Wayne Davison
e626b29e10 Make sure our select calls don't sleep for over one minute at a time,
even when io_timeout is a longer value (though the code in options.c
might set it to a shorter value if io_timeout is small).
2004-06-06 19:02:09 +00:00
Wayne Davison
f89b936801 Don't use single-line "if (condition) statement;" idiom. 2004-06-06 18:36:22 +00:00
Wayne Davison
17f59e818d Mention changes to the patches dir. 2004-06-05 21:23:59 +00:00
Wayne Davison
b5bd5542eb Neatened up some of the glob-expand code and made a few other
minor tweaks.
2004-06-05 20:26:56 +00:00
Wayne Davison
2e94e70e2b Some superficial code tweaks. 2004-06-05 19:59:03 +00:00
Wayne Davison
4e1f385711 Mentioned new --keep-dirlinks option. 2004-06-05 16:19:02 +00:00
Wayne Davison
716e73d483 New --keep-dirlinks option. 2004-06-05 16:16:30 +00:00
Wayne Davison
5b36173d11 Mention new SSH_* vars. 2004-06-03 17:20:33 +00:00
Wayne Davison
b2ef4f6134 The daemon-over-ssh code now looks for $SSH_CONNECTION and $SSH2_CLIENT
as well as $SSH_CLIENT to figure out the remote IP address.
2004-06-03 17:20:21 +00:00
Wayne Davison
c7be6dec11 - Added older news from NEWS file.
- Added missing releases from the Partial Protocol History section.
2004-06-01 21:27:52 +00:00
Wayne Davison
bd1574b208 Moved older news to OLDNEWS. 2004-06-01 21:27:12 +00:00
Wayne Davison
f376e67420 Got rid of an unneeded character pointer in send_file_entry(). 2004-05-29 21:21:17 +00:00
Wayne Davison
ef0bc0abff Mention the --bwlimit change. 2004-05-28 19:42:06 +00:00
Wayne Davison
71e586304b Improvements to make --bwlimit work better. 2004-05-27 22:09:31 +00:00
Wayne Davison
3c74c3a358 Set a new variable, bwlimit_writemax, based on the value of the bwlimit
option.
2004-05-27 21:51:53 +00:00
Wayne Davison
edad5898f2 Got rid of a superfluous call to gettimeofday(). 2004-05-24 22:59:16 +00:00
Wayne Davison
fa0c1939ed The various include/exclude options are not used on the server side,
so if someone is trying something funny, just quit.
2004-05-24 18:38:05 +00:00
Wayne Davison
9a5ade185c Made full_fname()'s char-pointer arg const. 2004-05-24 08:10:22 +00:00
Wayne Davison
f1dd0f27cb - Properly quote the $excl references.
- Moved the creation of our .cvsignore exclude file.
2004-05-24 00:16:07 +00:00
Wayne Davison
f9e5a0cde2 Improved the depth calculation in sanitize_path() so that it properly
handles a trailing slash, a leading slash, and an empty string.
2004-05-23 23:46:56 +00:00
Wayne Davison
ead751c62b Moved a couple lines. 2004-05-22 19:29:53 +00:00
Wayne Davison
0058c58edd A few minor improvements to the existing items. 2004-05-22 19:24:24 +00:00
Wayne Davison
221ddb9456 Fixed a typo in the sending of the --checksum-seed option to the server. 2004-05-22 06:09:22 +00:00
Wayne Davison
65e2487096 Fixed the comment for get_exclude_tok(). 2004-05-22 05:32:20 +00:00
Wayne Davison
0501f36390 Tweaked the alloc/realloc code in flist_expand(). 2004-05-21 23:22:14 +00:00
Wayne Davison
96981b9cff Tell rsync to preserve permissions. 2004-05-21 10:06:09 +00:00
Wayne Davison
f51e87f5ad Another new option. 2004-05-21 10:00:21 +00:00
Wayne Davison
cb213f1c1b Got rid of a compiler warning (which was only output by certain
compilers).
2004-05-21 09:59:49 +00:00
Wayne Davison
c8d895de26 Added the --checksum-seed option. 2004-05-21 09:44:32 +00:00
Wayne Davison
e51094b721 - Improved option_error() to make sure that the user sees the error in
daemon mode.
- Got rid of some repetitious outputting of the same error-message.
2004-05-21 09:41:38 +00:00
Wayne Davison
b03bded70b Document a couple more changes. 2004-05-21 09:29:17 +00:00
Wayne Davison
ee1df1ccae If --backup was specified without a --backup-dir, don't preserve the
directory timestamps.
2004-05-21 08:43:03 +00:00
Wayne Davison
bc6ebcd248 Moved a few externs. 2004-05-21 08:40:25 +00:00
Wayne Davison
ba582f753a Changed sum_init() to take a seed value as an arg instead of always
using checksum_init.  This fixes an authentication problem in server
mode (as pointed out by Craig Barratt).
2004-05-21 08:27:04 +00:00
Wayne Davison
cbd85b472e - Mention the change to the daemon-mode's exclude handling.
- Mention the new "write only" daemon-config option.
- Fixed another entry to refer to the right files.
2004-05-19 22:20:56 +00:00
Wayne Davison
7a92ded39a Added the "write only" option to the daemon config file. 2004-05-19 22:19:19 +00:00
Wayne Davison
831f05df51 A few minor text improvements. 2004-05-18 09:54:52 +00:00
Wayne Davison
0d94a6a66c Added a little more quoting. 2004-05-18 09:47:42 +00:00
Wayne Davison
3e35c34b6b Output a message when we skip a server-excluded file. 2004-05-18 08:50:17 +00:00
Wayne Davison
03a9ca0a97 Document the latest changes. 2004-05-18 01:13:14 +00:00
Wayne Davison
6f481bb0e0 - Use fromdir, todir, and tmpdir instead of FROM, TO, and TMP.
- Added chkdir.
- Quote the dir expansions to avoid problems with spaces.
- Added "exclude = foobar.baz" the the rsync.conf file we create.
2004-05-18 00:41:55 +00:00
Wayne Davison
f98cc5685d Test that a config-file-specified exclude works right. 2004-05-18 00:41:51 +00:00
Wayne Davison
9135621ff9 Quote the dir expansions to avoid problems with spaces. 2004-05-18 00:41:49 +00:00
Wayne Davison
8624daa7f8 - Use fromdir and todir instead of FROM and TO.
- Quote the dir expansions to avoid problems with spaces.
2004-05-18 00:41:46 +00:00
Wayne Davison
3051c46dc3 - Use $suitedir to find rsync.fns.
- Use tmpdir instead of TMP.
2004-05-18 00:41:43 +00:00
Wayne Davison
e920830ec5 Use $suitedir to find rsync.fns. 2004-05-18 00:41:40 +00:00
Wayne Davison
7892e5ac77 - Use $suitedir to find rsync.fns.
- The values of fromdir, todir, and chkdir are already set.
2004-05-18 00:41:38 +00:00
Wayne Davison
b0e9bafc78 - Use $suitedir to find rsync.fns.
- The values of fromdir and todir are already set.
2004-05-18 00:41:35 +00:00
Wayne Davison
44aa070770 Removing obsoleted test.sh file (we used the runtests.sh framework for
some time now).
2004-05-18 00:32:36 +00:00
Wayne Davison
97f9dcae6a If the server has excluded a file, we now exclude it from being
uploaded as well as downloaded.
2004-05-18 00:14:10 +00:00
Wayne Davison
8cbf495a57 Renamed free_exclude_list() to clear_exclude_list(). 2004-05-16 23:54:12 +00:00
Wayne Davison
c1b29492c5 Moved the setting of ret->match_flags up a little in make_exclude(). 2004-05-16 14:08:34 +00:00
Wayne Davison
669a31924e - Save some memory in each exclude_struct item by dumping the "include"
and "directory" ints and using bits in the match_flags value instead.
- Added defines for the new match-flag values, including a new one that
  lets get_exclude_tok() properly return an indication that it parsed
  the list-clearing token.
2004-05-16 07:28:24 +00:00
Wayne Davison
5e972dcf34 - Switched the "include" and "directory" ints into bits in match_flags.
- Made some length vars unsigned.
2004-05-16 07:28:21 +00:00
Wayne Davison
8fcdc444df - Improved rsyserr() to prefix RSYNC_NAME (as the TODO requested),
to construct the string in a better manner, and to have a buffer
  big enough to hold a full MAXPATHLEN filename plus some error
  text.
- Fixed some comments referring to vsprintf() returning -1 -- our
  configuration process now ensures that we replace such a function
  with our own lib version.
2004-05-15 19:31:16 +00:00
Wayne Davison
619d21ffc9 - Complain about an exclude that was too long and then dump it
(used to be silently truncated).
- Include extra space in our exclude-reading buffers so that we
  can fit a 2-char prefix and a trailing slash and still handle
  a MAXPATHLEN name.
2004-05-15 19:31:13 +00:00
Wayne Davison
d62bcc17f3 Changed rprintf() calls that included strerror() to use rsyserr(). 2004-05-15 19:31:10 +00:00
Wayne Davison
982e05bbd5 Changed rprintf() calls that included strerror() to use rsyserr(). 2004-05-15 19:31:10 +00:00
Wayne Davison
a3c8b36863 Added rsyserr(). 2004-05-15 19:31:05 +00:00
Wayne Davison
630e3c408b Whitespace tweaks. 2004-05-15 19:09:42 +00:00
Wayne Davison
1082b52bd4 Changing if (!write_batch) in front of send_exclude_list() to
if (!read_batch) -- fixes hang.
2004-05-15 18:51:21 +00:00
Wayne Davison
914f3066bb Added a "gen" rule to remake various generated files: configure,
config.h.in, proto.h, rsync.1, and rsyncd.conf.5 .
2004-05-15 00:48:11 +00:00
Wayne Davison
de91e75724 In the debug output, distinguish between a user-requested clearing
of the exclude list and the popping of the local exclude list that
occurs when we finish each subdir.
2004-05-14 21:23:41 +00:00
Wayne Davison
384431886a Changed PERMS_SKIP_TIME to PERMS_SKIP_MTIME. 2004-05-13 18:51:22 +00:00
Wayne Davison
82b302d928 Got rid of some useless externs. 2004-05-13 18:41:17 +00:00
Wayne Davison
4ecc9e6b64 The finish_transfer() call takes an arg that specifies if we should set the
modtime or not on the finished file.  It calls set_perms(), which now takes a
flag arg that allows us to specify if we want to skip the modtime modification.
2004-05-13 07:08:25 +00:00
Wayne Davison
55e50d890b If the file did not transfer correctly, only save it if --partial was
specified.  We also skip the setting of the modtime too on a partial
copy (that way the partial file won't be confused with an up-to-date
copy of the original).
2004-05-13 07:08:22 +00:00
Wayne Davison
6e86c951d7 Call finish_transfer() with its new arg. Also put the externs
at the top and got rid of some trailing whitespace.
2004-05-13 07:08:18 +00:00
Wayne Davison
c41b52c487 Use the new PERMS_REPORT flag when calling set_perms(). 2004-05-13 06:55:01 +00:00
Wayne Davison
5c6fc4a6a3 Added PERMS_REPORT and PERMS_SKIP_TIME. 2004-05-13 06:53:23 +00:00
Wayne Davison
edecdad54d If we got a read-error on a file, make sure that the whole-file
checksum we send to the receiver is wrong (so they won't save
the bogus file).
2004-05-13 06:46:20 +00:00
Wayne Davison
5291364f1d Don't force the modtime on our backup dirs -- the dirs in the
backup hierarchy should have their own timestamps.
2004-05-13 06:34:03 +00:00
Wayne Davison
41cc97ae64 In send_files(), changed the name of the map_struct variable from
"buf" to "mbuf" (so that it wouldn't be so similar to the "buff"
variable nor use a name that is more typically a char* buffer).
2004-05-11 19:53:16 +00:00
Wayne Davison
bf2b7ddfc5 Use memset() to initialize a new map_struct. 2004-05-11 19:46:56 +00:00
Wayne Davison
eb0cbdaa90 Got rid of an unused extern. 2004-05-11 17:25:16 +00:00
Wayne Davison
0d0142e812 Got rid of unused externs. 2004-05-11 17:25:01 +00:00
Wayne Davison
a43e21e05c Let's just remove all the UNUSED() macros for now. 2004-05-08 22:49:58 +00:00
Wayne Davison
4135d091a6 Changed the non-globbing version of glob_expand_one() so that it
checks the maxargs argument instead of leaving it unused.
2004-05-08 20:03:39 +00:00
Wayne Davison
534407b1f4 One more attempt to get HP-UX's cc to build popt successfully. 2004-05-08 19:50:22 +00:00
Wayne Davison
18cc8c7ef1 Improved a comment and got rid of some trailing whitespace. 2004-05-08 19:37:28 +00:00
Wayne Davison
58c9b4b7f6 Tweaked the sizeof syntax and some multi-statement lines. 2004-05-08 19:26:53 +00:00
Wayne Davison
cde719f49f Changed the order of the msgcode enum so that new items now get added
at the start (which avoids the need for trailing-comma changes on old
entries when new ones are added).
2004-05-08 18:48:09 +00:00
Wayne Davison
38cab94d9a - Improved the get_secret()'s function comments, made it accept a line
that doesn't end with a newline, and optimized it a bit.
- Improved getpassf() to work if the line does not end with a newline.
2004-05-08 18:18:42 +00:00
Wayne Davison
6ed6d7f5a8 Improved the function comments for read_line() and slightly tweaked
its code.  Also changed "IO" to "I/O" in various comments.
2004-05-08 18:03:43 +00:00
Wayne Davison
e40a46de71 Document the -4, -6, --ipv4, --ipv6 options. 2004-05-07 00:18:37 +00:00
Wayne Davison
c5bf99a1c2 Correct a typo. 2004-05-06 21:29:36 +00:00
Wayne Davison
2c7d63c765 - Updated the comments for open_socket_in().
- Changed open_socket_in() to return an array of ints with a trailing -1
  value to indicate the end of the list.
- Use the out_of_memory() routine to complain about no memory.
- Undid the recent IPV6_V6ONLY change, as I think it would prevent the
  use of IPv6 sockets on some older systems.
- If we get an EADDRINUSE error and this is not the first socket in the
  list, suggest that the user try --ipv4 or --ipv6.
- When forking, the child now closes all the open bound sockets, not just
  one of them (I'm not talking about the fd from accept(), obviously).
2004-05-06 21:26:46 +00:00
Wayne Davison
3dd22903ac Introduced long-option names for -4 and -6. 2004-05-06 21:08:01 +00:00
Wayne Davison
d8d36af452 If we need to set IPV6_V6ONLY but setsockopt() fails, close the
socket and skip it.
2004-05-05 22:17:48 +00:00
Wayne Davison
e610e50f9c Added missing extern for read_batch. 2004-05-05 17:15:03 +00:00
Wayne Davison
935c64173f Don't force the whole-file option when using read-batch. 2004-05-05 16:23:49 +00:00
Wayne Davison
377dbd2075 Calls to make_bak_dir() should only happen when we fail to create a
file/dir/etc. with errno == ENOENT.
2004-05-04 03:10:45 +00:00
Wayne Davison
93272700d2 A slight refinement to my last patch. 2004-05-03 01:24:10 +00:00
Wayne Davison
d508258ad8 Fixed crash bug that can affect --delete in certain circumstances. 2004-05-03 01:18:07 +00:00
Wayne Davison
f57b2e6150 Got rid of a TODO comment that was fixed long ago. 2004-05-02 17:04:14 +00:00
Wayne Davison
af45f9e27e Renamed variable STRIP to INSTALL_STRIP to avoid an accidental match
with an environment variable in OpenBSD.
2004-05-02 16:52:52 +00:00
Wayne Davison
4c4d61b046 Got rid of trailing comma in an enum. 2004-05-02 16:34:33 +00:00
Wayne Davison
7561c3e132 Moved some news items under new headings. 2004-04-30 21:10:58 +00:00
Wayne Davison
1514ad2a80 Changed the order that ssh and rsh are mentioned. 2004-04-30 20:39:29 +00:00
Wayne Davison
d8195637d4 Additional testing confirmed the limited scope of the sources affected
by the -R sorting bug.
2004-04-30 19:14:52 +00:00
Wayne Davison
c8d771a0fb Preparing for release of 2.6.2 2004-04-30 18:03:33 +00:00
Wayne Davison
9130776c4e Mention the last few tweaks that made it into 2.6.2. 2004-04-30 17:53:51 +00:00
Wayne Davison
9eac94a4dd Improved the program that checks for broken large-file locking. 2004-04-30 17:38:22 +00:00
Wayne Davison
6e06d2f31a Don't rely on the local shell's wildcard expansion to make the test
work right -- it might not be quite as compatible as we need.
2004-04-30 17:24:49 +00:00
Wayne Davison
6a6d21136a Only refer to AI_NUMERICHOST if it is defined. 2004-04-30 16:10:45 +00:00
Wayne Davison
f28bd83346 Fixed a few typos. 2004-04-30 15:46:41 +00:00
Wayne Davison
96fb478eae Mention the desire to improve how a daemon returns errors. 2004-04-29 21:12:46 +00:00
Wayne Davison
8752b3fcd8 Describe the changes for 2.6.2. 2004-04-29 21:09:33 +00:00
Wayne Davison
55ffed7e42 Preparing for release of 2.6.2pre1 2004-04-29 20:36:22 +00:00
Wayne Davison
e00df64bae Got rid of unused check for sys/sysctl.h. 2004-04-29 19:40:17 +00:00
Wayne Davison
080ddf58ae Fixed a sorting problem when an entry has an empty (but not NULL)
dirname (which I had thought impossible, but it appears to occur
with --relative in some instances).
2004-04-29 19:37:15 +00:00
Wayne Davison
4ce48a5bfd Restore old behavior of logging most daemon errors instead of sending
them to the user.  This should eventually be improved to duplicate
some of these messages to the user to keep them informed about what
went wrong.
2004-04-29 19:34:31 +00:00
Wayne Davison
20bf7f847f Undefined __attribute__ in some circumstances. 2004-04-28 17:35:08 +00:00
Wayne Davison
b66d00853b Fixed the use of an uninitialized variable in map_uid() and map_gid(). 2004-04-28 17:31:31 +00:00
Wayne Davison
8b602edda4 In copy_file(), check len < 0 before checking the close() return values. 2004-04-27 19:59:37 +00:00
Wayne Davison
9f27cd8ca6 Check the return code from close() and output an error if it
fails.
2004-04-27 19:51:33 +00:00
Wayne Davison
b084f9e092 Got rid of a debug-output statement. 2004-04-27 16:41:33 +00:00
Wayne Davison
4220e1098e Preparing for release of 2.6.1 2004-04-27 03:55:37 +00:00
Wayne Davison
c30468169a - Tweaked the bullet char so that vim can auto-format the items more
easily (and then used vim to re-flow the items).
- Added a mention about the daemon security fix.
- Added the 2.6.1 release date.
2004-04-27 03:53:28 +00:00
Wayne Davison
c0d9e8c76b - Changed XFLG_NO_PREFIXES to XFLG_WORDS_ONLY.
- Got rid of HP-UX kludge (since it didn't help).
2004-04-27 01:36:16 +00:00
Wayne Davison
90a973fe8a Changed XFLG_NO_PREFIXES to XFLG_WORDS_ONLY. 2004-04-27 01:36:10 +00:00
Wayne Davison
7f0feb4dd6 - Changed XFLG_NO_PREFIXES to XFLG_WORDS_ONLY.
- Don't parse comment lines in add_exclude_file() when XFLG_WORD_SPLIT
  is set.
2004-04-27 01:36:06 +00:00
Wayne Davison
33a5432ea6 Got rid of HP-UX kludge (since it didn't help). 2004-04-27 01:36:00 +00:00
Wayne Davison
968ff560d2 Made a comment clearer. 2004-04-27 01:00:58 +00:00
Wayne Davison
cd59be1d5e One more try at getting the HP-UX system in the build farm to compile
popt.
2004-04-25 20:36:41 +00:00
Wayne Davison
8b2869c0d2 Don't use __attribute__((__unused__)) on HP-UX w/o gcc. 2004-04-25 16:10:09 +00:00
Wayne Davison
82a51ea53d Improved the debug string for the local_exclude_list. 2004-04-24 08:00:39 +00:00
Wayne Davison
20af605eba Improved the EXCLUDE PATTERNS section some more. 2004-04-24 06:16:04 +00:00
Wayne Davison
a6536635e3 Fixed a comment. 2004-04-23 08:09:13 +00:00
Wayne Davison
adddd075eb Mention how --update behaves when the type of the file differs on
the source and destination systems.
2004-04-23 05:14:39 +00:00
Wayne Davison
a0c823b22b Recently added caveat is no longer true. 2004-04-23 01:33:35 +00:00
Wayne Davison
9fdb334e85 Restore the old include behavior where a command-line include could
override a .cvsignore exclude.
2004-04-22 22:17:15 +00:00
Wayne Davison
f89e890b87 Got rid of a wrong paragraph. 2004-04-22 21:35:45 +00:00
Wayne Davison
1c666c3fcb Got rid of a bunch of cruft. 2004-04-22 21:17:58 +00:00
Wayne Davison
2a383be0f1 Updated the default list of cvs-excluded files and added some extra
info on how the option interacts with other include/exclude rules.
2004-04-22 18:17:30 +00:00
Wayne Davison
ac1d2d3384 Added "debug_type" to the exclude_list_struct. 2004-04-22 09:58:24 +00:00
Wayne Davison
acfcfa7053 No need to pass a debug string to check_exclude() anymore. 2004-04-22 09:58:21 +00:00
Wayne Davison
8ef81dd452 No need to pass a debug string to check_exclude() anymore. When we
free an exclude list, make sure we don't clear the debug_type string.
2004-04-22 09:58:18 +00:00
Wayne Davison
67340e9523 Initialize the new debug_type string in each exclude list and output
it in a couple extra debug messages.  When we free an exclude list,
make sure we don't clear the debug_type string.
2004-04-22 09:58:15 +00:00
Wayne Davison
a7ceddae34 Changed check_exclude()'s prototype. 2004-04-22 09:58:11 +00:00
Wayne Davison
24e1569f8b The debug output for add_exclude() now needs to limit the pattern to
print only "pat_len" chars.
2004-04-22 08:41:03 +00:00
Wayne Davison
de31639fff A couple minor text improvements. 2004-04-19 17:52:39 +00:00
Wayne Davison
8b46340924 Mentioned the better handling of option paths when a daemon is not
running with chroot enabled.
2004-04-18 06:29:06 +00:00
Wayne Davison
d008bcb5cd Made the device-changes section agree with the latest code. 2004-04-17 19:58:12 +00:00
Wayne Davison
0484b5b0b7 Preparing for release of 2.6.1pre-2 2004-04-17 18:40:16 +00:00
Wayne Davison
f01b6368a5 Mention that --from0 does not affect --cvs-exclude's reading of the
.cvsignore files.
2004-04-17 18:12:33 +00:00
Wayne Davison
40d38dc0be In add_exclude_file(), if we're word-splitting, stop reading a "line"
at any whitespace (so that we don't overflow the line buffer).
2004-04-17 17:55:45 +00:00
Wayne Davison
33a2361cc2 The inode and dev values in the idev struct are now uint64. 2004-04-17 17:14:16 +00:00
Wayne Davison
4124540d61 Changed the dev handling for -H back to using an opaque 64-bit
integer instead of trying to transfer it as separate major & minor
values.  Since the value is not interpreted by the receiving side
(just compared for equality), this is a safer way to go.
2004-04-17 17:14:12 +00:00
Wayne Davison
5f38126817 Use "uint64" instead of INO64_T (which is now gone). 2004-04-17 17:07:23 +00:00
Wayne Davison
b05b3c9b48 Fixed alloc_sanitize_path()'s handling of a rootdir == "/" (the old
code would generate a string that started with "//" instead of "/").
2004-04-17 17:06:03 +00:00
Wayne Davison
a03a9f4efe Don't say "skipped" if the file is just not being transferred (i.e.
when other updates, such as owner/permissions/etc. might be made).
2004-04-15 18:32:24 +00:00
Wayne Davison
3e55030372 Mention exclude improvements. 2004-04-15 18:23:52 +00:00
Wayne Davison
273c0420d0 Got rid of a couple useless lines. 2004-04-15 18:22:56 +00:00
Wayne Davison
5774786fa5 Moved some externs. 2004-04-15 16:55:23 +00:00
Wayne Davison
1a9ec1fd1c Got rid of zlib/dummy ("dummy" is in the zlib .cvsignore, where it
should be).
2004-04-15 06:54:14 +00:00
Wayne Davison
b2aa573b1c Our exclude lists are now comprised of a base structure with a head
and a tail pointer pointing to a linked list of items (rather than
an array of pointers that has to be reallocated all the time).
2004-04-14 23:33:40 +00:00
Wayne Davison
63d0331991 Added a "next" pointer to "exclude_struct" and added a new structure
for exclude lists, exclude_list_struct, that holds the head/tail
pointers for the list.
2004-04-14 23:33:37 +00:00
Wayne Davison
bf6dcd1713 Updated the exclude-list code to handle the new linked-list
structure format.
2004-04-14 23:33:34 +00:00
Wayne Davison
495723bb26 Updated the exclude-list code to handle the new linked-list
structure format.
2004-04-14 23:33:34 +00:00
Wayne Davison
911cb0662c Updated stub version of check_exclude(). 2004-04-14 22:49:54 +00:00
Wayne Davison
5387514eaf Added a description arg to check_exclude(). 2004-04-14 21:59:45 +00:00
Wayne Davison
61414c83ce The check_exclude() and report_exclude_result() functions now take a
description string that describes what kind of an include/exclude is
happening (which only gets output when verbose is set to 2 or more).
2004-04-14 21:59:41 +00:00
Wayne Davison
43a9d0e7c2 Improved the exclude testing by adding tests that exercise --cvs-exclude
and --delete-excluded.
2004-04-14 20:50:32 +00:00
Wayne Davison
df5cd107a5 Moved (and expanded) a verbose message from clientserver.c to socket.c
to solve an old FIXME comment.
2004-04-14 16:51:48 +00:00
Wayne Davison
abca4eba67 Fixed a potential problem parsing the "!" token from a word-split string. 2004-04-13 19:07:21 +00:00
Wayne Davison
96d3590a08 A few more improvements to get_exclude_tok() and add_exclude(). 2004-04-13 18:35:08 +00:00
Wayne Davison
8429aa9e0e Added an example for --link-dest. 2004-04-13 00:32:58 +00:00
Wayne Davison
79d4053048 Updated with latest news and some spelling mistakes corrected. 2004-04-12 18:03:08 +00:00
Wayne Davison
753b6b4692 Replaced MISSING_OK, MISSING_FATAL, ADD_INCLUDE, and ADD_EXCLUDE with
some new XFLG_* values (for the add_exclude*() function).
2004-04-12 17:42:35 +00:00
Wayne Davison
f8f726449b - add_exclude() now takes a flag int and can optionally word-split
items and/or ignore +/- prefixes.
- add_exclude_file() changed to take the same flags as add_exclude().
- add_exclude_line() was removed since add_exclude() can now do its job.
- make_exclude() now takes a size-limited string without a +/- prefix.
- add_cvs_excludes() was changed to word-split the items that come from
  a .cvsignore file, and to ignore all +/- prefixes in all the ignore
  sources.  Since CVS doesn't check if its ignore items are directories,
  the dir-names (e.g. SCCS, CVS, etc.) no longer have a trailing slash
  (making our excludes match CVS's ignores more exactly).
2004-04-12 17:42:32 +00:00
Wayne Davison
357406ecb2 Use the new XFLG_* flags to call the add_exclude*() functions. 2004-04-12 17:42:29 +00:00
Wayne Davison
3915fd7583 No need to cast st.st_rdev to DEV64_T anymore. 2004-04-12 16:52:43 +00:00
Wayne Davison
9c5e91f848 - Use dev_t instead of DEV64_T.
- Changed rdev_high to rdev_major.
- Use major(), minor(), and makedev() to manipulate device numbers.
- Send the major and minor values separately in protocol 28 and beyond.
2004-04-12 16:52:40 +00:00
Wayne Davison
af107f6c08 - Got rid of DEV64_T and changed the internal device variables to dev_t.
- Changed XMIT_SAME_HIGH_RDEV to XMIT_SAME_RDEV_MAJOR.
- Added XMIT_RDEV_MINOR_IS_SMALL.
2004-04-12 16:52:37 +00:00
Wayne Davison
a3dbb20a0e Fixed a bug where an exclude name that got sent over the wire could get
an extra "- " or "+ " parsed off the start of the name (i.e. we have to
quote excluded names that start with those strings with an extra "- "
at the start).
2004-04-10 10:31:11 +00:00
Wayne Davison
a3779426b6 UNUSED() misbehaves on HP-UX, not AIX. 2004-04-09 22:25:33 +00:00
Wayne Davison
2f5ca63d92 AIX doesn't like our UNUSED() macro, so let's eliminate it for them. 2004-04-09 21:51:34 +00:00
Wayne Davison
0e1d98ae92 Silence compiler warnings on Solaris. 2004-04-09 20:22:44 +00:00
Wayne Davison
04575bcab5 Missed one void-pointer-arithmetic case. 2004-04-09 20:17:01 +00:00
Wayne Davison
71b291d71b AIX's cc was complaining about the void* arithmetic. 2004-04-09 19:53:50 +00:00
Wayne Davison
decba3ae73 Removed debug code. 2004-04-09 19:18:34 +00:00
Wayne Davison
f8ed564c9f Changed sysmacros.h to sys/sysmacros.h. 2004-04-09 19:04:03 +00:00
Wayne Davison
47ba39bef6 Added some test code to assist in the remote debugging of the build
farm's Solaris machines.
2004-04-09 18:36:01 +00:00
Wayne Davison
71f7051489 Use MAJOR_IN_MKDEV and MAJOR_IN_SYSMACROS. 2004-04-09 18:10:03 +00:00
Wayne Davison
3c3791e8be Use AC_HEADER_MAJOR for better makedev/major/minor determination. 2004-04-09 18:09:16 +00:00
Wayne Davison
c39d6514ab Include <sys/mkdev.h> if it exists. 2004-04-09 17:59:50 +00:00
Wayne Davison
1cb6f3bf4d Added sys/mkdev.h to the searched-for headers. 2004-04-09 17:56:58 +00:00
Wayne Davison
f09dc86ab6 Added a couple extra character devices to be copied. 2004-04-09 00:36:45 +00:00
Wayne Davison
f26ac1e8cb If we're listing a device, output the major and minor device numbers. 2004-04-09 00:33:34 +00:00
Wayne Davison
84a3efa0ab Simplify the setting of rdev & rdev_high in send_file_entry(). 2004-04-08 23:15:39 +00:00
Wayne Davison
00ed4b5bf3 Fixed a bug in the sending of rdev when the high-bits match. 2004-04-08 23:05:36 +00:00
Wayne Davison
e2e053bbd7 Explicitly cast our ~0xFF mask using ~(DEV64_T)0xFF, just to be sure
(sign-extention would have probably made the former work OK).
2004-04-08 21:51:49 +00:00
Wayne Davison
f8b33ab379 Mention the rsync-daemon fix for --sufix=''. 2004-04-07 23:13:02 +00:00
Wayne Davison
5df1fcf245 If --daemon was specified, exit the option-parsing code before
adjusting various default values (the real defaults will get
set when the client's options arrive).
2004-04-07 23:09:14 +00:00
Wayne Davison
b1ad6a3260 Added a couple missing items. 2004-04-05 15:05:46 +00:00
Wayne Davison
6442ccc606 Decided against "Source root" in the exclude/include examples. 2004-04-03 20:47:54 +00:00
Wayne Davison
b21813060c Mentioned the CoW improvement and got rid of a bug-fix mention that
was for a bug introduced during the 2.6.1 developement.
2004-04-03 18:13:51 +00:00
Wayne Davison
706c75307a Use getaddrinfo() to figure out if a numeric address is IPv4 or IPv6. 2004-04-01 21:39:35 +00:00
Wayne Davison
2b284ee33d Last of the cleanup before the patching starts. 2004-04-01 21:08:24 +00:00
Wayne Davison
4cfa6156e3 A couple more minor twiddles. 2004-04-01 20:56:50 +00:00
Wayne Davison
c1e7217fcb Updated the sizeof syntax and trimmed some trailing whitespace. 2004-04-01 20:53:39 +00:00
Wayne Davison
4b2f6a7c37 Decided to use "nobody" instead of "guest". 2004-04-01 18:05:40 +00:00
Wayne Davison
a8726d2a06 Some more IOERR_VANISHED support. 2004-04-01 18:04:59 +00:00
Wayne Davison
b5ebe6d9c7 Improved the include/exclude example section some more. Document
the new username default of "guest" if neither USER or LOGNAME is
set in the environment.
2004-03-31 18:53:57 +00:00
Wayne Davison
ef383c0d32 The auth_client function must not return without outputting something
on the socket, so a NULL or empty username now defaults to "guest".
2004-03-31 18:52:38 +00:00
Wayne Davison
8dcf93356e Don't complain about a null --suffix if we're the server/sender (since
we might not have received the --backup-dir path from the client).
2004-03-31 17:02:22 +00:00
Martin Pool
ce5f2732e4 I'm no longer maintaining this. Tell people to use the lists instead. 2004-03-31 02:48:47 +00:00
Wayne Davison
3e89da86df The --files-from option needs to allow a server-sender to sometimes
have just 1 arg on the command-line.
2004-03-30 02:08:07 +00:00
Wayne Davison
f5450e791d Try to avoid running on a system that allows us to create devices
without being root (like cygwin) because rsync won't copy the
devices if it is not root.
2004-03-29 17:02:31 +00:00
Wayne Davison
cb984e620e In sigchild_handler(), finish with waitpid() before reinitializing
the SIGCHLD handling.
2004-03-29 16:30:53 +00:00
Wayne Davison
be92ac6c36 Added one more example to the new include/exclude section to show how
--relative works with a non-absolute path.
2004-03-27 20:04:04 +00:00
Wayne Davison
5dc6e9c9ca Mention that certain options treat an absolute path as relative to the
module's "path" dir, even when chroot is off.
2004-03-27 19:47:27 +00:00
Wayne Davison
0b79c324ca Improved the "relative to the destination dir" description for
several options.
2004-03-27 19:46:28 +00:00
Wayne Davison
f39b6638f6 Got rid of debug-output statement. 2004-03-27 19:42:13 +00:00
Wayne Davison
a4b6f30579 Try to make the complexities of includes/excludes a little more clear. 2004-03-27 18:25:41 +00:00
Wayne Davison
7be73df4e7 Optionally sanitize the args in parse_arguments() using the new
alloc_sanitize_path() function.
2004-03-27 09:46:42 +00:00
Wayne Davison
14b61c63f0 Added alloc_sanitize_path(). 2004-03-27 09:44:49 +00:00
Wayne Davison
75a64762c2 The args are now sanitized in parse_arguments() instead of here. 2004-03-27 09:44:01 +00:00
Wayne Davison
028fdddb49 Fixed a crash bug when hlink_list is NULL and a link_u.links
pointer in one of the file_struct nodes is not.
2004-03-26 16:46:20 +00:00
Wayne Davison
f86b0f2e7b Fixed a typo and made a sentence read better. 2004-03-26 15:51:51 +00:00
Wayne Davison
285fba0759 Preparing for release of 2.6.1pre-1 2004-03-24 21:59:07 +00:00
Wayne Davison
92b9eb978e Moved a few externs and made a couple formatting tweaks. 2004-03-23 16:50:40 +00:00
Wayne Davison
1e82e2cea6 Got rid of an ancient (and no longer relevant) comment. 2004-03-23 16:36:00 +00:00
Wayne Davison
a7ed6ca618 A few formatting tweaks in delete_file(). 2004-03-23 16:16:15 +00:00
Wayne Davison
b4b90120ff Fixed the test for sin_len as noted by Shinichi Maruyama. Changed
the define name generated for this test and the sa_len test.
2004-03-16 01:26:39 +00:00
Wayne Davison
16f72adc49 Changed HAVE_SOCKADDR_SIN_LEN to HAVE_SOCKADDR_IN_LEN. 2004-03-16 01:26:31 +00:00
Wayne Davison
3d06165389 Check robust_rename()'s return value using < 0. 2004-03-13 20:18:03 +00:00
Wayne Davison
fd4893155d Mention the changes in the "patches" dir. 2004-03-10 08:32:38 +00:00
Wayne Davison
67e78a8231 Use CHMOD_BITS instead of ~_S_IFMT. 2004-03-07 20:29:59 +00:00
Wayne Davison
6b320e4045 Improved an entry. 2004-03-06 20:07:24 +00:00
Wayne Davison
7e5cb90983 Other files use S_IWUSR instead of S_IWRITE, so use S_IWUSR and S_IRUSR. 2004-03-06 07:45:52 +00:00
Wayne Davison
8120a98f47 Define S_IRUSR if it doesn't already exist. 2004-03-06 07:43:55 +00:00
Wayne Davison
8f3f8eec08 Updated to version from autoconf 2.59 (2003-10-03). 2004-03-06 07:00:47 +00:00
Wayne Davison
386b93dc60 Updated to version from autoconf 2.59 (2003-08-18). 2004-03-06 07:00:16 +00:00
Wayne Davison
b3bc31102c Moved out the old news and improved the new. 2004-03-04 19:36:28 +00:00
Wayne Davison
0f1aa0d3e5 Moved the previous release's NEWS here. 2004-03-04 19:35:57 +00:00
Wayne Davison
7a08ae31d2 Progress improvement. 2004-02-28 02:02:37 +00:00
Wayne Davison
304f127f56 Improved the progress reporting/E.T.A. using a (slightly modifed)
patch from Timo Sirainen.
2004-02-28 02:00:57 +00:00
Wayne Davison
c338460d66 Got rid of some superfluous parens. 2004-02-27 08:03:49 +00:00
Wayne Davison
48d704af52 Tru64 fix. 2004-02-27 07:37:43 +00:00
Wayne Davison
ac7aa92290 Use new HAVE_SOCKADDR_SIN_LEN define (replaces HAVE_SOCKADDR_LEN). 2004-02-27 07:22:40 +00:00
Wayne Davison
0042f81894 We now set HAVE_SOCKADDR_SA_LEN and HAVE_SOCKADDR_SIN_LEN based on
sockaddr.sa_len and sockaddr.sin_len, respectively (replacing
HAVE_SOCKADDR_LEN).
2004-02-27 07:22:39 +00:00
Wayne Davison
2c836acb37 No longer needed. 2004-02-26 04:03:44 +00:00
Wayne Davison
a1d8f29a3d A couple AC_DEFINE() changes so that we can do without acconfig.h. 2004-02-26 04:03:35 +00:00
Wayne Davison
a174e1ed0f Tweaked some comments and some whitespace. 2004-02-25 21:20:59 +00:00
Wayne Davison
530adb7625 Configure addition. 2004-02-23 20:09:14 +00:00
Wayne Davison
cd3fe9fb03 Allow the default (system) rsyncd.conf file to be specified via configure. 2004-02-23 20:00:20 +00:00
Wayne Davison
a8edfd53d1 Trivial whitespace tweak. 2004-02-23 19:23:53 +00:00
Wayne Davison
dbb665180c Shouldn't ignore .cvsignore. 2004-02-23 18:19:13 +00:00
Wayne Davison
9d78ed31a7 A couple fixes from Shinichi Maruyama. 2004-02-23 07:03:03 +00:00
Wayne Davison
89afe532d7 Mentioned the recent change in slash handling. 2004-02-23 02:28:04 +00:00
Wayne Davison
c67d13866b Changed the literal 9000 into "OPT_REFUSED_BASE". 2004-02-22 08:56:43 +00:00
Wayne Davison
3b98b08c4d Another bug fix. 2004-02-21 21:39:54 +00:00
Wayne Davison
9c15534511 Got rid of the "refuse options" section. 2004-02-21 21:37:14 +00:00
Wayne Davison
55afbb522c Complain in the daemon log file if there is an unknown option in the
"refuse options" value.  Also changed the idiom used to mark refused
options in the popt struct.
2004-02-21 21:36:55 +00:00
Wayne Davison
27ed20f7a0 Fixed the "refuse options" setting in the daemon after Fabrice Bellet
identified what was wrong.
2004-02-21 21:12:49 +00:00
Wayne Davison
f567e9b3d7 - Guard against and out-of-memory condition.
- Don't use the NGROUPS_MAX define.
2004-02-20 17:09:30 +00:00
Wayne Davison
40ae4f93a0 Don't use NGROUPS_MAX define. 2004-02-20 17:01:33 +00:00
Wayne Davison
7a27e9b599 Don't use ENOMSG -- it's not portable. 2004-02-18 22:33:21 +00:00
Wayne Davison
62c9e6b3a5 Moved the EXDEV handling into robust_rename(). 2004-02-17 23:13:10 +00:00
Wayne Davison
cfeed4da95 - If we return an error because of dry_run being set, we now set errno.
- The do_mkstemp() routine now preserves the errno value from fchmod()
  if that call fails.
- Improved the CHECK_RO macro stuff.
2004-02-17 23:00:00 +00:00
Wayne Davison
4068d8617d We no longer munge a double-leading slash in do_open() because we
shouldn't generate a path with a double-leading slash anymore.
2004-02-17 22:49:19 +00:00
Wayne Davison
421c2a2448 Don't create a pathname that has two leading slashes (which we used
to do when the root of the transfer was "/").
2004-02-17 21:57:44 +00:00
J.W. Schultz
d1e7726460 Remove "Conditional -z for old protocols" because those old
protocols are no longer supported.
2004-02-14 01:43:24 +00:00
Wayne Davison
0596df00b3 Reordered the items inside the file_struct so that alignment padding
should be minimized.
2004-02-11 08:01:21 +00:00
Wayne Davison
417c99f637 If --backup was specified, the links we remove are backed up. 2004-02-11 05:03:04 +00:00
Wayne Davison
de0e225076 - Revised and optimized the directory-making code.
- Optimized the keep_backup() code.
2004-02-11 05:02:21 +00:00
Wayne Davison
e0391f8149 Added backup_dir_buf and backup_dir_remainder. 2004-02-11 04:30:41 +00:00
Wayne Davison
7de2483fbd Fixed a crash bug when keep_backup() calls make_file() and the lastdir
pointer is no longer valid.
2004-02-11 02:48:58 +00:00
Wayne Davison
65d6212d03 Got rid of hard-link message (since I don't think it was ever
output in older rsync versions).
2004-02-11 02:33:17 +00:00
Wayne Davison
4d4df3cd2b Another attempt at measuring the minimum alignment for a system. 2004-02-10 23:35:12 +00:00
J.W. Schultz
62125b10c9 Simplified test for hardlink in make_backup debug message to
avoid core-dump.
2004-02-10 23:23:09 +00:00
Wayne Davison
81c3a3a86e Got rid of useless extern. 2004-02-10 22:56:16 +00:00
Wayne Davison
61d35e1844 Trying a different MINALIGN because of core dumps on the sparc-64
build-farm machines.
2004-02-10 22:28:36 +00:00
J.W. Schultz
15f85b1f63 Revert pool_alloc's use of bomb if pool == NULL. 2004-02-10 21:11:24 +00:00
J.W. Schultz
5bf63a11f4 Keep in sync with protocol if idev data on stream but no hlink_pool. 2004-02-10 21:11:24 +00:00
Wayne Davison
97a67bdfa9 If XMIT_HAS_IDEV_DATA is set in receive_file_entry(), we now bomb out
if flist->hlink_pool isn't set (instead of neglecting to read the idev
info).
2004-02-10 17:53:52 +00:00
Wayne Davison
aa0b9ca174 If we call pool_alloc() on a NULL pool, bomb out with an error. 2004-02-10 17:52:31 +00:00
Wayne Davison
b96efc2f67 Empty-line tweaks. 2004-02-10 17:35:04 +00:00
Wayne Davison
be20dc3448 Changed a while loop to a for loop. 2004-02-10 17:34:05 +00:00
Wayne Davison
cb869c26d9 Tweaked an if. 2004-02-10 17:28:59 +00:00
Wayne Davison
7cf8e8d05d Changed flist_init() to use offsetof(). 2004-02-10 17:28:31 +00:00
Wayne Davison
54fd3e5020 Added lib/pool_alloc.h to the HEADERS. 2004-02-10 17:06:11 +00:00
J.W. Schultz
3e4916822d Dropped support for protocol versions less than 20 (2.3.0
released 15 Mar 1999) and activated warnings for protocols
less than 25 (2.5.0 released 23 Aug 2001)
2004-02-10 03:54:47 +00:00
J.W. Schultz
7efdcf3218 Added allocation pool code. 2004-02-10 03:26:41 +00:00
J.W. Schultz
9935066b70 Make idev, hlink and file_struct + strings use allocation
pools.
2004-02-10 03:23:37 +00:00
Wayne Davison
6c2e5b56e4 Die if we overflowed the args[] array when building up the remote
command in do_cmd().
2004-02-09 21:22:59 +00:00
Wayne Davison
2289bf64cc The batch-options now set checksum_seed to the appropriate fixed value. 2004-02-09 18:32:54 +00:00
Wayne Davison
b1bf649cba Set checksum_seed only if it is still zero. 2004-02-09 18:32:53 +00:00
Wayne Davison
8ee6eb7134 Made checksum_seed an extern. 2004-02-09 18:32:52 +00:00
Wayne Davison
f98c60bfa8 Use asprintf() in server_options() (plus a few more whitespace tweaks). 2004-02-09 18:10:57 +00:00
Wayne Davison
a5c1113971 Updated the sizeof syntax and tweaked some whitespace. 2004-02-09 17:45:22 +00:00
Wayne Davison
736f46d1d9 Got rid of unused true/false defines. 2004-02-07 18:40:52 +00:00
Wayne Davison
a8f7e4b835 Made a couple comments a little clearer. 2004-02-07 00:12:40 +00:00
Wayne Davison
9352b0649b Got rid of unused string_area struct. 2004-02-06 15:33:15 +00:00
J.W. Schultz
a85906c756 Start flist with a more reasonable size, grow it linearly
once it reaches a largish size (16 million files) and make it
actually match the comments so it may be used to initialize
flists of known size (create_flist_from_batch()).
2004-02-06 10:00:33 +00:00
J.W. Schultz
8aa81e06e6 Update TODO to reflect recent changes.
Hardlink handling is improved.

	String area code is gone for other reasons.
2004-02-06 07:26:15 +00:00
Wayne Davison
1f9ae80a3e Fixed the indentation in init_flist(). 2004-02-06 07:19:57 +00:00
J.W. Schultz
71020fc3aa Correct sizeof usage and other whitespace. 2004-02-06 04:51:09 +00:00
J.W. Schultz
7b74bba15e Added a total memory allocated (allmem) line to
show_malloc_stats.
2004-02-06 01:56:25 +00:00
J.W. Schultz
e5fbaa713a Cause all three processes to report memory stats when -vv --stats 2004-02-05 03:27:54 +00:00
Wayne Davison
6609a9f17e Mention a couple more changes. 2004-02-05 02:56:57 +00:00
Wayne Davison
5204e853e1 Now that the long-standing chgrp bug is fixed, go back to -vvv from -vvvv. 2004-02-05 01:37:08 +00:00
Wayne Davison
01363a24e2 Fixed a problem handling GID_NONE in match_gid(). 2004-02-05 01:32:38 +00:00
Wayne Davison
d49def4832 - Fixed a bug using --numeric-ids as non-root when the receiver
does not have permissions to set one or more of the gids.
- If the add_[ug]id() routine couldn't find a name for an ID, we
  still note the ID in our list of IDs so that we don't try to
  look it up again (and again).  (The name-less IDs are stripped
  when sending the IDs from the sender to the receiver.)
- Created a better add_to_list() function that handles the linking
  of the new node into the list (rather than the caller doing it).
- Added new internal functions for some receiver-side work that
  needed to be done in multiple places (the recv_add_[ug]id()
  functions).
- We output debug info even for ID mappings that have no names.
  This make the list complete and also notes which gids get
  mapped to -1 (GID_NONE).
- Turned several while loops into for loops.
2004-02-05 01:07:23 +00:00
Wayne Davison
4836c3eece Added new extern. 2004-02-05 00:46:32 +00:00
Wayne Davison
9f7b8c3b8f Only call add_uid() or add_gid() if numeric_ids is not set. 2004-02-05 00:44:11 +00:00
Wayne Davison
ade7292aee Moved a function. 2004-02-04 20:09:21 +00:00
Wayne Davison
dbd8811b85 If a gid doesn't have a name on the originating system, the receiver
won't see it in the list of IDs to remap.  That means that we need to
call the is_in_group() function from inside match_gid() to know if we
can set the group or not (if we're not root).
2004-02-04 19:25:11 +00:00
Wayne Davison
05118158f4 Improved the trailing comment. 2004-02-04 18:24:41 +00:00
Wayne Davison
1df395f7c2 Use the new HAVE_GETGROUPS define. 2004-02-04 17:49:36 +00:00
Wayne Davison
5fdf2e7063 Added function check for getgroups. 2004-02-04 17:21:48 +00:00
Wayne Davison
6fe05820ff Use MY_UID() instead of getuid(). 2004-02-04 17:06:07 +00:00
Wayne Davison
670d8abf80 Use MY_GID() instead of getgid(). 2004-02-04 17:05:44 +00:00
Wayne Davison
b2bffbb2ca Added two defines: MY_UID() and MY_GID(). 2004-02-04 17:04:58 +00:00
Wayne Davison
13a6d667d2 Added getegid to the functions we check. 2004-02-04 16:45:26 +00:00
Wayne Davison
1be77f8336 Added geteuid to the functions to check. 2004-02-04 16:33:34 +00:00
Wayne Davison
187e9c24f1 Another improvement to the debug info we output. 2004-02-04 16:27:47 +00:00
Wayne Davison
eddeaf76f8 Set the "max verbosity" global to 9. 2004-02-04 07:32:48 +00:00
Wayne Davison
33e9d10d2a Use the new lp_max_verbosity() value to limit the server's "verbose"
value.
2004-02-04 07:32:12 +00:00
Wayne Davison
46f7dc3bf6 Added "max verbosity" global parameter that allows you to configure
a higher debug level instead of the default of level-l verbosity.
2004-02-04 07:31:29 +00:00
Wayne Davison
555b0e20f7 Tweaked the new debug-logging strings. 2004-02-04 07:24:13 +00:00
Wayne Davison
a57dfe710d Turned on 4 -v options for some build-farm testing. 2004-02-04 06:15:24 +00:00
Wayne Davison
53adbd7a3d If we encounter an error, output the rsyncd.log file, if it exists. 2004-02-04 05:34:29 +00:00
Wayne Davison
17f033b725 Temporarily switch to 4 -v options. 2004-02-04 03:58:19 +00:00
Wayne Davison
cefed3e8dc Delay the output the (verbose > 3) list of files until we've had a
chance to map the uid/gid info in the receiver.
2004-02-04 03:52:51 +00:00
Wayne Davison
84fa865c0c Output some debug info if verbose > 3. 2004-02-04 03:50:16 +00:00
Wayne Davison
f05f993eb7 If we're dumping the file list (i.e. verbose > 3), mention the uid and/or
gid (depending on applicability).
2004-02-04 03:28:22 +00:00
Wayne Davison
e90cdb8adf Changed the -x code to allow -L to copy a file on another filesystem
that is pointed to by a symlink on our exclusive filesystem.
2004-02-04 03:25:18 +00:00
Wayne Davison
4250941710 Fixed a dropped '-'. 2004-02-04 03:01:32 +00:00
Wayne Davison
a2687b64a2 Added a little more compatibility code for non-standard systems. 2004-02-03 23:28:19 +00:00
Wayne Davison
c284f34a49 Some indentation fixes and the removal of some superfluous parens. 2004-02-03 23:04:25 +00:00
Wayne Davison
5f5be796b0 Changed a couple sizeof calls and improved some string handling in
the {send,recv}_exclude_list() calls.
2004-02-03 23:01:58 +00:00
Wayne Davison
5cb374364b Modified sizeof usage and eliminated trailing whitespace. 2004-02-03 22:48:32 +00:00
Wayne Davison
f15256e156 Added some temporary code to try to figure out what is going wrong
on one NetBSD box in our build farm.
2004-02-03 20:01:26 +00:00
Wayne Davison
ce37eb2d83 If verbose > 2, mention it if we're setting the uid or the gid. 2004-02-03 20:00:35 +00:00
J.W. Schultz
0d6e308b51 correct sizeof usage. 2004-02-03 06:21:56 +00:00
Wayne Davison
b1dab2363a Made hard-link sending compatible with pre-28 protocols again. 2004-02-03 04:21:15 +00:00
J.W. Schultz
bd6abc4939 Corrected sizeof usage:
sizeof obj
	sizeof (type)
2004-02-03 03:42:49 +00:00
Wayne Davison
96eeda0324 Fix for memset bug found by buildfarm. 2004-02-02 22:35:07 +00:00
Wayne Davison
4c4266d9c9 Change to try to debug a failure on the build farm. 2004-02-02 22:18:23 +00:00
Wayne Davison
54e87b4b06 Don't warn about lack of -l support if we're the sender -- we just won't
send the receiver any symlinks.
2004-02-02 21:33:10 +00:00
Wayne Davison
44e9e221f3 - Call init_flist().
- Got rid of the symbolic-links-warning code (it was not right, and it is
  now handled in options.c).
2004-02-02 21:33:06 +00:00
Wayne Davison
61dec11ae0 - Use as little memory as possible for the file_struct (saves another 3
bytes per file).
- Made the idev struct allocated by the group-malloc again (J.W. suggested
  the proper way to align it for all systems).
- Added init_flist().
2004-02-02 21:33:03 +00:00
Wayne Davison
5009de7d2d Added comment about the position of file_list's "flags" var. 2004-02-02 21:32:56 +00:00
Wayne Davison
67f3feebcb Don't free link_u.idev. 2004-02-02 21:32:52 +00:00
Wayne Davison
b22260749f Use "%H:%M:%S" instead of "%T" in strftime() call since it looks to be
more portable.
2004-02-02 21:02:13 +00:00
Wayne Davison
06d76beb28 Clarify the safe/unsafe symlink options in the usage text. 2004-02-02 18:25:37 +00:00
Wayne Davison
7af4227ac2 Clarify the various safe/unsafe symlink options. 2004-02-02 18:23:09 +00:00
Wayne Davison
9312b7325e Go back to using malloc() for the hard-link data structure (for now
at least).
2004-02-02 07:06:54 +00:00
Wayne Davison
c6edb381f5 Free the hlink data again. 2004-02-02 07:06:50 +00:00
Wayne Davison
a1d55ad095 Make sure that the idev struct's data is 4-byte aligned. 2004-02-02 06:52:49 +00:00
Wayne Davison
a289addd96 - Changed the file-list allocation to alloc all the memory we need
with one call, not with several mallocs and strdups.
- Got rid of string_area() stuff (as suggested in the "@todo").
- Enhanced free_file() to optionally free the whole struct or to
  clear it (since we don't need to do both).
- Don't zero out the other flist data when we're about to free it.
2004-02-02 05:06:36 +00:00
Wayne Davison
13c5b46361 Don't free the hlink data (it is not separately allocated anymore). 2004-02-02 05:06:35 +00:00
Wayne Davison
f3af206d8d Changed args to make_file() and free_file(). 2004-02-02 05:06:34 +00:00
Wayne Davison
df0054ab13 Added CLEAR_STRUCT and FREE_STRUCT defines. 2004-02-02 05:06:33 +00:00
Wayne Davison
0d162bd17c Added some missing #if SUPPORT_HARD_LINK and #if SUPPORT_LINK directives. 2004-02-01 17:37:14 +00:00
Wayne Davison
e1add89334 - Fixed the bug where the --daemon option would squelch all option errors
for later parameters.
- Complain if someone passes us -l and we don't support symlinks.
2004-02-01 17:29:41 +00:00
Wayne Davison
22d49dc429 Changed the rdev code to have both an "rdev" variable (which always
has the full device value) and an "rdev_high" variable (which zeros
the lower byte in the last rdev value).
2004-02-01 16:28:31 +00:00
Wayne Davison
1aa4caf318 One more improvement to the 0-flag-byte avoidance algorithm. 2004-01-31 22:40:55 +00:00
Wayne Davison
306ffb8c71 A small optimization to the symlink-send code, and an extra sanity
check to the symlink-receive code.
2004-01-31 21:01:01 +00:00
Wayne Davison
0a98201164 Fixed the test to ensure that we don't send a flag-byte of 0 to the
receiver when transferring the file list.
2004-01-31 20:24:52 +00:00
Wayne Davison
e0870f1d7a One more minor variable-name change. 2004-01-31 11:36:03 +00:00
Wayne Davison
1923b1fce4 Switched a buffer name in make_file() to make the code a little more
similar to what is in receive_file_entry().
2004-01-31 11:32:30 +00:00
Wayne Davison
5dc4003e63 Fixed the optional sanitization of the files_from arg. 2004-01-30 16:14:46 +00:00
Wayne Davison
37c817eb81 OK, "find ... -print0 | xargs -0 ..." wasn't portable. This is. 2004-01-28 01:39:29 +00:00
Wayne Davison
284d628a7c Got rid of indeterminacy in the overlapping-files. 2004-01-28 00:37:55 +00:00
Wayne Davison
ff3184ca1e A couple more unsigned char changes to silence compiler warnings
on signed-char systems (like Solaris).
2004-01-28 00:04:57 +00:00
Wayne Davison
12865a9762 New test to make sure that merging files from multiple directories
continues to work.
2004-01-27 23:56:00 +00:00
Wayne Davison
ea847c6232 Use who_am_i() to qualify some debug messages. 2004-01-27 23:13:15 +00:00
Wayne Davison
b695f2423d Set the am_generator flag. Use who_am_i(). 2004-01-27 23:13:14 +00:00
Wayne Davison
c3e5e5851b New function: who_am_i() returns "sender", "receiver", or "generator". 2004-01-27 23:13:13 +00:00
Wayne Davison
4337c8f856 Added "am_generator". 2004-01-27 23:13:12 +00:00
Wayne Davison
4c7e46079d Don't free lastdir! It is still needed by the flist basedir pointers.
Also, output the basedir pointer when dumping the flist for debugging.
2004-01-27 23:00:47 +00:00
Wayne Davison
72a6e63136 Relocated the externs. 2004-01-27 22:35:15 +00:00
Wayne Davison
37101856a6 Silenced some compiler warnings. 2004-01-27 16:27:05 +00:00
Wayne Davison
65fc84b32e Better pid handling. 2004-01-27 08:14:33 +00:00
Wayne Davison
45e08edb08 Cast getpid() to a long for output. 2004-01-27 08:02:31 +00:00
Wayne Davison
05b7bab8e1 Better pid handling. 2004-01-27 07:57:12 +00:00
Wayne Davison
904817552d Fixed a comment. 2004-01-27 07:48:57 +00:00
Wayne Davison
6e195fe975 Tweaked the externs. 2004-01-27 07:48:19 +00:00
Wayne Davison
3eaf615f40 Percentage of file-count output was off by one. 2004-01-27 06:51:39 +00:00
J.W. Schultz
6156e72f85 EXCLUDE PATTERNS is not just about syntax. 2004-01-27 05:00:43 +00:00
Wayne Davison
73a4bdfd77 Mention the latest -x improvement. Also improved the description of
one of my previous fixes.
2004-01-27 03:49:54 +00:00
Wayne Davison
4844449a5d Optimized the -x option by removing the skip_filesystem() call and using the
new FLAG_MOUNT_POINT flag.
2004-01-27 01:47:41 +00:00
Wayne Davison
ae289aec1e Added FLAG_MOUNT_POINT. 2004-01-27 01:47:40 +00:00
Wayne Davison
9e4c32ea54 Tweaked a comment. 2004-01-27 01:27:37 +00:00
Wayne Davison
a5f9cff256 Improved the differentiation of the transmit flags from the live flags
by naming the transmit flags with an XMIT_ prefix.  Improved the names
of two other flags, got rid of the LIVE_FLAGS mask, and shortened the
flag storage in the flist struct (to save memory).
2004-01-27 01:05:14 +00:00
Wayne Davison
d01d15e096 Use the new names for the transmit-flag defines. We also make sure
that the FLAG_TOP_DIR flag doesn't get set in the live data for a
non-directory (when it's used as a kluge to prevent a 0x00 byte being
sent over the wire for the flag data).
2004-01-27 01:05:13 +00:00
Wayne Davison
a53426441b Use the new names for the transmit-flag defines. 2004-01-27 01:05:12 +00:00
Wayne Davison
5d1966948e Fixed reference to -u that should have been -o. 2004-01-26 22:35:04 +00:00
J.W. Schultz
f673ea84b2 Back out bad refactor (thanks Wayne) 2004-01-26 20:54:02 +00:00
Wayne Davison
64f21c31bf Mention new hard-link optimization. 2004-01-26 04:21:59 +00:00
Wayne Davison
520cf41711 Added defines (FLAG_HLINK_EOL, HL_CHECK_MASTER, and HL_SKIP) and changed
the struct hlink to have an index into the hlink_list[] array instead of
a head pointer.
2004-01-25 22:32:11 +00:00
Wayne Davison
d38fc30563 We now link the hard-linked flist entries into a circular list, mark
the last item with FLAG_HLINK_EOL, and save off an index for our
master entry in the hlink_list[] array.  Added the hard_link_check()
function.
2004-01-25 22:32:10 +00:00
Wayne Davison
6dff599288 Use the new hard_link_check() function to figure out which one of the
hard-linked files to send (when -H was specified, of course).  Moved
the call to do_hard_links() and the final directory-permissions scan
into generate_files() from recv_files().
2004-01-25 22:32:09 +00:00
Wayne Davison
f746dda0a0 Moved the call to do_hard_links() and the final directory-permissions
scan from recv_files() into generate_files().
2004-01-25 22:32:08 +00:00
Wayne Davison
91a1e147ae Changed F_HEAD to F_HLINDEX. 2004-01-25 22:32:07 +00:00
Wayne Davison
40da904230 Tweaked a comment. 2004-01-25 22:32:05 +00:00
J.W. Schultz
34fada3012 Tightened up code in skip_filesystem() 2004-01-25 22:11:09 +00:00
Wayne Davison
f91e01d9a5 Replaced an snprintf() call with pathjoin(). 2004-01-24 22:12:58 +00:00
Wayne Davison
3048b0a8ea The static last_in value in match_gid() needed to default to -2 so
that we don't accidentally return a GID of 0 when we don't have the
permissions to set it.
2004-01-24 18:36:36 +00:00
Wayne Davison
d99b4ccf93 Another improvement in the "use chroot" section. 2004-01-24 01:48:12 +00:00
Wayne Davison
58811a0a38 Refer to I/O (not IO), ID (not id), and "an rsync" (not "a rsync"). 2004-01-23 16:58:24 +00:00
Wayne Davison
cb290916be Improved the "use chroot" discussion on ID mapping. 2004-01-23 16:55:40 +00:00
Wayne Davison
a2b0471f1d More changes to make the --owner and --group items clearer. 2004-01-23 16:40:17 +00:00
Wayne Davison
bb18e7550c Use "an" in front of rsync, not "a". 2004-01-23 09:34:04 +00:00
Wayne Davison
db2b5cb75f Tweaked the --help text to refer to I/O (not IO) and use "an" in
front of rsync (not "a").
2004-01-23 09:32:50 +00:00
Wayne Davison
fa8c787d8b Improved the "use chroot" section to mention how to get user/group
preservation by name (getting rid of the erroneous bit about the
--numeric-ids option being implied).
2004-01-23 09:30:45 +00:00
Wayne Davison
ec40899bb9 Improved comments on --owner and --groups, and removed misinformation
on a chroot daemon (it does not imply --numeric-ids).
2004-01-23 09:29:16 +00:00
Wayne Davison
b5accabaa7 Properly punctuate "etc." and changed all occurrences of "IO" to "I/O". 2004-01-23 08:59:19 +00:00
Wayne Davison
4e308a9526 Fixed two more misspelled words. 2004-01-23 02:02:51 +00:00
Wayne Davison
4d88810810 Some spelling corrections and other simple fixes. 2004-01-23 01:36:59 +00:00
Wayne Davison
f321922214 When setting an flist entry's flags, mask it with LIVE_FLAGS. 2004-01-22 18:39:32 +00:00
Wayne Davison
cab13afe8d A couple comment tweaks. 2004-01-22 18:37:26 +00:00
Wayne Davison
72fc7ec59b Made the getgroups() code a little more portable. This will hopefully
make the chgrp test work on the NetBSD and OpenBSD systems where it is
failing.
2004-01-22 09:16:21 +00:00
Wayne Davison
58743a87b8 Improved to add the default gid if it is missing from the list. 2004-01-22 09:13:36 +00:00
Wayne Davison
54bf456e85 Removed an obsolete comment. 2004-01-22 09:05:09 +00:00
Wayne Davison
a24639bb36 Tweaked an argv-type variable so that it's a little clearer what
the code is doing.  Also added a comment.
2004-01-22 04:40:33 +00:00
Wayne Davison
3fef53645d Use the new f_name_to() calling syntax. 2004-01-22 04:38:18 +00:00
Wayne Davison
882e689312 - Ensure in make_file() that we can't make a name that overflows
our buffers (note that receive_file_entry() already does this).
- Changed f_name_to() to not do any length checking since it is
  now redundant.
2004-01-22 04:38:17 +00:00
Wayne Davison
b0a93231cf Added more missing news. 2004-01-22 02:02:00 +00:00
Wayne Davison
0c819b76d6 New news. 2004-01-22 01:23:43 +00:00
Wayne Davison
ce58b1b479 Size-check the --temp-dir string so we don't have to worry about it
overflowing elsewhere in the code.
2004-01-22 01:20:24 +00:00
Wayne Davison
a16d8f2b25 Improved a couple comments. 2004-01-21 02:45:10 +00:00
Wayne Davison
59187666b9 Use new push_dir() syntax. 2004-01-20 17:46:31 +00:00
Wayne Davison
808c57c343 - Use the new push_dir() and pop_dir() calling syntax.
- The "olddir" handling changed to accommodate the above, and to
  avoid using malloc()/free().
2004-01-20 17:46:30 +00:00
Wayne Davison
4af8fe4e78 - Changed push_dir() to not take a "save" arg and to return 1 or 0
for success or failure instead of a string pointer.  The function
  also ensures that we don't overflow the curr_dir[] buffer.
- Changed pop_dir() to not free() anything and to return 1 or 0
  for success or failure.
2004-01-20 17:46:29 +00:00
Wayne Davison
4034cb3f71 Use new stringjoin() function. 2004-01-20 05:35:57 +00:00
Wayne Davison
6fc048f438 Find last '@' in the user@site string, just in case the username has
a '@' in it.
2004-01-20 05:27:09 +00:00
Wayne Davison
5d2a707139 Use new stringjoin() and pathjoin() functions. 2004-01-20 05:24:07 +00:00
Wayne Davison
81d2b0ef9d Use new pathjoin() function. 2004-01-20 05:15:14 +00:00
Wayne Davison
248ed45fc6 Use new pathjoin() function. 2004-01-20 05:09:36 +00:00
Wayne Davison
893c4cc056 Use new stringjoin() function. 2004-01-20 04:56:20 +00:00
Wayne Davison
a7725e6df9 Use new pathjoin() function. 2004-01-20 04:53:59 +00:00
Wayne Davison
368ad70e05 Added stringjoin() and pathjoin(). 2004-01-20 04:43:49 +00:00
J.W. Schultz
b7cee9498b Eliminate unneeded strlen after strlcpy. 2004-01-20 03:37:04 +00:00
Wayne Davison
72d45525d2 Make sure that strlcpy() returns the right value when the bufsize is 0. 2004-01-20 00:59:26 +00:00
Wayne Davison
1fb8ec4b0d Fixed a bug in strlcat() where it would not properly detect a no-change
condition if called with an initial string longer than the specified
size limit (due to an unsigned var's inability to go negative).
2004-01-20 00:29:49 +00:00
Wayne Davison
beb9368481 Make sure that the batch-prefix string isn't overly long (avoiding
a potential problem in the batch-filename code).
2004-01-19 23:33:02 +00:00
Wayne Davison
981555bddb Actually, let's avoid snprintf() where possible. 2004-01-19 23:28:57 +00:00
Wayne Davison
9c7527085c Use snprintf() instead of strlcpy()+strlcat(). 2004-01-18 21:22:49 +00:00
Wayne Davison
eddd5d129e A few minor string optimizations and a new complaint if we try to
send a truncated filename.
2004-01-17 19:45:26 +00:00
Wayne Davison
26f76b7912 Got rid of an extra call to io_start_buffering_out(). 2004-01-17 05:04:04 +00:00
Wayne Davison
32eda0961e Unified the externs. 2004-01-17 04:58:24 +00:00
Wayne Davison
66964002df A fix for --cvs-exclude. 2004-01-17 01:23:41 +00:00
Wayne Davison
57469f6c31 Items read from a per-directory .cvsignore file should be added to the
local_exclude_list, not the exclude_list.
2004-01-17 01:16:49 +00:00
Wayne Davison
13c7bcbb2b Output an error before we die if we get a wacko message from the receiver. 2004-01-16 16:31:47 +00:00
Wayne Davison
d48c806560 Clarified the --delete-after descriptions. 2004-01-15 17:45:53 +00:00
Wayne Davison
ad1a09a509 Clarified the --delete-after help text. 2004-01-15 17:43:34 +00:00
Wayne Davison
d6631cf3a5 If we're a daemon talking with a pre-28 protocol, use FERROR for a
vanished-file message (not FINFO).
2004-01-15 08:56:33 +00:00
Wayne Davison
5a8543b8b8 In two places: needed to use protocol_version, not PROTOCOL_VERSION. 2004-01-15 08:39:25 +00:00
Wayne Davison
19119cbd35 Changed version to "2.6.1cvs". 2004-01-15 08:16:40 +00:00
Wayne Davison
442743b83c Improved receiver/generator communications. 2004-01-15 07:51:37 +00:00
Wayne Davison
419896af47 - Define FULL_FLUSH and NORMAL_FLUSH.
- Got rid of FNONE from logcode enum.
- Created msgcode enum with MSG_DATA, MSG_REDO, MSG_DONE, etc.
2004-01-15 07:42:27 +00:00
Wayne Davison
0569a1339d - Got rid of the f_gen pipe.
- Use new send_msg() call with MSG_DONE or MSG_REDO.
2004-01-15 07:42:25 +00:00
Wayne Davison
f1e3656ee2 - Call io_flush() with its new FULL_FLUSH/NORMAL_FLUSH arg.
- Got rid of the recv_pipe between the receiver and the generator.
- Use new send_msg(MSG_DONE,...) call to signal the generator
  when the receiver is done.
- Use the new get_redo_num() call in the generator to read the
  final -1 from the receiver.
2004-01-15 07:42:21 +00:00
Wayne Davison
a644fc3cc4 - Moved err_list* stuff to io.c and renamed them to msg_list*.
- Call the new send_msg() function to send a remote log message.
2004-01-15 07:42:19 +00:00
Wayne Davison
d17e1dd2da - Moved the err_list* stuff here from log.c and renamed them msg_list*.
- Renamed log_error_fd to msg_fd_out, and io_error_fd to msg_fd_in.
- Added a redo_list* to keep track of any redo items that come over
  the message channel from the receiver to the generator.
- The io_flush() and msg_list_push() functions now take an arg:
  NORMAL_FLUSH or FULL_FLUSH.  The latter ensures that we don't lose
  any log messages that haven't gotten written from the msg_list.
- Added a send_msg() function that log.c calls to send any remote
  log messages.  It is also called to send the new MSG_REDO and
  MSG_DONE messages.
2004-01-15 07:42:17 +00:00
Wayne Davison
b9b15fb165 We now call get_redo_num() instead of reading f_recv (which was removed). 2004-01-15 07:42:15 +00:00
Wayne Davison
ef732c3b54 Call io_flush() with its new FULL_FLUSH option. 2004-01-15 07:42:12 +00:00
Wayne Davison
baa4212ae1 If the do_lchown() fails and we weren't trying to change the user,
the error now says that chgrp failed, not chown.
2004-01-15 07:08:00 +00:00
Wayne Davison
0be976ec0a Fixed a bug when a non-root user copies a GID=0 file with -g set
and no permissions to set group 0.
2004-01-15 07:06:45 +00:00
Wayne Davison
f7f10340d6 The HAS_INODE_DATA flag is no longer a part of the LIVE_FLAGS define. 2004-01-15 02:25:38 +00:00
Wayne Davison
68f9910d94 Explain the --progress output. 2004-01-13 18:50:40 +00:00
Wayne Davison
fb6e0ea120 Give the user an idea of how far along in the transfer we are
when using --progress.
2004-01-13 18:25:03 +00:00
Wayne Davison
97feb557ed Set stats.current_file_index. 2004-01-13 18:22:43 +00:00
Wayne Davison
dc8293ff73 Added current_file_index. 2004-01-13 18:22:13 +00:00
Wayne Davison
785db4ced0 Merged a couple more f != -1 if sections. 2004-01-13 06:27:30 +00:00
Wayne Davison
5562deb169 Moved a couple externs. 2004-01-13 05:13:57 +00:00
Wayne Davison
983b1ed321 Merged some "if (f != -1)" checks, put the clean_flist() call in the
right spot, and moved some externs.
2004-01-13 05:11:56 +00:00
Wayne Davison
548abf96ce Relocated some externs. 2004-01-13 04:50:45 +00:00
Wayne Davison
f8ebdf9265 More hard-link stuff. 2004-01-12 03:59:53 +00:00
Wayne Davison
aa23c22004 Changed the hard-link check. 2004-01-12 03:50:07 +00:00
Wayne Davison
1d5cda2265 Updated to perform a much more efficient hlink algorithm that doesn't
require any binary searching of hlink data.
2004-01-12 03:49:47 +00:00
Wayne Davison
fe70ad26d3 Added F_HEAD and F_NEXT defines. 2004-01-12 03:48:43 +00:00
Wayne Davison
0a00748901 Mention more of the latest changes. 2004-01-11 22:39:34 +00:00
Wayne Davison
03979352b4 More cleanup, fixing an error in the fatal-message strings that tried
to output the "filename" value when it might not be initialized.
2004-01-11 22:11:25 +00:00
Wayne Davison
cb7fb45e42 Updated a questioning comment. 2004-01-11 08:17:19 +00:00
Wayne Davison
92cc9dd7c2 Use the new dev+inode union in the flist_struct. 2004-01-11 07:56:14 +00:00
Wayne Davison
88a7fb3edd Moved the inode & dev items out of the flist_struct. Based on a
preliminary patch by J.W.
2004-01-11 07:55:53 +00:00
Wayne Davison
728d092201 Use the new union-ified flist_struct values. 2004-01-11 07:28:45 +00:00
Wayne Davison
80707c983c Put 3 flist_struct items into a union: rdev, sum, and link (all
mutually exclusive based on mode).  Based on an idea by J.W.
2004-01-11 07:28:23 +00:00
Wayne Davison
5911fee567 A slightly better reset mechanism for send_file_entry() and
receive_file_entry().
2004-01-10 22:13:19 +00:00
Wayne Davison
a09f6f55da Use the new LIVE_FLAGS define to fix a potential flag problem. 2004-01-10 21:10:04 +00:00
Wayne Davison
caf5cc9152 Added LIVE_FLAGS define. 2004-01-10 21:09:06 +00:00
Wayne Davison
58422e8393 Changed the call to write_batch_csum_info() to the latest syntax. 2004-01-10 20:16:18 +00:00
Wayne Davison
e8d3168e3a Massive rewrite to replace the file-list read/write code with calls to
send_file_entry() and receive_file_entry().  Other cleanups too.
2004-01-10 20:16:13 +00:00
Wayne Davison
7b1a0c19b8 Allow the send_file_entry() and receive_file_entry() routines to be
called by the batch processor.
2004-01-10 20:15:55 +00:00
Wayne Davison
536492752b Support the recent changes in the flist_struct. 2004-01-10 08:39:57 +00:00
Wayne Davison
7c4f063b13 Got rid of tmpsum[]. 2004-01-09 18:35:41 +00:00
Wayne Davison
1a62c49d31 Note latest changes. 2004-01-09 18:27:15 +00:00
Wayne Davison
fea4db62bd - Never allocate a useless sum array for a non-regular flist item.
- Don't transmit the sum array for non-regular files (p28 onward).
- Tweaked a couple comments.
2004-01-09 18:19:32 +00:00
Wayne Davison
4499c0eebd A couple minor code improvements. 2004-01-09 18:10:31 +00:00
Wayne Davison
0c42946536 Added an extra comment. 2004-01-09 16:53:55 +00:00
J.W. Schultz
ab264c9e79 Added a few more devices to the devices.test to hopefully
test same, same high and different device numbers.
2004-01-09 14:02:00 +00:00
J.W. Schultz
dd7fb70f6e Finished the last_* renameing and fixed a cast.. 2004-01-09 13:55:56 +00:00
Wayne Davison
30f337c9ef Updated the send_file_name() and receive_file_entry() functions to make
some of the variable names more logical in the new program flow.  Also
improved the setting of the new last_rdev value that only remembers the
high 3 bytes.
2004-01-08 22:45:12 +00:00
Wayne Davison
9d35271938 Changed the OLD_SAME_RDEV define to SAME_RDEV_pre28. 2004-01-08 22:45:07 +00:00
Wayne Davison
bbfb1d016b Added explicit call to AC_PROG_EGREP. 2004-01-08 18:33:38 +00:00
Wayne Davison
c4b4df4fb4 Optimized the sending of dev+inode data for hard-linking support
(but only when speaking protocol 28).
2004-01-08 11:29:50 +00:00
Wayne Davison
a6d89d18bf - Added flags HAS_INODE_DATA and SAME_DEV.
- Changed PROTOCOL_VERSION to 28 now.
2004-01-08 11:28:07 +00:00
Wayne Davison
75bc860093 Implemented an extended-flag-byte in the transfer protocol by moving
the SAME_RDEV bit into the next 8 bits and adding an EXTENDED_FLAG
bit.  Also modified the meaning of this bit for protocol 28 and above:
SAME_HIGH_RDEV indicates that all but the lowest byte matches.  The
older protocols get OLD_SAME_RDEV set (with the old semantics) for
compatibility.  Note also that protocol 28 isn't turned on yet.
2004-01-08 11:08:30 +00:00
Wayne Davison
02a279a75f Added EXTENDED_FLAGS and SAME_HIGH_RDEV. Changed SAME_RDEV to OLD_SAME_RDEV. 2004-01-08 11:08:30 +00:00
Wayne Davison
584c7bf76d Pass the $srcdir/wildtest.txt file on the command-line to wildtest. 2004-01-08 09:00:14 +00:00
Wayne Davison
c4cd2ca6bf We now take a TESTFILE arg on the command-line. 2004-01-08 08:59:52 +00:00
Wayne Davison
1ef00d2072 Improved the code in send_file_entry() and receive_file_entry() to
make it a little easier to read and a little more optimized.  Also
made the flag size in our function calls match the size of the flags
in the flist_struct.  These changes will make it easier for me to
optimize the sending of the hard-link data in a future commit.
2004-01-08 04:56:27 +00:00
Wayne Davison
4dd4c72790 Made the flags in the file_struct a little smaller. 2004-01-08 04:53:16 +00:00
Wayne Davison
6aae748ea7 - No need to check S_ISREG() on files already in the hlink_list.
- The realloc in init_hard_links() might fail if the list is empty
  (which can happen if there are no regular files in the transfer).
  I changed the code to free the list in that case.
2004-01-08 03:17:07 +00:00
Wayne Davison
aa953c3201 Old-protocols. 2004-01-08 00:47:17 +00:00
Wayne Davison
3f55bd5dad Got rid of support for protocols 17 and 18. 2004-01-08 00:45:41 +00:00
J.W. Schultz
279b1c1ebb Noted hardlink memory footprint reduction. 2004-01-07 11:38:23 +00:00
J.W. Schultz
fa45cda1aa Cosmetic changes to file_compare() for readability and to
match hlink_compare()
2004-01-07 09:11:56 +00:00
J.W. Schultz
11dc274054 Change hlink_list so we only have a list of pointers to
file_struct instead of a copy of the file_struct list.
2004-01-07 09:06:37 +00:00
Wayne Davison
e7bef92205 Batch-mode fix. 2004-01-06 05:35:55 +00:00
Wayne Davison
4a1991d7c5 Fixed a byte-order problem for batch-file processing on big-endian
systems (reported by Jay Fenlason).
2004-01-06 05:33:02 +00:00
Wayne Davison
13aefa1365 Some whitespace tweaks. 2004-01-05 03:57:15 +00:00
Wayne Davison
addf0c4a1c A few formatting tweaks. 2004-01-05 03:56:19 +00:00
Wayne Davison
25bfc8cea1 Use new recv_generator() calling syntax. 2004-01-04 19:18:37 +00:00
Wayne Davison
dfd5ba6ab7 Changed recv_generator() to take a "struct file_struct *" instead of
a "struct file_list *", which allows us to call it with a copy of the
current file_struct entry that we've modified.  This is better than
modifying the entry directly because the latter causes the shared
memory between the generator and the receiver to slowly vanish as
the in-memory changes happen.
2004-01-04 18:43:18 +00:00
Wayne Davison
393ba2214d Try using "id -un" before "whoami" since the latter doesn't exist on
SunOS systems (and I hope the former works -- we'll see).
2004-01-04 07:07:08 +00:00
Wayne Davison
f358487f8e Silence a compiler warning on Sun OS systems. 2004-01-04 07:06:05 +00:00
Wayne Davison
a18381aca6 Improved the text. 2004-01-03 20:50:51 +00:00
Wayne Davison
f6e54812b7 Fixed autom4te*.cache entry. 2004-01-03 19:49:52 +00:00
Wayne Davison
31e7451aa5 Mention more INTERNALS work. 2004-01-03 19:28:17 +00:00
Wayne Davison
0e36d9da42 More variable-size cleanup. 2004-01-03 19:28:03 +00:00
Wayne Davison
da9d12f5d9 Made the types used in the sum_buf and sum_struct structures consistent
with the variables in the code that manipulates these values.
2004-01-03 18:37:41 +00:00
J.W. Schultz
a60e2dca6b Create GID_NONE for use gid test readability. 2004-01-03 13:17:32 +00:00
Wayne Davison
86c4601e12 Fixed a name. 2004-01-03 09:48:52 +00:00
Wayne Davison
173f5bf8cf Fixed a size check in the new code. 2004-01-03 09:44:20 +00:00
Wayne Davison
823edc686f Document the latest changes. 2004-01-03 09:36:30 +00:00
Wayne Davison
a3a841073e Added support for "Basic" authentication to our proxy, based on a
patch by Bardur Arantsson.
2004-01-03 09:19:06 +00:00
Wayne Davison
57385128c3 Made base64_encode() non-static. 2004-01-03 08:53:36 +00:00
Wayne Davison
2990e06f29 Silence a compiler warning. 2004-01-03 01:12:10 +00:00
Wayne Davison
2ef2e822d1 Added missing '[]'s to AC_CHECK_FUNCS() calls so that this works
with autoconf 2.58 and above.
2004-01-03 00:40:55 +00:00
Wayne Davison
b7736c797c Some cosmetic tweaks. 2004-01-02 23:41:32 +00:00
Wayne Davison
9b9c8aaf4d Improved flush_write_file(). 2004-01-02 18:42:33 +00:00
Wayne Davison
b0fd253afc Applied a slightly-tweaked version of Oliver Braun's patch that
implements listening on multiple addresses and a fix for IPv6-only
systems.
2004-01-02 18:05:51 +00:00
Wayne Davison
e028b9ff53 Call bind() with the right ai_addr/ai_addrlen info. 2004-01-02 17:47:44 +00:00
Wayne Davison
9c07d25345 Tidied up a few things in preparation for changes. 2004-01-02 17:20:21 +00:00
Wayne Davison
7352b8736b Moved the is_in_group() function to uidlist.c. 2004-01-02 16:52:29 +00:00
Wayne Davison
5b540e86a4 Set the file's gid to -1 if we don't have permissions to set it. 2004-01-02 16:51:54 +00:00
Wayne Davison
6744b62ddd Fixed --link-dest's check for identicalness to ignore the uid if
non-root, and to ignore a gid of -1.
2004-01-02 16:50:06 +00:00
Wayne Davison
e90b8acec3 Silence some compiler warnings. 2004-01-02 08:50:25 +00:00
Wayne Davison
925c517f19 Improved the setting of cleanup_got_literal so that we know if the
current file received some literal data yet or not.
2004-01-02 08:38:35 +00:00
Wayne Davison
cc964a518c Use the new f_name_to() call instead of strlcat() an f_name(). 2004-01-02 08:36:58 +00:00
Wayne Davison
3309507dd3 Some minor changes to some if statements. 2004-01-02 08:33:57 +00:00
Wayne Davison
5e7dbaca50 Use buffered I/O to read the exclude list. 2004-01-02 08:31:12 +00:00
Wayne Davison
76c2194714 Applying my updated version of Craig Barratt's buffered I/O patch. 2004-01-02 08:29:49 +00:00
Wayne Davison
968c8030cf Some name tweaks. 2004-01-02 08:19:26 +00:00
Wayne Davison
446e239e2c Use the f_name_to() function to avoid having to strdup() the name that
f_name() returns.  Also used in a call to recv_generator() to keep the
name safe for the duration of the call.
2004-01-02 08:18:53 +00:00
Wayne Davison
e7bc9b64a3 Use f_name_to() when producing a name for the recv_generator() call.
This prevents things like the hard-link code from losing the name
before we're finished with it.
2004-01-02 08:05:20 +00:00
Wayne Davison
8018edd3aa Optimized f_name(), generating: (1) f_name_cmp(), which optimizes
comparing two file_struct elements without copying them first, and
(2) f_name_to() which lets us supply the destination buffer for a
f_name() call (to allow it to persist without an extra copy).
2004-01-02 07:57:02 +00:00
Wayne Davison
64c3523a6f Got rid of /* dw */ comments. 2004-01-02 07:42:20 +00:00
Wayne Davison
310c9f30f0 Optimized hard_link_one() to not call f_name() so many times. 2004-01-02 07:34:49 +00:00
Wayne Davison
5c1b7bfd2a No need to conditionally-compile EINTR code -- no other files do this. 2004-01-02 07:31:02 +00:00
Wayne Davison
faf11086d8 More twiddling of the wildcard verbage. 2004-01-02 07:11:32 +00:00
Wayne Davison
52fa4d7893 Improved the itemized discussion under the wildcard changes. 2004-01-01 22:37:13 +00:00
Wayne Davison
de0551020b Allow function return values to start with "const". 2004-01-01 21:10:50 +00:00
Wayne Davison
c1456d83a7 Tweaked the date. 2004-01-01 19:00:11 +00:00
Wayne Davison
1cbbaea957 Preparing for release of 2.6.0 2004-01-01 11:36:16 +00:00
Wayne Davison
f6aeaa74d1 One more tweak to --modify-window verbage. 2003-12-30 18:17:16 +00:00
Wayne Davison
6839140eb5 Shorten some of the lines in the --help output. 2003-12-30 18:16:25 +00:00
Wayne Davison
915dd20705 Shortened a few lines, plus a couple minor tweaks. 2003-12-30 17:44:01 +00:00
Wayne Davison
c53217a2b8 Changed the VERSION section to refer to 2.x instead of 2.0. 2003-12-29 09:58:06 +00:00
Wayne Davison
b2ac00eb16 Preparing for release of 2.6.0pre2 2003-12-28 21:11:38 +00:00
Wayne Davison
45ddbf6204 Make the upper copyright year "2004". 2003-12-28 20:48:06 +00:00
Wayne Davison
276877cf77 Aged news from NEWS to OLDNEWS. 2003-12-27 00:14:21 +00:00
Wayne Davison
6b45fcf160 Undid previous change. 2003-12-26 23:04:01 +00:00
Wayne Davison
49c24eccd4 A change that wasn't needed. 2003-12-26 22:59:53 +00:00
Wayne Davison
0d7d3763f2 Use %{version} to refer to the current version. 2003-12-24 17:48:25 +00:00
Wayne Davison
241dc65eee Getting rid of klunky *.tmpl files. 2003-12-24 17:46:46 +00:00
Wayne Davison
860bdd4571 Mention the new-backup-dir mode change. 2003-12-24 01:46:38 +00:00
Wayne Davison
55bf051bbc Getting rid of an extra newline that accidentally crept into the code. 2003-12-24 01:46:07 +00:00
Wayne Davison
423dba8ea1 Simplified an internal function's name to remove a potentially
cryptic suffix.
2003-12-24 01:14:16 +00:00
Wayne Davison
517c7b4dee Updated the copyright year. 2003-12-20 18:00:13 +00:00
Wayne Davison
18ced14631 Output a warning about the new remote-shell default if the --with-rsh
option wasn't used.
2003-12-20 17:57:47 +00:00
Wayne Davison
ce67256218 Output a newline before the heap statistics. 2003-12-20 16:57:24 +00:00
Wayne Davison
9e83fa99fe - Mention the extra newlines in the verbose/stats output.
- Made some spelling corrections.
2003-12-20 16:56:51 +00:00
Wayne Davison
256a9e376c Added a couple missing items from John Van Essen. 2003-12-20 16:51:13 +00:00
Wayne Davison
ef5075e092 Quiet a compiler warning. 2003-12-19 22:19:54 +00:00
Wayne Davison
65653a6596 Mention the change we made to help ssh cleanup the tty on Ctrl-C. 2003-12-19 20:21:17 +00:00
Wayne Davison
d5a0b48379 Do a small msleep() in the sig_int() handler before shutting down.
This kluge allows things like SIGINT to find our children before
we go throwing around SIGUSR1's at them.
2003-12-19 06:52:02 +00:00
Wayne Davison
314a74d731 Got rid of the RSYNC_RSH_IO stuff for now. 2003-12-17 09:29:35 +00:00
Wayne Davison
90e22f4b51 Backed out the RSYNC_RSH_IO support for now. 2003-12-17 09:28:45 +00:00
J.W. Schultz
ab304c268c Removed hardlink reporting bug from TODO list -- seems to be
fixed.
2003-12-17 00:52:01 +00:00
J.W. Schultz
16a3fec02d Added keword base reporting to TODO features list. 2003-12-17 00:49:50 +00:00
J.W. Schultz
abb0b532f8 Reorganized and cleaned up TODO list. 2003-12-17 00:47:39 +00:00
Wayne Davison
43cd760fc1 - Changed the places that talked about rsh being the default shell.
- Document the new RSYNC_RSH_IO environment variable.
2003-12-16 23:07:19 +00:00
Wayne Davison
9af87151ec We now support an environment variable named RSYNC_RSH_IO which lets the
user set the blocking-IO value for the shell specified by RSYNC_RSH.
2003-12-16 23:06:25 +00:00
Wayne Davison
8dd99390f5 Added RSYNC_RSH_IO_ENV. 2003-12-16 23:04:59 +00:00
Wayne Davison
e636af6b23 Mention change to ssh. 2003-12-16 19:48:25 +00:00
Wayne Davison
e3217f1448 Tweaked an obsolete comment. 2003-12-16 18:02:15 +00:00
Wayne Davison
66b711633f Improved the default-blocking-I/O code to discern rsh from ssh
properly.
2003-12-16 18:02:03 +00:00
Wayne Davison
f40f2fc8ce Made the default remote-shell be "ssh" (override with --with-rsh=FOO). 2003-12-16 18:01:06 +00:00
Wayne Davison
e6f9e388cf Moved the information on the single-use ssh key so that the --server
option wasn't being mentioned early in the rsync manpage (which has
confused at least one user trying to figure out the --daemon mode
command-line syntax).
2003-12-15 20:10:21 +00:00
Wayne Davison
3c1e2ad956 Document new error code 24. 2003-12-15 19:49:38 +00:00
Wayne Davison
e6d2799170 Updated version. 2003-12-15 19:04:04 +00:00
Wayne Davison
2cfbf4bc0e Changed the version to 2.6.0pre1. 2003-12-15 19:00:20 +00:00
Wayne Davison
f7731f1fc2 Removed some obsolete items. 2003-12-15 18:45:27 +00:00
Wayne Davison
7d3f8ae2df Make sure we only use blocking-I/O if blocking_io is > 0. 2003-12-15 18:45:07 +00:00
Wayne Davison
a60fdd63f4 Changed version to 2.6.0. 2003-12-15 18:25:10 +00:00
Wayne Davison
3a7dec59bc Changed version to 2.6.0 in preparation for new release. 2003-12-15 18:22:12 +00:00
Wayne Davison
880ae34190 Got rid of setgroups() caveat for OSX -- we fixed that a while back. 2003-12-15 18:20:06 +00:00
Wayne Davison
d00daf1f3f Mentioned the vanished-file warning enhancement. 2003-12-15 08:44:55 +00:00
Wayne Davison
17fadf7d40 Twiddled some whitespace and multi-line comments. 2003-12-15 08:14:27 +00:00
Wayne Davison
06c28400fa New "io_error" variable handling for RERR_VANISHED support. 2003-12-15 08:10:31 +00:00
Wayne Davison
6e35c72fdb Return new RERR_VANISHED code, as appropriate. 2003-12-15 08:08:44 +00:00
Wayne Davison
e2d22fee53 Added new IOERR_* defines. 2003-12-15 08:07:38 +00:00
Wayne Davison
1bca1de6cc Handle new RERR_VANISHED error. 2003-12-15 08:06:52 +00:00
Wayne Davison
e0ed4e4087 Added RERR_VANISHED. 2003-12-15 08:04:14 +00:00
Wayne Davison
4a7319be12 Neatened up some whitespace issues and made multi-line comments more
consistent.
2003-12-15 01:45:01 +00:00
Wayne Davison
55d5937dd6 Simplified the setting of the reading_remotely variable in function
read_filesfrom_line() now that remote_filesfrom_file is set more
often.
2003-12-15 00:54:44 +00:00
Wayne Davison
63596e1c4a If we're the server and --files-from is "-", set remote_filesfrom_file
to "-" as well (since the data is coming over the socket from the remote
side).
2003-12-15 00:53:07 +00:00
Wayne Davison
603e6b05c7 Neatened up the indentation. 2003-12-12 17:13:22 +00:00
J.W. Schultz
dfad66a838 Sanity check s2length on recept. 2003-12-06 21:35:34 +00:00
Wayne Davison
58cadc8608 Merged in the security fixes from 2.5.7. 2003-12-06 21:07:27 +00:00
J.W. Schultz
b11b50bcd0 Added reminder to update rsync.yo manpage when adding to
exit codes.
2003-10-25 20:02:45 +00:00
Wayne Davison
a73de5f3ba Added exit code 0. 2003-10-25 17:53:57 +00:00
Wayne Davison
84c3645cea Updated exit codes as Jon Jensen and J.W. suggested. 2003-10-25 16:21:41 +00:00
Wayne Davison
2a88a8cd30 Fixed an operator-precedence problem in the batch-mode code. 2003-10-13 23:46:08 +00:00
Wayne Davison
8a97fc2e1b Tried to improve the documentation surrounding a trailing-slash
source-dir transfer.
2003-10-07 20:33:08 +00:00
Wayne Davison
7a2fd68b96 Tweaked the just-added error message to use my new full_fname()
function.  Also removed some trailing whitespace from lines.
2003-09-16 05:33:09 +00:00
J.W. Schultz
6a7cc46cb2 Detect and report when open or opendir succeed but read and
readdir fail caused by network filesystems issues and
truncated files.
			Thanks to David Norwood and Michael Brown
2003-09-16 02:49:59 +00:00
Wayne Davison
aa6dc37ccb Mention my recent changes. 2003-09-11 05:00:52 +00:00
Wayne Davison
ea42541fe0 Improved file-related error messages by using the new
full_fname() function.
2003-09-11 04:53:05 +00:00
Wayne Davison
b7b2741f3a Tweaked an error message. 2003-09-11 04:53:01 +00:00
Wayne Davison
eb61be192d Added a new function, full_fname(), that makes a filename more complete
for error messages.  If the path is in a module, we ensure that the
"path" setting (from the config file) is not revealed, while still
reminding the user that the path is relative to the module's root.
2003-09-11 04:48:15 +00:00
Wayne Davison
9b9114e8cd Include a few new stubs to handle the new full_fname() function. 2003-09-11 04:48:13 +00:00
Wayne Davison
857e38bb45 Got rid of some "/* dw */" comments and fixed some line's indentation. 2003-09-11 04:48:09 +00:00
Wayne Davison
4ea812445d Got rid of some "/* dw */" comments. 2003-09-11 04:48:07 +00:00
Wayne Davison
e80a765412 If lp_path() returns "/", set exclude_path_prefix to "" (because the
exclude code doesn't want any trailing slashes).
2003-09-11 04:00:19 +00:00
Wayne Davison
15089022d4 Make sure that the new slash-stripping P_PATH code doesn't turn
a "/" into an empty string.
2003-09-11 03:49:53 +00:00
Wayne Davison
f69204adad Changed main() definition to avoid an extra prototype being put
into the proto.h file.
2003-09-10 08:27:34 +00:00
Wayne Davison
459a83c9cc Make sure that the "path" value has any trailing slashes removed. 2003-09-10 08:08:14 +00:00
Wayne Davison
6464bdbe13 Got rid of trailing whitespace. 2003-09-10 07:31:58 +00:00
Wayne Davison
4f3e9a0fba Added the new --protocol option. 2003-09-09 15:58:56 +00:00
Wayne Davison
8a9709dee5 Changed most instances of "remote_version" to "protocol_version", and
others to "remote_protocol".  Downgrade the protocol_version if the
remote_protocol" is lower.  Output the protocol values if the verbose
level is large enough.  Exit if the user tried to force a protocol
value that is not within the range that we can handle.  Fixed the
output of the "very old version of rsync" message to output the right
Client/Server string.
2003-09-09 15:58:53 +00:00
Wayne Davison
daa598df11 Changed most instances of "remote_version" to "protocol_version", and
others to "remote_protocol".  Downgrade the protocol_version if the
remote_protocol is lower.
2003-09-09 15:58:50 +00:00
Wayne Davison
d04e9c51b4 Changed "remote_version" to "protocol_version". 2003-09-09 15:58:48 +00:00
J.W. Schultz
d89a3a313a *** empty log message *** 2003-09-04 05:54:20 +00:00
J.W. Schultz
350e4e4dec Allow non-dir special files to be replaced with regular
files and fix error that caused directories in link-dest or
compare-dest to prevent the creation of files of same path.
2003-09-04 05:49:50 +00:00
Wayne Davison
c95dcb3935 Cast various s->blength references inside of MIN() macros to OFF_T
so that compilers don't warn about signed/unsigned comparisons.
2003-08-22 21:26:08 +00:00
Wayne Davison
1e4f48d6c4 Whitespace tweaks. 2003-08-22 05:51:42 +00:00
Wayne Davison
fb55e28d83 Fixed the multiplying of blength*blength so that it can't overflow
before it gets cast to a uint64.
2003-08-22 05:42:13 +00:00
Wayne Davison
067669dac7 Made the UNUSED(parameter) macro calls read a little nicer. 2003-08-22 05:04:13 +00:00
Wayne Davison
24c906d3f7 Mark unused vars. 2003-08-22 00:31:46 +00:00
Wayne Davison
14820f635d Make extra backup dirs mode 0700, not 0755. 2003-08-22 00:30:46 +00:00
Wayne Davison
59192f5650 Got rid of a duplicate include for malloc.h and improved the "do we
need malloc.h" logic a bit more.  (Trying to prevent #warning and
#error problems on *BSD systems.)
2003-08-21 23:54:20 +00:00
Wayne Davison
365346ca30 Got rid of signed/unsigned-comparison warning if st_rdev is signed. 2003-08-21 23:46:10 +00:00
Wayne Davison
d01350a881 Got rid of signed/unsigned-comparison warning if st_dev is signed. 2003-08-21 23:45:49 +00:00
Wayne Davison
38b02c13d0 Let's try only including malloc.h if stdlib.h isn't around (and it
exists).
2003-08-21 23:32:35 +00:00
Wayne Davison
b017ec4e13 Silenced a couple compiler warnings. 2003-08-21 23:28:24 +00:00
Wayne Davison
2c873122b3 Mention some more bug fixes. 2003-08-20 23:36:45 +00:00
Wayne Davison
6969ebcfcf Call setgroups(1, &gid) after setting the gid (rather than calling
setgroups(0, NULL) before).
2003-08-20 23:25:52 +00:00
Wayne Davison
1dbb94cadf Use the AVAIL_OUT_SIZE() macro in a few more places to ensure
that the avail_out buffer is big enough to uncompress all the
compressed data.
2003-08-20 10:37:53 +00:00
Wayne Davison
8a78bb963d Fixed a couple option-name typos (that had '_' instead of '-'). 2003-08-18 23:52:43 +00:00
Wayne Davison
6931c13800 - Made special exclusion-handling of '.' work in -R mode (so that we
can't accidentally lose the '.' dir and not transfer anything at all).
- Add a trailing '.' onto all '/'-trailing names, even '/' (fixes
  skipped deletions in -R mode from '/').
- Fixed loss of FLAG_DELETE on user-specified dir when unduplicating '.'
  (could happen on "./." or similar).
2003-08-17 21:29:11 +00:00
J.W. Schultz
e6e3f12ffc Whitespace and indentation cleanup. There is a lot of deep
indentation mostly due to read_batch but at least it is now
consistant.
2003-08-15 00:57:27 +00:00
J.W. Schultz
e2559dbedc Make --progress imply --verbose without incrementing verbosity. 2003-08-06 06:45:14 +00:00
Wayne Davison
1f3d6cdd86 Got rid of unused OPT_* enums. 2003-08-05 17:56:54 +00:00
Wayne Davison
4a7ee79d4d Improved the mkstemp error message. 2003-08-04 21:03:07 +00:00
Wayne Davison
0c2ef5f42d Make sure that the error message for mkstemp() includes the full
path of where we're trying to create the temp file.
2003-08-04 21:00:57 +00:00
Wayne Davison
ca20c7fd62 Instead of ignoring SIG_CHLD, reap zombies in the signal handler. 2003-08-04 18:27:27 +00:00
Wayne Davison
191e40da17 Change the way we pass the --suffix option to the remote process so
that a string that starts with ~ doesn't get modified.
2003-08-01 20:19:51 +00:00
Wayne Davison
80ddadb7e8 Complain if the --suffix value contains slashes (which is all too easy
to accidentally have happen if you try to specify "~" with --backup-dir).
2003-08-01 19:40:31 +00:00
Wayne Davison
31f3b68a97 We should bump the deletion_count for backed-up deleted files too. 2003-08-01 08:20:53 +00:00
Wayne Davison
d594399c6a Mention the --backup fix. 2003-08-01 08:01:15 +00:00
Wayne Davison
d74a2e3ed5 Properly handle the backup_suffix/backup_dir settings when deleting
files.  Also optimized the code that calls delete_one().  Don't
neglect to mention a file being deleted with --backup set.
2003-08-01 07:58:47 +00:00
Wayne Davison
d175d7e13e Got rid of suffix_specified and instead set backup_suffix to the
correct default value for the current backup_dir mode.  Added two
new values: backup_suffix_len and backup_dir_len.  Improved some
error-message code to not output duplicate errors.
2003-08-01 07:58:44 +00:00
Wayne Davison
daa8ce838b Use the new backup_suffix_len and backup_dir_len variables. Got rid
of the suffix_specified kludge.
2003-08-01 07:58:41 +00:00
Wayne Davison
b19fd07c02 Clarify some --backup/--backup-dir/--suffix issues. 2003-08-01 00:50:23 +00:00
J.W. Schultz
47d6a60c2f Whitespace and indentation fixes. 2003-07-31 09:32:15 +00:00
Wayne Davison
980821ebab No longer needed (replaced by wildmatch). 2003-07-30 06:13:47 +00:00
Wayne Davison
592f4696dc Updated the exclude/include section to mention the "**" vs "*" change. 2003-07-30 06:12:41 +00:00
Wayne Davison
8a7846f97e Changed the "**" description to reflect its no-longer-buggy behavior. 2003-07-30 06:12:33 +00:00
Wayne Davison
87f18b6289 Include "lib/wildmatch.h", not "lib/fnmatch.h" or <fnmatch.h>. 2003-07-30 06:12:31 +00:00
Wayne Davison
28063ba5b2 Got rid of test for fnmatch. 2003-07-30 06:12:29 +00:00
Wayne Davison
fe332038c6 Call wildmatch(), not fnmatch(). 2003-07-30 06:12:27 +00:00
Wayne Davison
3c0b1ebf78 Changed lib/fnmatch.o to lib/wildmatch.o. 2003-07-30 06:12:25 +00:00
Wayne Davison
f2fe4903c9 Made the list of exclude/include changes more prominent and clear. 2003-07-26 18:13:38 +00:00
Wayne Davison
3151cbae89 Some superficial tweaks I made while reading through the io.c code. 2003-07-26 17:55:07 +00:00
Wayne Davison
3c30b99059 Added one more test. 2003-07-14 15:46:34 +00:00
Wayne Davison
a7735ba085 Updated for latest character-class change. 2003-07-14 15:13:31 +00:00
Wayne Davison
d811b68901 Make sure that no character class can match a '/'. 2003-07-14 15:12:59 +00:00
Wayne Davison
1c8162a921 Optimized show_progress() to reduce the calls to gettimeofday() when
am_server is set.  No need to check do_progress here anymore, since
we aren't called if do_progress isn't set.
2003-07-08 16:54:53 +00:00
Wayne Davison
16417f8b9d Only call show_progress() and end_progress() if do_progress is set. 2003-07-08 16:49:10 +00:00
Wayne Davison
b49d381d05 Changed "./0123456789" to just ".0123456789". 2003-07-07 19:37:58 +00:00
Wayne Davison
7da9a16d10 I decided to go with the slightly simpler logic Thorild Selen suggested
in a subsequent email.
2003-07-07 18:37:38 +00:00
Wayne Davison
32f60a6e7b Improved deficiencies in the hostname-vs-address check (reintroduced in the
last revision) based on the suggestions of Thorild Selen.
2003-07-07 18:25:01 +00:00
Wayne Davison
b7db090661 Commented-out a test that wasn't consistent across all platforms. 2003-07-07 07:28:02 +00:00
Wayne Davison
136c5c5ec3 Silence some compiler warnings on HP-UX. 2003-07-07 07:22:08 +00:00
Wayne Davison
85b80fbc73 A few more tests. 2003-07-07 07:10:40 +00:00
Wayne Davison
16859cdbdc Improved the summary output to use correct English for all counts. 2003-07-07 07:08:24 +00:00
Wayne Davison
fc96552d26 Don't treat "[:" as the start of a named set if there's no ":]". 2003-07-07 07:07:16 +00:00
Wayne Davison
15bb997d0a Added a few more items to the tests. 2003-07-06 18:54:08 +00:00
Wayne Davison
b6b42c892c Improve the format of the --iterations output. 2003-07-06 18:29:24 +00:00
Wayne Davison
5bb920003e - Return ABORT_ALL for a syntax error in the pattern (not FALSE).
- Abort if the [:class:] name is not known.
2003-07-06 18:26:34 +00:00
Wayne Davison
37ff0e344d Added match for new "no errors" line from wildtest. 2003-07-06 17:41:37 +00:00
Wayne Davison
97d53f8c75 Switch to using an input file so that backslashes are specified
normally, and so that test additions and changes are easier.
2003-07-06 17:41:01 +00:00
Wayne Davison
f2ac84c36d Added some portability code for the ctype functions. 2003-07-06 16:29:32 +00:00
Wayne Davison
c21eeef5bc Updated for latest wildmatch.c changes. 2003-07-06 04:34:19 +00:00
Wayne Davison
e11c425119 - Added [:class:] handling to the character-class code.
- Use explicit unsigned characters for proper set checks.
- Made the character-class code honor backslash escapes.
- Accept '^' as a class-negation character in addition to '!'.
2003-07-06 04:33:54 +00:00
Wayne Davison
84229c7ac9 We now figure out if diff accepts -u and we'll use it instead of -c,
if possible.
2003-07-05 22:57:08 +00:00
Wayne Davison
c9a59880f0 Simplified the character-class code a bit. 2003-07-05 22:40:27 +00:00
Wayne Davison
9a17dddbc5 Fixed the output of popt errors and changed our one option to be
--iterations (-i).
2003-07-05 19:21:41 +00:00
Wayne Davison
277d99e8c9 A wildtest change to handle someone using the included popt lib. 2003-07-05 19:14:10 +00:00
Wayne Davison
2a1874cc82 Added dependencies for wildtest.o. 2003-07-05 19:06:49 +00:00
Wayne Davison
d5c973ccb7 Changed some names since "depth" wasn't really the right term. 2003-07-05 19:03:42 +00:00
Wayne Davison
37f3ce61bb Another change to the wildtest rule to make it more portable. 2003-07-05 18:55:09 +00:00
Wayne Davison
076f60eed0 Added a --depth option to report recursion depth values. 2003-07-05 18:49:38 +00:00
Wayne Davison
20b2e9cef7 Improved the ABORT logic to allow aborting consecutive "*" wildcards
back to a "**" wildcard.  Added optional debug code for recursion stats.
2003-07-05 18:48:34 +00:00
Wayne Davison
e37d8229f5 Changed the build rule for wildtest. 2003-07-05 18:46:02 +00:00
Wayne Davison
710faea9a4 Added in the ABORT optimization logic from a newer wildmat release,
adapted for our code that distinguishes "**" from "*".
2003-07-05 17:30:53 +00:00
Wayne Davison
70a6051cf1 Restored an isdigit() check in the match_address() function, but check
the last character in the hostname, not the first.
2003-07-05 07:39:57 +00:00
Wayne Davison
7a1f46b6ac A couple comment tweaks. 2003-07-05 07:22:13 +00:00
Wayne Davison
7ca9250db0 Changed "diff -u" back to "diff -c" (for portability). 2003-07-05 07:09:31 +00:00
Wayne Davison
af7086c63f Change most SAME-AS-FNMATCH "false" values to "true" (since we _should_
work the same as fnmatch in most cases, if fnmatch was actually working
right).
2003-07-05 07:03:56 +00:00
Wayne Davison
8808589277 Get rid of a couple compiler warnings. 2003-07-05 06:56:16 +00:00
Wayne Davison
6cd5096063 Don't define COMPARE_WITH_FNMATCH by default. 2003-07-05 06:53:41 +00:00
Wayne Davison
677cd34acd Include lib/wildmatch.h directly for now (until we make rsync.h include
it for us).
2003-07-05 00:13:38 +00:00
Wayne Davison
08c5385e65 Test the new wildmatch() routine using the wildtest executable. 2003-07-05 00:08:11 +00:00
Wayne Davison
d7bf70f196 Build "wildtest" for "make check". 2003-07-05 00:07:35 +00:00
Wayne Davison
6f3cff41dd Ignore "wildtest". 2003-07-05 00:05:33 +00:00
Wayne Davison
5de45bcadc A testbed to stress the new wildmatch() routine. 2003-07-05 00:05:02 +00:00
Wayne Davison
446ee5b110 A new wildcard-matching routine to replace the fnmatch code. 2003-07-05 00:03:36 +00:00
Wayne Davison
d3e6fd3910 Changed "diff -c" to "diff -u". 2003-07-04 23:56:59 +00:00
Wayne Davison
6813fa7eac Attempting to fix the snprintf() conflict on a gcc-using HPUX 11.11. 2003-07-04 15:36:39 +00:00
Wayne Davison
0f5a04e3ff Use "return" at the end of main() to silence some compilers. 2003-07-04 15:11:46 +00:00
Wayne Davison
8801138b47 Made rprintf() of size_t value portable. 2003-07-04 15:11:44 +00:00
Wayne Davison
2473391971 Improved upon my last patch to make it clearer and cleaner. 2003-07-04 07:47:09 +00:00
Wayne Davison
7d6879328a Changed the syntax of a comment. 2003-07-03 18:33:53 +00:00
Wayne Davison
900454132e Mention the compression (-z) fix. 2003-07-03 17:41:08 +00:00
Wayne Davison
92b8abfe80 Fixed a problem where we might not have enough room to compress
unsent tokens into the obuf in a single call.
2003-07-03 17:38:12 +00:00
Wayne Davison
52e628a861 Mention the exclude changes. 2003-07-01 22:01:48 +00:00
Wayne Davison
4791825d49 Modified the glob_expand_one() function to check the args against the
server's config-specified exclude list.  This prevents the user from
going around directory exclusions.  Fixed push_dir() to not append
"/." onto the end of the current path if it is called with "." as the
"dir" arg.  Made curr_dir[] exported so the exclude code can use it
(for the daemon-config absolute-path excludes).
2003-07-01 21:45:31 +00:00
Wayne Davison
d542c20c5f New stubs to get the test setup to compile with the exclude changes. 2003-07-01 21:45:29 +00:00
Wayne Davison
4762db4fc9 Added some defines for the various exclude-function arg literals.
Added MATCHFLG_ABS_PATH flag for absolute-path patterns.
2003-07-01 21:45:27 +00:00
Wayne Davison
8645af1d8c Changed add_exclude*() calls to use the revised arg syntax. 2003-07-01 21:45:23 +00:00
Wayne Davison
429f98283f Modifications to handle the new server_exclude_list, and to use the
revised calling syntax and new defines for the various exclude
functions.
2003-07-01 21:45:18 +00:00
Wayne Davison
5be7fa93fc Made make_exclude() store anchored config-file excludes with the full
path (clear to the root).  Changed several functions to make the args
more general (to support separated lists), more consistent, and easier
to understand.
2003-07-01 21:45:16 +00:00
Wayne Davison
837cbad97f We now put the excludes from the config file into a "server_exclude_list"
using the revised add_exclude_line() arg syntax.
2003-07-01 21:45:13 +00:00
Wayne Davison
af1d91c562 Call make_file() using the revised arg syntax and new defines. 2003-07-01 21:45:07 +00:00
Martin Pool
908f5a9f9f Add a comment about using getpassphrase() or readpassphrase() rather
than getpass().  No code change.
2003-06-17 04:46:32 +00:00
J.W. Schultz
9b74643315 Credit where due. 2003-06-10 00:21:34 +00:00
J.W. Schultz
986066873e Clarified EXCLUDE PATTERNS to enforce the relativity of
paths.  Replaced undefined "base dir" with a defined "top
dir".
2003-06-10 00:11:24 +00:00
J.W. Schultz
9533e15a79 Changed write file to cope with partial writes by looping
until complete or errno is set.
					(John Van Essen)
2003-05-22 23:24:44 +00:00
Wayne Davison
8dc74608a3 Updated the long description for the --perms option. 2003-05-16 04:23:34 +00:00
J.W. Schultz
3e85237e5f Added AIX and OSX build workaround notes. 2003-05-14 12:54:15 +00:00
Wayne Davison
9d0523ef4c Another MD4 fix for protocol 27 (from Christoph Bartelmus). 2003-05-12 20:38:07 +00:00
Wayne Davison
4a7144ee7e Cleaned up whitespace/indentation. 2003-05-10 08:33:08 +00:00
Wayne Davison
c120ff37f5 Optimized away 3 calls to strcmp(). 2003-05-10 00:56:08 +00:00
J.W. Schultz
83fd337d8e Modified the (in|ex)clude [from] option descriptions to
better highlight the non-equivalence with client-side
--exclude.
2003-05-09 12:04:24 +00:00
Jos Backus
707c1a3085 Remove generated file config.log. 2003-05-04 19:59:47 +00:00
J.W. Schultz
8294b00c11 Added --link-dest to the --help output. 2003-05-02 23:36:10 +00:00
Wayne Davison
da2bcdd1c2 Exclude/include bug fixes. 2003-05-01 19:39:20 +00:00
Wayne Davison
093acc5dad Changed the expected results to match the new bug-fixed behavior. 2003-05-01 19:34:01 +00:00
Wayne Davison
fd73b94d31 Tweaked the exclude_struct for our improved matching code. 2003-05-01 19:33:59 +00:00
Wayne Davison
38499c1a49 Mention that a pattern with "**" is matched against the entire path, even
if the pattern doesn't contain a slash.
2003-05-01 19:33:57 +00:00
Wayne Davison
170381c052 Fixed some matching bugs; made the logic of the matching code a little
clearer by using defined flags; added several comments; optimized the
matching of an anchored literal string.
2003-05-01 19:33:54 +00:00
Wayne Davison
8113a033dd Mention the improved trailing-slash-in-destination handling. 2003-04-24 16:26:53 +00:00
Wayne Davison
87cc45e136 Made my last change a little better. 2003-04-24 16:26:09 +00:00
Wayne Davison
f6b8d591f7 If the user specifies a trailing slash on the destination, make sure
that we treat it as a directory reference.
2003-04-24 16:14:33 +00:00
J.W. Schultz
d31c09c872 Copy relative path caviat from --compare-dest to
--link-dest.
2003-04-23 23:17:41 +00:00
Wayne Davison
337a1a86a7 Changed one part of the exclude-test setup to test the --existing
option.  Also tweaked a few comment lines.
2003-04-23 02:15:59 +00:00
Wayne Davison
b7dc46c0f6 Fixed a typo and added a couple clarifying phrases to the exclude
descriptions.
2003-04-22 18:09:22 +00:00
Wayne Davison
ff57065957 Test various exclude/include patterns. 2003-04-22 17:53:53 +00:00
Wayne Davison
0406a3a7a4 Changed test_xfail to test_fail. 2003-04-22 16:45:24 +00:00
Wayne Davison
bc3b5b2558 Fixed a problem with the test code and enabled it (since rsync's
duplicate-elimination code is now fixed).
2003-04-22 00:25:05 +00:00
J.W. Schultz
d1cce1dd92 Make explicit that (in|ex)clude patterns are for relative
paths and that the leading / is the equivalent of ^ in
regex.
2003-04-21 08:44:25 +00:00
Wayne Davison
7bb7058e8d Made a slight tweak to the previous --stats change. 2003-04-18 20:03:41 +00:00
Wayne Davison
727fa3688f Mention the change to the --stats output. 2003-04-17 23:46:01 +00:00
Wayne Davison
577ab12ce5 Only display the malloc stats if we're at least double-verbose (and
--stats was specified, of course).  Also made the output of the short
(2-line) transfer summary get prefixed with an empty line in all
cases (not just with --stats).
2003-04-17 23:44:25 +00:00
Wayne Davison
0f2ac85576 Some whitespace/indentation cleanup. 2003-04-17 01:44:33 +00:00
J.W. Schultz
fab1f8898e document bug fix for --link-dest and lack of -pgo. 2003-04-11 03:15:53 +00:00
restrict
f63d68be97 (Really mbp)
Test commit from restricted CVS account.  No changes.
2003-04-10 04:35:12 +00:00
Wayne Davison
58665d23b4 Fixed a weird line corruption in the last check-in and tweaked the
format to be the same as in older releases.
2003-04-10 03:06:28 +00:00
J.W. Schultz
195bd906a2 - Per-file dynamic block size is now sqrt(file length).
-	The per-file checksum size is determined according
	to an algorythm provided by Donovan Baarda which
	reduces the probability of rsync algorithm
	corrupting data and falling back using the whole md4
	checksums.
2003-04-10 02:04:58 +00:00
J.W. Schultz
fc1ae6582f - for protocol version >= 27, mdfour_tail() is called when the block size
(including checksum_seed) is a multiple of 64.  Previously it was not
   called, giving the wrong MD4 checksum.

 - for protocol version >= 27, a 64 bit bit counter is used in mdfour.c as
   required by the RFC.  Previously only a 32 bit bit counter was used,
   causing incorrect MD4 file checksums for file sizes >= 512MB - 4.
						-- Craig Barratt
2003-04-10 01:50:12 +00:00
J.W. Schultz
fc0257c9fd Now support dynamic per-file checksum2 size.
This pushes protocol version to 27
2003-04-10 01:13:30 +00:00
J.W. Schultz
91c4da3fda versions prior to 1.7.0 (protcol version 17) cannot talk to
protocol versions > 20 so bumping up the minimum protocol
version and excising the pre-17 cruft.
2003-04-10 00:13:48 +00:00
Paul Green
990ff150ef Fix bug reported by engard.ferenc at innomed.hu whereby using the %f format
in sprintf with a value like 0.025 produced 0.250.  We were dropping the
leading zeros before the fractional digits.
2003-04-09 21:10:18 +00:00
J.W. Schultz
e72b18a9bd Remove tempname length problem and files-from from TODO. 2003-04-01 03:44:50 +00:00
J.W. Schultz
bc63ae3f13 Removing vestigial support for protocol versions prior to 15. 2003-03-31 17:28:34 +00:00
J.W. Schultz
6e12886393 Logic error in preserve_perms + link_dest 2003-03-31 08:09:41 +00:00
Wayne Davison
b5ca91ae4b Fixed a typo. 2003-03-30 23:19:22 +00:00
Wayne Davison
89855e78ab Started a new section for the next release. 2003-03-30 23:15:01 +00:00
Wayne Davison
e106de49c8 Tweaked the O_BINARY code to the latest idiom. 2003-03-30 23:00:51 +00:00
Wayne Davison
afbcc8f216 Define O_BINARY as "0" if it isn't defined. 2003-03-30 23:00:49 +00:00
Wayne Davison
f177b7cca2 Documented --files-from, --no-relative, --no-implied-dirs, and --from0. 2003-03-30 23:00:47 +00:00
Wayne Davison
ea5164d181 Support the new --files-from, --no-relative, --no-implied-dirs, and --from0
options.  Moved the find_colon() routine here from main.c.
2003-03-30 23:00:42 +00:00
Wayne Davison
ccdff3ebbf Open the file in BINARY fd mode, handle the normal line-ending characters
better than before, and add support for the new --from0 option (which changes
the line separator to a null).
2003-03-30 23:00:40 +00:00
Wayne Davison
24d0fcde7f Support the new --files-from and --no-implied-dirs options. 2003-03-30 23:00:37 +00:00
Wayne Davison
56014c8c0a Support the new --files-from and --from0 options. 2003-03-30 23:00:35 +00:00
Wayne Davison
7c2a9e766c Support the new --files-from option. 2003-03-30 23:00:33 +00:00
J.W. Schultz
bb24028f51 Make link-dest aware of --perms, --owner and --group.
---- Chris Darroch
2003-03-26 20:26:06 +00:00
J.W. Schultz
52d3e10613 Prevent tempfile names from overflowing.
Debian BUG# 183667
2003-03-26 11:04:14 +00:00
J.W. Schultz
67863f46e3 Warn if 64bit value sent or received on system that doesn't
support 64bit integers.
2003-03-25 07:13:40 +00:00
J.W. Schultz
9c28e52628 Seperate the uint64_t macros from int64_t 2003-03-25 05:46:52 +00:00
J.W. Schultz
1b2f167546 Frustration mounting. I'll get it right eventually.
Thank goodness for the build farm.
2003-03-25 04:18:10 +00:00
J.W. Schultz
702d0c4529 earlier problem was a typo. 2003-03-25 04:09:43 +00:00
J.W. Schultz
51106bafc6 Another stab at uint64 because some platforms seem to have
problem with the unsigned off64_t
2003-03-25 03:14:27 +00:00
J.W. Schultz
42d4edc067 removed log_transfer() It was no more than a conditional
rprintf() with an unused param.
2003-03-25 02:28:54 +00:00
J.W. Schultz
fbc0bc4d53 Create uint64 for INO64_T and DEV64_T eliminating type mismatches. 2003-03-25 02:02:22 +00:00
J.W. Schultz
1b2db7aecb Increased maximum protocol version.
Added warning for deprecated protocol versions.
2003-03-24 22:42:46 +00:00
J.W. Schultz
1ce29566e7 Minor correction to protocol annotation. 2003-03-24 22:32:47 +00:00
J.W. Schultz
3742bf3ac3 Annotated each release with protocol version and
added protocol version history from rsync.h log.
2003-03-24 22:13:16 +00:00
Wayne Davison
18d6b679af The close_all() function was missing its "void" prototype. 2003-03-21 23:43:50 +00:00
Wayne Davison
dbda5fbf06 Get rid of eol whitespace. 2003-03-21 22:53:46 +00:00
Wayne Davison
2154309a54 Optimized the implied-directory code to avoid putting so many duplicate
dirs into the file list.
2003-03-21 22:10:44 +00:00
Wayne Davison
afb6e9450d - Use popt to better effect for the two options that can be both
set and unset by the user.
- Even more whitespace cleanup.
2003-03-21 19:17:23 +00:00
Wayne Davison
dfa3248380 - Simplified the whole-file option handling.
- Fixed some whitespace issues.
2003-03-21 18:58:50 +00:00
Wayne Davison
2cda256088 - Simplified the whole-file option handling.
- Cleaned up some whitespace issues.
2003-03-21 18:53:00 +00:00
Wayne Davison
d9c7edf63f - Fixed lots of line-indentation problems, including a really huge section
of non-batch-mode code that was indented at the same level as its
  surrounding "if" statement.
- Moved the heavily-used am_* flags into global extern vars instead of
  externing them again and again in individual functions.
- Got rid of line-ending whitespace.
2003-03-21 18:33:48 +00:00
J.W. Schultz
a151343943 Cleanup: Added header files to dependancies. 2003-03-21 07:42:19 +00:00
J.W. Schultz
85ed0aa396 Typo corrections.
Thanks to Paul Slootman <paul@debian.org>
2003-03-21 07:27:31 +00:00
J.W. Schultz
3019f95f37 Removing --csum-length option documentation since there is
no such option.
2003-03-21 04:39:11 +00:00
Paul Green
5702bc12b3 Apply patch from Steve Bonds to repair this test. 2003-02-19 16:22:50 +00:00
Paul Green
b0d791bb35 Patch from Roderick Schertler (roderick at argon.org) to ignore
non-POSIX directory mode bits that are used by AIX.
2003-02-18 18:07:36 +00:00
Paul Green
3903928ca0 Remove RedHat-specific .spec files in favor of the .spec files
maintained under packaging/lsb.
2003-02-18 16:50:25 +00:00
Wayne Davison
827c37f631 The sender no longer removes the duplicate names from the file list -- we
let the receiver do that, since they are the one that requests names and
we want to be sure the sender has any name the receiver may ask for.
2003-02-12 09:15:23 +00:00
David Dykstra
b45b059a3d Back out one of the changes in log.c revision 1.62, and always send errors
to the client after multiplexing is enabled.
2003-02-11 19:13:51 +00:00
Paul Green
f39281ae56 Patch from jw schultz to reword "link" to "connection" in a couple of
spots.
2003-02-10 14:51:09 +00:00
Paul Green
e2bea9eb8d Update packaging spec files per patch submitted by Horst von Brand.
In the future, we need to be sure to keep *.spec and *.spec.tmpl
identical...the release macro produces *.spec from *.spec.tmpl.
2003-02-05 18:41:53 +00:00
Paul Green
931a979904 Restored changes accidentally backed out by Dave Dykstra in previous revision. 2003-01-29 21:04:28 +00:00
Paul Green
3fccfafd30 Apply fix from Horst von Brand. See comments in rsync.spec. 2003-01-29 20:52:59 +00:00
David Dykstra
7a6fd4c1c7 preparing for release of 2.5.6 2003-01-28 05:28:42 +00:00
David Dykstra
8395d24616 Add header for 2.5.6 release. 2003-01-28 05:13:16 +00:00
David Dykstra
7d085960eb Remove the Cygwin msleep(100) before the generator kills the receiver,
because it caused the testsuite/unsafe-links test to hang.
2003-01-28 05:05:53 +00:00
David Dykstra
3884317181 Change the default of --modify-window back to 0 on Cygwin. 2003-01-28 03:11:57 +00:00
David Dykstra
089a2435f8 Ack! I had accidentally ifdefed out the kill from the generator to the
receiver process for every platform except Cygwin.
2003-01-28 03:03:55 +00:00
David Dykstra
8ed16deb24 Change so the delay before generator signals receiver is only done on Cygwin. 2003-01-28 02:51:03 +00:00
Paul Green
a577af9067 Added a TODO item about temporary file names bumping up against the
maximum name length.  (I have an unfinished patch that will address
this).
2003-01-27 16:33:47 +00:00
David Dykstra
59af13651b Move the sleep to workaround the default modify-window of 1 on Cygwin to
the beginning of "checkit" rather than the end of "hands_setup" because
sometimes files are modified just before checkit is called and the copy
finishes within one second so they're considered to be the same time.
I don't think this would be a problem in real life, so just change the
test.
2003-01-27 04:41:30 +00:00
David Dykstra
787568f371 Insert a 100ms sleep just before sending the USR2 signal to the
child receiver process to prevent some hangs on Cygwin.  Anthony
Heading discovered the workaround first and suggested 30ms, and
Greger Cronquist had better luck with 100ms.
2003-01-27 03:52:42 +00:00
David Dykstra
f0019fc506 Remove the "Connection reset by peer" from TODO 2003-01-27 03:36:54 +00:00
David Dykstra
9f639210ca Prevent the "Connection reset by peer" messages often seen from Cygwin.
Result of a lot of discussion over the last year and a half.  Based on
a patch from Randy O'Meara, cleaned up a bit by Max Bowsher.
2003-01-27 03:35:08 +00:00
David Dykstra
deec574421 Update date on man page. 2003-01-27 03:13:46 +00:00
David Dykstra
04657e42d5 Update rsyncd.conf documentation to be right for rsync server mode over a
remote shell.
2003-01-27 03:07:18 +00:00
David Dykstra
1b88775534 Change erroneous references to a --config-file option to the correct --config
option.
2003-01-27 02:48:14 +00:00
David Dykstra
7f6537557d Change news item about handling of text mode in files to just permitting
any of the standard line termination styles.
2003-01-26 20:49:24 +00:00
Wayne Davison
518233ca79 Got rid of recent O_TEXT* and O_BINARY* changes. 2003-01-26 20:11:16 +00:00
Wayne Davison
bc72130d71 Got rid of O_TEXT_STR and added code to strip '\r' from the end of the
lines we read.
2003-01-26 20:10:23 +00:00
Wayne Davison
855decd3a7 Added back the O_BINARY #ifdef. 2003-01-26 20:09:02 +00:00
Wayne Davison
0090cbdba6 Got rid of O_TEXT_STR change. 2003-01-26 20:07:55 +00:00
Wayne Davison
73ff720972 File I/O already handles '\r', so we can remove the O_TEXT flags. 2003-01-26 19:37:54 +00:00
David Dykstra
c561e1378d Remove a couple items I know are no longer needed. 2003-01-26 04:04:47 +00:00
David Dykstra
aa2c47d835 Better fix for infinite recursion; don't return from exit_cleanup
unless the nesting is already pretty deep, because there are normal
cases where exit_cleanup is nested shallowly.  Patch from Marc Espie,
posted by Brian Poole.
2003-01-26 03:53:34 +00:00
David Dykstra
536b84680b Open config files in text mode when O_TEXT is defined. This helps on
Cygwin when the config files are on a filesystem that is mounted in
binary mode.  Patch from Ville Herva.
2003-01-26 03:46:54 +00:00
David Dykstra
7508b795bf Tests that use hands_setup to make a test file directory and right
afterward make a copy were failing on cygwin because the default
--modify-windows now 1 on Cygwin.  Adding a 2 second sleep at the end of
hands_setup so that hopefully the tests will succeed because the copy
will be made more than 1 second away from the original.
2003-01-26 03:34:19 +00:00
Wayne Davison
76ee1d18bf Don't try to run daemon tests as "nobody". 2003-01-25 03:46:57 +00:00
Wayne Davison
379bc86547 Getting rid of recent "chown" since we decided to forego trying to run
the daemon tests as "nobody".
2003-01-25 03:45:40 +00:00
David Dykstra
066696644f Change default of --modify-window on Cygwin from 2 to 1 because that's all
that's needed on FAT filesystems.  NTFS filesystems can do with a window of
0, but it shouldn't hurt because it's highly unlikely that any given file
will be modified within one second of the time that rsync last copied it.
2003-01-24 22:07:22 +00:00
Paul Green
755bcd3722 Restore trailing newline character at the end of the file. 2003-01-23 17:18:20 +00:00
Paul Green
1985aa9666 Mentioned the fact that config.sub and config.guess got updated. 2003-01-22 22:59:35 +00:00
Paul Green
f4663a36da Updated config.sub and config.guess to latest revision. 2003-01-22 22:24:53 +00:00
Wayne Davison
521e6fdcfc Mention test-case fixes. 2003-01-21 20:25:44 +00:00
Wayne Davison
61ab574e38 Moved the chown from the download test to the upload test. 2003-01-21 20:19:53 +00:00
Wayne Davison
660cb6a085 Chown the $TO and $FROM directories to $RSYNCD_UID:$RSYNCD_GID (if we
can, and don't fail if we can't).
2003-01-21 20:19:53 +00:00
Wayne Davison
4274208833 Chown the $TO and $FROM directories to $RSYNCD_UID:$RSYNCD_GID (if we
can, and don't fail if we can't).
2003-01-21 19:30:51 +00:00
Wayne Davison
34db05b421 Put the UID and GID that rsyncd will run as into variables. 2003-01-21 19:28:29 +00:00
Wayne Davison
1657be22a3 Separated a cat "..." command out from inside a double-quoted string
so that we don't run afoul of some shells quoting quirks.  (As Brian
Poole suggested.)
2003-01-21 19:27:11 +00:00
David Dykstra
3636b9ffaa Change the name on the --modify-window default for Cygwin to Lapo Luchini. 2003-01-21 14:22:49 +00:00
David Dykstra
e3cd264571 Change version to working version 2.5.6pre3cvs 2003-01-21 04:23:43 +00:00
David Dykstra
69555b0943 Change version to 2.5.6pre2 2003-01-21 04:00:56 +00:00
Wayne Davison
522c05cf9a Declare preserve_perms for latest syscall.o. 2003-01-21 01:35:23 +00:00
David Dykstra
f0b4fdaf5e Ignore errors from chmod when --preserve-perms/-p/-a are not set.
Gnu cp behaves the same way.
2003-01-21 00:58:50 +00:00
Wayne Davison
ac6ce98375 Added a couple missing NEWS items. 2003-01-20 23:49:22 +00:00
David Dykstra
1b3cadaa39 Re-activate the piece of code that creates intervening directories
when --relative-paths is used.  The code was accidentally skipped starting
in CVS version 1.32 of receiver.c.  Noticed by Craig Barratt.
2003-01-20 23:32:17 +00:00
David Dykstra
61ca7d596c Update description of hosts allow for IPv6. From Bert Vermeulen. 2003-01-20 23:10:22 +00:00
David Dykstra
688d573295 Make the default for --modify-window be 2 on cygwin. 2003-01-20 23:09:24 +00:00
Wayne Davison
ec6e0bf0c0 Backed out Paul Green's IRIX patch since it didn't seem to be a part of
the Makefile fix and I like the old EXE syntax better.
2003-01-20 18:26:14 +00:00
David Dykstra
184dede92f Save the value of the test for getaddrinfo defines in the config cache. 2003-01-20 17:25:26 +00:00
David Dykstra
d2cc0323fb Also need to include lib/getnameinfo when the getaddrinfo defines don't exist. 2003-01-20 16:59:18 +00:00
David Dykstra
3a1eefd331 Oops, lib/getaddrinfo wasn't pulled in when the system doesn't define
AI_PASSIVE.
2003-01-20 16:27:34 +00:00
David Dykstra
824f1c7944 Only look for a system getaddrinfo/getnameinfo if AI_PASSIVE is defined
by system headers.  This fixes compile errors on Irix 6.5.
2003-01-20 15:04:16 +00:00
David Dykstra
7bc8218d81 Fix bug that causes messages like
rsync: stack overflow in function match_address
on openbsd.  Patch from Brian Poole <raj@cerias.purdue.edu>.
2003-01-20 13:46:28 +00:00
David Dykstra
a405cda63c Add unsafe-byname tests with symlink destinations ending in '..'. 2003-01-20 12:42:42 +00:00
Wayne Davison
7afa3a4a48 Optimized unsafe_symlink() to avoid malloc/free calls. 2003-01-19 21:37:11 +00:00
Wayne Davison
c80b3d8c3f Added "extern" to io_{read,write}_phase line (they were being
multiply defined).
2003-01-19 05:53:07 +00:00
Wayne Davison
ef6122c622 Got rid of trailing whitespace and tweaked a few things that might
possibly be affecting the IRIX build (but probably not).
2003-01-18 19:11:55 +00:00
Wayne Davison
75fb17b891 Define DBL_EPSILON if it doesn't exist. 2003-01-18 19:00:07 +00:00
Wayne Davison
2abbf2498f Trying out Paul Green's IRIX patch to see if it fixes the syntax
error in the Makefile.
2003-01-18 18:52:50 +00:00
Wayne Davison
b91b50c01f Fixed the bug in clean_flist() where it did not get rid of all duplicate
names if there were more than 2 identical names in a row.
2003-01-18 18:00:23 +00:00
David Dykstra
06891710f2 Change rsync help for -a to show that it is equivalent to -rlptgoD.
I've had to go to the man page many times for that information and I
finally got sick of it.
2003-01-16 21:02:43 +00:00
David Dykstra
b765ec32b9 Prevent infinite recursion in exit_cleanup(). Patch from Sviatoslav Sviridov. 2003-01-16 20:09:31 +00:00
Wayne Davison
a70d070cc5 Make unsafe_symlink() take const args so that we don't get any
compiler warnings when calling it with a const char *.
2003-01-15 17:49:44 +00:00
David Dykstra
1f1fbe187e Add news item about fix of --copy-unsafe-links 2003-01-15 16:41:51 +00:00
David Dykstra
fc63847406 Fix bug in --copy-unsafe that made it totally broken, and re-enable
the tests that tested it.  As far as I can tell, it was always broken
since the day I put it in years ago.  In my investigation into this I
was unable to figure out what in the world I was thinking back then,
to introduce a global variable with the wrong information in it rather
than using a parameter that was already available in readlink_stat
function.  That still bothers me a bit but I decided to stop worrying
about it.
2003-01-15 16:14:07 +00:00
David Dykstra
f58677d123 Don't use the return value from sprintf because it doesn't work on Sunos4. 2003-01-14 21:37:08 +00:00
David Dykstra
7ab1538861 Now that the 2.5.6pre1 snapshot has been made, change the version to
2.5.6pre2cvs.
2003-01-13 17:21:12 +00:00
David Dykstra
7ad0f94de9 Change version to 2.5.6pre1 2003-01-13 16:40:15 +00:00
Wayne Davison
8af534a52c Changed the alloca warning message. 2003-01-12 22:45:47 +00:00
Wayne Davison
7447419266 Use the old kludge of using malloc() if alloca() is missing. 2003-01-12 21:49:44 +00:00
David Dykstra
5216de37a4 Reduced the severity of the warning about missing alloca to a warning, and
changed the test to the common form of prefixing an x to both sides of
an equivalence because it didn't even notice a problem on the cray when
it was instead using test -n.
Also noticed an error in the test for ANSI c, doing a "$xac..." = xno"
when it should have been "x$ac..." = xno, so I fixed that too.
2003-01-12 04:02:25 +00:00
David Dykstra
ccc0d1eb1d Oops, had the sense of the test for the existence of alloca() backwards. 2003-01-12 03:28:13 +00:00
David Dykstra
7fc0890881 Make configure bomb if the included popt is needed but alloca is not
available, as apparently is the case on Cray UNICOS.  The AC_FUNC_ALLOCA
autoconf documentation talks about having an included alloca.c and
periodically calling alloca(0) to garbage collect when C_ALLOCA is defined,
but I don't know where to get the code or if there's anybody that cares
enough about the UNICOS port for it to be worth the trouble.
2003-01-12 03:11:38 +00:00
David Dykstra
b17f1d76c0 Cast the return from alloca to work better on UNICOS. 2003-01-11 19:01:31 +00:00
David Dykstra
451b5fc969 Cast the return of alloca to remove a fatal error on Cray UNICOS. 2003-01-11 14:39:41 +00:00
Wayne Davison
1e678fcab1 Yet another try at getting this to skip on cygwin. 2003-01-11 08:19:24 +00:00
Wayne Davison
48bcc6ee2b Hopefully this version will skip correctly on cygwin. 2003-01-11 07:39:49 +00:00
Wayne Davison
32734c7c3c Try a different tact to get cygwin to skip this test. 2003-01-11 07:22:40 +00:00
Wayne Davison
aaf375d0a5 The inet_pton() man page says we need to pass in a pointer to a
struct in_addr, which means passing &sin.sin_addr instead of
&sin.sin_addr.s_addr.  Also changed the AF_INET6 version to pass
&sin6.sin6_addr.  Hopefully this will fix UNICOS and not break
anyone else.
2003-01-11 02:05:56 +00:00
Wayne Davison
9680f811f6 Cast poptGetOptArg() to remove a compiler warning. 2003-01-11 01:29:30 +00:00
Wayne Davison
bda41fa509 + The prototype for isc_net_pton() should have been inet_pton().
+ Define IN_LOOPBACKNET if it is not already defined.
2003-01-10 20:09:58 +00:00
Wayne Davison
7ea84b6890 Only refer to S_ISVTX if S_ISVTX is defined. 2003-01-10 20:08:43 +00:00
Wayne Davison
cc234d944a + Fixed a comment that referred to isc_net_pton() instead of inet_pton().
+ Only prototype inet_pton6() if INET6 is defined.
2003-01-10 20:08:12 +00:00
Wayne Davison
ac84096d1f Don't use '#' in the dsttmp filename. 2003-01-10 19:58:51 +00:00
Wayne Davison
a1cc591b29 Paul Green's changes to add $(EXEEXT) and $(CPPFLAGS) as appropriate. 2003-01-10 19:58:16 +00:00
David Dykstra
da0405080e The call to test_skipped if makepath failed didn't work, presumably because
makepath is builtin and there's some problem with it causing /bin/sh to
exit on cygwin.  Parens around the call to makepath should help.
2003-01-10 18:32:59 +00:00
David Dykstra
0c0a3e2dd3 Clean up better after the testsuite check programs. Patch from J.W. Schultz. 2003-01-10 15:16:23 +00:00
David Dykstra
ad301e487c Skip the longdir test if the long directory can't even be created, such as
on cygwin (maybe only on certain filesystems?).
2003-01-10 15:06:10 +00:00
Wayne Davison
b5ae4aba38 Reset the io_error_fd right before the generator kills off the receiver
(because the death of the receiver will close the fd and cause the
generator to fail in any subsequent IO).
2003-01-10 08:32:09 +00:00
David Dykstra
8d2aad49e3 AI_NUMERICHOST is not defined on AIX. 2003-01-09 21:30:24 +00:00
David Dykstra
bc2b4963a0 Support IPv6 addresses with "hosts allow" and "hosts deny". Patch from
Hideaki Yoshifuji.
2003-01-09 21:14:10 +00:00
David Dykstra
ee7118a816 Fixed bug that caused rsync to lose exit status of its child processes.
Based on patch submited by David R. Staples.  Todd Vander Does contributed
the following test which showed the problem:
  > mkdir /tmp/nowrite
  > chmod -w /tmp/nowrite
  > rsync /etc/group /tmp/nowrite || echo $status
  mkstemp .group.cUaaeY failed
  rsync error: partial transfer (code 23) at main.c(518)
  23
  > rsync -e ssh loki:/etc/group /tmp/nowrite || echo $status
  mkstemp .group.1rayeY failed
  > rsync -e ssh loki:/etc/group /tmp/nowrite && echo $status
  mkstemp .group.fbaGiY failed
  0
The remote copy should have returned non-zero exit code like the local copy.
2003-01-09 19:04:06 +00:00
Wayne Davison
95dd949c09 Added .svn/ to the cvs_ignore_list and some trailing slashes to the
other dirs in the list.
2003-01-09 03:55:57 +00:00
Wayne Davison
9326552e66 Added .svn/ to the --cvs-exclude list and some trailing slashes to the
other dirs in the list.
2003-01-09 03:53:24 +00:00
Jos Backus
1e34e4b7cd Add "void" to some function definitions so that all declarations in proto.h
have full parameter lists. This helps unbreaking compilation on SCO UNIXWare.

Submitted by: Stephen Friedl
2002-12-24 07:42:04 +00:00
Jos Backus
06464f55e2 Change all relevant occurrences of `rsync'' and `$rsync_bin'' to the
canonical form ``$RSYNC'' (set in testsuite/rsync.fns). This prevents any
stray rsync binaries in the user's PATH from being picked up by the test
scripts and ensures that the newly built rsync binary is used always.
2002-12-24 07:25:25 +00:00
David Dykstra
1b85e3f1a0 When a file shows up as not existent during an rsync run, always check
to see if it excluded before reporting an error.  Previously it was only
checking for the exclusion if copy_links was enabled, but the error can
also occur if a file disappears during an rsync run.  Suggested by Eugene
V. Chupriyanov and Bo Kersey.
2002-12-11 18:48:27 +00:00
Jos Backus
eac9dc63e3 Fix the chgrp and hardlinks tests by running $RSYNC instead of relying on the
new rsync being in $PATH; it may pick up an old version, invalidating the
result of the tests. This is what the other tests do already.

Submitted by: Joel Shprentz <ShprentzJ@nima.mil>
2002-11-05 18:35:59 +00:00
David Dykstra
30e8c8e1e4 When using daemon mode over a remote shell program and not running as root,
default the config file to just "rsyncd.conf" in the current directory
instead of /etc/rsyncd.conf.  Also, fix problems with logging messages when
running daemon mode over a remote shell program: it was pretty much doing
the opposite of what it should have, sending early error messages to the
log and later messages to the client.  Switched it around so the very early
error messages go to the client and the later ones go to the log.
2002-08-30 23:27:26 +00:00
David Dykstra
d53d7795ee Change wording of --compare-dest option to refer to the --link-dest option. 2002-08-30 15:12:47 +00:00
David Dykstra
59c95e4243 Add --link-dest option from J.W. Schultz. 2002-08-29 14:44:55 +00:00
David Dykstra
f8a94f0de8 Patch from J.W. Schultz to have --include-from and --exclude-from on
filename "-" read from standard input.
2002-08-29 14:37:20 +00:00
Wayne Davison
3b5f6214a6 * Don't call getnameinfo() if we've already populated the addr_buf.
* Moved some structures in client_name() so that they remain in-scope for
  the entire function (since we set pointers to their storage location).
* Allow the dot-counting loop to increment to 4 instead of stopping at 3.
2002-08-02 17:11:39 +00:00
David Dykstra
542ad675b9 Put in better method of checking whether or not daemon over --rsh mode is
in place: simply check the "am_server" global variable, which is not set
true when the daemon is listening for connections (daemon_main is not
called in main.c if am_server is set).
2002-08-02 15:39:43 +00:00
David Dykstra
1e736b8ff7 Fix client_name to work on when INET6 is enabled but using a 4-part IPv4
IP address.  Tested on Linux, but only with an IPv4 ssh.  Somebody who has
IPv6 enabled on ssh needs to test it yet.
2002-08-02 15:05:03 +00:00
David Dykstra
a6d8c3f336 Fix last change to use correct IPv6 structure names when using INET6.
Doesn't yet look up names correctly on Linux with INET6 enabled, however;
needs further work but I don't have time right now.
2002-08-01 21:57:23 +00:00
Wayne Davison
bb4aa89c10 Don't pass "-l user" to the remote shell if we're starting a server-daemon
and the command already has a "-l user" option.
2002-08-01 20:46:59 +00:00
David Dykstra
09021eabb5 Fix to correctly identify remote IP address and host name when using
-e ssh and :: together.  Uses $SSH_CLIENT to locate the IP address
(was attempting to before but it didn't always work) and then uses
inet_pton() on that and getnameinfo() to find the name.
2002-08-01 19:17:00 +00:00
Wayne Davison
8d69d57113 Documented that the rsync:// URL syntax is now legal in the destination. 2002-08-01 17:55:40 +00:00
Wayne Davison
eaa4c150ab Mention the new rsync:// URL-in-the-destination syntax. 2002-08-01 17:55:11 +00:00
Wayne Davison
a125c82ad2 Allow the rsync:// URL syntax in the destination field. 2002-08-01 17:53:38 +00:00
Wayne Davison
93eff16a6a Document more recent changes. 2002-08-01 17:53:07 +00:00
Wayne Davison
d2d9fe184d Mention the recent commits. 2002-08-01 16:50:46 +00:00
David Dykstra
2d4ca358db Slight change to refer to the section CONNECTING TO AN RSYNC SERVER OVER A
REMOTE SHELL PROGRAM from within the --rsh option.
2002-08-01 16:21:20 +00:00
Wayne Davison
39993af514 The function passed to start_accept_loop() now takes 2 fd ints (for
the daemon via remote-shell support).
2002-08-01 00:37:08 +00:00
Wayne Davison
bef4934045 Document the new server-daemon via remote-shell mode. 2002-08-01 00:37:06 +00:00
Wayne Davison
1312d9fc47 If daemon_over_rsh is set, we limit the generated options to just
--server and --daemon.
2002-08-01 00:37:01 +00:00
Wayne Davison
75aeac44e8 Handle the new server-daemon via remote-shell mode. 2002-08-01 00:36:59 +00:00
Wayne Davison
68f40ebba9 Moved the end of start_socket_client() into a new function called
start_inband_exchange() and made several functions take two fds
(for the daemon via remote-shell support).  The start_daemon()
function is no longer static and now works on non-socket fds.
2002-08-01 00:36:56 +00:00
Wayne Davison
973007daac Changed auth_server() to take two fds (for the daemon via remote-shell
support).
2002-08-01 00:36:54 +00:00
Wayne Davison
8060514230 Stefan Nehlsen's fix of a timeout problem on large files.
(Modified to work with the latest CVS source.)
2002-07-31 21:20:07 +00:00
Wayne Davison
b1a2f37a6e Mention the popt upgrade. 2002-07-27 18:33:54 +00:00
Wayne Davison
7c66b86028 Check for the float.h header file (for popt). 2002-07-27 18:33:30 +00:00
Wayne Davison
cc248aae9b Updated to version 1.6.4. 2002-07-27 18:32:25 +00:00
Wayne Davison
ca23c51aeb - Fixed a crash in flist_find() when the last item in the flist has
been removed as a duplicate.
- Got rid of a compiler warning about mixed signed/unsigned types in a
  conditional expression.
2002-07-27 18:01:21 +00:00
David Dykstra
fca9a9b0f0 Document in --owner and "use chroot" that --numeric-ids is implied when
use chroot is yes.
2002-06-27 17:51:25 +00:00
John H Terpstra
1ea15dbe05 Added Solaris PkgInfo build script from Jens Apel <jens.apel@web.de> 2002-06-22 16:52:15 +00:00
David Dykstra
8e34cd41f0 Close previously opened file descriptor when mkstemp fails in recv_files().
Every other failure condition in that function was alreadying doing this,
and I saw a case with a lot of "mkstemp...No space left on device" messages
started becoming "mkstemp...Too many open files" messages because of this
bug.  Not that it makes a whole lot of difference, since nothing gets copied
because the disk was out of space.
2002-05-28 15:42:51 +00:00
David Dykstra
9ef1cc7cdf Clarify the relationship of max connections and lock file. 2002-05-16 21:07:23 +00:00
Martin Pool
411acbbc2a Better notes about handling IPv6 on old machines 2002-05-14 05:44:51 +00:00
Martin Pool
32e83406c4 Fix little mistake 2002-05-14 05:31:11 +00:00
Martin Pool
7e28fca126 Note about lchmod. 2002-05-14 05:25:46 +00:00
David Dykstra
e4ffb53900 Fix the rsync home page URL to drop a trailing "/rsync". 2002-05-13 18:34:37 +00:00
David Dykstra
7c2d381c28 Clarify that exclude/include options in rsyncd.conf apply only to files
sent from the server or deleted on the server.
2002-05-13 18:22:28 +00:00
Martin Pool
bde47ca7c5 Note that using the old sockets API probably will not work
sufficiently on some ipv6 systems.
2002-05-13 07:54:47 +00:00
Wayne Davison
ea7f8108b0 Make the -e text a little less chatty, and mention the legality of
command-line options in the RSYNC_RSH section.
2002-05-11 08:31:55 +00:00
Wayne Davison
98393ae2e2 Mention that the -e COMMAND can contain options. 2002-05-10 19:56:23 +00:00
David Dykstra
759ac87019 Submit enhancement from Michael Zimmerman to allow --suffix to be used
with --backup-dir.
2002-05-09 21:44:46 +00:00
David Dykstra
a1e0e45e01 Indicate that the exclude options in rsyncd.conf only apply when receiving
files to a server and not when sending files to it.
2002-05-09 19:03:40 +00:00
Wayne Davison
54170a084d Tweaked the --rsh option's description. 2002-05-06 19:05:05 +00:00
Wayne Davison
1bbf83c07d - Improved the references to rsh to better indicate that rsync may be
configured to use some other remote shell by default.
- Fixed the mention of ssh's preferred IO-blocking mode.
2002-05-06 19:02:44 +00:00
Wayne Davison
ccd2b499ed Mention that --delete-after now implies --delete. 2002-05-06 18:47:57 +00:00
Wayne Davison
1de50993a7 Made the --delete-after option imply --delete. 2002-05-03 22:59:17 +00:00
Wayne Davison
786c36876b Mentioned that --delete-after and --delete-excluded imply --delete. 2002-05-03 22:58:01 +00:00
Martin Pool
8bd1a73e14 Add note about resolving Debian gid problem. 2002-04-26 00:55:34 +00:00
Martin Pool
c7d692c3c3 Notes about handling machines lacking getaddrinfo(). 2002-04-24 01:13:26 +00:00
Martin Pool
f9b9e2f067 Note from Alberto Accomazzi that rsync urls are broken for upload 2002-04-19 05:33:36 +00:00
Martin Pool
dafe63ca98 Doc. 2002-04-16 01:38:21 +00:00
Martin Pool
f49a7b227f When -e is specified along with an rsyncd url, the client should get a
warning but it should not be treated as an error.  (Bill Nottingham)

  http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=62489
2002-04-15 07:50:18 +00:00
Martin Pool
f5e4eadb74 --no-blocking-io might be broken in the same way as --no-whole-file;
somebody needs to check.
2002-04-15 05:05:57 +00:00
Martin Pool
717eb9b883 Note about testing "refuse options" 2002-04-13 12:17:47 +00:00
Martin Pool
5ba268efa8 *** empty log message *** 2002-04-13 03:52:48 +00:00
Martin Pool
25ff30e804 Notes on testing, release, and todo items from the Debian paper. 2002-04-12 05:05:44 +00:00
Martin Pool
bdae761ee1 reformat 2002-04-12 04:22:52 +00:00
Martin Pool
5af50297be Note about manual revision. 2002-04-11 02:35:25 +00:00
Martin Pool
32f761755e Try to fix ctype issues by always calling these functions as
if (!isdigit(* (unsigned char *) p)) {

so that the argument is always in the range of unsigned char when
coerced to an int.

(See digit 1.)
2002-04-11 02:25:53 +00:00
Martin Pool
c4fea82ff9 Doc. 2002-04-11 02:21:41 +00:00
Martin Pool
6ded1170ac Doxygen 2002-04-11 02:18:51 +00:00
Martin Pool
991f90f296 Receiving an @ERROR line from the server is (I think) always fatal, so
the client should exit upon receiving one and not be surprised that
the socket closes.
2002-04-11 02:16:34 +00:00
Martin Pool
c979dad54a Fix old typo. 2002-04-11 02:11:50 +00:00
Martin Pool
136ac7ecec Receiving an @ERROR line from the server is (I think) always fatal, so
the client should exit upon receiving one and not be surprised that
the socket closes.
2002-04-11 01:56:35 +00:00
Martin Pool
3e8369b6dc Correction from Nelson Beebe: argument to functions such as isspace()
must be an int, not a char.  This could cause sign-extension problems.
2002-04-09 06:32:07 +00:00
Martin Pool
a7dc44d27d Doc.
Correction from Nelson Beebe: argument to functions such as isspace()
must be an int, not a char.  This could cause sign-extension problems.
2002-04-09 06:18:13 +00:00
Martin Pool
07a874fd9b Correction from Nelson Beebe: argument to functions such as isspace()
must be an int, not a char.  This could cause sign-extension problems.
2002-04-09 06:15:13 +00:00
Martin Pool
e35080cede long int and signedness fix from Nelson Beebe 2002-04-09 06:11:06 +00:00
Martin Pool
ce8149b6fe long int fix from Nelson Beebe 2002-04-09 06:03:50 +00:00
Martin Pool
a86179f429 Fix type error. 2002-04-09 05:32:52 +00:00
Martin Pool
56cf38ac98 Add RERR_OK == 0 2002-04-09 05:29:26 +00:00
Martin Pool
b0f451eb3b Doc _exit_cleanup. 2002-04-09 05:26:46 +00:00
Martin Pool
d0829892c6 Doc start_socket_client 2002-04-09 05:23:07 +00:00
Martin Pool
fdf88d7574 Doc start_socket_client 2002-04-09 05:20:30 +00:00
Martin Pool
595f2d4d97 Notes about supplementary groups and -z. 2002-04-09 05:14:59 +00:00
Martin Pool
cae95647a4 Doc. 2002-04-09 05:07:15 +00:00
Martin Pool
a254fd9798 Doc. 2002-04-09 05:03:45 +00:00
Martin Pool
805edf9d7d A bit more support for IO phase names. 2002-04-09 05:00:03 +00:00
Martin Pool
eca2adb4b3 OK, we can now get phase messages if we fail in send_file_entry 2002-04-09 04:50:25 +00:00
Martin Pool
4eea7793ea Doc
Try symlinks with an empty target
2002-04-09 04:49:42 +00:00
Martin Pool
67684d038d long int fix from Nelson Beebe 2002-04-09 04:49:23 +00:00
Martin Pool
98b332edea Fix typo.
Show io phase name in error message.
2002-04-09 04:41:03 +00:00
Martin Pool
e681e82066 Rather than a loop subtracting 1e6 to convert usecs to secs/usecs, just
use div/mod.
2002-04-09 04:33:32 +00:00
Martin Pool
08571358b1 Factor out bwlimit sleep code from writefd_unbuffered into its own function. 2002-04-09 04:29:46 +00:00
Martin Pool
8901a07fdb Clarify "error writing %d bytes" message. 2002-04-09 04:23:18 +00:00
Martin Pool
880da0072e Clean up docs. 2002-04-09 04:20:36 +00:00
Martin Pool
a83600cc82 Change error message "partial transfer" to "some files could not be
transferred".

I don't generally like changing that sort of thing, but I think this
one was a persistent source of confusion.
2002-04-08 09:10:50 +00:00
Martin Pool
dd0628f85f Note code cleanups 2002-04-08 09:09:03 +00:00
Martin Pool
e66dfd1879 Doc and indent only. 2002-04-08 09:05:26 +00:00
Martin Pool
bf2daeaf2d Remove redundant list of options. It might be nice to summarise the
most frequently-used ones in here.

Nelson Beebe pointed out that the information about bug tracking was
out of date.
2002-04-08 08:58:26 +00:00
Martin Pool
bd0ad74f4b Notes on MD4 performance. This quite unnecessarily takes up 90% of
CPU on a local transfer, without achieving anything useful.
2002-04-08 08:39:03 +00:00
Martin Pool
79f671cc7c Doc 2002-04-08 08:35:30 +00:00
Martin Pool
0f9c48b1d2 Doc file 2002-04-08 08:34:03 +00:00
Martin Pool
538ba24fd7 Doc match_sums. 2002-04-08 08:33:13 +00:00
Martin Pool
d37d8d7b69 Doc sum_update 2002-04-08 08:29:04 +00:00
Martin Pool
f4a0483ab8 Add manual prototype for maintainer-mode function 2002-04-08 08:24:59 +00:00
Martin Pool
f5f95a38c4 Document the perversely-named matched() function, which is called even
if we have not matched!
2002-04-08 08:23:50 +00:00
Martin Pool
3e7053ac59 With -vv, show state of --whole-file once at the start of the transfer. 2002-04-08 08:06:18 +00:00
Martin Pool
420ef2c419 Doc. 2002-04-08 08:02:08 +00:00
Martin Pool
9fb3f7a9ab Doc rsync_panic_handler() 2002-04-08 07:46:34 +00:00
Martin Pool
734a94a20c Clean up prototype.
Drop unused variables.
2002-04-08 07:42:54 +00:00
Martin Pool
b44be3e944 Fix prototype. 2002-04-08 07:39:56 +00:00
Martin Pool
fc0302cf07 Show panic_action in --version. 2002-04-08 07:36:05 +00:00
Martin Pool
4fdc39dde8 Allow panic_action to be configured through environment variable RSYNC_PANIC_ACTION. 2002-04-08 07:34:17 +00:00
Martin Pool
9a933bc2ce t_unsafe needs asnprintf on some platforms. 2002-04-08 06:23:34 +00:00
Martin Pool
524dc9afd6 correct behaviour is unclear 2002-04-08 06:18:03 +00:00
Martin Pool
e4d709cbf8 Cleanup 2002-04-08 06:01:26 +00:00
Martin Pool
48c1586cd1 handle yodl and vpath 2002-04-08 05:38:51 +00:00
Martin Pool
7bd0cf5b8f Clarify meaning of unsafe symlinks 2002-04-08 05:30:28 +00:00
Martin Pool
fcb69e5cdc Fix copyright. 2002-04-08 05:28:31 +00:00
Martin Pool
96557d23a3 Add more test cases.
Turn off -x.
2002-04-08 05:22:50 +00:00
Martin Pool
4e5db0ad4a Doc. 2002-04-08 05:21:51 +00:00
Martin Pool
c81a32f071 Add more test cases. 2002-04-08 05:19:41 +00:00
Martin Pool
6f2623fd69 Formatting cleanup. 2002-04-08 04:59:34 +00:00
Martin Pool
b4235b3165 Doc. 2002-04-08 04:48:51 +00:00
Martin Pool
d25c0e42c7 A test suite that calls unsafe_symlink() directly to see how it
handles different strings.
2002-04-08 04:47:01 +00:00
Martin Pool
0ecfbf27c3 Split code out into separate files and remove some global variables to
reduce symbol dependencies between files and therefore make it easier
to write unit tests.  The diff is large, but the actual code changes
are pretty small.
2002-04-08 04:16:46 +00:00
Martin Pool
fb4c98c2c8 Test harness for unsafe_symlink: just passes in argv[]. 2002-04-08 04:13:43 +00:00
Martin Pool
cd8e38b13f Little stub module that replaces functions such as rprintf called from
many places with a redirector to stderr.  If you just want to test a
particular routine you can link to this rather than the whole framework.
2002-04-08 04:12:31 +00:00
Martin Pool
b35d0d8e9a Split code out into separate files and remove some global variables to
reduce symbol dependencies between files and therefore make it easier
to write unit tests.  The diff is large, but the actual code changes
are pretty small.
2002-04-08 04:10:20 +00:00
Martin Pool
c948e309f2 Don't generate code for zlib and popt. 2002-04-08 04:00:24 +00:00
Martin Pool
d1f83bcc81 Doc. 2002-04-08 03:43:54 +00:00
Martin Pool
e0fde757fd Doc. 2002-04-08 03:38:36 +00:00
Martin Pool
25d34a5c80 Rearrange code slightly to avoid util.c depending on main.c. 2002-04-08 03:37:19 +00:00
Martin Pool
610364e3a6 Tune doxygen output, remove warning. 2002-04-08 03:13:11 +00:00
Martin Pool
036e70b024 Document unsafe_symlink(). 2002-04-08 03:10:01 +00:00
Martin Pool
ac13ad106a Clean up comments for Doxygen. 2002-04-08 03:03:04 +00:00
Martin Pool
bd9e9eccbd Doc. 2002-04-08 02:41:23 +00:00
Martin Pool
8ff9d697c9 Note on debugging daemon 2002-04-08 02:39:00 +00:00
Martin Pool
62b68c8046 Notes about logging. 2002-04-08 01:59:21 +00:00
Martin Pool
e4724e5c1c Note about two small bugs. 2002-04-05 07:25:06 +00:00
Martin Pool
559e727bf7 Test more permutations. 2002-04-05 07:13:01 +00:00
Martin Pool
126642b633 Fix filenames. 2002-04-05 07:04:23 +00:00
Martin Pool
cca4e06786 Get rid of testlink after use. 2002-04-05 07:00:53 +00:00
Martin Pool
2f1faea89b Test case for --copy-unsafe-links, contributed by Vladimír Michl,
converted to the test suite.  Thankyou!

It fails at the moment; I don't know if that's a test bug or an rsync bug.
2002-04-05 06:57:47 +00:00
Martin Pool
3d90ec146f Doc 2002-04-05 06:17:50 +00:00
Martin Pool
1bc209b441 Fix completely braindead previous patch. Thanks Jos. 2002-04-03 06:55:24 +00:00
Martin Pool
1433e6da69 Patch from Zoong Pham and Albert Chin to improve detection of
getaddrinfo on Tru64.

Also configure.in test for mkfifo and sys/un.h, although we don't
actually use that yet.
2002-04-03 06:03:27 +00:00
Martin Pool
f8f4c862e8 Change code that writes s_count to a batch file to squish it into an
int first -- a stopgap for compilers that reasonably complain about a
ternary that returns either a size_t or an int.

Really we should not write an int, but rather a larger type.  Somebody
more familiar with the batch code should look at it.
2002-04-03 05:55:54 +00:00
Martin Pool
226df8e717 Support Doxygen pretty-printer 2002-04-03 04:29:19 +00:00
Martin Pool
6c92af2067 Commit patch based on one from John L. Allen to fix "forward name
lookup failed" on AIX 4.3.3.

When doing an name->addr lookup on the client address, there's no
point including the service name, because it can't be spoofed and it
apparently causes trouble when not present in /etc/services.
2002-04-03 02:33:42 +00:00
Martin Pool
54c7298ce4 Roll over version and news. 2002-04-03 02:13:42 +00:00
Martin Pool
642a979a27 Note about --dry-run. 2002-04-03 00:10:11 +00:00
Martin Pool
e733c93423 Remove warning about "run autoconf". It tends to break too much with
CVS.
2002-04-02 02:00:29 +00:00
Martin Pool
ffdb58a51a Bump to 2.5.5. 2002-04-02 01:41:58 +00:00
Martin Pool
c053133207 If configured with --enable-maintainer-mode, then on receipt of a
fatal signal rsync will try to open an xterm running gdb, similarly to
Samba's "panic action" or GNOME's bug-buddy.
2002-03-27 05:10:44 +00:00
Martin Pool
9098bbf3b3 Improved network error handling. (Greg A. Woods) 2002-03-27 01:03:13 +00:00
Martin Pool
68618b8810 Shell scripts should explicitly "exit 0" for portability. Thanks Jos. 2002-03-26 10:36:45 +00:00
Martin Pool
e553d27f41 Fix suggested by Jos for hands.test. Some of the functionality
previously built into Phil's test was clashing with the runtests.sh
framework.  I think one of the core problems might be that scripts
which don't explicitly "exit 0" have return codes which vary depending
on the particular shell.  (c.f. the autoconf portability guide.)

This might break the Debian test suite but I'm afraid I don't know
enough about how it works yet.  Hopefully eventually it can become
just a wrapper around our 'make check'.
2002-03-26 10:28:57 +00:00
Martin Pool
d092924c63 Updated spec file from Jason Haar. Seems to mostly just change the
path for manuals, and bumps the version.
2002-03-26 05:15:09 +00:00
Martin Pool
34027489e0 Ignore autoconf cache. (??) 2002-03-26 01:27:24 +00:00
Martin Pool
d1239eae92 Jos points out that test -L is still broken on Solaris. Now we try up
front to detect a command that will work properly, and use that
consistently.

Also, in test report, show setting of $preserve_scratch.

Reset version.
2002-03-26 01:25:47 +00:00
Martin Pool
331050969b Bump version to 2.5.5rc1. 2002-03-25 23:22:08 +00:00
Martin Pool
259c3e72b0 Add note about possible hardlink bug. 2002-03-25 23:09:31 +00:00
Martin Pool
8f7a38336d Make the situation w.r.t. dynamically linking zlib and libpopt clear. 2002-03-25 09:42:36 +00:00
Martin Pool
999dfffc9b Add link to Apple bug. 2002-03-25 07:29:43 +00:00
Martin Pool
527a51cec5 Doc 2002-03-25 07:07:03 +00:00
Martin Pool
20c15aead5 Hm, strange off-by-one bug. 2002-03-25 06:59:17 +00:00
Martin Pool
fb859e5674 Apparently the OS X port of gcc gags on __attribute__. 2002-03-25 06:49:08 +00:00
Martin Pool
4f2dcb1714 If we discover a hardlink with -vv say what it's a link to. 2002-03-25 06:27:44 +00:00
Martin Pool
64e74631e0 Fix from Jos for batch mode on Solaris. 2002-03-25 06:06:29 +00:00
Martin Pool
fba31efb74 Disambiguate hard link messages. 2002-03-25 05:54:31 +00:00
Martin Pool
435f1ed70d Apparently SGI make doesn't like $< in non-implicit rules. 2002-03-25 04:36:56 +00:00
Martin Pool
94f34ca10a Doc. 2002-03-25 04:04:23 +00:00
Martin Pool
b0633744fa Note about mkdir bug. 2002-03-25 03:56:38 +00:00
Martin Pool
c127e8aaec Add a test case for trim_trailing_slashes, and make it handle other cases. 2002-03-25 03:51:17 +00:00
Martin Pool
bf4e725d5d Code that was meant to trim trailing slashes from mkdir() paths
actually did not; fix it.
2002-03-25 03:29:47 +00:00
Martin Pool
663717f465 Need to also delete getgroups when cleaning. 2002-03-25 03:26:28 +00:00
Martin Pool
12b159ac41 Define NGROUPS if not already done. 2002-03-25 03:18:36 +00:00
Martin Pool
9299c8f0b4 Clean testtmp*, because we now put tests in their own directories.
Add "make cleantests"
2002-03-25 03:16:35 +00:00
Martin Pool
dfef3f1099 Change chgrp.test to use our getgroups rather than the system's. 2002-03-25 03:01:37 +00:00
Martin Pool
fa3690f488 Initial revision. 2002-03-25 02:58:59 +00:00
Martin Pool
4acbfa2ade Add our own little tool to call getgroups(2) because it's too hard to
find a portable shell command that does it.
2002-03-25 02:55:52 +00:00
Martin Pool
ef86d74736 Clean up text. 2002-03-22 22:36:22 +00:00
Martin Pool
118f39d45b Clean up text. 2002-03-22 22:33:49 +00:00
Martin Pool
77867907ed Doc permissions while testing. 2002-03-22 06:22:53 +00:00
Martin Pool
98c1b32565 Rather than literally "nobody", try using uid/gid = 65534 as
"nobody".  The existing code kind-of assumes this.
2002-03-22 06:12:51 +00:00
Martin Pool
7a176e87d5 Better messages. 2002-03-22 06:09:09 +00:00
Martin Pool
79c9d8a180 Proper messages for skipped tests. 2002-03-22 06:07:50 +00:00
Martin Pool
7d8219327b If tests are skipped, explain why. 2002-03-22 06:03:46 +00:00
Martin Pool
4ac4bdbb38 More sgml cleanups. 2002-03-22 06:02:28 +00:00
Martin Pool
f494f2864c Doc about checkit. 2002-03-22 05:59:12 +00:00
Martin Pool
017f22b47f Add /usr/xpg4/bin/ to PATH to help solaris. 2002-03-22 05:52:09 +00:00
Martin Pool
dec41b556b Cope on systems without the whoami command. 2002-03-22 05:20:47 +00:00
Martin Pool
be2961da2c If there's an error in start_socket_client, print an explanation as
well as failing.

Doc.

Trying to work out why daemon-gzip-download.test fails on SCO with

  rsync error: unexplained error (code 190) at main.c(886)
2002-03-22 05:19:19 +00:00
Martin Pool
914cc65c9d Doc. 2002-03-22 05:14:44 +00:00
Martin Pool
6479c2ed3f Notes on logging etc 2002-03-22 05:11:39 +00:00
Martin Pool
c1a04ecbfd Doc. 2002-03-22 05:08:53 +00:00
Martin Pool
69b06c50c4 Use id -G rather than groups to get a list of groups for this
user, so that we can cope on systems like Cygwin that tend to have
group names containing spaces.
2002-03-22 05:06:36 +00:00
Martin Pool
6aaf8d8c10 * Make "make install-strip" works properly, and "make install"
accepts a DESTDIR variable for help in building binary packages.
      (Peter Breitenlohner)
2002-03-20 05:53:40 +00:00
Martin Pool
4cf64834ed Patch from Paul Haas:
* Fix situation where failure to fork (e.g. because out of process
      slots) would cause rsync to kill all processes owned by the
      current user.  Yes, really!  (Paul Haas, Martin Pool)

Also, add a little more documentation and paranoia to make sure we
never call kill(2) with a negative pid.
2002-03-20 01:09:49 +00:00
David Dykstra
b8709f5046 Now that whole_file and no_whole_file are separate variables, have the
--whole-file and --no-whole-file options set/reset both variables so if
more than one option is specified the last one will be the one honored.
2002-03-19 20:16:42 +00:00
Martin Pool
24448f741f Clean up sgml.
Add note about building with gcc.
2002-03-19 05:52:34 +00:00
Martin Pool
76533c52dc todo: Versions of read() and write() that corrupt the stream, or abruptly fail 2002-03-19 05:23:04 +00:00
Martin Pool
3ff984d7a7 Fix --help layout. 2002-03-19 05:09:19 +00:00
Martin Pool
7a52790b50 Fix overly long line in version. 2002-03-19 05:01:36 +00:00
Martin Pool
7b329a2d79 Follow advice from GPL to insert a disclaimer of warranty in the
version and help information.
2002-03-19 05:00:05 +00:00
Martin Pool
599dc93c64 Doc: Pipe program that makes slow/jerky connections. 2002-03-19 04:14:30 +00:00
Martin Pool
8b54f00466 Include all fields in the options table to quieten gcc warnings about
missing initializers.
2002-03-19 04:10:07 +00:00
Martin Pool
8469faef03 Intentional test of assert :_) 2002-03-19 03:59:51 +00:00
Martin Pool
bceec82f35 Previous solution for --no-whole-file would probably break when
connecting to old servers that don't have --no-whole-file.

Instead, we handle no_whole_file and whole_file separately, without
the magic -1 value.  We don't modify no_whole_file after
initialization.
2002-03-19 03:39:42 +00:00
Martin Pool
ed521de525 Sending --no-whole-file is no good because it will not work with old
versions of rsync.
2002-03-19 03:27:33 +00:00
Martin Pool
d157de203a Typo. 2002-03-19 03:23:08 +00:00
Martin Pool
1bfbf40bd5 Fix --whole-file problem that caused it to be the default even for
remote connections.  (Frank Schulz)

<http://lists.samba.org/pipermail/rsync/2002-March/006526.html>

Also, add documentation for whole_file and add assertions that the
value is valid.
2002-03-19 03:21:53 +00:00
Martin Pool
6d19c6742c Need a test for "refuse options" 2002-03-16 09:26:33 +00:00
Martin Pool
a628b06977 Note about 100295@bugs.debian.org 2002-03-16 09:11:56 +00:00
Martin Pool
6b2d24de2c Make sure that freeaddrinfo is called on all code paths leading away
from a call to getaddrinfo.  (Dave Dykstra)
<20011219085021.A23107@lucent.com>
2002-03-16 09:00:44 +00:00
Martin Pool
e23d790fa7 Doc: Note from Dave Dykstra that getaddrinfo calls must be paired with
freeaddrinfo().
2002-03-16 08:23:08 +00:00
Martin Pool
2a5904a580 Add more rules for make distclean. 2002-03-16 08:21:15 +00:00
Martin Pool
4610ac79c2 "make distclean": We try to delete built files from both the source
and build directories, just in case somebody previously configured
things in the source directory.
2002-03-16 08:18:19 +00:00
Martin Pool
142f5be922 Note about --progress patch. 2002-03-16 00:00:43 +00:00
Martin Pool
b17dd0c435 Note about debian #28416 2002-03-15 14:01:43 +00:00
Martin Pool
3669201179 Add debian bug # 2002-03-15 13:42:42 +00:00
Martin Pool
a5c48193c7 Keep stderr and stdout properly separated (Debian #23626) 2002-03-15 13:38:12 +00:00
Martin Pool
4366275bab Doc: Debian uses "nogroup" instead of group "nobody", so our defaults
are not so good.
2002-03-15 12:53:21 +00:00
Martin Pool
c579310a00 If we've finished transferring a file, show the time taken; otherwise
show expected time to complete.  That's kind of inconsistent, but
people can probably cope.  Hopefully we'll get more consistent and
complete progress reporting soon. (Cameron Simpson)
2002-03-15 12:45:10 +00:00
Martin Pool
96553aa7ef Typo. 2002-03-15 06:29:22 +00:00
Martin Pool
2094283b80 On Solaris, put /usr/ucb/bin at the end of the path to help find
utilities we might need.  (Like 'whoami' in this case.)
2002-03-15 06:28:58 +00:00
Martin Pool
4c631ac621 Try to handle 'test -L' on Sun. 2002-03-15 01:22:09 +00:00
Martin Pool
d96d3893dd Try to handle 'test -L' on Sun. 2002-03-15 01:08:53 +00:00
Martin Pool
b73b51a9e4 More notes 2002-03-15 01:04:25 +00:00
Martin Pool
3c1edccb7b Suggestion from david.e.sewell to add --diff. 2002-03-15 01:03:24 +00:00
David Dykstra
b23c290630 Eliminate extraneous "done" messages in verbose mode. Problem reported by
Lee Eakin.
2002-03-14 21:20:20 +00:00
Martin Pool
c7b562becf Correct the plural in "1 file to consider." (Greg Louis) 2002-03-14 12:00:12 +00:00
Martin Pool
5648a81936 Add phony target to run Splint. 2002-03-14 10:42:52 +00:00
Martin Pool
daa3d0e2da "make install-strip" works. (Greg Louis) 2002-03-14 10:38:55 +00:00
Martin Pool
c9a66d41fe Roll over news file; put in page markers. 2002-03-14 10:33:59 +00:00
Martin Pool
0ee1bd82c5 Bump version to 2.5.5cvs 2002-03-14 03:10:23 +00:00
Martin Pool
53e1f937bc Show user name and uname -a in the test output header, to aid in bug
reports.  (We mostly want to know if they're root or not.)
2002-03-14 03:04:36 +00:00
Martin Pool
604f343c49 Doc: "opening tcp connection to %s port %d" is kind of misleading when
running the test case.
2002-03-14 02:55:11 +00:00
Martin Pool
e9c4c3018b More notes on testing. 2002-03-13 04:25:10 +00:00
Martin Pool
db1babe6a9 If a child of the rsync daemon dies with a signal, we should notice
that when we reap it and log a message.
2002-03-13 00:25:00 +00:00
124 changed files with 16221 additions and 9385 deletions

View File

@@ -1,9 +1,15 @@
ID
Makefile
autom4te*.cache
confdefs.h
config.cache
config.h
config.log
config.status
conftest.c
conftest.log
dox
getgroups
gmon.out
rsync
shconfig
@@ -12,7 +18,7 @@ tests-dont-exist
testtmp
testtmp.*
tls
zlib/dummy
confdefs.h
conftest.c
conftest.log
trimslash
t_unsafe
wildtest
getfsdev

187
Doxyfile Normal file
View File

@@ -0,0 +1,187 @@
# Doxyfile 1.2.15
#---------------------------------------------------------------------------
# General configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = rsync
PROJECT_NUMBER = HEAD
OUTPUT_DIRECTORY = dox
OUTPUT_LANGUAGE = English
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = YES
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH = *source
INTERNAL_DOCS = YES
STRIP_CODE_COMMENTS = NO
CASE_SENSE_NAMES = YES
SHORT_NAMES = NO
HIDE_SCOPE_NAMES = YES
VERBATIM_HEADERS = YES
SHOW_INCLUDE_FILES = YES
JAVADOC_AUTOBRIEF = YES
INHERIT_DOCS = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = NO
DISTRIBUTE_GROUP_DOC = NO
TAB_SIZE = 8
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
ALIASES =
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
SHOW_USED_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = NO
WARN_IF_UNDOCUMENTED = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = .
FILE_PATTERNS = *.c \
*.h
RECURSIVE = YES
EXCLUDE = proto.h \
zlib \
popt
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = YES
INLINE_SOURCES = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 3
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 3
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
LATEX_BATCHMODE = YES
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = NO
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HAVE_DOT = YES
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
TEMPLATE_RELATIONS = YES
HIDE_UNDOC_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
GRAPHICAL_HIERARCHY = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::addtions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO
CGI_NAME = search.cgi
CGI_URL =
DOC_URL =
DOC_ABSPATH =
BIN_ABSPATH = /usr/local/bin/
EXT_DOC_PATHS =

20
INSTALL
View File

@@ -11,11 +11,21 @@ to ./configure. To see them, use:
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,
and will be used it there is no popt library on your build host, or if
and will be used if there is no popt library on your build host, or if
the --with-included-popt option is passed to ./configure.
If you configure using --enable-maintainer-mode, then rsync will try
to pop up an xterm on DISPLAY=:0 if it crashes. You might find this
useful, but it should be turned off for production builds.
RPM NOTES
---------
Under packaging you will find .spec files for several distributions.
The .spec file in packaging/lsb can be used for Linux systems that
adhere to the Linux Standards Base (e.g., RedHat and others).
HP-UX NOTES
-----------
@@ -38,5 +48,11 @@ 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.
IBM AIX NOTES
-------------
IBM AIX has a largefile problem with mkstemp. See IBM PR-51921.
The workaround is to append the below to config.h
#ifdef _LARGE_FILES
#undef HAVE_SECURE_MKSTEMP
#endif

View File

@@ -9,9 +9,12 @@ mandir=@mandir@
LIBS=@LIBS@
CC=@CC@
CFLAGS=@CFLAGS@
CPPFLAGS=@CPPFLAGS@
EXEEXT=@EXEEXT@
LDFLAGS=@LDFLAGS@
INSTALLCMD=@INSTALL@
INSTALLMAN=@INSTALL@
srcdir=@srcdir@
VPATH=$(srcdir)
@@ -22,78 +25,113 @@ VERSION=@VERSION@
.SUFFIXES:
.SUFFIXES: .c .o
LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
lib/permstring.o \
@LIBOBJS@
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
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
zlib/zutil.o zlib/adler32.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
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 \
popt/popthelp.o popt/poptparse.o
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
TLS_OBJ = tls.o syscall.o lib/permstring.o
TLS_OBJ = tls.o syscall.o lib/permstring.o
# Programs we must have to run the test cases
CHECK_PROGS = rsync tls
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
# Objects for CHECK_PROGS to clean
CHECK_OBJS=getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
# note that the -I. is needed to handle config.h when using VPATH
.c.o:
@OBJ_SAVE@
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< @CC_SHOBJ_FLAG@
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
@OBJ_RESTORE@
all: rsync
man: rsync.1 rsyncd.conf.5
all: rsync$(EXEEXT)
install: all
-mkdir -p ${bindir}
${INSTALLCMD} -m 755 rsync ${bindir}
-mkdir -p ${mandir}/man1
-mkdir -p ${mandir}/man5
${INSTALLCMD} -m 644 $(srcdir)/rsync.1 ${mandir}/man1
${INSTALLCMD} -m 644 $(srcdir)/rsyncd.conf.5 ${mandir}/man5
-mkdir -p ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
-mkdir -p ${DESTDIR}${mandir}/man1
-mkdir -p ${DESTDIR}${mandir}/man5
${INSTALLMAN} -m 644 $(srcdir)/rsync.1 ${DESTDIR}${mandir}/man1
${INSTALLMAN} -m 644 $(srcdir)/rsyncd.conf.5 ${DESTDIR}${mandir}/man5
install-strip:
$(MAKE) INSTALLCMD='$(INSTALLCMD) -s' install
$(MAKE) INSTALL_STRIP='-s' install
rsync: $(OBJS)
@echo "Please ignore warnings below about mktemp -- it is used in a safe way"
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
rsync$(EXEEXT): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(OBJS): config.h
$(OBJS): $(HEADERS)
tls: $(TLS_OBJ)
tls$(EXEEXT): $(TLS_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
Makefile: Makefile.in configure config.status
echo "WARNING: You need to run ./config.status --recheck"
getgroups$(EXEEXT): getgroups.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getgroups.o $(LIBS)
# don't actually run autoconf, just issue a warning
configure: configure.in
echo "WARNING: you need to rerun autoconf"
getfsdev$(EXEEXT): getfsdev.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getfsdev.o $(LIBS)
rsync.1: rsync.yo
yodl2man -o rsync.1 rsync.yo
TRIMSLASH_OBJ = trimslash.o syscall.o
trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
rsyncd.conf.5: rsyncd.conf.yo
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
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
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
proto:
cat $(srcdir)/*.c $(srcdir)/lib/compat.c | awk -f $(srcdir)/mkproto.awk > $(srcdir)/proto.h
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
clean:
rm -f *~ $(OBJS) rsync $(TLS_OBJ) tls
rm -rf ./testtmp
rm -f config.cache
clean: cleantests
rm -f *~ $(OBJS) $(TLS_OBJ) $(CHECK_PROGS) $(CHECK_OBJS)
cleantests:
rm -rf ./testtmp*
# We try to delete built files from both the source and build
# directories, just in case somebody previously configured things in
# the source directory.
distclean: clean
rm -f Makefile config.h config.status
rm -f $(srcdir)/Makefile $(srcdir)/config.h $(srcdir)/config.status
rm -f config.cache config.log
rm -f $(srcdir)/config.cache $(srcdir)/config.log
rm -f shconfig $(srcdir)/shconfig
# this target is really just for my use. It only works on a limited
# range of machines and is used to produce a list of potentially
@@ -101,7 +139,7 @@ distclean: clean
finddead:
nm *.o */*.o |grep 'U ' | awk '{print $$2}' | sort -u > nmused.txt
nm *.o */*.o |grep 'T ' | awk '{print $$3}' | sort -u > nmfns.txt
comm -13 nmused.txt nmfns.txt
comm -13 nmused.txt nmfns.txt
# 'check' is the GNU name, 'test' is the name for everybody else :-)
.PHONY: check test
@@ -112,9 +150,6 @@ test: check
# There seems to be no standard way to specify some variables as
# exported from a Makefile apart from listing them like this.
# TODO: Tests that depend on built test aide programs like tls need to
# know where the build directory is.
# This depends on building rsync; if we need any helper programs it
# should depend on them too.
@@ -123,22 +158,41 @@ test: check
# might lose in the future where POSIX diverges from old sh.
check: all $(CHECK_PROGS)
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin=`pwd`/rsync srcdir="$(srcdir)" $(srcdir)/runtests.sh
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)
# 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,
# if you want.
installcheck: $(CHECK_PROGS)
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin="$(bindir)/rsync" srcdir="$(srcdir)" $(srcdir)/runtests.sh
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin="$(bindir)/rsync$(EXEEXT)" srcdir="$(srcdir)" $(srcdir)/runtests.sh
# TODO: Add 'dist' target; need to know which files will be included
# Run the SPLINT (Secure Programming Lint) tool. <www.splint.org>
.PHONY: splint
splint:
splint +unixlib +gnuextensions -weak rsync.c
rsync.dvi: doc/rsync.texinfo
texi2dvi -o $@ $<
rsync.ps: rsync.dvi
rsync.ps: rsync.dvi
dvips -ta4 -o $@ $<
rsync.pdf: doc/rsync.texinfo
texi2dvi -o $@ --pdf $<
doxygen:
cd $(srcdir) && rm dox/html/* && doxygen
# for maintainers only
doxygen-upload:
rsync -avzv $(srcdir)/dox/html/ --delete \
samba.org:/home/httpd/html/rsync/doxygen/head/

243
NEWS
View File

@@ -1,16 +1,241 @@
rsync 2.5.4 (13 March 2002)
NEWS for rsync 2.6.3 (UNRELEASED)
Protocol: 28 (unchanged)
Changes since 2.6.2:
"Imitation lizard skin"
SECURITY FIXES:
- A bug in the sanitize_path routine (which affects a non-chrooted
rsync daemon) could allow a user to craft a pathname that would get
transformed into an absolute path for certain options (but not for
file-transfer names). If you're running an rsync daemon with chroot
disabled, *please upgrade*, ESPECIALLY if the user privs you run
rsync under is anything above "nobody".
OUTPUT CHANGES (ATTN: those using a script to parse the verbose output):
- Please note that the 2-line footer (output when verbose) now uses the
term "sent" instead of "wrote" and "received" instead of "read". If
you are not parsing the numeric values out of this footer, a script
would be better off using the empty line prior to the footer as the
indicator that the verbose output is over.
- The output from the --stats option was similarly affected to change
"written" to "sent" and "read" to "received".
- Rsync ensures that a filename that contains a newline gets mentioned
with each newline transformed into a question mark (which prevents a
filename from causing an empty line to be output).
BUG FIXES:
* Additional fix for zlib double-free bug. (Martin Pool, Andrew
Tridgell) (CVE CAN-2002-0059)
- Fixed a crash bug that might appear when --delete was used and
multiple source directories were specified.
- Fixed the 32-bit truncation of the file length when generating the
checksums.
- The --backup code no longer attempts to create some directories
over and over again (generating warnings along the way).
- Fixed a bug in the reading of the secrets file (by the daemon) and
the password file (by the client): the files no longer need to be
terminated by a newline for their content to be read in.
- If a file has a read error on the sending side or the reconstructed
data doesn't match the expected checksum (perhaps due to the basis
file changing during the transfer), the receiver will no longer
retain the resulting file unless the --partial option was specified.
(Note: for the read-error detection to work, neither side can be
older than 2.6.3 -- older receivers will always retain the file, and
older senders don't tell the receiver that the file had a read
error.)
- If a file gets resent in a single transfer and the --backup option
is enabled, rsync no longer performs a duplicate backup (it used to
overwrite the original file in the backup area).
- Files specified in the daemon's "exclude" or "exclude from" config
items are now excluded from being uploaded (assuming that the module
allows uploading at all) in addition to the old download exclusion.
- Got rid of a potential hang in the receiver when near the end of a
phase.
- When using --backup without a --backup-dir, rsync no longer preserves
the modify time on directories. This avoids confusing NFS.
- When --copy-links (-L) is specified, we now output a separate error
for a symlink that has no referent instead of claiming that a file
"vanished".
- The --copy-links (-L) option no longer has the side-effect of telling
the receiving side to follow symlinks. See the --keep-dirlinks
option (mentioned below) for a way to specify that behavior.
- Error messages from the daemon server's option-parsing (such as
refused options) now get sent back to the client (the server used
to just exit because the socket wasn't in the right state to send
the message).
- Most errors that occur during a daemon transfer are now returned to
the user in addition to being logged (some messages are intended to
be daemon-only).
- Fixed a bug in the daemon authentication code when using one of the
batch-processing options.
- We try to work around some buggy IPv6 implementations that fail to
implement IPV6_V6ONLY. This should fix the "address in use" error
that some daemons get when running on an OS with a buggy IPv6
implementation. Also, if the new code gets this error, we might
suggest that the user specify --ipv4 or --ipv6 (if we think it will
help).
- When the remote rsync dies, make a better effort to recover any error
messages it may have sent before dying (the local rsync used to just
die with a socket-write error).
- When using --delete and a --backup-dir that contains files that are
hard-linked to their destination equivalents, rsync now makes sure
that removed files really get removed (works around a really weird
rename() behavior).
- Avoid a bogus run-time complaint about a lack of 64-bit integers when
the int64 type is defined as an off_t and it actually has 64-bits.
- Added a configure check for open64() without mkstemp64() so that we
can avoid using mkstemp() when such a combination is encountered.
This bypasses a problem writing out large temp files on OSes such as
AIX and HP-UX.
- Fixed an age-old crash problem with --read-batch on a local copy
(rsync was improperly assuming --whole-file for the local copy).
- When --dry-run (-n) is used and the destination directory does not
exist, rsync now produces a correct report of files that would be
sent instead of dying with a chdir() error.
- The "backed up ..." message that is output when at least 2 --verbose
options are specified is now the same both with and without the
--backup-dir option.
- Fixed a bug that could cause a slow-to-connect rsync daemon to die
with an error instead of waiting for the connection to finish.
ENHANCEMENTS:
* Merge in changes from zlib 1.1.3 to zlib 1.1.4. (Jos Backus)
(Note that rsync still uses a custom version of zlib; you can
not just link against a system library. See zlib/README.rsync)
- Added the --partial-dir=DIR option that lets you specify where to
(temporarily) put a partially transferred file (instead of over-
writing the destination file). E.g. --partial-dir=.rsync-partial
Also added support for the RSYNC_PARTIAL_DIR environment variable
that, when found, transforms a regular --partial option (such as
the convenient -P option) into one that also specifies a directory.
- Added --keep-dirlinks (-K), which allows you to symlink a directory
onto another partition on the receiving side and have rsync treat it
as matching a normal directory from the sender.
- Added the --inplace option that tells rsync to write each destination
file without using a temporary file. The matching of existing data
in the destination file can be severely limited by this, but there
are also cases where this is more efficient (such as appending data).
Use only when needed (see the man page for more details).
- Added the "write only" option for the daemon's config file.
- Added long-option names for -4 and -6 (namely --ipv4 and --ipv6)
and documented all these options in the man page.
- Improved the handling of the --bwlimit option so that it's less
bursty, more accurate, and works properly over a larger range of
values.
- The rsync daemon-over-ssh code now looks for SSH_CONNECTION and
SSH2_CLIENT in addition to SSH_CLIENT to figure out the IP address.
- Added the --checksum-seed=N option for advanced users.
- Batch writing/reading has a brand-new implementation that is simpler,
fixes a few weird problems with the old code (such as no longer
sprinkling the batch files into different dirs or even onto different
systems), and is much less intrusive into the code (making it easier
to maintain for the future). The new code generates just one data
file instead of three, which makes it possible to read the batch on
stdin via a remote shell. Also, the old requirement of forcing the
same fixed checksum-seed for all batch processing has been removed.
- If an rsync daemon has a module set with "list = no" (which hides its
presence in the list of available modules), a user that fails to
authenticate gets the same "unknown module" error that they would get
if the module were actually unknown (while still logging the real
error to the daemon's log file). This prevents fishing for module
names.
- The daemon's "refuse options" config item now allows you to match
option names using wildcards and/or the single-letter option names.
- Each transferred file now gets its permissions and modified-time
updated before the temp-file gets moved into place. Previously, the
finished file would have a very brief window where its permissions
disallowed all group and world access.
- Added the ability to parse a literal IPv6 address in an "rsync:" URL
(e.g. rsync://[2001:638:500:101::21]:873/module/dir).
INTERNAL:
- Some cleanup in the exclude code has saved some per-exclude memory
and made the code easier to maintain.
- Improved the argv-overflow checking for a remote command that has a
lot of args.
- Use rsyserr() in the various places that were still calling rprintf()
with strerror() as an arg.
- If an rsync daemon is listening on multiple sockets (to handle both
IPv4 and IPv6 to a single port), we now close all the unneeded file
handles after we accept a connection (we used to close just one of
them).
- Optimized the handling of larger block sizes (rsync used to slow to a
crawl if the block size got too large).
- Optimized away a loop in hash_search().
- Some improvements to the sanitize_path() and clean_fname() functions
makes them more efficient and produce better results (while still
being compatible with the file-name cleaning that gets done on both
sides when sending the file-list).
- Got rid of alloc_sanitize_path() after adding a destination-buffer
arg to sanitize_path() made it possible to put all the former's
functionality into the latter.
- The file-list that is output when at least 4 verbose options are
specified reports the uid value on the sender even when rsync is
not running as root (since we might be sending to a root receiver).
BUILD CHANGES:
- Added a "gen" target to rebuild most of the generated files,
including configure, config.h.in, the man pages, and proto.h.
- If "make proto" doesn't find some changes in the prototypes, the
proto.h file is left untouched (its time-stamp used to always be
updated).
- The variable $STRIP (that is optionally set by the install-strip
target's rule) was changed to $INSTALL_STRIP because some systems
have $STRIP set in the environment.
- Fixed a build problem when SUPPORT_HARD_LINKS isn't defined.
DEVELOPER RELATED:
- The scripts in the testsuite dir were cleaned up a bit and a few
new tests added.
- Some new diffs were added to the patches dir, and some accepted
ones were removed.
* Additional test cases for --compress. (Martin Pool)

634
OLDNEWS
View File

@@ -1,6 +1,548 @@
rsync 2.5.3 (11 March 2002)
NEWS for rsync 2.6.2 (30 Apr 2004)
Protocol: 28 (unchanged)
Changes since 2.6.1:
"Happy 26"
BUG FIXES:
- Fixed a major bug in the sorting of the filenames when --relative
is used for some sources (just sources such as "/" and "/*" were
affected). This fix ensures that we ask for the right file-list
item when requesting changes from the sender.
- Rsync now checks the return value of the close() function to
better report disk-full problems on an NFS file system.
- Restored the old daemon-server behavior of logging error messages
rather than returning them to the user. (A better long-term fix
will be sought in the future.)
- An obscure uninitialized-variable bug was fixed in the uid/gid
code. (This bug probably had no ill effects.)
BUILD CHANGES:
- Got rid of the configure check for sys/sysctl.h (it wasn't used
and was causing a problem on some systems). Also improved the
broken-largefile-locking test to try to avoid failure due to an
NFS build-dir.
- Fixed a compile problem on systems that don't define
AI_NUMERICHOST.
- Fixed a compile problem in the popt source for compilers that
don't support __attribute__.
DEVELOPER RELATED:
- Improved the testsuite's "merge" test to work on OSF1.
- Two new diffs were added to the patches dir.
NEWS for rsync 2.6.1 (26 Apr 2004)
Protocol: 28 (changed)
Changes since 2.6.0:
SECURITY FIXES:
- Paths sent to an rsync daemon are more thoroughly sanitized when
chroot is not used. If you're running a non-read-only rsync
daemon with chroot disabled, *please upgrade*, ESPECIALLY if the
user privs you run rsync under is anything above "nobody".
ENHANCEMENTS:
- Lower memory use, more optimal transfer of data over the socket,
and lower CPU usage (see the INTERNAL section for details).
- The RSYNC_PROXY environment variable can now contain a
"USER:PASS@" prefix before the "HOST:PORT" information.
(Bardur Arantsson)
- The --progress output now mentions how far along in the transfer
we are, including both a count of files transferred and a
percentage of the total file-count that we've processed. It also
shows better current-rate-of-transfer and remaining-transfer-time
values.
- Documentation changes now attempt to describe some often mis-
understood features more clearly.
BUG FIXES:
- When -x (--one-file-system) is combined with -L (--copy-links) or
--copy-unsafe-links, no symlinked files are skipped, even if the
referent file is on a different filesystem.
- The --link-dest code now works properly for a non-root user when
(1) the UIDs of the source and destination differ and -o was
specified, or (2) when the group of the source can't be used on
the destination and -g was specified.
- Fixed a bug in the handling of -H (hard-links) that might cause
the expanded PATH/NAME value of the current item to get
overwritten (due to an expanded-name caching bug).
- 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
over the wire for that file.
- Fixed a byte-order problem in --batch-mode on big-endian machines.
(Jay Fenlason)
- When using --cvs-exclude, the exclude items we get from a
per-directory's .cvsignore file once again only affect that one
directory (not all following directories too). The items are also
now properly word-split and parsed without any +/- prefix parsing.
- When specifying the USER@HOST: prefix for a file, the USER part
can now contain an '@', if needed (i.e. the last '@' is used to
find the HOST, not the first).
- Fixed some bugs in the handling of group IDs for non-root users:
(1) It properly handles a group that the sender didn't have a name
for (it would previously skip changing the group on any files in
that group). (2) If --numeric-ids is used, rsync no longer
attempts to set groups that the user doesn't have the permission
to set.
- Fixed the "refuse options" setting in the rsyncd.conf file.
- Improved the -x (--one-file-system) flag's handling of any mount-
point directories we encounter. It is both more optimal (in that
it no longer does a useless scan of the contents of the mount-
point dirs) and also fixes a bug where a remapped mount of the
original filesystem could get discovered in a subdir we should be
ignoring.
- Rsync no longer discards a double-slash at the start of a filename
when trying to open the file. It also no longer constructs names
that start with a double slash (unless the user supplied them).
- Path-specifying options to a daemon should now work the same with
or without chroot turned on. Previously, such a option (such as
--link-dest) would get its absolute path munged into a relative
one if chroot was not on, making that setting fairly useless.
Rsync now transforms the path into one that is based on the
module's base dir when chroot is not enabled.
- Fixed a compatibility problem interacting with older rsync
versions that might send us an empty --suffix value without
telling us that --backup-dir was specified.
- The "hosts allow" option for a daemon-over-remote-shell process
now has improved support for IPv6 addresses and a fix for systems
that have a length field in their socket structs.
- Fixed the ability to request an empty backup --suffix when sending
files to an rsync daemon.
INTERNAL:
- Most of the I/O is now buffered, which results in a pretty large
speedup when running under MS Windows. (Craig Barratt)
- Optimizations to the name-handling/comparing code have made some
significant reductions in user-CPU time for large file sets.
- Some cleanup of the variable types make the code more consistent.
- Reduced memory requirements of hard link preservation.
(J.W. Schultz)
- Implemented a new algorithm for hard-link handling that speeds up
the code significantly. (J.W. Schultz and Wayne Davison)
- The --hard-link option now uses the first existing file in the
group of linked files as the basis for the transfer. This
prevents the sub-optimal transfer of a file's data when a new
hardlink is added on the sending side and it sorts alphabetically
earlier in the list than the files that are already present on the
receiving side.
- Dropped support for protocol versions less than 20 (2.3.0 released
15 Mar 1999) and activated warnings for protocols less than 25
(2.5.0 released 23 Aug 2001). (Wayne Davison and J.W. Schultz,
severally)
- More optimal data transmission for --hard-links (protocol 28).
- More optimal data transmission for --checksum (protocol 28).
- Less memory is used when --checksum is specified.
- Less memory is used in the file list (a per-file savings).
- The generator is now better about not modifying the file list
during the transfer in order to avoid a copy-on-write memory
bifurcation (on systems where fork() uses shared memory).
Previously, rsync's shared memory would slowly become unshared,
resulting in real memory usage nearly doubling on the receiving
side by the end of the transfer. Now, as long as permissions
are being preserved, the shared memory should remain that way
for the entire transfer.
- Changed hardlink info and file_struct + strings to use allocation
pools. This reduces memory use for large file-sets and permits
freeing memory to the OS. (J.W. Schultz)
- The 2 pipes used between the receiver and generator processes
(which are forked on the same machine) were reduced to 1 pipe and
the protocol improved so that (1) it is now impossible to have the
"redo" pipe fill up and hang rsync, and (2) trailing messages from
the receiver don't get lost on their way through the generator
over to the sender (which mainly affected hard-link messages and
verbose --stats output).
- Improved the internal uid/gid code to be more portable and a
little more optimized.
- The device numbers sent when using --devices are now sent as
separate major/minor values with 32-bit accuracy (protocol 28).
Previously, the copied devices were sent as a single 32-bit
number. This will make inter-operation of 64-bit binaries more
compatible with their 32-bit brethren (with both ends of the
connection are using protocol 28). Note that optimizations in the
binary protocol for sending the device numbers often results in
fewer bytes being used than before, even though more precision is
now available.
- Some cleanup of the exclude/include structures and its code made
things clearer (internally), simpler, and more efficient.
- The reading & writing of the file-list in batch-mode is now
handled by the same code that sends & receives the list over the
wire. This makes it much easier to maintain. (Note that the
batch code is still considered to be experimental.)
BUILD CHANGES:
- The configure script now accepts --with-rsyncd-conf=PATH to
override the default value of the /etc/rsyncd.conf file.
- Fixed configure bug when running "./configure --disable-ipv6".
- Fixed compilation problem on Tru64 Unix (having to do with
sockaddr.sa_len and sockaddr.sin_len).
DEVELOPER RELATED:
- Fixed "make test" bug when build dir is not the source dir.
- Added a couple extra diffs in the "patches" dir, removed the ones
that got applied, and rebuilt the rest.
NEWS for rsync 2.6.0 (1 Jan 2004)
Protocol: 27 (changed)
Changes since 2.5.7:
ENHANCEMENTS:
* "ssh" is now the default remote shell for rsync. If you want to
change this, configure like this: "./configure --with-rsh=rsh".
* Added --files-from, --no-relative, --no-implied-dirs, and --from0.
Note that --from0 affects the line-ending character for all the
files read by the --*-from options. (Wayne Davison)
* Length of csum2 is now per-file starting with protocol version
27. (J.W. Schultz)
* Per-file dynamic block size is now sqrt(file length). The
per-file checksum size is determined according to an algorithm
provided by Donovan Baarda which reduces the probability of rsync
algorithm corrupting data and falling back using the whole md4
checksums. (J.W. Schultz, Donovan Baarda)
* The --stats option no longer includes the (debug) malloc summary
unless the verbose option was specified at least twice.
* Added a new error/warning code for when files vanish from the
sending side. Made vanished source files not interfere with the
file-deletion pass when --delete-after was specified.
* Various trailing-info sections are now preceded by a newline.
BUG FIXES:
* Fixed several exclude/include matching bugs when using wild-cards.
This has a several user-visible effects, all of which make the
matching more consistent and intuitive. This should hopefully not
cause anyone problems since it makes the matching work more like
what people are expecting. (Wayne Davison)
- A pattern with a "**" no longer causes a "*" to match slashes.
For example, with "/*/foo/**", "foo" must be 2 levels deep.
[If your string has BOTH "*" and "**" wildcards, changing the
"*" wildcards to "**" will provide the old behavior in all
versions.]
- "**/foo" now matches at the base of the transfer (like /foo
does). [Use "/**/foo" to get the old behavior in all versions.]
- A non-anchored wildcard term floats to match beyond the base of
the transfer. E.g. "CVS/R*" matches at the end of the path,
just like the non-wildcard term "CVS/Root" does. [Use "/CVS/R*"
to get the old behavior in all versions.]
- Including a "**" in the match term causes it to be matched
against the entire path, not just the name portion, even if
there aren't any interior slashes in the term. E.g. "foo**bar"
would exclude "/path/foo-bar" (just like before) as well as
"/foo-path/baz-bar" (unlike before). [Use "foo*bar" to get the
old behavior in all versions.]
* The exclude list specified in the daemon's config file is now
properly applied to the pulled items no matter how deep the
user's file-args are in the source tree. (Wayne Davison)
* For protocol version >= 27, mdfour_tail() is called when the
block size (including checksum_seed) is a multiple of 64.
Previously it was not called, giving the wrong MD4 checksum.
(Craig Barratt)
* For protocol version >= 27, a 64 bit bit counter is used in
mdfour.c as required by the RFC. Previously only a 32 bit bit
counter was used, causing incorrect MD4 file checksums for
file sizes >= 512MB - 4. (Craig Barratt)
* Fixed a crash bug when interacting with older rsync versions and
multiple files of the same name are destined for the same dir.
(Wayne Davison)
* Keep tmp names from overflowing MAXPATHLEN.
* Make --link-dest honor the absence of -p, -o, and -g.
* Made rsync treat a trailing slash in the destination in a more
consistent manner.
* Fixed file I/O error detection. (John Van Essen)
* Fixed bogus "malformed address {hostname}" message in rsyncd log
when checking IP address against hostnames from "hosts allow"
and "hosts deny" parameters in config file.
* Print heap statistics when verbose >= 2 instead of when >= 1.
* Fixed a compression (-z) bug when syncing a mostly-matching file
that contains already-compressed data. (Yasuoka Masahiko and
Wayne Davison)
* Fixed a bug in the --backup code that could cause deleted files
to not get backed up.
* When the backup code makes new directories, create them with mode
0700 instead of 0755 (since the directory permissions in the
backup tree are not yet copied from the main tree).
* Call setgroups() in a more portable manner.
* Improved file-related error messages to better indicate exactly
what pathname failed. (Wayne Davison)
* Fixed some bugs in the handling of --delete and --exclude when
using the --relative (-R) option. (Wayne Davison)
* Fixed bug that prevented regular files from replacing
special files and caused a directory in --link-dest or
--compare-dest to block the creation of a file with the
same path. A directory still cannot be replaced by a
regular file unless --delete specified. (J.W. Schultz)
* Detect and report when open or opendir succeed but read and
readdir fail caused by network filesystem issues and truncated
files. (David Norwood, Michael Brown, J.W. Schultz)
* Added a fix that should give ssh time to restore the tty settings
if the user presses Ctrl-C at an ssh password prompt.
INTERNAL:
* Eliminated vestigial support for old versions that we stopped
supporting. (J.W. Schultz)
* Simplified some of the option-parsing code. (Wayne Davison)
* Some cleanup made to the exclude code, as well as some new
defines added to enhance readability. (Wayne Davison)
* Changed the protocol-version code so that it can interact at a
lower protocol level than the maximum supported by both sides.
Added an undocumented option, --protocol=N, to force the value
we advertise to the other side (primarily for testing purposes).
(Wayne Davison)
NEWS for rsync 2.5.7 (4 Dec 2003)
Protocol: 26 (unchanged)
Changes since 2.5.6:
SECURITY FIXES:
* Fix buffer handling bugs. (Andrew Tridgell, Martin Pool, Paul
Russell, Andrea Barisani)
NEWS for rsync 2.5.6, aka "the dwd-between-jobs release" (26 Jan 2003)
Protocol: 26 (unchanged)
Changes since 2.5.5:
ENHANCEMENTS:
* The --delete-after option now implies --delete. (Wayne Davison)
* The --suffix option can now be used with --backup-dir. (Michael
Zimmerman)
* Combining "::" syntax with the -rsh/-e option now uses the
specified remote-shell as a transport to talk to a (newly-spawned)
server-daemon. This allows someone to use daemon features, such
as modules, over a secure protocol, such as ssh. (JD Paul)
* The rsync:// syntax for daemon connections is now accepted in the
destination field.
* If the file name given to --include-from or --exclude-from is "-",
rsync will read from standard input. (J.W. Schultz)
* New option --link-dest which is like --compare-dest except that
unchanged files are hard-linked in to the destination directory.
(J.W. Schultz)
* Don't report an error if an excluded file disappears during an
rsync run. (Eugene Chupriyanov and Bo Kersey)
* Added .svn to --cvs-exclude list to support subversion. (Jon
Middleton)
* Properly support IPv6 addresses in the rsyncd.conf "hosts allow"
and "hosts deny" fields. (Hideaki Yoshifuji)
* Changed exclude file handling to permit DOS or MAC style line
terminations. (J.W. Schultz)
* Ignore errors from chmod when -p/-a/--preserve-perms is not set.
(Dave Dykstra)
BUG FIXES:
* Fix "forward name lookup failed" errors on AIX 4.3.3. (John
L. Allen, Martin Pool)
* Generate each file's rolling-checksum data as we send it, not
in a separate (memory-eating) pass before hand. This prevents
timeout errors on really large files. (Stefan Nehlsen)
* Fix compilation on Tru64. (Albert Chin, Zoong Pham)
* Better handling of some client-server errors. (Martin Pool)
* Fixed a crash that would occur when sending a list of files that
contains a duplicate name (if it sorts to the end of the file
list) and using --delete. (Wayne Davison)
* Fixed the file-name duplicate-removal code when dealing with multiple
dups in a row. (Wayne Davison)
* Fixed a bug that caused rsync to lose the exit status of its child
processes and sometimes return an exit code of 0 instead of showing
an error. (David R. Staples, Dave Dykstra)
* Fixed bug in --copy-unsafe-links that caused it to be completely
broken. (Dave Dykstra)
* Prevent infinite recursion in cleanup code under certain circumstances.
(Sviatoslav Sviridov and Marc Espie)
* Fixed a bug that prevented rsync from creating intervening directories
when --relative-paths/-R is set. (Craig Barratt)
* Prevent "Connection reset by peer" messages from Cygwin. (Randy O'Meara)
INTERNAL:
* Many code cleanups and improved internal documentation. (Martin
Pool, Nelson Beebe)
* Portability fixes. (Dave Dykstra and Wayne Davison)
* More test cases. (Martin Pool)
* Some test-case fixes. (Brian Poole, Wayne Davison)
* Updated included popt to the latest vendor drop, version 1.6.4.
(Jos Backus)
* Updated config.guess and config.sub to latest versions; this
means rsync should build on more platforms. (Paul Green)
NEWS for rsync 2.5.5, aka Snowy River (2 Apr 2002)
Protocol: 26 (unchanged)
Changes since 2.5.4:
ENHANCEMENTS:
* With --progress, when a transfer is complete show the time taken;
otherwise show expected time to complete. (Cameron Simpson)
* Make "make install-strip" works properly, and "make install"
accepts a DESTDIR variable for help in building binary packages.
(Peter Breitenlohner, Greg Louis)
* If configured with --enable-maintainer-mode, then on receipt of
a fatal signal rsync will try to open an xterm running gdb,
similarly to Samba's "panic action" or GNOME's bug-buddy.
(Martin Pool)
BUG FIXES:
* Fix situation where failure to fork (e.g. because out of process
slots) would cause rsync to kill all processes owned by the
current user. Yes, really! (Paul Haas, Martin Pool)
* Fix test suite on Solaris. (Jos Backus, Martin Pool)
* Fix minor memory leak in socket code. (Dave Dykstra, Martin
Pool.)
* Fix --whole-file problem that caused it to be the default even
for remote connections. (Martin Pool, Frank Schulz)
* Work around bug in Mac OS X mkdir(2), which cannot handle
trailing slashes.
<http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html>
(Martin Pool)
* Improved network error handling. (Greg A. Woods)
NEWS for rsync 2.5.4, aka "Imitation lizard skin" (13 Mar 2002)
Protocol: 26 (unchanged)
Changes since 2.5.3:
BUG FIXES:
* Additional fix for zlib double-free bug. (Martin Pool, Andrew
Tridgell) (CVE CAN-2002-0059)
ENHANCEMENTS:
* Merge in changes from zlib 1.1.3 to zlib 1.1.4. (Jos Backus)
(Note that rsync still uses a custom version of zlib; you can
not just link against a system library. See zlib/README.rsync)
* Additional test cases for --compress. (Martin Pool)
NEWS for rsync 2.5.3, aka "Happy 26" (11 Mar 2002)
Protocol: 26 (unchanged)
Changes since 2.5.2:
SECURITY FIXES:
@@ -13,7 +555,7 @@ rsync 2.5.3 (11 March 2002)
* Fix zlib double-free bug. (Owen Taylor, Mark J Cox) (CVE
CAN-2002-0059)
* Fixed problem that in many cases caused the error message
* Fixed problem that in many cases caused the error message
unexpected read size of 0 in map_ptr
and resulted in the wrong data being copied.
@@ -34,7 +576,7 @@ rsync 2.5.3 (11 March 2002)
* Merge in changes from zlib 1.1.2 to zlib 1.1.3. (Note that
rsync still uses a custom version of zlib; you can not just link
against a system library. See zlib/README.rsync)
* Command to initiate connections is only shown with -vv, rather
than -v as in 2.5.2. Output from plain -v is more similar to
what was historically used so as not to break scripts that try
@@ -48,7 +590,10 @@ rsync 2.5.3 (11 March 2002)
* If the daemon is unable to fork a child to accept a connection,
print an error message. (Colin Walters)
rsync 2.5.2 (26 Jan 2002)
NEWS for rsync 2.5.2 (26 Jan 2002)
Protocol: 26 (changed)
Changes since 2.5.1:
SECURITY FIXES:
@@ -75,7 +620,7 @@ rsync 2.5.2 (26 Jan 2002)
connection.
* --statistics now shows memory heap usage on platforms that
support mallinfo().
support mallinfo().
* "The Ted T'so school of program optimization": make progress
visible and people will think it's faster. (With --progress,
@@ -84,14 +629,17 @@ rsync 2.5.2 (26 Jan 2002)
* Improvements to batch mode support. This is still experimental
but testing would be welcome. (Jos Backus)
* New --ignore-existing option, patch previously distributed with
Vipul's Razor. (Debian #124286)
rsync 2.5.1 (2002-01-03)
NEWS for rsync 2.5.1 (3 Jan 2002)
Protocol: 25 (unchanged)
Changes since 2.5.0:
BUG FIXES:
BUG FIXES:
* Fix for segfault in --daemon mode configuration parser. (Paul
Mackerras)
@@ -113,16 +661,19 @@ rsync 2.5.1 (2002-01-03)
ENHANCEMENTS:
* --progress and -P now show estimated data transfer rate (in a
multiple of bytes/s) and estimated time to completion. (Rik
Faith)
multiple of bytes/s) and estimated time to completion. (Rik
Faith)
* --no-detach option, required to run as a W32 service and also
useful when running on Unix under daemontools, AIX's SRC, or a
debugger. (Max Bowsher, Jos Backus)
useful when running on Unix under daemontools, AIX's SRC, or a
debugger. (Max Bowsher, Jos Backus)
* Clearer error messages for some conditions.
rsync 2.5.0 (2001-11-30)
NEWS for rsync 2.5.0 (30 Nov 2001)
Protocol: 25 (changed)
Changes since 2.4.6:
ANNOUNCEMENTS
@@ -184,7 +735,7 @@ rsync 2.5.0 (2001-11-30)
* Attempt to fix error handling lockup bug.
* Give a non-0 exit code if *any* of the files we have been asked
to transfer fail to transfer
to transfer fail to transfer.
* For log messages containing ridiculously long strings that might
overflow a buffer rsync no longer aborts, but rather prints an
@@ -195,7 +746,7 @@ rsync 2.5.0 (2001-11-30)
* Improved support for UNICOS (tested on Cray T3E and Cray SV1)
* autoconf2.52 (or later) is now required to rebuild the autoconf
scripts. It is not required to simply build rsync.
scripts. It is not required to simply build rsync.
* Platforms thought to work in this release:
@@ -236,3 +787,50 @@ rsync 2.5.0 (2001-11-30)
* The existing test.sh script by Phil Hands has been merged into a
test framework that works from both "make check" and the Samba
build farm.
Partial Protocol History
RELEASE DATE VER. DATE OF COMMIT PROTOCOL
30 Apr 2004 2.6.2 28
26 Apr 2004 2.6.1 08 Jan 2004 28
01 Jan 2004 2.6.0 10 Apr 2003 27 (MAX=40)
04 Dec 2003 2.5.7 26
26 Jan 2003 2.5.6 26
02 Apr 2002 2.5.5 26
13 Mar 2002 2.5.4 26
11 Mar 2002 2.5.3 26
26 Jan 2002 2.5.2 11 Jan 2002 26
03 Jan 2002 2.5.1 25
30 Nov 2001 2.5.0 23 Aug 2001 25
06 Sep 2000 2.4.6 24
19 Aug 2000 2.4.5 24
29 Jul 2000 2.4.4 24
09 Apr 2000 2.4.3 24
30 Mar 2000 2.4.2 24
30 Jan 2000 2.4.1 29 Jan 2000 24
29 Jan 2000 2.4.0 28 Jan 2000 23
25 Jan 2000 2.3.3 23 Jan 2000 22
08 Nov 1999 2.3.2 26 Jun 1999 21
06 Apr 1999 2.3.1 20
15 Mar 1999 2.3.0 15 Mar 1999 20
25 Nov 1998 2.2.1 19
03 Nov 1998 2.2.0 19
09 Sep 1998 2.1.1 19
20 Jul 1998 2.1.0 19
17 Jul 1998 2.0.19 19
18 Jun 1998 2.0.17 19
01 Jun 1998 2.0.16 19
27 May 1998 2.0.13 27 May 1998 19
26 May 1998 2.0.12 18
22 May 1998 2.0.11 18
18 May 1998 2.0.9 18 May 1998 18
17 May 1998 2.0.8 17
15 May 1998 2.0.1 17
14 May 1998 2.0.0 17
17 Apr 1998 1.7.4 17
13 Apr 1998 1.7.3 17
05 Apr 1998 1.7.2 17
26 Mar 1998 1.7.1 17
26 Mar 1998 1.7.0 26 Mar 1998 17 (MAX=30)
13 Jan 1998 1.6.9 13 Jan 1998 15 (MAX=20)
* DATE OF COMMIT is the date the protocol change was committed to CVS.

88
README
View File

@@ -18,81 +18,20 @@ this package.
USAGE
-----
Basically you use rsync just like rcp, but rsync has many additional options.
Basically you use rsync just like rcp, but rsync has many additional
options. To get a complete list of supported options type
Here is a brief description of rsync usage:
Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
or rsync [OPTION]... [USER@]HOST:SRC DEST
or rsync [OPTION]... SRC [SRC]... DEST
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
SRC on single-colon remote HOST will be expanded by remote shell
SRC on server remote HOST may contain shell wildcards or multiple
sources separated by space as long as they have same top-level
Options
-v, --verbose increase verbosity
-q, --quiet decrease verbosity
-c, --checksum always checksum
-a, --archive archive mode
-r, --recursive recurse into directories
-R, --relative use relative path names
-b, --backup make backups (default ~ suffix)
--suffix=SUFFIX override backup suffix
-u, --update update only (don't overwrite newer files)
-l, --links preserve soft links
-L, --copy-links treat soft links like regular files
--copy-unsafe-links copy links outside the source tree
--safe-links ignore links outside the destination tree
-H, --hard-links preserve hard links
-p, --perms preserve permissions
-o, --owner preserve owner (root only)
-g, --group preserve group
-D, --devices preserve devices (root only)
-t, --times preserve times
-S, --sparse handle sparse files efficiently
-n, --dry-run show what would have been transferred
-W, --whole-file copy whole files, no incremental checks
-x, --one-file-system don't cross filesystem boundaries
-B, --block-size=SIZE checksum blocking size (default 700)
-e, --rsh=COMMAND specify rsh replacement
--rsync-path=PATH specify path to rsync on the remote machine
-C, --cvs-exclude auto ignore files in the same way CVS does
--delete delete files that don't exist on the sending side
--delete-excluded also delete excluded files on the receiving side
--partial keep partially transferred files
--force force deletion of directories even if not empty
--numeric-ids don't map uid/gid values by user/group name
--timeout=TIME set IO timeout in seconds
-I, --ignore-times don't exclude files that match length and time
--size-only only use file size when determining if a file should be transferred
-T --temp-dir=DIR create temporary files in directory DIR
--compare-dest=DIR also compare destination files relative to DIR
-z, --compress compress file data
--exclude=PATTERN exclude files matching PATTERN
--exclude-from=FILE exclude patterns listed in FILE
--include=PATTERN don't exclude files matching PATTERN
--include-from=FILE don't exclude patterns listed in FILE
--version print version number
--daemon run as a rsync daemon
--config=FILE specify alternate rsyncd.conf file
--port=PORT specify alternate rsyncd port number
--stats give some file transfer stats
--progress show progress during transfer
--log-format=FORMAT log file transfers using specified format
--password-file=FILE get password from FILE
-h, --help show this help screen
rsync --help
and see the manual for more information.
SETUP
-----
Rsync normally uses rsh or ssh for communication. It does not need to
Rsync normally uses ssh or rsh for communication. It does not need to
be setuid and requires no special privileges for installation. You
must, however, have a working rsh or ssh system. Using ssh is
must, however, have a working ssh or rsh system. Using ssh is
recommended for its security features.
Alternatively, rsync can run in `daemon' mode, listening on a socket.
@@ -137,13 +76,18 @@ BUG REPORTS
-----------
If you have web access then please look at
http://rsync.samba.org/rsync/
This will give you access to the bug tracking system used by the
developers of rsync and will allow you to look at other bug reports or
submit a new bug report.
http://rsync.samba.org/
If you don't have web access then mail bug reports to rsync@samba.org.
That page contains links to the current bug list, and information on
how to report a bug well. You might also like to try searching the
internet for the error message you've received, or looking in the
mailing list archives at
http://mail-archive.com/rsync@lists.samba.org/
To send a bug report, follow the instructions on the bug-tracking
page of the web site.
CVS TREE

961
TODO
View File

File diff suppressed because it is too large Load Diff

194
access.c
View File

@@ -27,57 +27,185 @@
static int match_hostname(char *host, char *tok)
{
if (!host || !*host) return 0;
return (fnmatch(tok, host, 0) == 0);
return wildmatch(tok, host);
}
static int match_binary(char *b1, char *b2, char *mask, int addrlen)
{
int i;
for (i=0; i<addrlen; i++) {
if ((b1[i]^b2[i])&mask[i]) {
return 0;
}
}
return 1;
}
static void make_mask(char *mask, int plen, int addrlen) {
int w, b;
w = plen >> 3;
b = plen & 0x7;
if (w)
memset(mask, 0xff, w);
if (w < addrlen)
mask[w] = 0xff & (0xff<<(8-b));
if (w+1 < addrlen)
memset(mask+w+1, 0, addrlen-w-1);
return;
}
static int match_address(char *addr, char *tok)
{
char *p;
unsigned long a, t, mask = (unsigned long)~0;
struct addrinfo hints, *resa, *rest;
int gai;
int ret = 0;
int addrlen = 0;
#ifdef HAVE_STRTOL
long int bits;
#else
int bits;
#endif
char mask[16];
char *a = NULL, *t = NULL;
unsigned int len;
if (!addr || !*addr) return 0;
if (!isdigit(tok[0])) return 0;
p = strchr(tok,'/');
if (p) *p = 0;
a = inet_addr(addr);
t = inet_addr(tok);
if (p) {
*p = '/';
*p = '\0';
len = p - tok;
}
else
len = strlen(tok);
if (t == INADDR_NONE) {
rprintf(FERROR,"malformed address %s\n", tok);
/* Fail quietly if tok is a hostname (not an address) */
if (strspn(tok, ".0123456789") != len
#ifdef INET6
&& !strchr(tok, ':')
#endif
) return 0;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
#ifdef AI_NUMERICHOST
hints.ai_flags = AI_NUMERICHOST;
#endif
gai = getaddrinfo(addr, NULL, &hints, &resa);
if (gai) return 0;
gai = getaddrinfo(tok, NULL, &hints, &rest);
if (p)
*p++ = '/';
if (gai) {
rprintf(FERROR,
"error matching address %s: %s\n",
tok,
gai_strerror(gai));
freeaddrinfo(resa);
return 0;
}
a = ntohl(a);
t = ntohl(t);
if (p) {
if (strchr(p+1,'.')) {
mask = inet_addr(p+1);
if (mask == INADDR_NONE) {
rprintf(FERROR,"malformed mask in %s\n", tok);
return 0;
}
mask = ntohl(mask);
} else {
int bits = atoi(p+1);
if (bits == 0) return 1;
if (bits <= 0 || bits > 32) {
rprintf(FERROR,"malformed mask in %s\n", tok);
return 0;
}
mask &= (mask << (32-bits));
}
if (rest->ai_family != resa->ai_family) {
ret = 0;
goto out;
}
return ((a&mask) == (t&mask));
switch(resa->ai_family) {
case PF_INET:
a = (char *)&((struct sockaddr_in *)resa->ai_addr)->sin_addr;
t = (char *)&((struct sockaddr_in *)rest->ai_addr)->sin_addr;
addrlen = 4;
break;
#ifdef INET6
case PF_INET6:
{
struct sockaddr_in6 *sin6a, *sin6t;
sin6a = (struct sockaddr_in6 *)resa->ai_addr;
sin6t = (struct sockaddr_in6 *)rest->ai_addr;
a = (char *)&sin6a->sin6_addr;
t = (char *)&sin6t->sin6_addr;
addrlen = 16;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
if (sin6t->sin6_scope_id &&
sin6a->sin6_scope_id != sin6t->sin6_scope_id) {
ret = 0;
goto out;
}
#endif
break;
}
#endif
default:
rprintf(FERROR,"unknown family %u\n", rest->ai_family);
ret = 0;
goto out;
}
bits = -1;
if (p) {
if (inet_pton(resa->ai_addr->sa_family, p, mask) <= 0) {
#ifdef HAVE_STRTOL
char *ep = NULL;
#else
unsigned char *pp;
#endif
#ifdef HAVE_STRTOL
bits = strtol(p, &ep, 10);
if (!*p || *ep) {
rprintf(FERROR,"malformed mask in %s\n", tok);
ret = 0;
goto out;
}
#else
for (pp = (unsigned char *)p; *pp; pp++) {
if (!isascii(*pp) || !isdigit(*pp)) {
rprintf(FERROR,"malformed mask in %s\n", tok);
ret = 0;
goto out;
}
}
bits = atoi(p);
#endif
if (bits == 0) {
ret = 1;
goto out;
}
if (bits < 0 || bits > (addrlen << 3)) {
rprintf(FERROR,"malformed mask in %s\n", tok);
ret = 0;
goto out;
}
}
} else {
bits = 128;
}
if (bits >= 0)
make_mask(mask, bits, addrlen);
ret = match_binary(a, t, mask, addrlen);
out:
freeaddrinfo(resa);
freeaddrinfo(rest);
return ret;
}
static int access_match(char *list, char *addr, char *host)

View File

@@ -1,10 +0,0 @@
#undef ino_t
#undef HAVE_CONNECT
#undef HAVE_SHORT_INO_T
#undef HAVE_GETOPT_LONG
#undef REPLACE_INET_NTOA
#undef REPLACE_INET_ATON
#undef HAVE_GETTIMEOFDAY_TZ
#undef ENABLE_IPV6
#undef HAVE_SOCKADDR_LEN
#undef HAVE_SOCKETPAIR

View File

@@ -1,17 +1,17 @@
/* -*- c-file-style: "linux"; -*-
Copyright (C) 1998-2000 by Andrew Tridgell
Copyright (C) 1998-2000 by Andrew Tridgell
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -20,11 +20,14 @@
/* support rsync authentication */
#include "rsync.h"
extern char *password_file;
extern int am_root;
/***************************************************************************
encode a buffer using base64 - simple and slow algorithm. null terminates
the result.
***************************************************************************/
static void base64_encode(char *buf, int len, char *out)
void base64_encode(char *buf, int len, char *out)
{
char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int bit_offset, byte_offset, idx, i;
@@ -33,7 +36,7 @@ static void base64_encode(char *buf, int len, char *out)
memset(out, 0, bytes+1);
for (i=0;i<bytes;i++) {
for (i = 0; i < bytes; i++) {
byte_offset = (i*6)/8;
bit_offset = (i*6)%8;
if (bit_offset < 3) {
@@ -54,7 +57,7 @@ static void gen_challenge(char *addr, char *challenge)
char input[32];
struct timeval tv;
memset(input, 0, sizeof(input));
memset(input, 0, sizeof input);
strlcpy((char *)input, addr, 17);
sys_gettimeofday(&tv);
@@ -62,28 +65,26 @@ static void gen_challenge(char *addr, char *challenge)
SIVAL(input, 20, tv.tv_usec);
SIVAL(input, 24, getpid());
sum_init();
sum_update(input, sizeof(input));
sum_init(0);
sum_update(input, sizeof input);
sum_end(challenge);
}
/* return the secret for a user from the sercret file. maximum length
is len. null terminate it */
/* Return the secret for a user from the secret file, null terminated.
* Maximum length is len (not counting the null). */
static int get_secret(int module, char *user, char *secret, int len)
{
char *fname = lp_secrets_file(module);
int fd, found=0;
char line[MAXPATHLEN];
char *p, *pass=NULL;
STRUCT_STAT st;
int ok = 1;
extern int am_root;
int fd, ok = 1;
char ch, *p;
if (!fname || !*fname) return 0;
if (!fname || !*fname)
return 0;
fd = open(fname,O_RDONLY);
if (fd == -1) return 0;
if ((fd = open(fname, O_RDONLY)) < 0)
return 0;
if (do_stat(fname, &st) == -1) {
rsyserr(FERROR, errno, "stat(%s)", fname);
@@ -103,80 +104,92 @@ static int get_secret(int module, char *user, char *secret, int len)
return 0;
}
while (!found) {
int i = 0;
memset(line, 0, sizeof line);
while ((size_t) i < (sizeof(line)-1)) {
if (read(fd, &line[i], 1) != 1) {
memset(line, 0, sizeof(line));
close(fd);
return 0;
}
if (line[i] == '\r') continue;
if (line[i] == '\n') break;
i++;
}
line[i] = 0;
if (line[0] == '#') continue;
p = strchr(line,':');
if (!p) continue;
*p = 0;
if (strcmp(user, line)) continue;
pass = p+1;
found = 1;
if (*user == '#') {
/* Reject attempt to match a comment. */
close(fd);
return 0;
}
close(fd);
if (!found) return 0;
/* Try to find a line that starts with the user name and a ':'. */
p = user;
while (1) {
if (read(fd, &ch, 1) != 1) {
close(fd);
return 0;
}
if (ch == '\n')
p = user;
else if (p) {
if (*p == ch)
p++;
else if (!*p && ch == ':')
break;
else
p = NULL;
}
}
/* Slurp the secret into the "secret" buffer. */
p = secret;
while (len > 0) {
if (read(fd, p, 1) != 1 || *p == '\n')
break;
if (*p == '\r')
continue;
p++;
len--;
}
*p = '\0';
close(fd);
strlcpy(secret, pass, len);
return 1;
}
static char *getpassf(char *filename)
{
char buffer[100];
int fd=0;
STRUCT_STAT st;
int ok = 1;
extern int am_root;
char *envpw=getenv("RSYNC_PASSWORD");
char buffer[512], *p;
int fd, n, ok = 1;
char *envpw = getenv("RSYNC_PASSWORD");
if (!filename) return NULL;
if (!filename)
return NULL;
if ( (fd=open(filename,O_RDONLY)) == -1) {
if ((fd = open(filename,O_RDONLY)) < 0) {
rsyserr(FERROR, errno, "could not open password file \"%s\"",filename);
if (envpw) rprintf(FERROR,"falling back to RSYNC_PASSWORD environment variable.\n");
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)", 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 (am_root && st.st_uid != 0) {
rprintf(FERROR,"password file must be owned by root when running as root\n");
ok = 0;
}
if (!ok) {
rprintf(FERROR,"continuing without password file\n");
if (envpw) rprintf(FERROR,"using RSYNC_PASSWORD environment variable.\n");
if (envpw)
rprintf(FERROR, "using RSYNC_PASSWORD environment variable.\n");
close(fd);
return NULL;
}
if (envpw) rprintf(FERROR,"RSYNC_PASSWORD environment variable ignored\n");
if (envpw)
rprintf(FERROR, "RSYNC_PASSWORD environment variable ignored\n");
buffer[sizeof(buffer)-1]='\0';
if (read(fd,buffer,sizeof(buffer)-1) > 0)
{
char *p = strtok(buffer,"\n\r");
close(fd);
if (p) p = strdup(p);
return p;
}
n = read(fd, buffer, sizeof buffer - 1);
close(fd);
if (n > 0) {
buffer[n] = '\0';
if ((p = strtok(buffer, "\n\r")) != NULL)
return strdup(p);
}
return NULL;
}
@@ -186,7 +199,7 @@ static void generate_hash(char *in, char *challenge, char *out)
{
char buf[16];
sum_init();
sum_init(0);
sum_update(in, strlen(in));
sum_update(challenge, strlen(challenge));
sum_end(buf);
@@ -194,16 +207,13 @@ static void generate_hash(char *in, char *challenge, char *out)
base64_encode(buf, 16, out);
}
/* possible negotiate authentication with the client. Use "leader" to
start off the auth if necessary
return NULL if authentication failed
return "" if anonymous access
otherwise return username
*/
char *auth_server(int fd, int module, char *addr, char *leader)
/* Possibly negotiate authentication with the client. Use "leader" to
* start off the auth if necessary.
*
* 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 *users = lp_auth_users(module);
char challenge[16];
@@ -216,46 +226,46 @@ char *auth_server(int fd, int module, char *addr, char *leader)
char *tok;
/* if no auth list then allow anyone in! */
if (!users || !*users) return "";
if (!users || !*users)
return "";
gen_challenge(addr, challenge);
base64_encode(challenge, 16, b64_challenge);
io_printf(fd,"%s%s\n", leader, b64_challenge);
io_printf(f_out, "%s%s\n", leader, b64_challenge);
if (!read_line(fd, line, sizeof(line)-1)) {
if (!read_line(f_in, line, sizeof line - 1))
return NULL;
}
memset(user, 0, sizeof(user));
memset(pass, 0, sizeof(pass));
memset(user, 0, sizeof user);
memset(pass, 0, sizeof pass);
if (sscanf(line,"%99s %29s", user, pass) != 2) {
if (sscanf(line,"%99s %29s", user, pass) != 2)
return NULL;
}
users = strdup(users);
if (!users) return NULL;
if (!users)
return NULL;
for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL," ,\t")) {
if (fnmatch(tok, user, 0) == 0) break;
if (wildmatch(tok, user))
break;
}
free(users);
if (!tok) {
if (!tok)
return NULL;
}
memset(secret, 0, sizeof(secret));
if (!get_secret(module, user, secret, sizeof(secret)-1)) {
memset(secret, 0, sizeof(secret));
memset(secret, 0, sizeof secret);
if (!get_secret(module, user, secret, sizeof secret - 1)) {
memset(secret, 0, sizeof secret);
return NULL;
}
generate_hash(secret, b64_challenge, pass2);
memset(secret, 0, sizeof(secret));
memset(secret, 0, sizeof secret);
if (strcmp(pass, pass2) == 0)
return user;
@@ -267,20 +277,26 @@ void auth_client(int fd, char *user, char *challenge)
{
char *pass;
char pass2[30];
extern char *password_file;
if (!user || !*user) return;
if (!user || !*user)
user = "nobody";
if (!(pass=getpassf(password_file)) && !(pass=getenv("RSYNC_PASSWORD"))) {
if (!(pass = getpassf(password_file))
&& !(pass = getenv("RSYNC_PASSWORD"))) {
/* XXX: cyeoh says that getpass is deprecated, because
it may return a truncated password on some systems,
and it is not in the LSB. */
* it may return a truncated password on some systems,
* and it is not in the LSB.
*
* Andrew Klein says that getpassphrase() is present
* on Solaris and reads up to 256 characters.
*
* OpenBSD has a readpassphrase() that might be more suitable.
*/
pass = getpass("Password: ");
}
if (!pass || !*pass) {
if (!pass)
pass = "";
}
generate_hash(pass, challenge, pass2);
io_printf(fd, "%s %s\n", user, pass2);

379
backup.c
View File

@@ -1,16 +1,16 @@
/*
/*
Copyright (C) Andrew Tridgell 1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -21,271 +21,248 @@
#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];
extern char *backup_suffix;
extern char *backup_dir;
extern int am_root;
extern int preserve_devices;
extern int preserve_links;
extern int preserve_hard_links;
extern int orig_umask;
extern int safe_symlinks;
/* make a complete pathname for backup file */
char *get_backup_name(char *fname)
{
if (backup_dir) {
if (stringjoin(backup_dir_buf + backup_dir_len, backup_dir_remainder,
fname, backup_suffix, NULL) < backup_dir_remainder)
return backup_dir_buf;
} else {
if (stringjoin(backup_dir_buf, MAXPATHLEN,
fname, backup_suffix, NULL) < MAXPATHLEN)
return backup_dir_buf;
}
rprintf(FERROR, "backup filename too long\n");
return NULL;
}
/* simple backup creates a backup with a suffix in the same directory */
static int make_simple_backup(char *fname)
{
char fnamebak[MAXPATHLEN];
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
rprintf(FERROR,"backup filename too long\n");
return 0;
}
char *fnamebak = get_backup_name(fname);
snprintf(fnamebak,sizeof(fnamebak),"%s%s",fname,backup_suffix);
if (do_rename(fname,fnamebak) != 0) {
if (!fnamebak)
return 0;
if (do_rename(fname, fnamebak) != 0) {
/* cygwin (at least version b19) reports EINVAL */
if (errno != ENOENT && errno != EINVAL) {
rsyserr(FERROR, errno, "rename %s to backup %s", fname, fnamebak);
rsyserr(FERROR, errno,
"rename %s to backup %s", fname, fnamebak);
return 0;
}
} else if (verbose > 1) {
rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
rprintf(FINFO, "backed up %s to %s\n", fname, fnamebak);
}
return 1;
}
/* recursively make a directory path */
static int make_dir(char *name, int mask)
{
char newdir [MAXPATHLEN];
char *p, *d;
/* copy pathname over, look for last '/' */
for (p = d = newdir; *name; *d++ = *name++)
if (*name == '/')
p = d;
if (p == newdir)
return 0;
*p = 0;
/* make the new directory, if that fails then make its parent */
while (do_mkdir (newdir, mask) != 0)
if ((errno != ENOENT) || !make_dir (newdir, mask))
return 0;
return 1;
} /* make_dir */
/****************************************************************************
Create a directory given an absolute path, perms based upon another directory
path
****************************************************************************/
static int make_bak_dir(char *fname,char *bak_path)
static int make_bak_dir(char *fullpath)
{
STRUCT_STAT st;
STRUCT_STAT *st2;
char fullpath[MAXPATHLEN];
extern int orig_umask;
char *p;
char *q;
STRUCT_STAT st;
char *rel = fullpath + backup_dir_len;
char *end = rel + strlen(rel);
char *p = end;
while(strncmp(bak_path,"./",2)==0) bak_path += 2;
while (strncmp(fullpath, "./", 2) == 0)
fullpath += 2;
if(bak_path[strlen(bak_path)-1]!='/') {
snprintf(fullpath,sizeof(fullpath),"%s/",bak_path);
} else {
snprintf(fullpath,sizeof(fullpath),"%s",bak_path);
}
p=fullpath;
q=&fullpath[strlen(fullpath)]; /* End of bak_path string */
strcat(fullpath,fname);
/* Try to find an existing dir, starting from the deepest dir. */
while (1) {
if (--p == fullpath) {
p += strlen(p);
goto failure;
}
if (*p == '/') {
*p = '\0';
if (do_mkdir(fullpath, 0777 & ~orig_umask) == 0)
break;
if (errno != ENOENT) {
rsyserr(FERROR, errno,
"make_bak_dir mkdir %s failed",
full_fname(fullpath));
goto failure;
}
}
}
/* Make the directories */
while ((p=strchr(p,'/'))) {
*p = 0;
if(do_lstat(fullpath,&st)!=0) {
do_mkdir(fullpath,0777 & ~orig_umask);
if(p>q) {
if(do_lstat(q,&st)!=0) {
rprintf(FERROR,"make_bak_dir stat %s : %s\n",fullpath,strerror(errno));
} else {
st2=&st;
set_modtime(fullpath,st2->st_mtime);
if(do_lchown(fullpath,st2->st_uid,st2->st_gid)!=0) {
rprintf(FERROR,"make_bak_dir chown %s : %s\n",fullpath,strerror(errno));
};
if(do_chmod(fullpath,st2->st_mode)!=0) {
rprintf(FERROR,"make_bak_dir failed to set permissions on %s : %s\n",fullpath,strerror(errno));
};
};
}
};
*p = '/';
p++;
}
return 0;
/* Make all the dirs that we didn't find on the way here. */
while (1) {
if (p >= rel) {
/* Try to transfer the directory settings of the
* actual dir that the files are coming from. */
if (do_stat(rel, &st) < 0) {
rsyserr(FERROR, errno,
"make_bak_dir stat %s failed",
full_fname(rel));
} else {
do_lchown(fullpath, st.st_uid, st.st_gid);
do_chmod(fullpath, st.st_mode);
}
}
*p = '/';
p += strlen(p);
if (p == end)
break;
if (do_mkdir(fullpath, 0777 & ~orig_umask) < 0) {
rsyserr(FERROR, errno, "make_bak_dir mkdir %s failed",
full_fname(fullpath));
goto failure;
}
}
return 0;
failure:
while (p != end) {
*p = '/';
p += strlen(p);
}
return -1;
}
/* robustly move a file, creating new directory structures if necessary */
static int robust_move(char *src, char *dst)
{
int keep_trying = 4;
int keep_path_extfs = 0;
int failed;
while (keep_trying) {
if (keep_path_extfs) {
failed = copy_file(src, dst, 0755);
if (!failed) {
do_unlink(src);
}
} else {
failed = robust_rename (src, dst);
}
if (failed) {
if (verbose > 2)
rprintf (FERROR, "robust_move failed: %s(%d)\n",
strerror (errno), errno);
switch (errno) {
/* external filesystem */
case EXDEV:
keep_path_extfs = 1;
keep_trying--;
break;
/* no directory to write to */
case ENOENT:
make_dir (dst, 0755);
keep_trying--;
break;
default:
keep_trying = 0;
} /* switch */
} else
keep_trying = 0;
} /* while */
return (!failed);
} /* robust_move */
if (robust_rename(src, dst, 0755) < 0 && (errno != ENOENT
|| make_bak_dir(dst) < 0 || robust_rename(src, dst, 0755) < 0))
return -1;
return 0;
}
/* if we have a backup_dir, then we get here from make_backup().
We will move the file to be deleted into a parallel directory tree */
/* If we have a --backup-dir, then we get here from make_backup().
* We will move the file to be deleted into a parallel directory tree. */
static int keep_backup(char *fname)
{
static int initialised;
char keep_name [MAXPATHLEN];
STRUCT_STAT st;
struct file_struct *file;
int kept=0;
char *buf;
int kept = 0;
int ret_code;
if (!initialised) {
if (backup_dir[strlen(backup_dir) - 1] == '/')
backup_dir[strlen(backup_dir) - 1] = 0;
if (verbose > 0)
rprintf (FINFO, "backup_dir is %s\n", backup_dir);
initialised = 1;
}
/* return if no file to keep */
#if SUPPORT_LINKS
if (do_lstat (fname, &st)) return 1;
ret_code = do_lstat(fname, &st);
#else
if (do_stat (fname, &st)) return 1;
ret_code = do_stat(fname, &st);
#endif
if (ret_code < 0)
return 1;
file = make_file(-1, fname, NULL, 1);
/* the file could have disappeared */
if (!file) return 1;
/* make a complete pathname for backup file */
if (strlen(backup_dir) + strlen(fname) > (MAXPATHLEN - 1)) {
rprintf (FERROR, "keep_backup filename too long\n");
return 0;
}
snprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname);
if (!(file = make_file(fname, NULL, NO_EXCLUDES)))
return 1; /* the file could have disappeared */
if (!(buf = get_backup_name(fname)))
return 0;
#ifdef HAVE_MKNOD
/* Check to see if this is a device file, or link */
if(IS_DEVICE(file->mode)) {
if(am_root && preserve_devices) {
make_bak_dir(fname,backup_dir);
if(do_mknod(keep_name,file->mode,file->rdev)!=0) {
rprintf(FERROR,"mknod %s : %s\n",keep_name,strerror(errno));
} else {
if(verbose>2)
rprintf(FINFO,"make_backup : DEVICE %s successful.\n",fname);
};
};
kept=1;
do_unlink(fname);
};
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",
fname);
}
}
kept = 1;
do_unlink(fname);
}
#endif
if(!kept && S_ISDIR(file->mode)) {
if (!kept && S_ISDIR(file->mode)) {
/* make an empty directory */
make_bak_dir(fname,backup_dir);
do_mkdir(keep_name,file->mode);
ret_code=do_rmdir(fname);
if(verbose>2)
rprintf(FINFO,"make_backup : RMDIR %s returns %i\n",fname,ret_code);
kept=1;
};
if (do_mkdir(buf, file->mode) < 0
&& (errno != ENOENT || make_bak_dir(buf) < 0
|| do_mkdir(buf, file->mode) < 0)) {
rsyserr(FINFO, errno, "mkdir %s failed",
full_fname(buf));
}
ret_code = do_rmdir(fname);
if (verbose > 2) {
rprintf(FINFO, "make_backup: RMDIR %s returns %i\n",
full_fname(fname), ret_code);
}
kept = 1;
}
#if SUPPORT_LINKS
if(!kept && preserve_links && S_ISLNK(file->mode)) {
extern int safe_symlinks;
if (safe_symlinks && unsafe_symlink(file->link, keep_name)) {
if (verbose) {
rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n",
keep_name,file->link);
}
kept=1;
}
make_bak_dir(fname,backup_dir);
if(do_symlink(file->link,keep_name) != 0) {
rprintf(FERROR,"link %s -> %s : %s\n",keep_name,file->link,strerror(errno));
};
do_unlink(fname);
kept=1;
};
if (!kept && preserve_links && S_ISLNK(file->mode)) {
if (safe_symlinks && unsafe_symlink(file->u.link, buf)) {
if (verbose) {
rprintf(FINFO, "ignoring unsafe symlink %s -> %s\n",
full_fname(buf), file->u.link);
}
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), file->u.link);
}
do_unlink(fname);
kept = 1;
}
#endif
if(!kept && preserve_hard_links && check_hard_link(file)) {
if(verbose > 1) rprintf(FINFO,"%s is a hard link\n",f_name(file));
};
if(!kept && !S_ISREG(file->mode)) {
rprintf(FINFO,"make_bak: skipping non-regular file %s\n",fname);
}
if (!kept && !S_ISREG(file->mode)) {
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
fname);
return 1;
}
/* move to keep tree if a file */
if(!kept) {
if (!robust_move (fname, keep_name))
rprintf(FERROR, "keep_backup failed %s -> %s : %s\n",
fname, keep_name, strerror(errno));
};
set_perms (keep_name, file, NULL, 0);
free_file (file);
free (file);
if (!kept) {
if (robust_move(fname, buf) != 0) {
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
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);
free(file);
if (verbose > 1)
rprintf (FINFO, "keep_backup %s -> %s\n", fname, keep_name);
rprintf(FINFO, "backed up %s to %s\n", fname, buf);
return 1;
} /* keep_backup */
}
/* main backup switch routine */
int make_backup(char *fname)
{
if (backup_dir)
return (keep_backup(fname));
else
return (make_simple_backup(fname));
return keep_backup(fname);
return make_simple_backup(fname);
}

686
batch.c
View File

@@ -1,5 +1,5 @@
/* -*- c-file-style: "linux" -*-
Weiss 1/1999
Batch utilities for rsync.
@@ -8,563 +8,171 @@
#include "rsync.h"
#include <time.h>
extern char *batch_prefix;
extern char *batch_name;
extern int eol_nulls;
extern int recurse;
extern int preserve_links;
extern int preserve_hard_links;
extern int preserve_devices;
extern int preserve_uid;
extern int preserve_gid;
extern int always_checksum;
struct file_list *batch_flist;
extern struct exclude_list_struct exclude_list;
static char rsync_flist_file[] = ".rsync_flist";
static char rsync_csums_file[] = ".rsync_csums";
static char rsync_delta_file[] = ".rsync_delta";
static char rsync_argvs_file[] = ".rsync_argvs";
static int *flag_ptr[] = {
&recurse,
&preserve_uid,
&preserve_gid,
&preserve_links,
&preserve_devices,
&preserve_hard_links,
&always_checksum,
NULL
};
static int fdb;
static int fdb_delta;
static int fdb_open;
static int fdb_close;
static char *flag_name[] = {
"--recurse (-r)",
"--owner (-o)",
"--group (-g)",
"--links (-l)",
"--devices (-D)",
"--hard-links (-H)",
"--checksum (-c)",
NULL
};
void write_batch_flist_file(char *buff, int bytes_to_write)
void write_stream_flags(int fd)
{
char filename[MAXPATHLEN];
int i, flags;
if (fdb_open) {
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_flist_file, sizeof(filename));
/* Start the batch file with a bitmap of data-stream-affecting
* flags. */
for (i = 0, flags = 0; flag_ptr[i]; i++) {
if (*flag_ptr[i])
flags |= 1 << i;
}
write_int(fd, flags);
}
/*
* Open batch flist file for writing;
* create it if it doesn't exist
*/
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
void read_stream_flags(int fd)
{
int i, flags;
for (i = 0, flags = read_int(fd); flag_ptr[i]; i++) {
int set = flags & (1 << i) ? 1 : 0;
if (*flag_ptr[i] != set) {
if (verbose) {
rprintf(FINFO,
"%sing the %s option to match the batchfile.\n",
set ? "Sett" : "Clear", flag_name[i]);
}
*flag_ptr[i] = set;
}
fdb_open = 0;
}
}
static void write_arg(int fd, char *arg)
{
char *x, *s;
if (*arg == '-' && (x = strchr(arg, '=')) != NULL) {
write(fd, arg, x - arg + 1);
arg += x - arg + 1;
}
/* Write buffer to batch flist file */
if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) {
write(fd, "'", 1);
for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) {
write(fd, s, x - s + 1);
write(fd, "'", 1);
}
write(fd, s, strlen(s));
write(fd, "'", 1);
return;
}
if (write(fdb, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
filename, strerror(errno));
close(fdb);
write(fd, arg, strlen(arg));
}
static void write_excludes(int fd)
{
struct exclude_struct *ent;
write_sbuf(fd, " <<'#E#'\n");
for (ent = exclude_list.head; ent; ent = ent->next) {
char *p = ent->pattern;
if (ent->match_flags & MATCHFLG_INCLUDE)
write_buf(fd, "+ ", 2);
else if (((*p == '-' || *p == '+') && p[1] == ' ')
|| *p == '#' || *p == ';')
write_buf(fd, "- ", 2);
write_sbuf(fd, p);
if (ent->match_flags & MATCHFLG_DIRECTORY)
write_byte(fd, '/');
write_byte(fd, eol_nulls ? 0 : '\n');
}
if (eol_nulls)
write_sbuf(fd, ";\n");
write_sbuf(fd, "#E#");
}
/* This routine tries to write out an equivalent --read-batch command
* given the user's --write-batch args. However, it doesn't really
* understand most of the options, so it uses some overly simple
* heuristics to munge the command line into something that will
* (hopefully) work. */
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
{
int fd, i;
char *p, filename[MAXPATHLEN];
stringjoin(filename, sizeof filename,
batch_name, ".sh", NULL);
fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IEXEC);
if (fd < 0) {
rsyserr(FERROR, errno, "Batch file %s open error", filename);
exit_cleanup(1);
}
if (fdb_close) {
close(fdb);
}
}
void write_batch_flist_info(int flist_count, struct file_struct **fptr)
{
int i;
int bytes_to_write;
/* Write flist info to batch file */
bytes_to_write =
sizeof(unsigned) +
sizeof(time_t) +
sizeof(OFF_T) +
sizeof(mode_t) +
sizeof(INO64_T) +
sizeof(DEV64_T) +
sizeof(DEV64_T) +
sizeof(uid_t) +
sizeof(gid_t);
fdb_open = 1;
fdb_close = 0;
for (i = 0; i < flist_count; i++) {
write_batch_flist_file((char *) fptr[i], bytes_to_write);
write_char_bufs(fptr[i]->basename);
write_char_bufs(fptr[i]->dirname);
write_char_bufs(fptr[i]->basedir);
write_char_bufs(fptr[i]->link);
if (i == flist_count - 1) {
fdb_close = 1;
/* Write argvs info to BATCH.sh file */
write_arg(fd, argv[0]);
if (exclude_list.head)
write_sbuf(fd, " --exclude-from=-");
for (i = 1; i < argc - file_arg_cnt; i++) {
p = argv[i];
if (strncmp(p, "--files-from", 12) == 0
|| strncmp(p, "--include", 9) == 0
|| strncmp(p, "--exclude", 9) == 0) {
if (strchr(p, '=') == NULL)
i++;
continue;
}
write_char_bufs(fptr[i]->sum);
}
}
void write_char_bufs(char *buf)
{
/* Write the size of the string which will follow */
char b[4];
SIVAL(b, 0, buf != NULL ? strlen(buf) : 0);
write_batch_flist_file(b, sizeof(int));
/* Write the string if there is one */
if (buf != NULL) {
write_batch_flist_file(buf, strlen(buf));
}
}
void write_batch_argvs_file(int argc, char *argv[])
{
int fdb;
int i;
char buff[256]; /* XXX */
char buff2[MAXPATHLEN + 6];
char filename[MAXPATHLEN];
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_argvs_file, sizeof(filename));
/*
* Open batch argvs file for writing;
* create it if it doesn't exist
*/
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE | S_IEXEC);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
buff[0] = '\0';
/* Write argvs info to batch file */
for (i = 0; i < argc; ++i) {
if (i == argc - 2) /* Skip source directory on cmdline */
continue;
/*
* FIXME:
* I think directly manipulating argv[] is probably bogus
*/
if (!strncmp(argv[i], "--write-batch",
strlen("--write-batch"))) {
/* Safer to change it here than script */
/*
* Change to --read-batch=prefix
* to get ready for remote
*/
strlcat(buff, "--read-batch=", sizeof(buff));
strlcat(buff, batch_prefix, sizeof(buff));
write(fd, " ", 1);
if (strncmp(p, "--write-batch", 13) == 0) {
write(fd, "--read-batch", 12);
if (p[13] == '=') {
write(fd, "=", 1);
write_arg(fd, p + 14);
}
} else
if (i == argc - 1) {
snprintf(buff2, sizeof(buff2), "${1:-%s}", argv[i]);
strlcat(buff, buff2, sizeof(buff));
}
else {
strlcat(buff, argv[i], sizeof(buff));
}
if (i < (argc - 1)) {
strlcat(buff, " ", sizeof(buff));
}
write_arg(fd, p);
}
strlcat(buff, "\n", sizeof(buff));
if (!write(fdb, buff, strlen(buff))) {
rprintf(FERROR, "Batch file %s write error: %s\n",
filename, strerror(errno));
close(fdb);
if ((p = find_colon(argv[argc - 1])) != NULL) {
if (*++p == ':')
p++;
} else
p = argv[argc - 1];
write(fd, " ${1:-", 6);
write_arg(fd, p);
write_byte(fd, '}');
if (exclude_list.head)
write_excludes(fd);
if (write(fd, "\n", 1) != 1 || close(fd) < 0) {
rsyserr(FERROR, errno, "Batch file %s write error", filename);
exit_cleanup(1);
}
close(fdb);
}
struct file_list *create_flist_from_batch(void)
{
unsigned char flags;
fdb_open = 1;
fdb_close = 0;
batch_flist = (struct file_list *) malloc(sizeof(batch_flist[0]));
if (!batch_flist) {
out_of_memory("create_flist_from_batch");
}
batch_flist->count = 0;
batch_flist->malloced = 1000;
batch_flist->files =
(struct file_struct **) malloc(sizeof(batch_flist->files[0]) *
batch_flist->malloced);
if (!batch_flist->files) {
out_of_memory("create_flist_from_batch");
}
for (flags = read_batch_flags(); flags; flags = read_batch_flags()) {
int i = batch_flist->count;
if (i >= batch_flist->malloced) {
if (batch_flist->malloced < 1000)
batch_flist->malloced += 1000;
else
batch_flist->malloced *= 2;
batch_flist->files =
(struct file_struct **) realloc(batch_flist->
files,
sizeof
(batch_flist->
files[0]) *
batch_flist->
malloced);
if (!batch_flist->files)
out_of_memory("create_flist_from_batch");
}
read_batch_flist_info(&batch_flist->files[i]);
batch_flist->files[i]->flags = flags;
batch_flist->count++;
}
return batch_flist;
}
int read_batch_flist_file(char *buff, int len)
{
int bytes_read;
char filename[MAXPATHLEN];
if (fdb_open) {
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_flist_file, sizeof(filename));
/* Open batch flist file for reading */
fdb = do_open(filename, O_RDONLY, 0);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
fdb_open = 0;
}
/* Read flist batch file */
switch (bytes_read = read(fdb, buff, len)) {
case -1:
rprintf(FERROR, "Batch file %s read error: %s\n",
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
break;
case 0: /* EOF */
close(fdb);
}
return bytes_read;
}
unsigned char read_batch_flags()
{
int flags;
if (read_batch_flist_file((char *) &flags, 4)) {
return 1;
} else {
return 0;
}
}
void read_batch_flist_info(struct file_struct **fptr)
{
int int_str_len;
char char_str_len[4];
char buff[256];
struct file_struct *file;
file = (struct file_struct *) malloc(sizeof(*file));
if (!file)
out_of_memory("read_batch_flist_info");
memset((char *) file, 0, sizeof(*file));
*fptr = file;
/*
* Keep these in sync with bytes_to_write assignment
* in write_batch_flist_info()
*/
read_batch_flist_file((char *) &file->modtime, sizeof(time_t));
read_batch_flist_file((char *) &file->length, sizeof(OFF_T));
read_batch_flist_file((char *) &file->mode, sizeof(mode_t));
read_batch_flist_file((char *) &file->inode, sizeof(INO64_T));
read_batch_flist_file((char *) &file->dev, sizeof(DEV64_T));
read_batch_flist_file((char *) &file->rdev, sizeof(DEV64_T));
read_batch_flist_file((char *) &file->uid, sizeof(uid_t));
read_batch_flist_file((char *) &file->gid, sizeof(gid_t));
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file->basename = strdup(buff);
} else {
file->basename = NULL;
}
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file[0].dirname = strdup(buff);
} else {
file[0].dirname = NULL;
}
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file[0].basedir = strdup(buff);
} else {
file[0].basedir = NULL;
}
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file[0].link = strdup(buff);
} else {
file[0].link = NULL;
}
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file[0].sum = strdup(buff);
} else {
file[0].sum = NULL;
}
}
void write_batch_csums_file(void *buff, int bytes_to_write)
{
static int fdb_open = 1;
char filename[MAXPATHLEN];
if (fdb_open) {
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_csums_file, sizeof(filename));
/*
* Open batch csums file for writing;
* create it if it doesn't exist
*/
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
fdb_open = 0;
}
/* Write buffer to batch csums file */
if (write(fdb, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
}
void close_batch_csums_file(void)
{
close(fdb);
}
void write_batch_csum_info(int *flist_entry, int flist_count,
struct sum_struct *s)
{
size_t i;
unsigned int int_zero = 0;
extern int csum_length;
fdb_open = 1;
/* Write csum info to batch file */
/* FIXME: This will break if s->count is ever not exactly an int. */
write_batch_csums_file(flist_entry, sizeof(int));
write_batch_csums_file(s ? &s->count : &int_zero, sizeof(int));
if (s) {
for (i = 0; i < s->count; i++) {
write_batch_csums_file(&s->sums[i].sum1, sizeof(uint32));
if ((*flist_entry == flist_count - 1)
&& (i == s->count - 1)) {
fdb_close = 1;
}
write_batch_csums_file(s->sums[i].sum2, csum_length);
}
}
}
int read_batch_csums_file(char *buff, int len)
{
static int fdb_open = 1;
int bytes_read;
char filename[MAXPATHLEN];
if (fdb_open) {
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_csums_file, sizeof(filename));
/* Open batch flist file for reading */
fdb = do_open(filename, O_RDONLY, 0);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
fdb_open = 0;
}
/* Read csums batch file */
bytes_read = read(fdb, buff, len);
if (bytes_read == -1) {
rprintf(FERROR, "Batch file %s read error: %s\n",
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
return bytes_read;
}
void read_batch_csum_info(int flist_entry, struct sum_struct *s,
int *checksums_match)
{
int i;
int file_flist_entry;
int file_chunk_ct;
uint32 file_sum1;
char file_sum2[SUM_LENGTH];
extern int csum_length;
read_batch_csums_file((char *) &file_flist_entry, sizeof(int));
if (file_flist_entry != flist_entry) {
rprintf(FINFO, "file_flist_entry (%d) != flist_entry (%d)\n",
file_flist_entry, flist_entry);
close(fdb);
exit_cleanup(1);
} else {
read_batch_csums_file((char *) &file_chunk_ct,
sizeof(int));
*checksums_match = 1;
for (i = 0; i < file_chunk_ct; i++) {
read_batch_csums_file((char *) &file_sum1,
sizeof(uint32));
read_batch_csums_file(file_sum2, csum_length);
if ((s->sums[i].sum1 != file_sum1) ||
(memcmp(s->sums[i].sum2, file_sum2, csum_length)
!= 0)) {
*checksums_match = 0;
}
} /* end for */
}
}
void write_batch_delta_file(char *buff, int bytes_to_write)
{
static int fdb_delta_open = 1;
char filename[MAXPATHLEN];
if (fdb_delta_open) {
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_delta_file, sizeof(filename));
/*
* Open batch delta file for writing;
* create it if it doesn't exist
*/
fdb_delta = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb_delta == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
filename, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
fdb_delta_open = 0;
}
/* Write buffer to batch delta file */
if (write(fdb_delta, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
filename, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
}
void close_batch_delta_file(void)
{
close(fdb_delta);
}
int read_batch_delta_file(char *buff, int len)
{
static int fdb_delta_open = 1;
int bytes_read;
char filename[MAXPATHLEN];
if (fdb_delta_open) {
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_delta_file, sizeof(filename));
/* Open batch flist file for reading */
fdb_delta = do_open(filename, O_RDONLY, 0);
if (fdb_delta == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
filename, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
fdb_delta_open = 0;
}
/* Read delta batch file */
bytes_read = read(fdb_delta, buff, len);
if (bytes_read == -1) {
rprintf(FERROR, "Batch file %s read error: %s\n",
filename, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
return bytes_read;
}
void show_flist(int index, struct file_struct **fptr)

View File

@@ -1,17 +1,17 @@
/*
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -23,8 +23,8 @@ int csum_length=2; /* initial value */
#define CSUM_CHUNK 64
int checksum_seed = 0;
extern int remote_version;
extern int checksum_seed;
extern int protocol_version;
/*
a simple 32 bit checksum that can be upadted from either end
@@ -38,9 +38,9 @@ uint32 get_checksum1(char *buf1,int len)
s1 = s2 = 0;
for (i = 0; i < (len-4); i+=4) {
s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] +
s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] +
10*CHAR_OFFSET;
s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);
s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);
}
for (; i < len; i++) {
s1 += (buf[i]+CHAR_OFFSET); s2 += s1;
@@ -58,26 +58,32 @@ void get_checksum2(char *buf,int len,char *sum)
if (len > len1) {
if (buf1) free(buf1);
buf1 = (char *)malloc(len+4);
buf1 = new_array(char, len+4);
len1 = len;
if (!buf1) out_of_memory("get_checksum2");
}
mdfour_begin(&m);
memcpy(buf1,buf,len);
if (checksum_seed) {
SIVAL(buf1,len,checksum_seed);
len += 4;
}
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
}
if (len - i > 0) {
/*
* Prior to version 27 an incorrect MD4 checksum was computed
* by failing to call mdfour_tail() for block sizes that
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes.
*/
if (len - i > 0 || protocol_version >= 27) {
mdfour_update(&m, (uchar *)(buf1+i), (len-i));
}
mdfour_result(&m, (uchar *)sum);
}
@@ -88,27 +94,29 @@ void file_checksum(char *fname,char *sum,OFF_T size)
struct map_struct *buf;
int fd;
OFF_T len = size;
char tmpchunk[CSUM_CHUNK];
struct mdfour m;
memset(sum,0,MD4_SUM_LENGTH);
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) return;
buf = map_file(fd,size);
if (fd == -1)
return;
buf = map_file(fd, size, MAX_MAP_SIZE, CSUM_CHUNK);
mdfour_begin(&m);
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
memcpy(tmpchunk, map_ptr(buf,i,CSUM_CHUNK), CSUM_CHUNK);
mdfour_update(&m, (uchar *)tmpchunk, CSUM_CHUNK);
mdfour_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
CSUM_CHUNK);
}
if (len - i > 0) {
memcpy(tmpchunk, map_ptr(buf,i,len-i), len-i);
mdfour_update(&m, (uchar *)tmpchunk, (len-i));
}
/* Prior to version 27 an incorrect MD4 checksum was computed
* by failing to call mdfour_tail() for block sizes that
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes. */
if (len - i > 0 || protocol_version >= 27)
mdfour_update(&m, (uchar *)map_ptr(buf, i, len-i), len-i);
mdfour_result(&m, (uchar *)sum);
@@ -117,30 +125,28 @@ void file_checksum(char *fname,char *sum,OFF_T size)
}
void checksum_init(void)
{
if (remote_version >= 14)
csum_length = 2; /* adaptive */
else
csum_length = SUM_LENGTH;
}
static int sumresidue;
static char sumrbuf[CSUM_CHUNK];
static struct mdfour md;
void sum_init(void)
void sum_init(int seed)
{
char s[4];
mdfour_begin(&md);
sumresidue=0;
SIVAL(s,0,checksum_seed);
sum_update(s,4);
sumresidue = 0;
SIVAL(s, 0, seed);
sum_update(s, 4);
}
void sum_update(char *p,int len)
/**
* Feed data into an MD4 accumulator, md. The results may be
* retrieved using sum_end(). md is used for different purposes at
* different points during execution.
*
* @todo Perhaps get rid of md and just pass in the address each time.
* Very slightly clearer and slower.
**/
void sum_update(char *p, int len)
{
int i;
if (len + sumresidue < CSUM_CHUNK) {
@@ -166,13 +172,13 @@ void sum_update(char *p,int len)
sumresidue = len-i;
memcpy(sumrbuf,p+i,sumresidue);
} else {
sumresidue = 0;
sumresidue = 0;
}
}
void sum_end(char *sum)
{
if (sumresidue) {
if (sumresidue || protocol_version >= 27) {
mdfour_update(&md, (uchar *)sumrbuf, sumresidue);
}

140
cleanup.c
View File

@@ -1,18 +1,19 @@
/* -*- c-file-style: "linux" -*-
Copyright (C) 1996-2000 by Andrew Tridgell
Copyright (C) Paul Mackerras 1996
Copyright (C) 2002 by Martin Pool
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -20,67 +21,133 @@
#include "rsync.h"
/* handling the cleanup when a transfer is interrupted is tricky when
--partial is selected. We need to ensure that the partial file is
kept if any real data has been transferred */
int cleanup_got_literal=0;
extern int io_error;
extern int keep_partial;
extern int log_got_error;
/**
* Close all open sockets and files, allowing a (somewhat) graceful
* shutdown() of socket connections. This eliminates the abortive
* TCP RST sent by a Winsock-based system when the close() occurs.
**/
void close_all(void)
{
#ifdef SHUTDOWN_ALL_SOCKETS
int max_fd;
int fd;
int ret;
struct stat st;
max_fd = sysconf(_SC_OPEN_MAX) - 1;
for (fd = max_fd; fd >= 0; fd--) {
ret = fstat(fd,&st);
if (fstat(fd,&st) == 0) {
if (is_a_socket(fd))
ret = shutdown(fd, 2);
ret = close(fd);
}
}
#endif
}
/**
* @file cleanup.c
*
* Code for handling interrupted transfers. Depending on the @c
* --partial option, we may either delete the temporary file, or go
* ahead and overwrite the destination. This second behaviour only
* occurs if we've sent literal data and therefore hopefully made
* progress on the transfer.
**/
/**
* Set to True once literal data has been sent across the link for the
* current file. (????)
*
* Handling the cleanup when a transfer is interrupted is tricky when
* --partial is selected. We need to ensure that the partial file is
* kept if any real data has been transferred.
**/
int cleanup_got_literal = 0;
static char *cleanup_fname;
static char *cleanup_new_fname;
static struct file_struct *cleanup_file;
static int cleanup_fd1, cleanup_fd2;
static struct map_struct *cleanup_buf;
static int cleanup_pid = 0;
extern int io_error;
static int cleanup_fd_r, cleanup_fd_w;
static pid_t cleanup_pid = 0;
pid_t cleanup_child_pid = -1;
/*
* Code is one of the RERR_* codes from errcode.h.
*/
/**
* Eventually calls exit(), passing @p code, therefore does not return.
*
* @param code one of the RERR_* codes from errcode.h.
**/
void _exit_cleanup(int code, const char *file, int line)
{
extern int keep_partial;
extern int log_got_error;
int ocode = code;
static int inside_cleanup = 0;
if (inside_cleanup > 10) {
/* prevent the occasional infinite recursion */
return;
}
inside_cleanup++;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
if (verbose > 3) {
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
code, file, line);
}
if (cleanup_child_pid != -1) {
int status;
if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
status = WEXITSTATUS(status);
if (status > code) code = status;
if (status > code)
code = status;
}
}
if (cleanup_got_literal && cleanup_fname && keep_partial) {
if (cleanup_got_literal && cleanup_fname && keep_partial
&& handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
char *fname = cleanup_fname;
cleanup_fname = NULL;
if (cleanup_buf) unmap_file(cleanup_buf);
if (cleanup_fd1 != -1) close(cleanup_fd1);
if (cleanup_fd2 != -1) close(cleanup_fd2);
finish_transfer(cleanup_new_fname, fname, cleanup_file);
if (cleanup_fd_r != -1)
close(cleanup_fd_r);
if (cleanup_fd_w != -1)
close(cleanup_fd_w);
finish_transfer(cleanup_new_fname, fname, cleanup_file, 0);
}
io_flush();
io_flush(FULL_FLUSH);
if (cleanup_fname)
do_unlink(cleanup_fname);
if (code) {
if (code)
kill_all(SIGUSR1);
}
if ((cleanup_pid != 0) && (cleanup_pid == (int) getpid())) {
if (cleanup_pid && cleanup_pid == getpid()) {
char *pidf = lp_pid_file();
if (pidf && *pidf) {
if (pidf && *pidf)
unlink(lp_pid_file());
}
}
if (code == 0 && (io_error || log_got_error)) {
code = RERR_PARTIAL;
if (code == 0) {
if ((io_error & ~IOERR_VANISHED) || log_got_error)
code = RERR_PARTIAL;
else if (io_error)
code = RERR_VANISHED;
}
if (code) log_exit(code, file, line);
if (code)
log_exit(code, file, line);
if (verbose > 2) {
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
ocode, file, line, code);
}
close_all();
exit(code);
}
@@ -92,17 +159,16 @@ void cleanup_disable(void)
void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
struct map_struct *buf, int fd1, int fd2)
int fd_r, int fd_w)
{
cleanup_fname = fnametmp;
cleanup_new_fname = fname;
cleanup_file = file;
cleanup_buf = buf;
cleanup_fd1 = fd1;
cleanup_fd2 = fd2;
cleanup_fd_r = fd_r;
cleanup_fd_w = fd_w;
}
void cleanup_set_pid(int pid)
void cleanup_set_pid(pid_t pid)
{
cleanup_pid = pid;
}

View File

@@ -1,20 +1,20 @@
/* -*- c-file-style: "linux" -*-
rsync -- fast file replication program
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -22,7 +22,7 @@
/**
* @file clientname.c
*
*
* Functions for looking up the remote name or addr of a socket.
*
* This file is now converted to use the new-style getaddrinfo()
@@ -34,27 +34,42 @@
#include "rsync.h"
static const char default_name[] = "UNKNOWN";
extern int am_daemon;
extern int am_server;
/**
* Return the IP addr of the client as a string
* Return the IP addr of the client as a string
**/
char *client_addr(int fd)
{
struct sockaddr_storage ss;
socklen_t length = sizeof ss;
static char addr_buf[100];
static int initialised;
struct sockaddr_storage ss;
socklen_t length = sizeof ss;
char *ssh_info, *p;
if (initialised) return addr_buf;
if (initialised)
return addr_buf;
initialised = 1;
client_sockaddr(fd, &ss, &length);
if (am_server) { /* daemon over --rsh mode */
strcpy(addr_buf, "0.0.0.0");
if ((ssh_info = getenv("SSH_CONNECTION")) != NULL
|| (ssh_info = getenv("SSH_CLIENT")) != NULL
|| (ssh_info = getenv("SSH2_CLIENT")) != NULL) {
strlcpy(addr_buf, ssh_info, sizeof addr_buf);
/* Truncate the value to just the IP address. */
if ((p = strchr(addr_buf, ' ')) != NULL)
*p = '\0';
}
} else {
client_sockaddr(fd, &ss, &length);
getnameinfo((struct sockaddr *)&ss, length,
addr_buf, sizeof addr_buf, NULL, 0, NI_NUMERICHOST);
}
getnameinfo((struct sockaddr *)&ss, length,
addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
return addr_buf;
}
@@ -74,24 +89,65 @@ static int get_sockaddr_family(const struct sockaddr_storage *ss)
* If anything goes wrong, including the name->addr->name check, then
* we just use "UNKNOWN", so you can use that value in hosts allow
* lines.
*
* After translation from sockaddr to name we do a forward lookup to
* make sure nobody is spoofing PTR records.
**/
char *client_name(int fd)
{
struct sockaddr_storage ss;
socklen_t ss_len = sizeof ss;
static char name_buf[100];
static char port_buf[100];
static int initialised;
struct sockaddr_storage ss;
socklen_t ss_len;
if (initialised) return name_buf;
if (initialised)
return name_buf;
strcpy(name_buf, default_name);
initialised = 1;
client_sockaddr(fd, &ss, &ss_len);
memset(&ss, 0, sizeof ss);
if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf))
check_name(fd, &ss, name_buf, port_buf);
if (am_server) { /* daemon over --rsh mode */
char *addr = client_addr(fd);
struct addrinfo hint, *answer;
int err;
memset(&hint, 0, sizeof hint);
#ifdef AI_NUMERICHOST
hint.ai_flags = AI_NUMERICHOST;
#endif
hint.ai_socktype = SOCK_STREAM;
if ((err = getaddrinfo(addr, NULL, &hint, &answer)) != 0) {
rprintf(FERROR, RSYNC_NAME ": malformed address %s: %s\n",
addr, gai_strerror(err));
return name_buf;
}
switch (answer->ai_family) {
case AF_INET:
ss_len = sizeof (struct sockaddr_in);
memcpy(&ss, answer->ai_addr, ss_len);
break;
#ifdef INET6
case AF_INET6:
ss_len = sizeof (struct sockaddr_in6);
memcpy(&ss, answer->ai_addr, ss_len);
break;
#endif
}
freeaddrinfo(answer);
} else {
ss_len = sizeof ss;
client_sockaddr(fd, &ss, &ss_len);
}
if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf,
port_buf, sizeof port_buf))
check_name(fd, &ss, name_buf);
return name_buf;
}
@@ -108,15 +164,16 @@ void client_sockaddr(int fd,
struct sockaddr_storage *ss,
socklen_t *ss_len)
{
memset(ss, 0, sizeof *ss);
if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
/* FIXME: Can we really not continue? */
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
fd, strerror(errno));
rsyserr(FERROR, errno, "getpeername on fd%d failed", fd);
exit_cleanup(RERR_SOCKETIO);
}
#ifdef INET6
if (get_sockaddr_family(ss) == AF_INET6 &&
if (get_sockaddr_family(ss) == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
/* OK, so ss is in the IPv6 family, but it is really
* an IPv4 address: something like
@@ -127,12 +184,12 @@ void client_sockaddr(int fd,
struct sockaddr_in6 sin6;
struct sockaddr_in *sin;
memcpy(&sin6, ss, sizeof(sin6));
memcpy(&sin6, ss, sizeof sin6);
sin = (struct sockaddr_in *)ss;
memset(sin, 0, sizeof(*sin));
memset(sin, 0, sizeof *sin);
sin->sin_family = AF_INET;
*ss_len = sizeof(struct sockaddr_in);
#ifdef HAVE_SOCKADDR_LEN
*ss_len = sizeof (struct sockaddr_in);
#if HAVE_SOCKADDR_IN_LEN
sin->sin_len = *ss_len;
#endif
sin->sin_port = sin6.sin6_port;
@@ -141,14 +198,16 @@ void client_sockaddr(int fd,
* (IN6_V4MAPPED_TO_SINADDR ?), but it does not seem
* to be present in the Linux headers. */
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
sizeof(sin->sin_addr));
}
sizeof sin->sin_addr);
}
#endif
}
/**
* Look up a name from @p ss into @p name_buf.
*
* @param fd file descriptor for client socket.
**/
int lookup_name(int fd, const struct sockaddr_storage *ss,
socklen_t ss_len,
@@ -156,7 +215,7 @@ int lookup_name(int fd, const struct sockaddr_storage *ss,
char *port_buf, size_t port_buf_len)
{
int name_err;
/* reverse lookup */
name_err = getnameinfo((struct sockaddr *) ss, ss_len,
name_buf, name_buf_len,
@@ -185,7 +244,7 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
{
int ss_family = get_sockaddr_family(ss);
const char fn[] = "compare_addrinfo_sockaddr";
if (ai->ai_family != ss_family) {
rprintf(FERROR,
"%s: response family %d != %d\n",
@@ -199,25 +258,39 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
sin1 = (const struct sockaddr_in *) ss;
sin2 = (const struct sockaddr_in *) ai->ai_addr;
return memcmp(&sin1->sin_addr, &sin2->sin_addr,
sizeof sin1->sin_addr);
}
#ifdef INET6
else if (ss_family == AF_INET6) {
if (ss_family == AF_INET6) {
const struct sockaddr_in6 *sin1, *sin2;
sin1 = (const struct sockaddr_in6 *) ss;
sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
return memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
sizeof sin1->sin6_addr);
if (ai->ai_addrlen < sizeof (struct sockaddr_in6)) {
rprintf(FERROR,
"%s: too short sockaddr_in6; length=%d\n",
fn, ai->ai_addrlen);
return 1;
}
if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
sizeof sin1->sin6_addr))
return 1;
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
if (sin1->sin6_scope_id != sin2->sin6_scope_id)
return 1;
#endif
return 0;
}
#endif /* INET6 */
else {
/* don't know */
return 1;
}
/* don't know */
return 1;
}
@@ -226,21 +299,24 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
* @p ss -- otherwise we may be being spoofed. If we suspect we are,
* then we don't abort the connection but just emit a warning, and
* change @p name_buf to be "UNKNOWN".
*
* We don't do anything with the service when checking the name,
* because it doesn't seem that it could be spoofed in any way, and
* getaddrinfo on random service names seems to cause problems on AIX.
**/
int check_name(int fd,
const struct sockaddr_storage *ss,
char *name_buf,
const char *port_buf)
char *name_buf)
{
struct addrinfo hints, *res, *res0;
int error;
int ss_family = get_sockaddr_family(ss);
memset(&hints, 0, sizeof(hints));
memset(&hints, 0, sizeof hints);
hints.ai_family = ss_family;
hints.ai_flags = AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(name_buf, port_buf, &hints, &res0);
error = getaddrinfo(name_buf, NULL, &hints, &res0);
if (error) {
rprintf(FERROR,
RSYNC_NAME ": forward name lookup for %s failed: %s\n",

View File

@@ -1,254 +1,325 @@
/* -*- c-file-style: "linux"; -*-
Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*
* Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001-2002 by Martin Pool <mbp@samba.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* the socket based protocol for setting up a connection with rsyncd */
/**
* @file
*
* The socket based protocol for setting up a connection with
* rsyncd.
**/
#include "rsync.h"
extern int am_sender;
extern int am_server;
extern int am_daemon;
extern int am_root;
extern int module_id;
extern int read_only;
extern int verbose;
extern int rsync_port;
char *auth_user;
int sanitize_paths = 0;
extern int kludge_around_eof;
extern int daemon_over_rsh;
extern int list_only;
extern int sanitize_paths;
extern int filesfrom_fd;
extern int remote_protocol;
extern int protocol_version;
extern int io_timeout;
extern int orig_umask;
extern int no_detach;
extern int default_af_hint;
extern char *bind_address;
extern struct exclude_list_struct server_exclude_list;
extern char *exclude_path_prefix;
extern char *config_file;
extern char *files_from;
/*
char *auth_user;
/**
* Run a client connected to an rsyncd. The alternative to this
* function for remote-shell connections is do_cmd.
*/
* function for remote-shell connections is do_cmd().
*
* After negotiating which module to use and reading the server's
* motd, this hands over to client_run(). Telling the server the
* module will cause it to chroot/setuid/etc.
*
* Instead of doing a transfer, the client may at this stage instead
* get a listing of remote modules and exit.
*
* @return -1 for error in startup, or the result of client_run().
* Either way, it eventually gets passed to exit_cleanup().
**/
int start_socket_client(char *host, char *path, int argc, char *argv[])
{
int fd, i;
char *sargs[MAX_ARGS];
int sargc=0;
char line[MAXPATHLEN];
char *p, *user=NULL;
extern int remote_version;
extern int am_sender;
extern char *shell_cmd;
extern int kludge_around_eof;
extern char *bind_address;
extern int default_af_hint;
if (argc == 0 && !am_sender) {
extern int list_only;
list_only = 1;
}
int fd, ret;
char *p, *user = NULL;
/* This is just a friendliness enhancement: if the connection
* is to an rsyncd then there is no point specifying the -e option.
* Note that this is only set if the -e was explicitly specified,
* not if the environment variable just happens to be set.
* See http://lists.samba.org/pipermail/rsync/2000-September/002744.html
*/
if (shell_cmd) {
rprintf(FERROR, "WARNING: --rsh or -e option ignored when "
"connecting to rsync daemon\n");
/* continue */
}
/* This is redundant with code in start_inband_exchange(), but this
* short-circuits a problem in the client before we open a socket,
* and the extra check won't hurt. */
if (*path == '/') {
rprintf(FERROR,"ERROR: The remote path must start with a module name not a /\n");
rprintf(FERROR,
"ERROR: The remote path must start with a module name not a /\n");
return -1;
}
p = strchr(host, '@');
if (p) {
if ((p = strchr(host, '@')) != NULL) {
user = host;
host = p+1;
*p = 0;
*p = '\0';
}
if (!user) user = getenv("USER");
if (!user) user = getenv("LOGNAME");
if (verbose >= 2) {
rprintf(FINFO, "opening tcp connection to %s port %d\n",
host, rsync_port);
}
fd = open_socket_out_wrapped (host, rsync_port, bind_address,
default_af_hint);
if (fd == -1) {
fd = open_socket_out_wrapped(host, rsync_port, bind_address,
default_af_hint);
if (fd == -1)
exit_cleanup(RERR_SOCKETIO);
ret = start_inband_exchange(user, path, fd, fd, argc);
return ret < 0? ret : client_run(fd, fd, -1, argc, argv);
}
int start_inband_exchange(char *user, char *path, int f_in, int f_out,
int argc)
{
int i;
char *sargs[MAX_ARGS];
int sargc = 0;
char line[MAXPATHLEN];
char *p;
if (argc == 0 && !am_sender)
list_only = 1;
if (*path == '/') {
rprintf(FERROR,
"ERROR: The remote path must start with a module name\n");
return -1;
}
server_options(sargs,&sargc);
if (!user)
user = getenv("USER");
if (!user)
user = getenv("LOGNAME");
/* set daemon_over_rsh to false since we need to build the
* true set of args passed through the rsh/ssh connection;
* this is a no-op for direct-socket-connection mode */
daemon_over_rsh = 0;
server_options(sargs, &sargc);
sargs[sargc++] = ".";
if (path && *path)
if (path && *path)
sargs[sargc++] = path;
sargs[sargc] = NULL;
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
io_printf(f_out, "@RSYNCD: %d\n", protocol_version);
if (!read_line(fd, line, sizeof(line)-1)) {
if (!read_line(f_in, line, sizeof line - 1)) {
rprintf(FERROR, "rsync: did not see server greeting\n");
return -1;
}
if (sscanf(line,"@RSYNCD: %d", &remote_version) != 1) {
if (sscanf(line,"@RSYNCD: %d", &remote_protocol) != 1) {
/* note that read_line strips of \n or \r */
rprintf(FERROR, "rsync: server sent \"%s\" rather than greeting\n",
line);
return -1;
}
if (protocol_version > remote_protocol)
protocol_version = remote_protocol;
p = strchr(path,'/');
if (p) *p = 0;
io_printf(fd,"%s\n",path);
io_printf(f_out, "%s\n", path);
if (p) *p = '/';
/* Old servers may just drop the connection here,
rather than sending a proper EXIT command. Yuck. */
kludge_around_eof = remote_version < 25;
kludge_around_eof = list_only && (protocol_version < 25);
while (1) {
if (!read_line(fd, line, sizeof(line)-1)) {
if (!read_line(f_in, line, sizeof line - 1)) {
rprintf(FERROR, "rsync: didn't get server startup line\n");
return -1;
}
if (strncmp(line,"@RSYNCD: AUTHREQD ",18) == 0) {
auth_client(fd, user, line+18);
auth_client(f_out, user, line+18);
continue;
}
if (strcmp(line,"@RSYNCD: OK") == 0) break;
if (strcmp(line,"@RSYNCD: OK") == 0)
break;
if (strcmp(line,"@RSYNCD: EXIT") == 0) exit(0);
if (strcmp(line,"@RSYNCD: EXIT") == 0) {
/* This is sent by recent versions of the
* server to terminate the listing of modules.
* We don't want to go on and transfer
* anything; just exit. */
exit(0);
}
if (strncmp(line, "@ERROR", 6) == 0)
rprintf(FERROR,"%s\n", line);
else
if (strncmp(line, "@ERROR", 6) == 0) {
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);
}
}
kludge_around_eof = False;
for (i=0;i<sargc;i++) {
io_printf(fd,"%s\n", sargs[i]);
for (i = 0; i < sargc; i++) {
io_printf(f_out, "%s\n", sargs[i]);
}
io_printf(fd,"\n");
io_printf(f_out, "\n");
if (remote_version < 23) {
if (remote_version == 22 || (remote_version > 17 && !am_sender))
io_start_multiplex_in(fd);
if (protocol_version < 23) {
if (protocol_version == 22 || !am_sender)
io_start_multiplex_in();
}
return client_run(fd, fd, -1, argc, argv);
return 0;
}
static int rsync_module(int fd, int i)
static int rsync_module(int f_in, int f_out, int i)
{
int argc=0;
char *argv[MAX_ARGS];
int argc = 0;
int maxargs;
char **argv;
char **argp;
char line[MAXPATHLEN];
uid_t uid = (uid_t)-2; /* canonically "nobody" */
gid_t gid = (gid_t)-2;
char *p;
char *addr = client_addr(fd);
char *host = client_name(fd);
char *addr = client_addr(f_in);
char *host = client_name(f_in);
char *name = lp_name(i);
int use_chroot = lp_use_chroot(i);
int start_glob=0;
int start_glob = 0;
int ret;
char *request=NULL;
extern int am_sender;
extern int remote_version;
extern int am_root;
char *request = NULL;
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
rprintf(FERROR,"rsync denied on module %s from %s (%s)\n",
rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
name, host, addr);
io_printf(fd,"@ERROR: access denied to %s from %s (%s)\n",
name, host, addr);
return -1;
}
if (!claim_connection(lp_lock_file(i), lp_max_connections(i))) {
if (errno) {
rprintf(FERROR,"failed to open lock file %s : %s\n",
lp_lock_file(i), strerror(errno));
io_printf(fd,"@ERROR: failed to open lock file %s : %s\n",
lp_lock_file(i), strerror(errno));
} else {
rprintf(FERROR,"max connections (%d) reached\n",
lp_max_connections(i));
io_printf(fd,"@ERROR: max connections (%d) reached - try again later\n", lp_max_connections(i));
if (!lp_list(i))
io_printf(f_out, "@ERROR: Unknown module '%s'\n", name);
else {
io_printf(f_out,
"@ERROR: access denied to %s from %s (%s)\n",
name, host, addr);
}
return -1;
}
auth_user = auth_server(fd, i, addr, "@RSYNCD: AUTHREQD ");
if (am_daemon && am_server) {
rprintf(FLOG, "rsync allowed access on module %s from %s (%s)\n",
name, host, addr);
}
if (!claim_connection(lp_lock_file(i), lp_max_connections(i))) {
if (errno) {
rsyserr(FLOG, errno, "failed to open lock file %s",
lp_lock_file(i));
io_printf(f_out, "@ERROR: failed to open lock file %s\n",
lp_lock_file(i));
} else {
rprintf(FLOG, "max connections (%d) reached\n",
lp_max_connections(i));
io_printf(f_out, "@ERROR: max connections (%d) reached - try again later\n",
lp_max_connections(i));
}
return -1;
}
auth_user = auth_server(f_in, f_out, i, addr, "@RSYNCD: AUTHREQD ");
if (!auth_user) {
rprintf(FERROR,"auth failed on module %s from %s (%s)\n",
name, client_name(fd), client_addr(fd));
io_printf(fd,"@ERROR: auth failed on module %s\n",name);
return -1;
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;
}
module_id = i;
am_root = (getuid() == 0);
am_root = (MY_UID() == 0);
if (am_root) {
p = lp_uid(i);
if (!name_to_uid(p, &uid)) {
if (!isdigit(*p)) {
rprintf(FERROR,"Invalid uid %s\n", p);
io_printf(fd,"@ERROR: invalid uid %s\n", p);
if (!isdigit(*(unsigned char *)p)) {
rprintf(FLOG, "Invalid uid %s\n", p);
io_printf(f_out, "@ERROR: invalid uid %s\n", p);
return -1;
}
}
uid = atoi(p);
}
p = lp_gid(i);
if (!name_to_gid(p, &gid)) {
if (!isdigit(*p)) {
rprintf(FERROR,"Invalid gid %s\n", p);
io_printf(fd,"@ERROR: invalid gid %s\n", p);
if (!isdigit(*(unsigned char *)p)) {
rprintf(FLOG, "Invalid gid %s\n", p);
io_printf(f_out, "@ERROR: invalid gid %s\n", p);
return -1;
}
}
gid = atoi(p);
}
}
/* TODO: If we're not root, but the configuration requests
* that we change to some uid other than the current one, then
* log a warning. */
/* TODO: Perhaps take a list of gids, and make them into the
* supplementary groups. */
/* TODO: If we're not root, but the configuration requests
* that we change to some uid other than the current one, then
* log a warning. */
/* TODO: Perhaps take a list of gids, and make them into the
* supplementary groups. */
exclude_path_prefix = use_chroot? "" : lp_path(i);
if (*exclude_path_prefix == '/' && !exclude_path_prefix[1])
exclude_path_prefix = "";
p = lp_include_from(i);
add_exclude_file(p, 1, 1);
add_exclude_file(&server_exclude_list, p,
XFLG_FATAL_ERRORS | XFLG_DEF_INCLUDE);
p = lp_include(i);
add_include_line(p);
add_exclude(&server_exclude_list, p,
XFLG_WORD_SPLIT | XFLG_DEF_INCLUDE);
p = lp_exclude_from(i);
add_exclude_file(p, 1, 0);
add_exclude_file(&server_exclude_list, p,
XFLG_FATAL_ERRORS);
p = lp_exclude(i);
add_exclude_line(p);
add_exclude(&server_exclude_list, p, XFLG_WORD_SPLIT);
exclude_path_prefix = NULL;
log_init();
@@ -266,37 +337,27 @@ static int rsync_module(int fd, int i)
* in which case we fail.
*/
if (chroot(lp_path(i))) {
rsyserr(FERROR, errno, "chroot %s failed", lp_path(i));
io_printf(fd,"@ERROR: chroot failed\n");
rsyserr(FLOG, errno, "chroot %s failed", lp_path(i));
io_printf(f_out, "@ERROR: chroot failed\n");
return -1;
}
if (!push_dir("/", 0)) {
rsyserr(FERROR, errno, "chdir %s failed\n", lp_path(i));
io_printf(fd,"@ERROR: chdir failed\n");
if (!push_dir("/")) {
rsyserr(FLOG, errno, "chdir %s failed\n", lp_path(i));
io_printf(f_out, "@ERROR: chdir failed\n");
return -1;
}
} else {
if (!push_dir(lp_path(i), 0)) {
rsyserr(FERROR, errno, "chdir %s failed\n", lp_path(i));
io_printf(fd,"@ERROR: chdir failed\n");
if (!push_dir(lp_path(i))) {
rsyserr(FLOG, errno, "chdir %s failed\n", lp_path(i));
io_printf(f_out, "@ERROR: chdir failed\n");
return -1;
}
sanitize_paths = 1;
}
if (am_root) {
#ifdef HAVE_SETGROUPS
/* Get rid of any supplementary groups this process
* might have inheristed. */
if (setgroups(0, NULL)) {
rsyserr(FERROR, errno, "setgroups failed");
io_printf(fd, "@ERROR: setgroups failed\n");
return -1;
}
#endif
/* XXXX: You could argue that if the daemon is started
* by a non-root user and they explicitly specify a
* gid, then we should try to change to that gid --
@@ -308,81 +369,80 @@ static int rsync_module(int fd, int i)
* all their supplementary groups. */
if (setgid(gid)) {
rsyserr(FERROR, errno, "setgid %d failed", (int) gid);
io_printf(fd,"@ERROR: setgid failed\n");
rsyserr(FLOG, errno, "setgid %d failed", (int)gid);
io_printf(f_out, "@ERROR: setgid failed\n");
return -1;
}
#ifdef HAVE_SETGROUPS
/* Get rid of any supplementary groups this process
* might have inheristed. */
if (setgroups(1, &gid)) {
rsyserr(FLOG, errno, "setgroups failed");
io_printf(f_out, "@ERROR: setgroups failed\n");
return -1;
}
#endif
if (setuid(uid)) {
rsyserr(FERROR, errno, "setuid %d failed", (int) uid);
io_printf(fd,"@ERROR: setuid failed\n");
rsyserr(FLOG, errno, "setuid %d failed", (int)uid);
io_printf(f_out, "@ERROR: setuid failed\n");
return -1;
}
am_root = (getuid() == 0);
am_root = (MY_UID() == 0);
}
io_printf(fd,"@RSYNCD: OK\n");
io_printf(f_out, "@RSYNCD: OK\n");
maxargs = MAX_ARGS;
if (!(argv = new_array(char *, maxargs)))
out_of_memory("rsync_module");
argv[argc++] = "rsyncd";
while (1) {
if (!read_line(fd, line, sizeof(line)-1)) {
if (!read_line(f_in, line, sizeof line - 1))
return -1;
}
if (!*line) break;
if (!*line)
break;
p = line;
argv[argc] = strdup(p);
if (!argv[argc]) {
return -1;
if (argc == maxargs) {
maxargs += MAX_ARGS;
if (!(argv = realloc_array(argv, char *, maxargs)))
out_of_memory("rsync_module");
}
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, MAX_ARGS);
} else {
glob_expand(name, &argv, &argc, &maxargs);
} else
argc++;
}
if (strcmp(line,".") == 0) {
if (strcmp(line, ".") == 0)
start_glob = 1;
}
if (argc == MAX_ARGS) {
return -1;
}
}
if (sanitize_paths) {
/*
* Note that this is applied to all parameters, whether or not
* they are filenames, but no other legal parameters contain
* the forms that need to be sanitized so it doesn't hurt;
* it is not known at this point which parameters are files
* and which aren't.
*/
for (i = 1; i < argc; i++) {
sanitize_path(argv[i], NULL);
}
}
argp = argv;
argp = argv;
ret = parse_arguments(&argc, (const char ***) &argp, 0);
if (filesfrom_fd == 0)
filesfrom_fd = f_in;
if (request) {
if (*auth_user) {
rprintf(FINFO,"rsync %s %s from %s@%s (%s)\n",
am_sender?"on":"to",
rprintf(FLOG, "rsync %s %s from %s@%s (%s)\n",
am_sender ? "on" : "to",
request, auth_user, host, addr);
} else {
rprintf(FINFO,"rsync %s %s from %s (%s)\n",
am_sender?"on":"to",
rprintf(FLOG, "rsync %s %s from %s (%s)\n",
am_sender ? "on" : "to",
request, host, addr);
}
free(request);
@@ -390,33 +450,33 @@ static int rsync_module(int fd, int i)
#ifndef DEBUG
/* don't allow the logs to be flooded too fast */
if (verbose > 1) verbose = 1;
if (verbose > lp_max_verbosity())
verbose = lp_max_verbosity();
#endif
if (remote_version < 23) {
if (remote_version == 22 || (remote_version > 17 && am_sender))
io_start_multiplex_out(fd);
if (protocol_version < 23
&& (protocol_version == 22 || am_sender))
io_start_multiplex_out();
else if (!ret) {
/* 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. */
setup_protocol(f_out, f_in);
if (files_from && !am_sender && strcmp(files_from, "-") != 0)
write_byte(f_out, 0);
io_start_multiplex_out();
}
/* For later protocol versions, we don't start multiplexing
* until we've configured nonblocking in start_server. That
* means we're in a sticky situation now: there's no way to
* convey errors to the client. */
/* FIXME: Hold off on reporting option processing errors until
* we've set up nonblocking and multiplexed IO and can get the
* message back to them. */
if (!ret) {
option_error();
exit_cleanup(RERR_UNSUPPORTED);
option_error();
msleep(400);
exit_cleanup(RERR_UNSUPPORTED);
}
if (lp_timeout(i)) {
extern int io_timeout;
if (lp_timeout(i))
io_timeout = lp_timeout(i);
}
start_server(fd, fd, argc, argp);
start_server(f_in, f_out, argc, argp);
return 0;
}
@@ -427,137 +487,137 @@ static void send_listing(int fd)
{
int n = lp_numservices();
int i;
extern int remote_version;
for (i=0;i<n;i++)
for (i = 0; i < n; i++) {
if (lp_list(i))
io_printf(fd, "%-15s\t%s\n", lp_name(i), lp_comment(i));
io_printf(fd, "%-15s\t%s\n", lp_name(i), lp_comment(i));
}
if (remote_version >= 25)
if (protocol_version >= 25)
io_printf(fd,"@RSYNCD: EXIT\n");
}
/* this is called when a socket connection is established to a client
/* this is called when a connection is established to a client
and we want to start talking. The setup of the system is done from
here */
static int start_daemon(int fd)
int start_daemon(int f_in, int f_out)
{
char line[200];
char *motd;
int i = -1;
extern char *config_file;
extern int remote_version;
int i;
if (!lp_load(config_file, 0)) {
io_set_sock_fds(f_in, f_out);
if (!lp_load(config_file, 0))
exit_cleanup(RERR_SYNTAX);
log_init();
if (!am_server) {
set_socket_options(f_in, "SO_KEEPALIVE");
set_socket_options(f_in, lp_socket_options());
set_nonblocking(f_in);
}
set_socket_options(fd,"SO_KEEPALIVE");
set_socket_options(fd,lp_socket_options());
set_nonblocking(fd);
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
io_printf(f_out, "@RSYNCD: %d\n", protocol_version);
motd = lp_motd_file();
if (motd && *motd) {
FILE *f = fopen(motd,"r");
while (f && !feof(f)) {
int len = fread(line, 1, sizeof(line)-1, f);
int len = fread(line, 1, sizeof line - 1, f);
if (len > 0) {
line[len] = 0;
io_printf(fd,"%s", line);
io_printf(f_out, "%s", line);
}
}
if (f) fclose(f);
io_printf(fd,"\n");
if (f)
fclose(f);
io_printf(f_out, "\n");
}
if (!read_line(fd, line, sizeof(line)-1)) {
if (!read_line(f_in, line, sizeof line - 1))
return -1;
if (sscanf(line,"@RSYNCD: %d", &remote_protocol) != 1) {
io_printf(f_out, "@ERROR: protocol startup error\n");
return -1;
}
if (protocol_version > remote_protocol)
protocol_version = remote_protocol;
line[0] = 0;
if (!read_line(f_in, line, sizeof line - 1))
return -1;
if (!*line || strcmp(line, "#list") == 0) {
send_listing(f_out);
return -1;
}
if (sscanf(line,"@RSYNCD: %d", &remote_version) != 1) {
io_printf(fd,"@ERROR: protocol startup error\n");
if (*line == '#') {
/* it's some sort of command that I don't understand */
io_printf(f_out, "@ERROR: Unknown command '%s'\n", line);
return -1;
}
while (i == -1) {
line[0] = 0;
if (!read_line(fd, line, sizeof(line)-1)) {
return -1;
}
if (!*line || strcmp(line,"#list")==0) {
send_listing(fd);
return -1;
}
if (*line == '#') {
/* it's some sort of command that I don't understand */
io_printf(fd,"@ERROR: Unknown command '%s'\n", line);
return -1;
}
i = lp_number(line);
if (i == -1) {
io_printf(fd,"@ERROR: Unknown module '%s'\n", line);
return -1;
}
}
return rsync_module(fd, i);
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);
}
int daemon_main(void)
{
extern char *config_file;
extern int orig_umask;
char *pid_file;
extern int no_detach;
if (is_a_socket(STDIN_FILENO)) {
int i;
/* we are running via inetd - close off stdout and
stderr so that library functions (and getopt) don't
try to use them. Redirect them to /dev/null */
for (i=1;i<3;i++) {
close(i);
* stderr so that library functions (and getopt) don't
* try to use them. Redirect them to /dev/null */
for (i = 1; i < 3; i++) {
close(i);
open("/dev/null", O_RDWR);
}
return start_daemon(STDIN_FILENO);
return start_daemon(STDIN_FILENO, STDIN_FILENO);
}
if (!no_detach)
become_daemon();
become_daemon();
if (!lp_load(config_file, 1)) {
if (!lp_load(config_file, 1))
exit_cleanup(RERR_SYNTAX);
}
log_init();
rprintf(FINFO, "rsyncd version %s starting, listening on port %d\n",
RSYNC_VERSION,
rsync_port);
/* TODO: If listening on a particular address, then show that
* address too. In fact, why not just do inet_ntop on the
* local address??? */
rprintf(FLOG, "rsyncd version %s starting, listening on port %d\n",
RSYNC_VERSION, rsync_port);
/* TODO: If listening on a particular address, then show that
* address too. In fact, why not just do inet_ntop on the
* local address??? */
if (((pid_file = lp_pid_file()) != NULL) && (*pid_file != '\0')) {
char pidbuf[16];
int fd;
int pid = (int) getpid();
pid_t pid = getpid();
cleanup_set_pid(pid);
if ((fd = do_open(lp_pid_file(), O_WRONLY|O_CREAT|O_TRUNC,
0666 & ~orig_umask)) == -1) {
cleanup_set_pid(0);
rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
exit_cleanup(RERR_FILEIO);
cleanup_set_pid(0);
rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
exit_cleanup(RERR_FILEIO);
}
snprintf(pidbuf, sizeof(pidbuf), "%d\n", pid);
snprintf(pidbuf, sizeof pidbuf, "%ld\n", (long)pid);
write(fd, pidbuf, strlen(pidbuf));
close(fd);
}
@@ -565,4 +625,3 @@ int daemon_main(void)
start_accept_loop(rsync_port, start_daemon);
return -1;
}

View File

@@ -17,59 +17,68 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* compatability routines for older rsync protocol versions */
/**
* @file compat.c
*
* Compatibility routines for older rsync protocol versions.
**/
#include "rsync.h"
extern int am_server;
int remote_protocol = 0;
extern int preserve_links;
extern int preserve_perms;
extern int preserve_devices;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_times;
extern int always_checksum;
extern int checksum_seed;
extern int remote_version;
extern int verbose;
extern int read_batch; /* dw */
extern int write_batch; /* dw */
extern int am_server;
extern int am_sender;
extern int read_batch;
extern int checksum_seed;
extern int protocol_version;
void setup_protocol(int f_out,int f_in)
{
if (remote_version == 0) {
if (am_server) {
remote_version = read_int(f_in);
write_int(f_out,PROTOCOL_VERSION);
} else {
write_int(f_out,PROTOCOL_VERSION);
remote_version = read_int(f_in);
}
if (remote_protocol == 0) {
if (!read_batch)
write_int(f_out, protocol_version);
remote_protocol = read_int(f_in);
if (protocol_version > remote_protocol)
protocol_version = remote_protocol;
}
if (read_batch && remote_protocol > protocol_version) {
rprintf(FERROR, "The protocol version in the batch file is too new (%d > %d).\n",
remote_protocol, protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
if (remote_version < MIN_PROTOCOL_VERSION ||
remote_version > MAX_PROTOCOL_VERSION) {
if (verbose > 3) {
rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
am_server? "Server" : "Client", remote_protocol, protocol_version);
}
if (remote_protocol < MIN_PROTOCOL_VERSION
|| remote_protocol > MAX_PROTOCOL_VERSION) {
rprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
rprintf(FERROR,"(see the rsync man page for an explanation)\n");
exit_cleanup(RERR_PROTOCOL);
}
if (remote_version >= 12) {
if (am_server) {
if (read_batch || write_batch) /* dw */
checksum_seed = 32761;
else
checksum_seed = time(NULL);
write_int(f_out,checksum_seed);
} else {
checksum_seed = read_int(f_in);
}
}
checksum_init();
}
if (remote_protocol < OLD_PROTOCOL_VERSION) {
rprintf(FINFO,"%s is very old version of rsync, upgrade recommended.\n",
am_server? "Client" : "Server");
}
if (protocol_version < MIN_PROTOCOL_VERSION) {
rprintf(FERROR, "--protocol must be at least %d on the %s.\n",
MIN_PROTOCOL_VERSION, am_server? "Server" : "Client");
exit_cleanup(RERR_PROTOCOL);
}
if (protocol_version > PROTOCOL_VERSION) {
rprintf(FERROR, "--protocol must be no more than %d on the %s.\n",
PROTOCOL_VERSION, am_server? "Server" : "Client");
exit_cleanup(RERR_PROTOCOL);
}
if (am_server) {
if (!checksum_seed)
checksum_seed = time(NULL);
write_int(f_out, checksum_seed);
} else {
checksum_seed = read_int(f_in);
}
}

553
config.guess vendored
View File

@@ -1,9 +1,9 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2001-07-19'
timestamp='2003-10-03'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -24,8 +24,9 @@ timestamp='2001-07-19'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Written by Per Bothner <bothner@cygnus.com>.
# Please send patches to <config-patches@gnu.org>.
# Originally written by Per Bothner <per@bothner.com>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -87,30 +88,42 @@ if test $# != 0; then
exit 1
fi
trap 'exit 1' 1 2 15
dummy=dummy-$$
trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# CC_FOR_BUILD -- compiler used by this script.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int dummy(){}" > $dummy.c ;
for c in cc gcc c89 ; do
($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
if test $? = 0 ; then
# Portable tmp directory creation inspired by the Autoconf team.
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int x;" > $dummy.c ;
for c in cc gcc c89 c99 ; do
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
rm -f $dummy.c $dummy.o $dummy.rel ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac'
esac ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
@@ -127,29 +140,30 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# Netbsd (nbsd) targets should (where applicable) match one or
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
# Determine the machine/vendor (is the vendor relevant).
case "${UNAME_MACHINE}" in
amiga) machine=m68k-unknown ;;
arm32) machine=arm-unknown ;;
atari*) machine=m68k-atari ;;
sun3*) machine=m68k-sun ;;
mac68k) machine=m68k-apple ;;
macppc) machine=powerpc-apple ;;
hp3[0-9][05]) machine=m68k-hp ;;
ibmrt|romp-ibm) machine=romp-ibm ;;
*) machine=${UNAME_MACHINE}-unknown ;;
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE}" in
i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
@@ -166,72 +180,112 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
;;
esac
# The OS release
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
case "${UNAME_VERSION}" in
Debian*)
release='-gnu'
;;
*)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
macppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvmeppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
pmax:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sgi:OpenBSD:*:*)
echo mipseb-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
fi
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
UNAME_MACHINE="alpha" ;;
"EV4.5 (21064)")
UNAME_MACHINE="alpha" ;;
"LCA4 (21066/21068)")
UNAME_MACHINE="alpha" ;;
"EV5 (21164)")
UNAME_MACHINE="alphaev5" ;;
"EV5.6 (21164A)")
UNAME_MACHINE="alphaev56" ;;
"EV5.6 (21164PC)")
UNAME_MACHINE="alphapca56" ;;
"EV5.7 (21164PC)")
UNAME_MACHINE="alphapca57" ;;
"EV6 (21264)")
UNAME_MACHINE="alphaev6" ;;
"EV6.7 (21264A)")
UNAME_MACHINE="alphaev67" ;;
"EV6.8CB (21264C)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8AL (21264B)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8CX (21264D)")
UNAME_MACHINE="alphaev68" ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE="alphaev69" ;;
"EV7 (21364)")
UNAME_MACHINE="alphaev7" ;;
"EV7.9 (21364A)")
UNAME_MACHINE="alphaev79" ;;
esac
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
cat <<EOF >$dummy.s
.data
\$Lformat:
.byte 37,100,45,37,120,10,0 # "%d-%x\n"
.text
.globl main
.align 4
.ent main
main:
.frame \$30,16,\$26,0
ldgp \$29,0(\$27)
.prologue 1
.long 0x47e03d80 # implver \$0
lda \$2,-1
.long 0x47e20c21 # amask \$2,\$1
lda \$16,\$Lformat
mov \$0,\$17
not \$1,\$18
jsr \$26,printf
ldgp \$29,0(\$26)
mov 0,\$16
jsr \$26,exit
.end main
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
case `./$dummy` in
0-0)
UNAME_MACHINE="alpha"
;;
1-0)
UNAME_MACHINE="alphaev5"
;;
1-1)
UNAME_MACHINE="alphaev56"
;;
1-101)
UNAME_MACHINE="alphapca56"
;;
2-303)
UNAME_MACHINE="alphaev6"
;;
2-307)
UNAME_MACHINE="alphaev67"
;;
esac
fi
rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit 0 ;;
Alpha*:OpenVMS:*:*)
echo alpha-hp-vms
exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -244,29 +298,11 @@ EOF
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit 0;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
arc64:OpenBSD:*:*)
echo mips64el-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
hkmips:OpenBSD:*:*)
echo mips-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
pmax:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sgi:OpenBSD:*:*)
echo mips-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
@@ -288,6 +324,13 @@ EOF
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
DRS?6000:unix:4.0:6*)
echo sparc-icl-nx6
exit 0 ;;
DRS?6000:UNIX_SV:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7 && exit 0 ;;
esac ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
@@ -316,7 +359,7 @@ EOF
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
@@ -330,9 +373,6 @@ EOF
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
@@ -359,18 +399,6 @@ EOF
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
@@ -387,6 +415,7 @@ EOF
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
@@ -408,16 +437,20 @@ EOF
exit (-1);
}
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy \
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
$CC_FOR_BUILD -o $dummy $dummy.c \
&& $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& exit 0
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit 0 ;;
Motorola:*:4.3:PL8-*)
echo powerpc-harris-powermax
exit 0 ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
echo powerpc-harris-powermax
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
@@ -478,6 +511,7 @@ EOF
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
@@ -489,9 +523,7 @@ EOF
exit(0);
}
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
@@ -500,7 +532,7 @@ EOF
fi
exit 0 ;;
*:AIX:*:[45])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
@@ -540,10 +572,8 @@ EOF
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
case "${HPUX_REV}" in
11.[0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
@@ -552,12 +582,13 @@ EOF
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
fi ;;
esac
if [ "${HP_ARCH}" = "" ]; then
sed 's/^ //' << EOF >$dummy.c
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
@@ -590,12 +621,21 @@ EOF
exit (0);
}
EOF
eval $set_cc_for_build
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
rm -f $dummy.c $dummy
fi ;;
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
# avoid double evaluation of $set_cc_for_build
test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
then
HP_ARCH="hppa2.0w"
else
HP_ARCH="hppa64"
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
ia64:HP-UX:*:*)
@@ -603,6 +643,7 @@ EOF
echo ia64-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
@@ -628,9 +669,7 @@ EOF
exit (0);
}
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
@@ -658,9 +697,6 @@ EOF
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
hppa*:OpenBSD:*:*)
echo hppa-unknown-openbsd
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
@@ -679,9 +715,6 @@ EOF
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
@@ -694,27 +727,21 @@ EOF
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*T3D:*:*:*)
echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
*:UNICOS/mp:*:*)
echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
@@ -724,11 +751,22 @@ EOF
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
*:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
# Determine whether the default compiler uses glibc.
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#if __GLIBC__ >= 2
LIBC=gnu
#else
LIBC=
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
# GNU/FreeBSD systems have a "k" prefix to indicate we are using
# FreeBSD's kernel, but not the complete OS.
case ${LIBC} in gnu) kernel_only='k' ;; esac
echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
@@ -739,11 +777,17 @@ EOF
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit 0 ;;
x86:Interix*:[34]*)
echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
exit 0 ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit 0 ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i386-pc-interix
echo i586-pc-interix
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
@@ -763,17 +807,52 @@ EOF
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
cris:Linux:*:*)
echo cris-axis-linux-gnu
exit 0 ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
mips:Linux:*:*)
case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
big) echo mips-unknown-linux-gnu && exit 0 ;;
little) echo mipsel-unknown-linux-gnu && exit 0 ;;
esac
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips
#undef mipsel
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mipsel
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
;;
mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips64
#undef mips64el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mips64el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips64
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
@@ -789,7 +868,7 @@ EOF
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
@@ -809,6 +888,9 @@ EOF
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit 0 ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
@@ -822,7 +904,8 @@ EOF
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
ld_supported_targets=`cd /; ld --help 2>&1 \
# Set LC_ALL=C to ensure ld outputs messages in English.
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
@@ -834,7 +917,7 @@ EOF
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0 ;;
exit 0 ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0 ;;
@@ -845,33 +928,32 @@ EOF
exit 0 ;;
esac
# Determine whether the default compiler is a.out or elf
cat >$dummy.c <<EOF
#include <features.h>
#ifdef __cplusplus
#include <stdio.h> /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
printf ("%s-pc-linux-gnu\n", argv[1]);
# else
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
# endif
# else
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
# endif
#else
printf ("%s-pc-linux-gnuaout\n", argv[1]);
#endif
return 0;
}
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
sed 's/^ //' << EOF >$dummy.c
#include <features.h>
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
LIBC=gnu
# else
LIBC=gnulibc1
# endif
# else
LIBC=gnulibc1
# endif
#else
#ifdef __INTEL_COMPILER
LIBC=gnu
#else
LIBC=gnuaout
#endif
#endif
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
;;
i*86:DYNIX/ptx:4*:*)
@@ -888,6 +970,23 @@ EOF
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit 0 ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit 0 ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit 0 ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit 0 ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
@@ -909,22 +1008,19 @@ EOF
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit 0 ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -948,9 +1044,15 @@ EOF
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
mc68k:UNIX:SYSTEM5:3.51m)
echo m68k-convergent-sysv
exit 0 ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
@@ -967,9 +1069,6 @@ EOF
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
@@ -996,8 +1095,8 @@ EOF
echo ns32k-sni-sysv
fi
exit 0 ;;
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
@@ -1009,6 +1108,10 @@ EOF
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
@@ -1037,6 +1140,9 @@ EOF
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit 0 ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit 0 ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
@@ -1044,18 +1150,24 @@ EOF
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Darwin:*:*)
echo `uname -p`-apple-darwin${UNAME_RELEASE}
case `uname -p` in
*86) UNAME_PROCESSOR=i686 ;;
powerpc) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit 0 ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
if test "${UNAME_MACHINE}" = "x86pc"; then
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo `uname -p`-${UNAME_MACHINE}-nto-qnx
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit 0 ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
NSR-[KW]:NONSTOP_KERNEL:*:*)
NSR-[DGKLNPTVWY]:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
@@ -1078,11 +1190,6 @@ EOF
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit 0 ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit 0 ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit 0 ;;
@@ -1101,11 +1208,15 @@ EOF
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
@@ -1220,9 +1331,7 @@ main ()
}
EOF
eval $set_cc_for_build
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
# Apollos put the system type in the environment.

365
config.sub vendored
View File

@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2001-06-08'
timestamp='2003-08-18'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -29,7 +29,8 @@ timestamp='2001-06-08'
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to <config-patches@gnu.org>.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -117,7 +118,7 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
nto-qnx* | linux-gnu* | linux-dietlibc | kfreebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -223,26 +224,50 @@ esac
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
| arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
| pyramid | mn10200 | mn10300 | tron | a29k \
| 580 | i960 | h8300 \
| x86 | ppcbe | mipsbe | mipsle | shbe | shle \
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
| hppa64 \
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
| alphaev6[78] \
| we32k | ns16k | clipper | i370 | sh | sh[34] \
| powerpc | powerpcle \
| 1750a | dsp16xx | pdp10 | pdp11 \
| mips16 | mips64 | mipsel | mips64el \
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
| mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
| sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
| v850 | c4x \
| thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
| pj | pjl | h8500 | z8k)
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| msp430 \
| ns16k | ns32k \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@@ -265,31 +290,61 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
# FIXME: clean up the formatting here.
vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
| arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
| xmp-* | ymp-* \
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
| hppa2.0n-* | hppa64-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
| alphaev6[78]-* \
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
| clipper-* | orion-* \
| sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
| powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
| mips16-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
| mipstx39-* | mipstx39el-* | mcore-* \
| f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
| [cjt]90-* \
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
| thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
| bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| msp430-* \
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -321,6 +376,9 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -352,6 +410,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -372,16 +434,8 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
cray2)
basic_machine=cray2-cray
os=-unicos
;;
[cjt]90)
basic_machine=${basic_machine}-cray
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
crds | unos)
@@ -396,6 +450,14 @@ case $basic_machine in
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
@@ -576,14 +638,6 @@ case $basic_machine in
basic_machine=m68k-atari
os=-mint
;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux-gnu
;;
mips*-linux*)
basic_machine=mips-unknown
os=-linux-gnu
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
@@ -598,6 +652,10 @@ case $basic_machine in
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -670,6 +728,10 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
nv1)
basic_machine=nv1-cray
os=-unicosmp
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -677,6 +739,10 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@@ -699,42 +765,58 @@ case $basic_machine in
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen)
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon)
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2)
pentiumii | pentium2 | pentiumiii | pentium3)
basic_machine=i686-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
@@ -752,10 +834,26 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
@@ -763,7 +861,10 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs)
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -830,19 +931,35 @@ case $basic_machine in
os=-dynix
;;
t3e)
basic_machine=t3e-cray
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -867,8 +984,8 @@ case $basic_machine in
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -889,17 +1006,13 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
windows32)
basic_machine=i386-pc
os=-windows32-msvcrt
;;
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@@ -920,13 +1033,6 @@ case $basic_machine in
op60c)
basic_machine=hppa1.1-oki
;;
mips)
if [ x$os = x-linux-gnu ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;;
romp)
basic_machine=romp-ibm
;;
@@ -946,13 +1052,16 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh3 | sh4)
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -967,10 +1076,6 @@ case $basic_machine in
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
c4x*)
basic_machine=c4x-none
os=-coff
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
@@ -1026,16 +1131,19 @@ case $os in
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1047,8 +1155,10 @@ case $os in
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=-nto-qnx
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
@@ -1057,6 +1167,9 @@ case $os in
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
@@ -1087,14 +1200,20 @@ case $os in
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
os=-nextstep2
;;
-nsk*)
os=-nsk
@@ -1133,8 +1252,14 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-none)
;;
@@ -1167,10 +1292,14 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1197,6 +1326,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@@ -1260,19 +1392,19 @@ case $basic_machine in
*-next)
os=-nextstep3
;;
*-gould)
*-gould)
os=-sysv
;;
*-highlevel)
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
*-sgi)
os=-irix
;;
*-siemens)
*-siemens)
os=-sysv4
;;
*-masscomp)
@@ -1344,7 +1476,7 @@ case $basic_machine in
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks*)
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
@@ -1359,6 +1491,9 @@ case $basic_machine in
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;

View File

@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.52)
RSYNC_VERSION=2.5.4
RSYNC_VERSION=2.6.3pre2
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -18,6 +18,7 @@ AC_CANONICAL_TARGET([])
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_EGREP
AC_PROG_INSTALL
AC_PROG_CC_STDC
AC_SUBST(SHELL)
@@ -25,7 +26,7 @@ AC_SUBST(SHELL)
AC_DEFINE([_GNU_SOURCE], 1,
[Define _GNU_SOURCE so that we get all necessary prototypes])
if test "$xac_cv_prog_cc_stdc" = xno
if test "x$ac_cv_prog_cc_stdc" = xno
then
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
fi
@@ -65,6 +66,17 @@ then
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
CFLAGS="$CFLAGS -DMAINTAINER_MODE"
fi
# This is needed for our included version of popt. Kind of silly, but
# I don't want our version too far out of sync.
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
@@ -79,14 +91,35 @@ AC_ARG_WITH(included-popt,
[ --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\")],
[ --with-rsync-path=PATH set default --rsync-path to PATH (default: rsync)],
[ RSYNC_PATH="$with_rsync_path" ],
[ RSYNC_PATH="rsync" ])
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
AC_ARG_WITH(rsyncd-conf,
AC_HELP_STRING([--with-rsyncd-conf=PATH], [set configuration file for rsync server to PATH (default: /etc/rsyncd.conf)]),
[ if test ! -z "$with_rsyncd_conf" ; then
case $with_rsyncd_conf in
yes|no)
RSYNCD_SYSCONF="/etc/rsyncd.conf"
;;
/*)
RSYNCD_SYSCONF="$with_rsyncd_conf"
;;
*)
AC_MSG_ERROR(You must specify an absolute path to --with-rsyncd-conf=PATH)
;;
esac
else
RSYNCD_SYSCONF="/etc/rsyncd.conf"
fi ],
[ RSYNCD_SYSCONF="/etc/rsyncd.conf" ])
AC_DEFINE_UNQUOTED(RSYNCD_SYSCONF, "$RSYNCD_SYSCONF", [location of configuration file for rsync server])
AC_ARG_WITH(rsh,
AC_HELP_STRING([--with-rsh=CMD], [set rsh command to CMD (default: \"remsh\" or \"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])
@@ -94,11 +127,8 @@ AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [remote shell is remsh not rsh])
if test x"$with_rsh" != x
then
RSYNC_RSH="$with_rsh"
elif test x"$HAVE_REMSH" = x1
then
RSYNC_RSH="remsh"
else
RSYNC_RSH="rsh"
RSYNC_RSH="ssh"
fi
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
@@ -113,24 +143,29 @@ AC_TRY_RUN([
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
int main(void)
{
struct flock lock;
int status;
int fd = open("conftest.dat", O_CREAT|O_RDWR, 0600);
int status;
char tpl[32] = "/tmp/locktest.XXXXXX";
int fd = mkstemp(tpl);
if (fd < 0) {
strcpy(tpl, "conftest.dat");
fd = open(tpl, O_CREAT|O_RDWR, 0600);
}
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 1;
lock.l_pid = 0;
fcntl(fd,F_SETLK,&lock);
if (fork() == 0) {
lock.l_start = 1;
exit(fcntl(fd,F_SETLK,&lock) == 0);
}
wait(&status);
unlink("conftest.dat");
lock.l_start = 1;
_exit(fcntl(fd,F_SETLK,&lock) == 0);
}
wait(&status);
unlink(tpl);
exit(WEXITSTATUS(status));
}
],
@@ -143,7 +178,7 @@ ipv6type=unknown
ipv6lib=none
ipv6trylibc=yes
AC_ARG_ENABLE(ipv6,
AC_ARG_ENABLE(ipv6,
AC_HELP_STRING([--disable-ipv6], [don't even try to use IPv6]))
if test "x$enable_ipv6" != xno
@@ -169,7 +204,7 @@ yes
#ifdef __KAME__
yes
#endif],
[ipv6type=$i;
[ipv6type=$i;
AC_DEFINE(INET6, 1, [true if you have IPv6])])
;;
linux-glibc)
@@ -236,16 +271,25 @@ yes
AC_SEARCH_LIBS(getaddrinfo, inet6)
fi
AC_MSG_CHECKING([whether to call shutdown on all sockets])
case $host_os in
*cygwin* ) AC_MSG_RESULT(yes)
AC_DEFINE(SHUTDOWN_ALL_SOCKETS, 1,
[Define if sockets need to be shutdown])
;;
* ) AC_MSG_RESULT(no);;
esac
AC_C_BIGENDIAN
AC_HEADER_DIRENT
AC_HEADER_TIME
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)
AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h)
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h)
AC_CHECK_HEADERS(glob.h alloca.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
AC_CHECK_HEADERS(netdb.h)
AC_CHECK_HEADERS(malloc.h)
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)
AC_HEADER_MAJOR
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
@@ -300,7 +344,7 @@ if test x"$ac_cv_func_connect" = x"no"; then
esac
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
dnl has been cached.
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
# ac_cv_func_connect=yes
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
@@ -312,29 +356,77 @@ AC_CHECK_LIB(resolv, inet_ntop)
dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
AC_CHECK_FUNCS(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
AC_CHECK_FUNCS(inet_pton, , AC_LIBOBJ(lib/inet_pton))
AC_CHECK_FUNCS(inet_ntop, , [AC_LIBOBJ(lib/inet_ntop)])
AC_CHECK_FUNCS(inet_pton, , [AC_LIBOBJ(lib/inet_pton)])
AC_CHECK_FUNCS(getaddrinfo, , AC_LIBOBJ(lib/getaddrinfo))
AC_CHECK_FUNCS(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
# Irix 6.5 has getaddrinfo but not the corresponding defines, so use
# builtin getaddrinfo if one of the defines don't exist
AC_CACHE_CHECK([whether defines needed by getaddrinfo exist],
rsync_cv_HAVE_GETADDR_DEFINES,[
AC_EGREP_CPP(yes, [
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#ifdef AI_PASSIVE
yes
#endif],
rsync_cv_HAVE_GETADDR_DEFINES=yes,
rsync_cv_HAVE_GETADDR_DEFINES=no)])
if test x"$rsync_cv_HAVE_GETADDR_DEFINES" = x"yes"; then
# Tru64 UNIX has getaddrinfo() but has it renamed in libc as
# something else so we must include <netdb.h> to get the
# redefinition.
AC_CHECK_FUNCS(getaddrinfo, ,
[AC_MSG_CHECKING([for getaddrinfo by including <netdb.h>])
AC_TRY_LINK([#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>],[getaddrinfo(NULL, NULL, NULL, NULL);],
[AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_GETADDRINFO, 1,
[Define if you have the `getaddrinfo' function.])],
[AC_MSG_RESULT([no])
AC_LIBOBJ(lib/getaddrinfo)])])
AC_CHECK_FUNCS(getnameinfo, , [AC_LIBOBJ(lib/getnameinfo)])
else
AC_LIBOBJ(lib/getaddrinfo)
AC_LIBOBJ(lib/getnameinfo)
fi
AC_CHECK_MEMBER([struct sockaddr.sa_len],
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
AC_CHECK_MEMBER([struct sockaddr.sa_len],
[ AC_DEFINE(HAVE_SOCKADDR_LEN, 1, [Do we have sockaddr.sa_len?]) ],
[],
[
#include <sys/types.h>
#include <sys/socket.h>
])
AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
[ AC_DEFINE(HAVE_SOCKADDR_IN_LEN, 1, [Do we have sockaddr_in.sin_len?]) ],
[],
[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
])
AC_MSG_CHECKING(struct sockaddr_storage)
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/socket.h>],
[struct sockaddr_storage x;],
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1,
AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1,
[Define if you have strct sockaddr_storage.] ),
AC_MSG_RESULT(no))
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_scope_id],
[ AC_DEFINE(HAVE_SOCKADDR_IN6_SCOPE_ID, 1, [Do we have sockaddr_in6.sin6_scope_id?]) ],
[],
[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
])
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
#
AC_CHECK_FUNCS(strcasecmp)
@@ -344,14 +436,16 @@ fi
dnl At the moment we don't test for a broken memcmp(), because all we
dnl need to do is test for equality, not comparison, and it seems that
dnl every platform has a memcmp that can do at least that.
dnl every platform has a memcmp that can do at least that.
dnl AC_FUNC_MEMCMP
AC_FUNC_UTIME_NULL
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
AC_CHECK_FUNCS(strlcat strlcpy mtrace mallinfo setgroups)
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 \
memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk \
strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
open64 mkstemp64)
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
AC_TRY_RUN([
@@ -367,15 +461,6 @@ if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
AC_DEFINE(HAVE_SOCKETPAIR, 1, [ ])
fi
AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[
AC_TRY_RUN([#include <fnmatch.h>
main() { exit((fnmatch("*.o", "x.o", FNM_PATHNAME) == 0 &&
fnmatch("a/b/*", "a/b/c/d", FNM_PATHNAME) != 0) ? 0: 1); }],
rsync_cv_HAVE_FNMATCH=yes,rsync_cv_HAVE_FNMATCH=no,rsync_cv_HAVE_FNMATCH=cross)])
if test x"$rsync_cv_HAVE_FNMATCH" = x"yes"; then
AC_DEFINE(HAVE_FNMATCH, 1, [ ])
fi
if test x"$with_included_popt" != x"yes"
then
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
@@ -387,6 +472,12 @@ then
AC_MSG_RESULT($srcdir/popt)
BUILD_POPT='$(popt_OBJS)'
CFLAGS="$CFLAGS -I$srcdir/popt"
if test x"$ALLOCA" != x
then
# this can be removed when/if we add an included alloca.c;
# see autoconf documentation on AC_FUNC_ALLOCA
AC_MSG_WARN([included libpopt will use malloc, not alloca (which wastes a small amount of memory)])
fi
else
AC_MSG_RESULT(no)
fi
@@ -460,7 +551,7 @@ AC_CACHE_CHECK([for C99 vsnprintf],rsync_cv_HAVE_C99_VSNPRINTF,[
AC_TRY_RUN([
#include <sys/types.h>
#include <stdarg.h>
void foo(const char *format, ...) {
void foo(const char *format, ...) {
va_list ap;
int len;
char buf[5];
@@ -487,10 +578,10 @@ AC_TRY_RUN([#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
main() {
main() {
struct stat st;
char tpl[20]="/tmp/test.XXXXXX";
int fd = mkstemp(tpl);
char tpl[20]="/tmp/test.XXXXXX";
int fd = mkstemp(tpl);
if (fd == -1) exit(1);
unlink(tpl);
if (fstat(fd, &st) != 0) exit(1);
@@ -513,7 +604,7 @@ AC_TRY_RUN([
#include <arpa/inet.h>
main() { struct in_addr ip; ip.s_addr = 0x12345678;
if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(1); }
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(1); }
exit(0);}],
rsync_cv_REPLACE_INET_NTOA=no,rsync_cv_REPLACE_INET_NTOA=yes,rsync_cv_REPLACE_INET_NTOA=cross)])
if test x"$rsync_cv_REPLACE_INET_NTOA" = x"yes"; then
@@ -527,7 +618,7 @@ AC_TRY_RUN([
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
main() { struct in_addr ip;
main() { struct in_addr ip;
if (inet_aton("example", &ip) == 0) exit(0); exit(1);}],
rsync_cv_REPLACE_INET_ATON=no,rsync_cv_REPLACE_INET_ATON=yes,rsync_cv_REPLACE_INET_ATON=cross)])
if test x"$rsync_cv_REPLACE_INET_ATON" = x"yes"; then
@@ -568,6 +659,21 @@ 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()

2
doc/.cvsignore Normal file
View File

@@ -0,0 +1,2 @@
rsync.pdf
rsync.ps

View File

@@ -253,10 +253,27 @@ running rsync giving the network directory.
</qandaentry>
<qandaentry>
<question>
<para>
Why is rsync so much bigger when I build it with
<command>gcc</command>?
</para>
</question>
<answer>
<para>
On gcc, rsync builds by default with debug symbols
included. If you strip both executables, they should end
up about the same size. (Use <command>make
install-strip</command>.)
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
Is rsync useful for a single large file like an ISO image?
<para>Is rsync useful for a single large file like an ISO image?</para>
</question>
<answer>
<para>
@@ -319,12 +336,16 @@ running rsync giving the network directory.
This answer, formatted with "real" bullets, can be found at:
-[4]http://twiki.org/cgi-bin/view/Wikilearn/RsyncingALargeFileFAQ*
Note: I modified this on Oct. 9. 2001 -- I marked the changes with asterisks. The only deletion
without a corresponding correction was the deletion of an "(IIRC)".
2001-Oct-09 7:47am rhkramerATfastDOTnet
</para>
</answer>
</qandaentry>
</qandaset>
</chapter>
<appendix>
<title>Other Resources</title>
<para><ulink url="http://www.ccp14.ac.uk/ccp14admin/rsync/"></ulink></para>
</appendix>
</book>

View File

@@ -19,13 +19,14 @@
/*
* error codes returned by rsync. If you change these, please also update the
* string mappings in log.c
* string mappings in log.c and the EXIT VALUES in rsync.yo
*/
#define RERR_OK 0
#define RERR_SYNTAX 1 /* syntax or usage error */
#define RERR_PROTOCOL 2 /* protocol incompatibility */
#define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */
#define RERR_UNSUPPORTED 4 /* requested action not supported */
#define RERR_UNSUPPORTED 4 /* requested action not supported */
#define RERR_STARTCLIENT 5 /* error starting client-server protocol */
#define RERR_SOCKETIO 10 /* error in socket IO */
@@ -38,6 +39,7 @@
#define RERR_WAITCHILD 21 /* some error returned by waitpid() */
#define RERR_MALLOC 22 /* error allocating core memory buffers */
#define RERR_PARTIAL 23 /* partial transfer */
#define RERR_VANISHED 24 /* file(s) vanished on sender side */
#define RERR_TIMEOUT 30 /* timeout in data send/receive */

655
exclude.c
View File

@@ -1,22 +1,23 @@
/* -*- c-file-style: "linux" -*-
Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 1996 by Paul Mackerras
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*
* Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
* Copyright (C) 1996 by Paul Mackerras
* Copyright (C) 2002 by Martin Pool
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* a lot of this stuff was originally derived from GNU tar, although
it has now changed so much that it is hard to tell :) */
@@ -26,96 +27,164 @@
#include "rsync.h"
extern int verbose;
extern int delete_mode;
extern int eol_nulls;
extern int list_only;
extern int recurse;
static struct exclude_struct **exclude_list;
extern char curr_dir[];
/* build an exclude structure given a exclude pattern */
static struct exclude_struct *make_exclude(const char *pattern, int include)
struct exclude_list_struct exclude_list = { 0, 0, "" };
struct exclude_list_struct local_exclude_list = { 0, 0, "per-dir .cvsignore " };
struct exclude_list_struct server_exclude_list = { 0, 0, "server " };
char *exclude_path_prefix = NULL;
/** Build an exclude structure given an exclude pattern. */
static void make_exclude(struct exclude_list_struct *listp, const char *pat,
unsigned int pat_len, unsigned int mflags)
{
struct exclude_struct *ret;
const char *cp;
unsigned int ex_len;
ret = (struct exclude_struct *)malloc(sizeof(*ret));
if (!ret) out_of_memory("make_exclude");
ret = new(struct exclude_struct);
if (!ret)
out_of_memory("make_exclude");
memset(ret, 0, sizeof(*ret));
memset(ret, 0, sizeof ret[0]);
if (strncmp(pattern,"- ",2) == 0) {
pattern += 2;
} else if (strncmp(pattern,"+ ",2) == 0) {
ret->include = 1;
pattern += 2;
} else {
ret->include = include;
if (exclude_path_prefix)
mflags |= MATCHFLG_ABS_PATH;
if (exclude_path_prefix && *pat == '/')
ex_len = strlen(exclude_path_prefix);
else
ex_len = 0;
ret->pattern = new_array(char, ex_len + pat_len + 1);
if (!ret->pattern)
out_of_memory("make_exclude");
if (ex_len)
memcpy(ret->pattern, exclude_path_prefix, ex_len);
strlcpy(ret->pattern + ex_len, pat, pat_len + 1);
pat_len += ex_len;
if (strpbrk(ret->pattern, "*[?")) {
mflags |= MATCHFLG_WILD;
if ((cp = strstr(ret->pattern, "**")) != NULL) {
mflags |= MATCHFLG_WILD2;
/* If the pattern starts with **, note that. */
if (cp == ret->pattern)
mflags |= MATCHFLG_WILD2_PREFIX;
}
}
ret->pattern = strdup(pattern);
if (!ret->pattern) out_of_memory("make_exclude");
if (strpbrk(pattern, "*[?")) {
ret->regular_exp = 1;
ret->fnmatch_flags = FNM_PATHNAME;
if (strstr(pattern, "**")) {
static int tested;
if (!tested) {
tested = 1;
if (fnmatch("a/b/*", "a/b/c/d", FNM_PATHNAME)==0) {
rprintf(FERROR,"WARNING: fnmatch FNM_PATHNAME is broken on your system\n");
}
}
ret->fnmatch_flags = 0;
}
if (pat_len > 1 && ret->pattern[pat_len-1] == '/') {
ret->pattern[pat_len-1] = 0;
mflags |= MATCHFLG_DIRECTORY;
}
if (strlen(pattern) > 1 && pattern[strlen(pattern)-1] == '/') {
ret->pattern[strlen(pattern)-1] = 0;
ret->directory = 1;
}
for (cp = ret->pattern; (cp = strchr(cp, '/')) != NULL; cp++)
ret->slash_cnt++;
if (!strchr(ret->pattern,'/')) {
ret->local = 1;
}
ret->match_flags = mflags;
return ret;
if (!listp->tail)
listp->head = listp->tail = ret;
else {
listp->tail->next = ret;
listp->tail = ret;
}
}
static void free_exclude(struct exclude_struct *ex)
{
free(ex->pattern);
memset(ex,0,sizeof(*ex));
free(ex);
}
static int check_one_exclude(char *name, struct exclude_struct *ex,
STRUCT_STAT *st)
void clear_exclude_list(struct exclude_list_struct *listp)
{
char *p;
int match_start=0;
char *pattern = ex->pattern;
struct exclude_struct *ent, *next;
if (ex->local && (p=strrchr(name,'/')))
name = p+1;
if (!name[0]) return 0;
if (ex->directory && !S_ISDIR(st->st_mode)) return 0;
if (*pattern == '/' && *name != '/') {
match_start = 1;
pattern++;
for (ent = listp->head; ent; ent = next) {
next = ent->next;
free_exclude(ent);
}
if (ex->regular_exp) {
if (fnmatch(pattern, name, ex->fnmatch_flags) == 0) {
return 1;
listp->head = listp->tail = NULL;
}
static int check_one_exclude(char *name, struct exclude_struct *ex,
int name_is_dir)
{
char *p, full_name[MAXPATHLEN];
int match_start = 0;
char *pattern = ex->pattern;
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->slash_cnt && !(ex->match_flags & MATCHFLG_WILD2)) {
if ((p = strrchr(name,'/')) != NULL)
name = p+1;
}
else if (ex->match_flags & MATCHFLG_ABS_PATH && *name != '/'
&& curr_dir[1]) {
pathjoin(full_name, sizeof full_name, curr_dir + 1, name);
name = full_name;
}
if (ex->match_flags & MATCHFLG_DIRECTORY && !name_is_dir)
return 0;
if (*pattern == '/') {
match_start = 1;
pattern++;
if (*name == '/')
name++;
}
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->slash_cnt
&& !(ex->match_flags & MATCHFLG_WILD2)) {
int cnt = ex->slash_cnt + 1;
for (p = name + strlen(name) - 1; p >= name; p--) {
if (*p == '/' && !--cnt)
break;
}
name = p+1;
}
if (wildmatch(pattern, name))
return 1;
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 1;
}
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 1;
}
}
} else if (match_start) {
if (strcmp(name,pattern) == 0)
return 1;
} else {
int l1 = strlen(name);
int l2 = strlen(pattern);
if (l2 <= l1 &&
if (l2 <= l1 &&
strcmp(name+(l1-l2),pattern) == 0 &&
(l1==l2 || (!match_start && name[l1-(l2+1)] == '/'))) {
(l1==l2 || name[l1-(l2+1)] == '/')) {
return 1;
}
}
@@ -126,287 +195,263 @@ static int check_one_exclude(char *name, struct exclude_struct *ex,
static void report_exclude_result(char const *name,
struct exclude_struct const *ent,
STRUCT_STAT const *st)
int name_is_dir, const char *type)
{
/* If a trailing slash is present to match only directories,
* then it is stripped out by make_exclude. So as a special
* case we add it back in here. */
if (verbose >= 2)
rprintf(FINFO, "%s %s %s because of pattern %s%s\n",
ent->include ? "including" : "excluding",
S_ISDIR(st->st_mode) ? "directory" : "file",
name, ent->pattern,
ent->directory ? "/" : "");
/* If a trailing slash is present to match only directories,
* then it is stripped out by make_exclude. So as a special
* case we add it back in here. */
if (verbose >= 2) {
rprintf(FINFO, "[%s] %scluding %s %s because of %spattern %s%s\n",
who_am_i(),
ent->match_flags & MATCHFLG_INCLUDE ? "in" : "ex",
name_is_dir ? "directory" : "file", name, type,
ent->pattern,
ent->match_flags & MATCHFLG_DIRECTORY ? "/" : "");
}
}
/*
* Return true if file NAME is defined to be excluded by either
* LOCAL_EXCLUDE_LIST or the globals EXCLUDE_LIST.
* Return -1 if file "name" is defined to be excluded by the specified
* exclude list, 1 if it is included, and 0 if it was not matched.
*/
int check_exclude(char *name, struct exclude_struct **local_exclude_list,
STRUCT_STAT *st)
int check_exclude(struct exclude_list_struct *listp, char *name, int name_is_dir)
{
int n;
struct exclude_struct *ent;
struct exclude_struct *ent;
if (name && (name[0] == '.') && !name[1])
/* never exclude '.', even if somebody does --exclude '*' */
return 0;
if (exclude_list) {
for (n=0; exclude_list[n]; n++) {
ent = exclude_list[n];
if (check_one_exclude(name, ent, st)) {
report_exclude_result(name, ent, st);
return !ent->include;
}
}
}
if (local_exclude_list) {
for (n=0; local_exclude_list[n]; n++) {
ent = local_exclude_list[n];
if (check_one_exclude(name, ent, st)) {
report_exclude_result(name, ent, st);
return !ent->include;
}
}
for (ent = listp->head; ent; ent = ent->next) {
if (check_one_exclude(name, ent, name_is_dir)) {
report_exclude_result(name, ent, name_is_dir,
listp->debug_type);
return ent->match_flags & MATCHFLG_INCLUDE ? 1 : -1;
}
}
return 0;
}
void add_exclude_list(const char *pattern, struct exclude_struct ***list, int include)
/* Get the next include/exclude arg from the string. The token will not
* be '\0' terminated, so use the returned length to limit the string.
* Also, be sure to add this length to the returned pointer before passing
* it back to ask for the next token. This routine parses the +/- prefixes
* and the "!" token unless xflags contains XFLG_WORDS_ONLY. The *flag_ptr
* value will also be set to the MATCHFLG_* bits for the current token.
*/
static const char *get_exclude_tok(const char *p, unsigned int *len_ptr,
unsigned int *flag_ptr, int xflags)
{
int len=0;
if (list && *list)
for (; (*list)[len]; len++) ;
const unsigned char *s = (const unsigned char *)p;
unsigned int len, mflags = 0;
if (strcmp(pattern,"!") == 0) {
if (verbose > 2)
rprintf(FINFO,"clearing exclude list\n");
while ((len)--) {
free_exclude((*list)[len]);
if (xflags & XFLG_WORD_SPLIT) {
/* Skip over any initial whitespace. */
while (isspace(*s))
s++;
/* Update for "!" check. */
p = (const char *)s;
}
/* Is this a '+' or '-' followed by a space (not whitespace)? */
if (!(xflags & XFLG_WORDS_ONLY)
&& (*s == '-' || *s == '+') && s[1] == ' ') {
if (*s == '+')
mflags |= MATCHFLG_INCLUDE;
s += 2;
} else if (xflags & XFLG_DEF_INCLUDE)
mflags |= MATCHFLG_INCLUDE;
if (xflags & XFLG_WORD_SPLIT) {
const unsigned char *cp = s;
/* Token ends at whitespace or the end of the string. */
while (!isspace(*cp) && *cp != '\0')
cp++;
len = cp - s;
} else
len = strlen(s);
if (*p == '!' && len == 1 && !(xflags & XFLG_WORDS_ONLY))
mflags |= MATCHFLG_CLEAR_LIST;
*len_ptr = len;
*flag_ptr = mflags;
return (const char *)s;
}
void add_exclude(struct exclude_list_struct *listp, const char *pattern,
int xflags)
{
unsigned int pat_len, mflags;
const char *cp;
if (!pattern)
return;
cp = pattern;
pat_len = 0;
while (1) {
cp = get_exclude_tok(cp + pat_len, &pat_len, &mflags, xflags);
if (!pat_len)
break;
if (mflags & MATCHFLG_CLEAR_LIST) {
if (verbose > 2) {
rprintf(FINFO,
"[%s] clearing %sexclude list\n",
who_am_i(), listp->debug_type);
}
clear_exclude_list(listp);
continue;
}
make_exclude(listp, cp, pat_len, mflags);
if (verbose > 2) {
rprintf(FINFO, "[%s] add_exclude(%.*s, %s%sclude)\n",
who_am_i(), (int)pat_len, cp, listp->debug_type,
mflags & MATCHFLG_INCLUDE ? "in" : "ex");
}
}
}
void add_exclude_file(struct exclude_list_struct *listp, const char *fname,
int xflags)
{
FILE *fp;
char line[MAXPATHLEN+3]; /* Room for "x " prefix and trailing slash. */
char *eob = line + sizeof line - 1;
int word_split = xflags & XFLG_WORD_SPLIT;
if (!fname || !*fname)
return;
if (*fname != '-' || fname[1])
fp = fopen(fname, "rb");
else
fp = stdin;
if (!fp) {
if (xflags & XFLG_FATAL_ERRORS) {
rsyserr(FERROR, errno,
"failed to open %s file %s",
xflags & XFLG_DEF_INCLUDE ? "include" : "exclude",
fname);
exit_cleanup(RERR_FILEIO);
}
free((*list));
*list = NULL;
return;
}
*list = (struct exclude_struct **)Realloc(*list,sizeof(struct exclude_struct *)*(len+2));
if (!*list || !((*list)[len] = make_exclude(pattern, include)))
out_of_memory("add_exclude");
if (verbose > 2) {
rprintf(FINFO,"add_exclude(%s,%s)\n",pattern,
include ? "include" : "exclude");
}
(*list)[len+1] = NULL;
}
void add_exclude(const char *pattern, int include)
{
add_exclude_list(pattern,&exclude_list, include);
}
struct exclude_struct **make_exclude_list(const char *fname,
struct exclude_struct **list1,
int fatal, int include)
{
struct exclude_struct **list=list1;
FILE *f = fopen(fname,"r");
char line[MAXPATHLEN];
if (!f) {
if (fatal) {
rsyserr(FERROR, errno,
"failed to open %s file %s",
include ? "include" : "exclude",
fname);
exit_cleanup(RERR_FILEIO);
while (1) {
char *s = line;
int ch, overflow = 0;
while (1) {
if ((ch = getc(fp)) == EOF) {
if (ferror(fp) && errno == EINTR)
continue;
break;
}
if (word_split && isspace(ch))
break;
if (eol_nulls? !ch : (ch == '\n' || ch == '\r'))
break;
if (s < eob)
*s++ = ch;
else
overflow = 1;
}
return list;
}
while (fgets(line,MAXPATHLEN,f)) {
int l = strlen(line);
if (l && line[l-1] == '\n') l--;
line[l] = 0;
if (line[0] && (line[0] != ';') && (line[0] != '#')) {
/* Skip lines starting with semicolon or pound.
It probably wouldn't cause any harm to not skip
them but there's no need to save them. */
add_exclude_list(line,&list,include);
if (overflow) {
rprintf(FERROR, "discarding over-long exclude: %s...\n", line);
s = line;
}
*s = '\0';
/* Skip an empty token and (when line parsing) comments. */
if (*line && (word_split || (*line != ';' && *line != '#')))
add_exclude(listp, line, xflags);
if (ch == EOF)
break;
}
fclose(f);
return list;
}
void add_exclude_file(const char *fname, int fatal, int include)
{
if (!fname || !*fname) return;
exclude_list = make_exclude_list(fname,exclude_list,fatal,include);
fclose(fp);
}
void send_exclude_list(int f)
{
int i;
extern int remote_version;
extern int list_only, recurse;
struct exclude_struct *ent;
/* This is a complete hack - blame Rusty.
*
* FIXME: This pattern shows up in the output of
* report_exclude_result(), which is not ideal. */
if (list_only && !recurse) {
add_exclude("/*/*", 0);
}
if (list_only && !recurse)
add_exclude(&exclude_list, "/*/*", 0);
if (!exclude_list) {
write_int(f,0);
return;
}
for (ent = exclude_list.head; ent; ent = ent->next) {
unsigned int l;
char p[MAXPATHLEN+1];
for (i=0;exclude_list[i];i++) {
int l;
char pattern[MAXPATHLEN];
strlcpy(pattern,exclude_list[i]->pattern,sizeof(pattern));
if (exclude_list[i]->directory) strlcat(pattern,"/", sizeof(pattern));
l = strlen(pattern);
if (l == 0) continue;
if (exclude_list[i]->include) {
if (remote_version < 19) {
rprintf(FERROR,"remote rsync does not support include syntax - aborting\n");
exit_cleanup(RERR_UNSUPPORTED);
}
write_int(f,l+2);
write_buf(f,"+ ",2);
} else {
write_int(f,l);
l = strlcpy(p, ent->pattern, sizeof p);
if (l == 0 || l >= MAXPATHLEN)
continue;
if (ent->match_flags & MATCHFLG_DIRECTORY) {
p[l++] = '/';
p[l] = '\0';
}
write_buf(f,pattern,l);
}
write_int(f,0);
if (ent->match_flags & MATCHFLG_INCLUDE) {
write_int(f, l + 2);
write_buf(f, "+ ", 2);
} else if ((*p == '-' || *p == '+') && p[1] == ' ') {
write_int(f, l + 2);
write_buf(f, "- ", 2);
} else
write_int(f, l);
write_buf(f, p, l);
}
write_int(f, 0);
}
void recv_exclude_list(int f)
{
char line[MAXPATHLEN];
char line[MAXPATHLEN+3]; /* Room for "x " prefix and trailing slash. */
unsigned int l;
while ((l=read_int(f))) {
if (l >= MAXPATHLEN) overflow("recv_exclude_list");
read_sbuf(f,line,l);
add_exclude(line,0);
while ((l = read_int(f)) != 0) {
if (l >= sizeof line)
overflow("recv_exclude_list");
read_sbuf(f, line, l);
add_exclude(&exclude_list, line, 0);
}
}
/* Get the next include/exclude arg from the string. It works in a similar way
** to strtok - initially an arg is sent over, from then on NULL. This
** routine takes into account any +/- in the strings and does not
** consider the space following it as a delimeter.
*/
char *get_exclude_tok(char *p)
{
static char *s;
static int more;
char *t;
if (p) {
s=p;
if (*p)
more=1;
}
if (!more)
return(NULL);
/* Skip over any initial spaces */
while(isspace(*s))
s++;
/* Are we at the end of the string? */
if (*s) {
/* remember the beginning of the token */
t=s;
/* Is this a '+' or '-' followed by a space (not whitespace)? */
if ((*s=='+' || *s=='-') && *(s+1)==' ')
s+=2;
/* Skip to the next space or the end of the string */
while(!isspace(*s) && *s!='\0')
s++;
} else {
t=NULL;
}
/* Have we reached the end of the string? */
if (*s)
*s++='\0';
else
more=0;
return(t);
}
void add_exclude_line(char *p)
{
char *tok;
if (!p || !*p) return;
p = strdup(p);
if (!p) out_of_memory("add_exclude_line");
for (tok=get_exclude_tok(p); tok; tok=get_exclude_tok(NULL))
add_exclude(tok, 0);
free(p);
}
void add_include_line(char *p)
{
char *tok;
if (!p || !*p) return;
p = strdup(p);
if (!p) out_of_memory("add_include_line");
for (tok=get_exclude_tok(p); tok; tok=get_exclude_tok(NULL))
add_exclude(tok, 1);
free(p);
}
static char *cvs_ignore_list[] = {
"RCS","SCCS","CVS","CVS.adm","RCSLOG","cvslog.*",
"tags","TAGS",".make.state",".nse_depinfo",
"*~", "#*", ".#*", ",*", "*.old", "*.bak", "*.BAK", "*.orig",
"*.rej", ".del-*", "*.a", "*.o", "*.obj", "*.so", "*.Z", "*.elc", "*.ln",
"core",NULL};
static char default_cvsignore[] =
/* These default ignored items come from the CVS manual. */
"RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS"
" .make.state .nse_depinfo *~ #* .#* ,* _$* *$"
" *.old *.bak *.BAK *.orig *.rej .del-*"
" *.a *.olb *.o *.obj *.so *.exe"
" *.Z *.elc *.ln core"
/* The rest we added to suit ourself. */
" .svn/";
void add_cvs_excludes(void)
{
char fname[MAXPATHLEN];
char *p;
int i;
for (i=0; cvs_ignore_list[i]; i++)
add_exclude(cvs_ignore_list[i], 0);
if ((p=getenv("HOME")) && strlen(p) < (MAXPATHLEN-12)) {
snprintf(fname,sizeof(fname), "%s/.cvsignore",p);
add_exclude_file(fname,0,0);
add_exclude(&exclude_list, default_cvsignore,
XFLG_WORD_SPLIT | XFLG_WORDS_ONLY);
if ((p = getenv("HOME"))
&& pathjoin(fname, sizeof fname, p, ".cvsignore") < sizeof fname) {
add_exclude_file(&exclude_list, fname,
XFLG_WORD_SPLIT | XFLG_WORDS_ONLY);
}
add_exclude_line(getenv("CVSIGNORE"));
add_exclude(&exclude_list, getenv("CVSIGNORE"),
XFLG_WORD_SPLIT | XFLG_WORDS_ONLY);
}

153
fileio.c
View File

@@ -1,30 +1,31 @@
/*
/*
Copyright (C) Andrew Tridgell 1998
Copyright (C) 2002 by Martin Pool
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
File IO utilities used in rsync
File IO utilities used in rsync
*/
#include "rsync.h"
extern int sparse_files;
static char last_byte;
static int last_sparse;
extern int sparse_files;
int sparse_end(int f)
{
@@ -42,8 +43,8 @@ static int write_sparse(int f,char *buf,size_t len)
size_t l1=0, l2=0;
int ret;
for (l1=0;l1<len && buf[l1]==0;l1++) ;
for (l2=0;l2<(len-l1) && buf[len-(l2+1)]==0;l2++) ;
for (l1 = 0; l1 < len && buf[l1] == 0; l1++) {}
for (l2 = 0; l2 < len-l1 && buf[len-(l2+1)] == 0; l2++) {}
last_byte = buf[len-1];
@@ -51,39 +52,83 @@ static int write_sparse(int f,char *buf,size_t len)
last_sparse=1;
if (l1 > 0) {
do_lseek(f,l1,SEEK_CUR);
do_lseek(f,l1,SEEK_CUR);
}
if (l1 == len)
if (l1 == len)
return len;
ret = write(f, buf + l1, len - (l1+l2));
if (ret == -1 || ret == 0)
return ret;
else if (ret != (int) (len - (l1+l2)))
else if (ret != (int) (len - (l1+l2)))
return (l1+ret);
if (l2 > 0)
do_lseek(f,l2,SEEK_CUR);
return len;
}
static char *wf_writeBuf;
static size_t wf_writeBufSize;
static size_t wf_writeBufCnt;
int flush_write_file(int f)
{
int ret = 0;
char *bp = wf_writeBuf;
while (wf_writeBufCnt > 0) {
if ((ret = write(f, bp, wf_writeBufCnt)) < 0) {
if (errno == EINTR)
continue;
return ret;
}
wf_writeBufCnt -= ret;
bp += ret;
}
return ret;
}
/*
* write_file does not allow incomplete writes. It loops internally
* until len bytes are written or errno is set.
*/
int write_file(int f,char *buf,size_t len)
{
int ret = 0;
if (!sparse_files) {
return write(f,buf,len);
}
while (len>0) {
int len1 = MIN(len, SPARSE_WRITE_SIZE);
int r1 = write_sparse(f, buf, len1);
while (len > 0) {
int r1;
if (sparse_files) {
int len1 = MIN(len, SPARSE_WRITE_SIZE);
r1 = write_sparse(f, buf, len1);
} else {
if (!wf_writeBuf) {
wf_writeBufSize = WRITE_SIZE * 8;
wf_writeBufCnt = 0;
wf_writeBuf = new_array(char, wf_writeBufSize);
if (!wf_writeBuf)
out_of_memory("write_file");
}
r1 = MIN(len, wf_writeBufSize - wf_writeBufCnt);
if (r1) {
memcpy(wf_writeBuf + wf_writeBufCnt, buf, r1);
wf_writeBufCnt += r1;
}
if (wf_writeBufCnt == wf_writeBufSize) {
if (flush_write_file(f) < 0)
return -1;
if (!r1 && len)
continue;
}
}
if (r1 <= 0) {
if (ret > 0) return ret;
if (ret > 0)
return ret;
return r1;
}
len -= r1;
@@ -94,28 +139,30 @@ int write_file(int f,char *buf,size_t len)
}
/* this provides functionality somewhat similar to mmap() but using
read(). It gives sliding window access to a file. mmap() is not
used because of the possibility of another program (such as a
mailer) truncating the file thus giving us a SIGBUS */
struct map_struct *map_file(int fd,OFF_T len)
/* This provides functionality somewhat similar to mmap() but using read().
* It gives sliding window access to a file. mmap() is not used because of
* the possibility of another program (such as a mailer) truncating the
* file thus giving us a SIGBUS. */
struct map_struct *map_file(int fd, OFF_T len, OFF_T map_size,
size_t block_size)
{
struct map_struct *map;
map = (struct map_struct *)malloc(sizeof(*map));
if (!map) out_of_memory("map_file");
if (!(map = new(struct map_struct)))
out_of_memory("map_file");
if (block_size && (map_size % block_size))
map_size += block_size - (map_size % block_size);
memset(map, 0, sizeof map[0]);
map->fd = fd;
map->file_size = len;
map->p = NULL;
map->p_size = 0;
map->p_offset = 0;
map->p_fd_offset = 0;
map->p_len = 0;
map->def_window_size = map_size;
return map;
}
/* slide the read window in the file */
char *map_ptr(struct map_struct *map,OFF_T offset,int len)
{
@@ -123,9 +170,8 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
OFF_T window_start, read_start;
int window_size, read_size, read_offset;
if (len == 0) {
if (len == 0)
return NULL;
}
/* can't go beyond the end of file */
if (len > (map->file_size - offset)) {
@@ -133,20 +179,14 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
}
/* in most cases the region will already be available */
if (offset >= map->p_offset &&
if (offset >= map->p_offset &&
offset+len <= map->p_offset+map->p_len) {
return (map->p + (offset - map->p_offset));
}
/* nope, we are going to have to do a read. Work out our desired window */
if (offset > 2*CHUNK_SIZE) {
window_start = offset - 2*CHUNK_SIZE;
window_start &= ~((OFF_T)(CHUNK_SIZE-1)); /* assumes power of 2 */
} else {
window_start = 0;
}
window_size = MAX_MAP_SIZE;
window_start = offset;
window_size = map->def_window_size;
if (window_start + window_size > map->file_size) {
window_size = map->file_size - window_start;
}
@@ -156,8 +196,9 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
/* make sure we have allocated enough memory for the window */
if (window_size > map->p_size) {
map->p = (char *)Realloc(map->p, window_size);
if (!map->p) out_of_memory("map_ptr");
map->p = realloc_array(map->p, char, window_size);
if (!map->p)
out_of_memory("map_ptr");
map->p_size = window_size;
}
@@ -188,7 +229,11 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
}
if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
if (nread < 0) nread = 0;
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);
@@ -198,18 +243,22 @@ char *map_ptr(struct map_struct *map,OFF_T offset,int len)
map->p_offset = window_start;
map->p_len = window_size;
return map->p + (offset - map->p_offset);
return map->p + (offset - map->p_offset);
}
void unmap_file(struct map_struct *map)
int unmap_file(struct map_struct *map)
{
int ret;
if (map->p) {
free(map->p);
map->p = NULL;
}
memset(map, 0, sizeof(*map));
ret = map->status;
memset(map, 0, sizeof map[0]);
free(map);
}
return ret;
}

1669
flist.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,21 +1,21 @@
/* -*- c-file-style: "linux" -*-
rsync -- fast file replication program
Copyright (C) 1996-2000 by Andrew Tridgell
Copyright (C) 1996-2000 by Andrew Tridgell
Copyright (C) Paul Mackerras 1996
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -26,241 +26,318 @@
extern int verbose;
extern int dry_run;
extern int relative_paths;
extern int keep_dirlinks;
extern int preserve_links;
extern int am_root;
extern int preserve_devices;
extern int preserve_hard_links;
extern int preserve_perms;
extern int preserve_uid;
extern int preserve_gid;
extern int update_only;
extern int opt_ignore_existing;
extern int whole_file;
extern int block_size;
extern int inplace;
extern int make_backups;
extern int csum_length;
extern int ignore_times;
extern int size_only;
extern int io_timeout;
extern int remote_version;
extern int protocol_version;
extern int always_checksum;
extern int modify_window;
extern char *partial_dir;
extern char *compare_dest;
extern int link_dest;
extern int whole_file;
extern int local_server;
extern int list_only;
extern int read_batch;
extern int only_existing;
extern int orig_umask;
extern int safe_symlinks;
extern unsigned int block_size;
extern struct exclude_list_struct server_exclude_list;
/* choose whether to skip a particular file */
static int skip_file(char *fname,
struct file_struct *file, STRUCT_STAT *st)
static int skip_file(char *fname, struct file_struct *file, STRUCT_STAT *st)
{
if (st->st_size != file->length) {
if (st->st_size != file->length)
return 0;
if (link_dest) {
if (preserve_perms
&& (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
return 0;
if (am_root && preserve_uid && st->st_uid != file->uid)
return 0;
if (preserve_gid && file->gid != GID_NONE
&& st->st_gid != file->gid)
return 0;
}
/* if always checksum is set then we use the checksum instead
/* if always checksum is set then we use the checksum instead
of the file time to determine whether to sync */
if (always_checksum && S_ISREG(st->st_mode)) {
char sum[MD4_SUM_LENGTH];
char fnamecmpdest[MAXPATHLEN];
if (compare_dest != NULL) {
if (access(fname, 0) != 0) {
snprintf(fnamecmpdest,MAXPATHLEN,"%s/%s",
compare_dest,fname);
fname = fnamecmpdest;
}
}
file_checksum(fname,sum,st->st_size);
if (remote_version < 21) {
return (memcmp(sum,file->sum,2) == 0);
} else {
return (memcmp(sum,file->sum,MD4_SUM_LENGTH) == 0);
}
return memcmp(sum, file->u.sum, protocol_version < 21 ? 2
: MD4_SUM_LENGTH) == 0;
}
if (size_only) {
if (size_only)
return 1;
}
if (ignore_times) {
if (ignore_times)
return 0;
}
return (cmp_modtime(st->st_mtime,file->modtime) == 0);
}
/* use a larger block size for really big files */
static int adapt_block_size(struct file_struct *file, int bsize)
{
int ret;
if (bsize != BLOCK_SIZE) return bsize;
ret = file->length / (10000); /* rough heuristic */
ret = ret & ~15; /* multiple of 16 */
if (ret < bsize) ret = bsize;
if (ret > CHUNK_SIZE/2) ret = CHUNK_SIZE/2;
return ret;
return cmp_modtime(st->st_mtime, file->modtime) == 0;
}
/*
send a sums struct down a fd
*/
static void send_sums(struct sum_struct *s, int f_out)
* NULL sum_struct means we have no checksums
*/
void write_sum_head(int f, struct sum_struct *sum)
{
if (s) {
size_t i;
static struct sum_struct null_sum;
/* tell the other guy how many we are going to be
doing and how many bytes there are in the last
chunk */
write_int(f_out, s->count);
write_int(f_out, s->n);
write_int(f_out, s->remainder);
if (sum == NULL)
sum = &null_sum;
for (i = 0; i < s->count; i++) {
write_int(f_out, s->sums[i].sum1);
write_buf(f_out, s->sums[i].sum2, csum_length);
}
write_int(f, sum->count);
write_int(f, sum->blength);
if (protocol_version >= 27)
write_int(f, sum->s2length);
write_int(f, sum->remainder);
}
/*
* set (initialize) the size entries in the per-file sum_struct
* calculating dynamic block and checksum sizes.
*
* This is only called from generate_and_send_sums() but is a separate
* function to encapsulate the logic.
*
* The block size is a rounded square root of file length.
*
* The checksum size is determined according to:
* blocksum_bits = BLOCKSUM_EXP + 2*log2(file_len) - log2(block_len)
* provided by Donovan Baarda which gives a probability of rsync
* algorithm corrupting data and falling back using the whole md4
* checksums.
*
* This might be made one of several selectable heuristics.
*/
static void sum_sizes_sqroot(struct sum_struct *sum, uint64 len)
{
unsigned int blength;
int s2length;
uint32 c;
uint64 l;
if (block_size) {
blength = block_size;
} else if (len <= BLOCK_SIZE * BLOCK_SIZE) {
blength = BLOCK_SIZE;
} else {
/* we don't have checksums */
write_int(f_out, 0);
write_int(f_out, block_size);
write_int(f_out, 0);
l = len;
c = 1;
while (l >>= 2) {
c <<= 1;
}
blength = 0;
do {
blength |= c;
if (len < (uint64)blength * blength)
blength &= ~c;
c >>= 1;
} while (c >= 8); /* round to multiple of 8 */
blength = MAX(blength, BLOCK_SIZE);
}
if (protocol_version < 27) {
s2length = csum_length;
} else if (csum_length == SUM_LENGTH) {
s2length = SUM_LENGTH;
} else {
int b = BLOCKSUM_BIAS;
l = len;
while (l >>= 1) {
b += 2;
}
c = blength;
while (c >>= 1 && b) {
b--;
}
s2length = (b + 1 - 32 + 7) / 8; /* add a bit,
* subtract rollsum,
* round up
* --optimize in compiler--
*/
s2length = MAX(s2length, csum_length);
s2length = MIN(s2length, SUM_LENGTH);
}
sum->flength = len;
sum->blength = blength;
sum->s2length = s2length;
sum->count = (len + (blength - 1)) / blength;
sum->remainder = (len % blength);
if (sum->count && verbose > 2) {
rprintf(FINFO, "count=%.0f rem=%u blength=%u s2length=%d flength=%.0f\n",
(double)sum->count, sum->remainder, sum->blength,
sum->s2length, (double)sum->flength);
}
}
/*
generate a stream of signatures/checksums that describe a buffer
generate approximately one checksum every n bytes
*/
static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
/*
* Generate and send a stream of signatures/checksums that describe a buffer
*
* Generate approximately one checksum every block_len bytes.
*/
static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
{
int i;
struct sum_struct *s;
int count;
int block_len = n;
int remainder = (len%block_len);
size_t i;
struct map_struct *mapbuf;
struct sum_struct sum;
OFF_T offset = 0;
count = (len+(block_len-1))/block_len;
sum_sizes_sqroot(&sum, len);
s = (struct sum_struct *)malloc(sizeof(*s));
if (!s) out_of_memory("generate_sums");
if (len > 0)
mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength);
else
mapbuf = NULL;
s->count = count;
s->remainder = remainder;
s->n = n;
s->flength = len;
write_sum_head(f_out, &sum);
if (count==0) {
s->sums = NULL;
return s;
}
for (i = 0; i < sum.count; i++) {
unsigned int n1 = MIN(len, sum.blength);
char *map = map_ptr(mapbuf, offset, n1);
uint32 sum1 = get_checksum1(map, n1);
char sum2[SUM_LENGTH];
if (verbose > 3)
rprintf(FINFO,"count=%d rem=%d n=%d flength=%.0f\n",
s->count,s->remainder,s->n,(double)s->flength);
if (f_copy >= 0)
full_write(f_copy, map, n1);
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
if (!s->sums) out_of_memory("generate_sums");
for (i=0;i<count;i++) {
int n1 = MIN(len,n);
char *map = map_ptr(buf,offset,n1);
s->sums[i].sum1 = get_checksum1(map,n1);
get_checksum2(map,n1,s->sums[i].sum2);
s->sums[i].offset = offset;
s->sums[i].len = n1;
s->sums[i].i = i;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] offset=%.0f len=%d sum1=%08x\n",
i,(double)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
get_checksum2(map, n1, sum2);
if (verbose > 3) {
rprintf(FINFO,
"chunk[%.0f] offset=%.0f len=%u sum1=%08lx\n",
(double)i, (double)offset, n1,
(unsigned long)sum1);
}
write_int(f_out, sum1);
write_buf(f_out, sum2, sum.s2length);
len -= n1;
offset += n1;
}
return s;
if (mapbuf)
unmap_file(mapbuf);
}
/*
* Acts on file number I from FLIST, whose name is fname.
* Acts on file number @p i from @p flist, whose name is @p fname.
*
* First fixes up permissions, then generates checksums for the file.
*
* (This comment was added later by mbp who was trying to work it out;
* it might be wrong.)
*/
void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
{
int fd;
STRUCT_STAT st;
struct map_struct *buf;
struct sum_struct *s;
int statret;
struct file_struct *file = flist->files[i];
char *fnamecmp;
* @note This comment was added later by mbp who was trying to work it
* out. It might be wrong.
*/
static void recv_generator(char *fname, struct file_struct *file, int i,
int f_out)
{
int fd, f_copy;
STRUCT_STAT st, partial_st;
struct file_struct *back_file;
int statret, stat_errno;
char *fnamecmp, *partialptr, *backupptr;
char fnamecmpbuf[MAXPATHLEN];
extern char *compare_dest;
extern int list_only;
extern int preserve_perms;
extern int only_existing;
if (list_only) return;
if (list_only)
return;
if (verbose > 2)
rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
rprintf(FINFO, "recv_generator(%s,%d)\n", safe_fname(fname), i);
statret = link_stat(fname,&st);
if (only_existing && statret == -1 && errno == ENOENT) {
/* we only want to update existing files */
if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
if (server_exclude_list.head
&& check_exclude(&server_exclude_list, fname,
S_ISDIR(file->mode)) < 0) {
if (verbose) {
rprintf(FINFO, "skipping server-excluded file \"%s\"\n",
safe_fname(fname));
}
return;
}
if (statret == 0 &&
!preserve_perms &&
(S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
if (dry_run > 1) {
statret = -1;
stat_errno = ENOENT;
} else {
statret = link_stat(fname, &st,
keep_dirlinks && S_ISDIR(file->mode));
stat_errno = errno;
}
if (only_existing && statret == -1 && stat_errno == ENOENT) {
/* we only want to update existing files */
if (verbose > 1) {
rprintf(FINFO, "not creating new file \"%s\"\n",
safe_fname(fname));
}
return;
}
if (statret == 0 && !preserve_perms
&& S_ISDIR(st.st_mode) == S_ISDIR(file->mode)) {
/* if the file exists already and we aren't perserving
presmissions then act as though the remote end sent
us the file permissions we already have */
file->mode = (file->mode & _S_IFMT) | (st.st_mode & ~_S_IFMT);
* permissions then act as though the remote end sent
* us the file permissions we already have */
file->mode = (file->mode & ~CHMOD_BITS)
| (st.st_mode & CHMOD_BITS);
}
if (S_ISDIR(file->mode)) {
/* The file to be received is a directory, so we need
* to prepare appropriately. If there is already a
* file of that name and it is *not* a directory, then
* we need to delete it. If it doesn't exist, then
* recursively create it. */
if (dry_run) return; /* XXXX -- might cause inaccuracies?? -- mbp */
/* The file to be received is a directory, so we need
* to prepare appropriately. If there is already a
* file of that name and it is *not* a directory, then
* we need to delete it. If it doesn't exist, then
* recursively create it. */
if (dry_run)
return; /* TODO: causes inaccuracies -- fix */
if (statret == 0 && !S_ISDIR(st.st_mode)) {
if (robust_unlink(fname) != 0) {
rprintf(FERROR, RSYNC_NAME
": recv_generator: unlink \"%s\" to make room for directory: %s\n",
fname,strerror(errno));
rsyserr(FERROR, errno,
"recv_generator: unlink %s to make room for directory",
full_fname(fname));
return;
}
statret = -1;
}
if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
if (!(relative_paths && errno==ENOENT &&
create_directory_path(fname)==0 &&
do_mkdir(fname,file->mode)==0)) {
rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
fname,strerror(errno));
if (!(relative_paths && errno == ENOENT
&& create_directory_path(fname, orig_umask) == 0
&& do_mkdir(fname, file->mode) == 0)) {
rsyserr(FERROR, errno,
"recv_generator: mkdir %s failed",
full_fname(fname));
}
}
/* f_out is set to -1 when doing final directory
permission and modification time repair */
if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
rprintf(FINFO,"%s/\n",fname);
/* f_out is set to -1 when doing final directory-permission
* and modification-time repair. */
if (set_perms(fname, file, statret ? NULL : &st, 0)
&& verbose && f_out != -1)
rprintf(FINFO, "%s/\n", safe_fname(fname));
return;
}
@@ -268,12 +345,11 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
#if SUPPORT_LINKS
char lnk[MAXPATHLEN];
int l;
extern int safe_symlinks;
if (safe_symlinks && unsafe_symlink(file->link, fname)) {
if (safe_symlinks && unsafe_symlink(file->u.link, fname)) {
if (verbose) {
rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
fname,file->link);
rprintf(FINFO, "ignoring unsafe symlink %s -> \"%s\"\n",
full_fname(fname), file->u.link);
}
return;
}
@@ -284,23 +360,25 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
/* A link already pointing to the
* right place -- no further action
* required. */
if (strcmp(lnk,file->link) == 0) {
set_perms(fname,file,&st,1);
if (strcmp(lnk,file->u.link) == 0) {
set_perms(fname, file, &st,
PERMS_REPORT);
return;
}
}
}
/* Not a symlink, so delete whatever's
* already there and put a new symlink
* in place. */
* in place. */
delete_file(fname);
}
if (do_symlink(file->link,fname) != 0) {
rprintf(FERROR,RSYNC_NAME": symlink \"%s\" -> \"%s\": %s\n",
fname,file->link,strerror(errno));
if (do_symlink(file->u.link,fname) != 0) {
rsyserr(FERROR, errno, "symlink %s -> \"%s\" failed",
full_fname(fname), safe_fname(file->u.link));
} else {
set_perms(fname,file,NULL,0);
if (verbose) {
rprintf(FINFO,"%s -> %s\n", fname,file->link);
rprintf(FINFO, "%s -> %s\n", safe_fname(fname),
safe_fname(file->u.link));
}
}
#endif
@@ -309,150 +387,217 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
#ifdef HAVE_MKNOD
if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
if (statret != 0 ||
if (statret != 0 ||
st.st_mode != file->mode ||
st.st_rdev != file->rdev) {
st.st_rdev != file->u.rdev) {
delete_file(fname);
if (verbose > 2)
if (verbose > 2) {
rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
fname,(int)file->mode,(int)file->rdev);
if (do_mknod(fname,file->mode,file->rdev) != 0) {
rprintf(FERROR,"mknod %s : %s\n",fname,strerror(errno));
safe_fname(fname),
(int)file->mode, (int)file->u.rdev);
}
if (do_mknod(fname,file->mode,file->u.rdev) != 0) {
rsyserr(FERROR, errno, "mknod %s failed",
full_fname(fname));
} else {
set_perms(fname,file,NULL,0);
if (verbose)
rprintf(FINFO,"%s\n",fname);
if (verbose) {
rprintf(FINFO, "%s\n",
safe_fname(fname));
}
}
} else {
set_perms(fname,file,&st,1);
set_perms(fname, file, &st, PERMS_REPORT);
}
return;
}
#endif
if (preserve_hard_links && check_hard_link(file)) {
if (verbose > 1)
rprintf(FINFO, "\"%s\" is a hard link\n",f_name(file));
if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
return;
}
if (!S_ISREG(file->mode)) {
rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
rprintf(FINFO, "skipping non-regular file \"%s\"\n",
safe_fname(fname));
return;
}
fnamecmp = fname;
if ((statret == -1) && (compare_dest != NULL)) {
if (statret == -1 && compare_dest != NULL) {
/* try the file at compare_dest instead */
int saveerrno = errno;
snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",compare_dest,fname);
statret = link_stat(fnamecmpbuf,&st);
if (!S_ISREG(st.st_mode))
statret = -1;
if (statret == -1)
errno = saveerrno;
else
fnamecmp = fnamecmpbuf;
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf, compare_dest, fname);
if (link_stat(fnamecmpbuf, &st, 0) == 0
&& S_ISREG(st.st_mode)) {
#if HAVE_LINK
if (link_dest && !dry_run) {
if (do_link(fnamecmpbuf, fname) < 0) {
if (verbose) {
rsyserr(FINFO, errno,
"link %s => %s",
fnamecmpbuf,
safe_fname(fname));
}
fnamecmp = fnamecmpbuf;
}
} else
#endif
fnamecmp = fnamecmpbuf;
statret = 0;
}
}
if (statret == 0 && !S_ISREG(st.st_mode)) {
if (delete_file(fname) != 0)
return;
statret = -1;
stat_errno = ENOENT;
}
if (partial_dir && (partialptr = partial_dir_fname(fname))
&& link_stat(partialptr, &partial_st, 0) == 0
&& S_ISREG(partial_st.st_mode)) {
if (statret == -1)
goto prepare_to_open;
} else
partialptr = NULL;
if (statret == -1) {
if (errno == ENOENT) {
write_int(f_out,i);
if (!dry_run) send_sums(NULL,f_out);
} else {
if (verbose > 1)
rprintf(FERROR, RSYNC_NAME
": recv_generator failed to open \"%s\": %s\n",
fname, strerror(errno));
}
return;
}
if (!S_ISREG(st.st_mode)) {
if (delete_file(fname) != 0) {
if (preserve_hard_links && hard_link_check(file, HL_SKIP))
return;
if (stat_errno == ENOENT) {
write_int(f_out,i);
if (!dry_run && !read_batch)
write_sum_head(f_out, NULL);
} else if (verbose > 1) {
rsyserr(FERROR, stat_errno,
"recv_generator: failed to stat %s",
full_fname(fname));
}
/* now pretend the file didn't exist */
write_int(f_out,i);
if (!dry_run) send_sums(NULL,f_out);
return;
}
if (opt_ignore_existing && fnamecmp == fname) {
if (opt_ignore_existing && fnamecmp == fname) {
if (verbose > 1)
rprintf(FINFO,"%s exists\n",fname);
return;
}
if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
if (verbose > 1)
rprintf(FINFO,"%s is newer\n",fname);
rprintf(FINFO, "%s exists\n", safe_fname(fname));
return;
}
if (skip_file(fname, file, &st)) {
if (update_only && fnamecmp == fname
&& cmp_modtime(st.st_mtime, file->modtime) > 0) {
if (verbose > 1)
rprintf(FINFO, "%s is newer\n", safe_fname(fname));
return;
}
if (skip_file(fnamecmp, file, &st)) {
if (fnamecmp == fname)
set_perms(fname,file,&st,1);
set_perms(fname, file, &st, PERMS_REPORT);
return;
}
if (dry_run) {
prepare_to_open:
if (dry_run || read_batch) {
write_int(f_out,i);
return;
}
if (whole_file) {
if (whole_file > 0) {
write_int(f_out,i);
send_sums(NULL,f_out);
write_sum_head(f_out, NULL);
return;
}
/* open the file */
if (partialptr) {
st = partial_st;
fnamecmp = partialptr;
}
/* open the file */
fd = do_open(fnamecmp, O_RDONLY, 0);
if (fd == -1) {
rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
rsyserr(FERROR, errno, "failed to open %s, continuing",
full_fname(fnamecmp));
pretend_missing:
/* pretend the file didn't exist */
if (preserve_hard_links && hard_link_check(file, HL_SKIP))
return;
write_int(f_out,i);
send_sums(NULL,f_out);
write_sum_head(f_out, NULL);
return;
}
if (st.st_size > 0) {
buf = map_file(fd,st.st_size);
if (inplace && make_backups) {
if (!(backupptr = get_backup_name(fname))) {
close(fd);
return;
}
if (!(back_file = make_file(fname, NULL, NO_EXCLUDES))) {
close(fd);
goto pretend_missing;
}
if (robust_unlink(backupptr) && errno != ENOENT) {
rsyserr(FERROR, errno, "unlink %s",
full_fname(backupptr));
free(back_file);
close(fd);
return;
}
if ((f_copy = do_open(backupptr,
O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
rsyserr(FERROR, errno, "open %s",
full_fname(backupptr));
free(back_file);
close(fd);
return;
}
} else {
buf = NULL;
backupptr = NULL;
back_file = NULL;
f_copy = -1;
}
if (verbose > 3)
rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
if (verbose > 3) {
rprintf(FINFO, "gen mapped %s of size %.0f\n",
safe_fname(fnamecmp), (double)st.st_size);
}
if (verbose > 2)
rprintf(FINFO,"sending sums for %d\n",i);
rprintf(FINFO, "generating and sending sums for %d\n", i);
write_int(f_out,i);
send_sums(s,f_out);
generate_and_send_sums(fd, st.st_size, f_out, f_copy);
if (f_copy >= 0) {
close(f_copy);
set_perms(backupptr, back_file, NULL, 0);
if (verbose > 1)
rprintf(FINFO, "backed up %s to %s\n", fname, backupptr);
free(back_file);
}
close(fd);
if (buf) unmap_file(buf);
free_sums(s);
}
void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
void generate_files(int f_out, struct file_list *flist, char *local_name)
{
int i;
int phase=0;
int phase = 0;
char fbuf[MAXPATHLEN];
if (verbose > 2)
rprintf(FINFO,"generator starting pid=%d count=%d\n",
(int)getpid(),flist->count);
if (verbose > 2) {
rprintf(FINFO, "generator starting pid=%ld count=%d\n",
(long)getpid(), flist->count);
}
if (verbose >= 2) {
rprintf(FINFO,
whole_file > 0
? "delta-transmission disabled for local transfer or --whole-file\n"
: "delta transmission enabled\n");
}
/* we expect to just sit around now, so don't exit on a
timeout. If we really get a timeout then the other process should
@@ -461,46 +606,61 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
for (i = 0; i < flist->count; i++) {
struct file_struct *file = flist->files[i];
mode_t saved_mode = file->mode;
if (!file->basename) continue;
struct file_struct copy;
if (!file->basename)
continue;
/* we need to ensure that any directories we create have writeable
permissions initially so that we can create the files within
them. This is then fixed after the files are transferred */
if (!am_root && S_ISDIR(file->mode)) {
file->mode |= S_IWUSR; /* user write */
/* XXX: Could this be causing a problem on SCO? Perhaps their
* handling of permissions is strange? */
if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR)) {
copy = *file;
/* XXX: Could this be causing a problem on SCO? Perhaps their
* handling of permissions is strange? */
copy.mode |= S_IWUSR; /* user write */
file = &copy;
}
recv_generator(local_name?local_name:f_name(file),
flist,i,f);
file->mode = saved_mode;
recv_generator(local_name ? local_name : f_name_to(file, fbuf),
file, i, f_out);
}
phase++;
csum_length = SUM_LENGTH;
ignore_times=1;
ignore_times = 1;
if (verbose > 2)
rprintf(FINFO,"generate_files phase=%d\n",phase);
write_int(f,-1);
write_int(f_out, -1);
if (remote_version >= 13) {
/* in newer versions of the protocol the files can cycle through
the system more than once to catch initial checksum errors */
for (i=read_int(f_recv); i != -1; i=read_int(f_recv)) {
struct file_struct *file = flist->files[i];
recv_generator(local_name?local_name:f_name(file),
flist,i,f);
}
phase++;
if (verbose > 2)
rprintf(FINFO,"generate_files phase=%d\n",phase);
write_int(f,-1);
/* files can cycle through the system more than once
* to catch initial checksum errors */
while ((i = get_redo_num()) != -1) {
struct file_struct *file = flist->files[i];
recv_generator(local_name ? local_name : f_name_to(file, fbuf),
file, i, f_out);
}
phase++;
if (verbose > 2)
rprintf(FINFO,"generate_files phase=%d\n",phase);
write_int(f_out, -1);
if (preserve_hard_links)
do_hard_links();
/* now we need to fix any directory permissions that were
* modified during the transfer */
for (i = 0; i < flist->count; i++) {
struct file_struct *file = flist->files[i];
if (!file->basename || !S_ISDIR(file->mode))
continue;
recv_generator(local_name ? local_name : f_name(file),
file, i, -1);
}
if (verbose > 2)
rprintf(FINFO,"generate_files finished\n");
}

17
getfsdev.c Normal file
View File

@@ -0,0 +1,17 @@
#include "rsync.h"
int main(int argc, char *argv[])
{
STRUCT_STAT st;
while (--argc > 0) {
if (stat(*++argv, &st) < 0) {
fprintf(stderr, "Unable to stat `%s'\n", *argv);
exit(1);
}
printf("%ld/%ld\n", (long)major(st.st_dev),
(long)minor(st.st_dev));
}
return 0;
}

68
getgroups.c Normal file
View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2002 by Martin Pool
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/**
* @file getgroups.c
*
* Print out the gids of all groups for the current user. This is
* like `id -G` on Linux, but it's too hard to find a portable
* equivalent.
**/
#include "rsync.h"
int
main(UNUSED(int argc), UNUSED(char *argv[]))
{
int n, i;
gid_t *list;
gid_t gid = MY_GID();
int gid_in_list = 0;
#ifdef HAVE_GETGROUPS
if ((n = getgroups(0, NULL)) < 0) {
perror("getgroups");
return 1;
}
#else
n = 0;
#endif
list = (gid_t*)malloc(sizeof (gid_t) * (n + 1));
if (!list) {
fprintf(stderr, "out of memory!\n");
exit(1);
}
#ifdef HAVE_GETGROUPS
if (n > 0)
n = getgroups(n, list);
#endif
for (i = 0; i < n; i++) {
printf("%lu ", (unsigned long)list[i]);
if (list[i] == gid)
gid_in_list = 1;
}
/* The default gid might not be in the list on some systems. */
if (!gid_in_list)
printf("%lu", (unsigned long)gid);
printf("\n");
return 0;
}

227
hlink.c
View File

@@ -1,18 +1,18 @@
/*
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
Copyright (C) 2002 by Martin Pool <mbp@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -22,133 +22,146 @@
extern int dry_run;
extern int verbose;
extern int make_backups;
#if SUPPORT_HARD_LINKS
static int hlink_compare(struct file_struct *f1, struct file_struct *f2)
static int hlink_compare(struct file_struct **file1, struct file_struct **file2)
{
if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode))
return 0;
if (!S_ISREG(f1->mode))
return -1;
if (!S_ISREG(f2->mode))
return 1;
struct file_struct *f1 = *file1;
struct file_struct *f2 = *file2;
if (f1->dev != f2->dev)
return (int) (f1->dev > f2->dev ? 1 : -1);
if (f1->F_DEV != f2->F_DEV)
return (int) (f1->F_DEV > f2->F_DEV ? 1 : -1);
if (f1->inode != f2->inode)
return (int) (f1->inode > f2->inode ? 1 : -1);
if (f1->F_INODE != f2->F_INODE)
return (int) (f1->F_INODE > f2->F_INODE ? 1 : -1);
return file_compare(&f1, &f2);
return file_compare(file1, file2);
}
static struct file_struct *hlink_list;
static struct file_struct **hlink_list;
static int hlink_count;
#define LINKED(p1,p2) ((p1)->F_DEV == (p2)->F_DEV \
&& (p1)->F_INODE == (p2)->F_INODE)
/* Analyze the data in the hlink_list[], remove items that aren't multiply
* linked, and replace the dev+inode data with the hlindex+next linked list. */
static void link_idev_data(struct file_list *flist)
{
struct file_struct *head;
int from, to, start;
alloc_pool_t hlink_pool;
alloc_pool_t idev_pool = flist->hlink_pool;
hlink_pool = pool_create(128 * 1024, sizeof (struct hlink),
out_of_memory, POOL_INTERN);
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, hlink_list[from]->link_u.idev);
hlink_list[from]->link_u.links = pool_talloc(hlink_pool,
struct hlink, 1, "hlink_list");
hlink_list[from]->F_HLINDEX = to;
hlink_list[from]->F_NEXT = hlink_list[from+1];
from++;
}
if (from > start) {
pool_free(idev_pool, 0, hlink_list[from]->link_u.idev);
hlink_list[from]->link_u.links = pool_talloc(hlink_pool,
struct hlink, 1, "hlink_list");
hlink_list[from]->F_HLINDEX = to;
hlink_list[from]->F_NEXT = head;
hlink_list[from]->flags |= FLAG_HLINK_EOL;
hlink_list[to++] = head;
} else {
pool_free(idev_pool, 0, head->link_u.idev);
head->link_u.idev = NULL;
}
}
if (!to) {
free(hlink_list);
hlink_list = NULL;
pool_destroy(hlink_pool);
hlink_pool = NULL;
} else {
hlink_count = to;
if (!(hlink_list = realloc_array(hlink_list,
struct file_struct *, hlink_count)))
out_of_memory("init_hard_links");
}
flist->hlink_pool = hlink_pool;
pool_destroy(idev_pool);
}
#endif
void init_hard_links(struct file_list *flist)
{
#if SUPPORT_HARD_LINKS
int i;
if (flist->count < 2)
return;
if (hlink_list)
free(hlink_list);
if (!(hlink_list =
(struct file_struct *) malloc(sizeof(hlink_list[0]) *
flist->count)))
if (!(hlink_list = new_array(struct file_struct *, flist->count)))
out_of_memory("init_hard_links");
for (i = 0; i < flist->count; i++)
memcpy(&hlink_list[i], flist->files[i],
sizeof(hlink_list[0]));
hlink_count = 0;
for (i = 0; i < flist->count; i++) {
if (flist->files[i]->link_u.idev)
hlink_list[hlink_count++] = flist->files[i];
}
qsort(hlink_list, flist->count,
sizeof(hlink_list[0]), (int (*)()) hlink_compare);
qsort(hlink_list, hlink_count,
sizeof hlink_list[0], (int (*)()) hlink_compare);
hlink_count = flist->count;
if (!hlink_count) {
free(hlink_list);
hlink_list = NULL;
} else
link_idev_data(flist);
#endif
}
/* check if a file should be skipped because it is the same as an
earlier hard link */
int check_hard_link(struct file_struct *file)
int hard_link_check(struct file_struct *file, int skip)
{
#if SUPPORT_HARD_LINKS
int low = 0, high = hlink_count - 1;
int ret = 0;
if (!hlink_list || !S_ISREG(file->mode))
if (!hlink_list || !file->link_u.links)
return 0;
while (low != high) {
int mid = (low + high) / 2;
ret = hlink_compare(&hlink_list[mid], file);
if (ret == 0) {
low = mid;
break;
if (skip && !(file->flags & FLAG_HLINK_EOL))
hlink_list[file->F_HLINDEX] = file->F_NEXT;
if (hlink_list[file->F_HLINDEX] != file) {
if (verbose > 1) {
rprintf(FINFO, "\"%s\" is a hard link\n",
f_name(file));
}
if (ret > 0)
high = mid;
else
low = mid + 1;
}
if (hlink_compare(&hlink_list[low], file) != 0)
return 0;
if (low > 0 &&
S_ISREG(hlink_list[low - 1].mode) &&
file->dev == hlink_list[low - 1].dev &&
file->inode == hlink_list[low - 1].inode)
return 1;
}
#endif
return 0;
}
#if SUPPORT_HARD_LINKS
static void hard_link_one(int i)
static void hard_link_one(char *hlink1, char *hlink2)
{
STRUCT_STAT st1, st2;
if (link_stat(f_name(&hlink_list[i - 1]), &st1) != 0)
return;
if (link_stat(f_name(&hlink_list[i]), &st2) != 0) {
if (do_link
(f_name(&hlink_list[i - 1]),
f_name(&hlink_list[i])) != 0) {
if (verbose > 0)
rprintf(FINFO, "link %s => %s : %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i - 1]),
strerror(errno));
return;
}
} else {
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino)
return;
if (robust_unlink(f_name(&hlink_list[i])) != 0 ||
do_link(f_name(&hlink_list[i - 1]),
f_name(&hlink_list[i])) != 0) {
if (verbose > 0)
rprintf(FINFO, "link %s => %s : %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i - 1]),
strerror(errno));
return;
if (do_link(hlink1, hlink2)) {
if (verbose) {
rsyserr(FINFO, errno, "link %s => %s failed",
hlink2, hlink1);
}
}
if (verbose > 0)
rprintf(FINFO, "%s => %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i - 1]));
else if (verbose)
rprintf(FINFO, "%s => %s\n", hlink2, hlink1);
}
#endif
@@ -161,18 +174,38 @@ static void hard_link_one(int i)
void do_hard_links(void)
{
#if SUPPORT_HARD_LINKS
struct file_struct *file, *first;
char hlink1[MAXPATHLEN];
char *hlink2;
STRUCT_STAT st1, st2;
int i;
if (!hlink_list)
return;
for (i = 1; i < hlink_count; i++) {
if (S_ISREG(hlink_list[i].mode) &&
S_ISREG(hlink_list[i - 1].mode) &&
hlink_list[i].basename && hlink_list[i - 1].basename &&
hlink_list[i].dev == hlink_list[i - 1].dev &&
hlink_list[i].inode == hlink_list[i - 1].inode) {
hard_link_one(i);
for (i = 0; i < hlink_count; i++) {
first = file = hlink_list[i];
if (link_stat(f_name_to(first, hlink1), &st1, 0) < 0)
continue;
while ((file = file->F_NEXT) != first) {
hlink2 = f_name(file);
if (link_stat(hlink2, &st2, 0) == 0) {
if (st2.st_dev == st1.st_dev
&& st2.st_ino == st1.st_ino)
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(hlink1, hlink2);
}
}
#endif

View File

@@ -208,7 +208,7 @@ else
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
dsttmp=$dstdir/_inst.$$_
# Move or copy the file name to the temp name

1119
io.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,49 +1 @@
.cvsignore
Makefile
a
b
config.cache
config.h
config.log
config.status
dist.tar.gz
dummy
rsync
rsync-0.1
rsync-0.1
rsync-0.1
rsync-0.1.tar.gz
rsync-0.2
rsync-0.2
rsync-0.2.tar.gz
rsync-0.3
rsync-0.3
rsync-0.3.tar.gz
rsync-0.4
rsync-0.4
rsync-0.4.tar.gz
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5.tar.gz
rsync-0.6
rsync-0.7
rsync-0.7
rsync-0.8
rsync-0.8
rsync-0.8
rsync-0.8
rsync-ERSION
rsync.aux
rsync.dvi
rsync.log
tech_report.aux
tech_report.dvi
tech_report.log
tech_report.ps
test

View File

@@ -1,5 +1,6 @@
/*
Copyright (C) Andrew Tridgell 1998
Copyright (C) 2002 by Martin Pool
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
@@ -16,11 +17,15 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
compatibility functions - replacing functions for platforms that don't
have them.
/**
* @file compat.c
*
* Reimplementations of standard functions for platforms that don't
* have them.
**/
*/
#include "rsync.h"
@@ -78,9 +83,11 @@
#endif
#ifndef HAVE_STRPBRK
/* Find the first ocurrence in S of any character in ACCEPT.
derived from glibc
*/
/**
* Find the first ocurrence in @p s of any character in @p accept.
*
* Derived from glibc
**/
char *strpbrk(const char *s, const char *accept)
{
while (*s != '\0') {
@@ -97,36 +104,45 @@
#ifndef HAVE_STRLCPY
/* Like strncpy but does not 0 fill the buffer and always null
* terminates. bufsize is the size of the destination buffer.
/**
* Like strncpy but does not 0 fill the buffer and always null
* terminates.
*
* Returns the index of the terminating byte. */
* @param bufsize is the size of the destination buffer.
*
* @return index of the terminating byte.
**/
size_t strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len = strlen(s);
size_t ret = len;
if (bufsize <= 0) return 0;
if (len >= bufsize) len = bufsize-1;
memcpy(d, s, len);
d[len] = 0;
if (bufsize > 0) {
if (len >= bufsize)
len = bufsize-1;
memcpy(d, s, len);
d[len] = 0;
}
return ret;
}
#endif
#ifndef HAVE_STRLCAT
/* like strncat but does not 0 fill the buffer and always null
terminates. bufsize is the length of the buffer, which should
be one more than the maximum resulting string length */
/**
* Like strncat() but does not 0 fill the buffer and always null
* terminates.
*
* @param bufsize length of the buffer, which should be one more than
* the maximum resulting string length.
**/
size_t strlcat(char *d, const char *s, size_t bufsize)
{
size_t len1 = strlen(d);
size_t len2 = strlen(s);
size_t ret = len1 + len2;
if (len1+len2 >= bufsize) {
len2 = bufsize - (len1+1);
}
if (len2 > 0) {
if (len1 < bufsize - 1) {
if (len2 >= bufsize - len1)
len2 = bufsize - len1 - 1;
memcpy(d+len1, s, len2);
d[len1+len2] = 0;
}

View File

@@ -1,482 +0,0 @@
#include "../rsync.h"
#ifndef HAVE_FNMATCH
/* ----- THE FOLLOWING UP TO 'END' is glibc-2.1.2 posix/fnmatch.c
except for the parts with '#if 0' */
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#if 0 /* header files included better by ../rsync.h */
#if HAVE_CONFIG_H
# include <config.h>
#endif
/* Enable GNU extensions in fnmatch.h. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#include <errno.h>
#include <fnmatch.h>
#include <ctype.h>
#if HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
#endif
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#endif
#endif /* 0 */
/* For platform which support the ISO C amendement 1 functionality we
support user defined character classes. */
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
# include <wchar.h>
# include <wctype.h>
#endif
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if 1
# if defined STDC_HEADERS || !defined isascii
# define ISASCII(c) 1
# else
# define ISASCII(c) isascii(c)
# endif
#ifdef isblank
# define ISBLANK(c) (ISASCII (c) && isblank (c))
#else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef isgraph
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
#else
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
#endif
#define ISPRINT(c) (ISASCII (c) && isprint (c))
#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
#define ISALNUM(c) (ISASCII (c) && isalnum (c))
#define ISALPHA(c) (ISASCII (c) && isalpha (c))
#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
#define ISLOWER(c) (ISASCII (c) && islower (c))
#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
#define ISSPACE(c) (ISASCII (c) && isspace (c))
#define ISUPPER(c) (ISASCII (c) && isupper (c))
#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* The GNU C library provides support for user-defined character classes
and the functions from ISO C amendement 1. */
# ifdef CHARCLASS_NAME_MAX
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
# else
/* This shouldn't happen but some implementation might still have this
problem. Use a reasonable default value. */
# define CHAR_CLASS_MAX_LENGTH 256
# endif
# ifdef _LIBC
# define IS_CHAR_CLASS(string) __wctype (string)
# else
# define IS_CHAR_CLASS(string) wctype (string)
# endif
# else
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
# define IS_CHAR_CLASS(string) \
(STREQ (string, "alpha") || STREQ (string, "upper") \
|| STREQ (string, "lower") || STREQ (string, "digit") \
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|| STREQ (string, "space") || STREQ (string, "print") \
|| STREQ (string, "punct") || STREQ (string, "graph") \
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
# endif
/* Avoid depending on library functions or files
whose names are inconsistent. */
# if !defined _LIBC && !defined getenv
extern char *getenv ();
# endif
# ifndef errno
extern int errno;
# endif
/* Match STRING against the filename pattern PATTERN, returning zero if
it matches, nonzero if not. */
static int
#ifdef _LIBC
internal_function
#endif
internal_fnmatch (const char *pattern, const char *string,
int no_leading_period, int flags)
{
register const char *p = pattern, *n = string;
register unsigned char c;
/* Note that this evaluates C many times. */
# ifdef _LIBC
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
# else
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
# endif
while ((c = *p++) != '\0')
{
c = FOLD (c);
switch (c)
{
case '?':
if (*n == '\0')
return FNM_NOMATCH;
else if (*n == '/' && (flags & FNM_FILE_NAME))
return FNM_NOMATCH;
else if (*n == '.' && no_leading_period
&& (n == string
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
return FNM_NOMATCH;
break;
case '\\':
if (!(flags & FNM_NOESCAPE))
{
c = *p++;
if (c == '\0')
/* Trailing \ loses. */
return FNM_NOMATCH;
c = FOLD (c);
}
if (FOLD ((unsigned char) *n) != c)
return FNM_NOMATCH;
break;
case '*':
if (*n == '.' && no_leading_period
&& (n == string
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++)
{
if (*n == '/' && (flags & FNM_FILE_NAME))
/* A slash does not match a wildcard under FNM_FILE_NAME. */
return FNM_NOMATCH;
else if (c == '?')
{
/* A ? needs to match one character. */
if (*n == '\0')
/* There isn't another character; no match. */
return FNM_NOMATCH;
else
/* One character of the string is consumed in matching
this ? wildcard, so *??? won't match if there are
less than three characters. */
++n;
}
}
if (c == '\0')
/* The wildcard(s) is/are the last element of the pattern.
If the name is a file name and contains another slash
this does mean it cannot match. */
return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
? FNM_NOMATCH : 0);
else
{
const char *endp;
#if 0
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
#else
/* replace call to internal glibc function with equivalent */
if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL))
endp = n + strlen(n);
#endif
if (c == '[')
{
int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD));
for (--p; n < endp; ++n)
if (internal_fnmatch (p, n,
(no_leading_period
&& (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME)))),
flags2)
== 0)
return 0;
}
else if (c == '/' && (flags & FNM_FILE_NAME))
{
while (*n != '\0' && *n != '/')
++n;
if (*n == '/'
&& (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
flags) == 0))
return 0;
}
else
{
int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD));
if (c == '\\' && !(flags & FNM_NOESCAPE))
c = *p;
c = FOLD (c);
for (--p; n < endp; ++n)
if (FOLD ((unsigned char) *n) == c
&& (internal_fnmatch (p, n,
(no_leading_period
&& (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME)))),
flags2) == 0))
return 0;
}
}
/* If we come here no match is possible with the wildcard. */
return FNM_NOMATCH;
case '[':
{
/* Nonzero if the sense of the character class is inverted. */
static int posixly_correct;
register int not;
char cold;
if (posixly_correct == 0)
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
if (*n == '\0')
return FNM_NOMATCH;
if (*n == '.' && no_leading_period && (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME))))
return FNM_NOMATCH;
if (*n == '/' && (flags & FNM_FILE_NAME))
/* `/' cannot be matched. */
return FNM_NOMATCH;
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
if (not)
++p;
c = *p++;
for (;;)
{
unsigned char fn = FOLD ((unsigned char) *n);
if (!(flags & FNM_NOESCAPE) && c == '\\')
{
if (*p == '\0')
return FNM_NOMATCH;
c = FOLD ((unsigned char) *p);
++p;
if (c == fn)
goto matched;
}
else if (c == '[' && *p == ':')
{
/* Leave room for the null. */
char str[CHAR_CLASS_MAX_LENGTH + 1];
size_t c1 = 0;
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
wctype_t wt;
# endif
const char *startp = p;
for (;;)
{
if (c1 == CHAR_CLASS_MAX_LENGTH)
/* The name is too long and therefore the pattern
is ill-formed. */
return FNM_NOMATCH;
c = *++p;
if (c == ':' && p[1] == ']')
{
p += 2;
break;
}
if (c < 'a' || c >= 'z')
{
/* This cannot possibly be a character class name.
Match it as a normal range. */
p = startp;
c = '[';
goto normal_bracket;
}
str[c1++] = c;
}
str[c1] = '\0';
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
wt = IS_CHAR_CLASS (str);
if (wt == 0)
/* Invalid character class name. */
return FNM_NOMATCH;
if (__iswctype (__btowc ((unsigned char) *n), wt))
goto matched;
# else
if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
goto matched;
# endif
}
else if (c == '\0')
/* [ (unterminated) loses. */
return FNM_NOMATCH;
else
{
normal_bracket:
if (FOLD (c) == fn)
goto matched;
cold = c;
c = *p++;
if (c == '-' && *p != ']')
{
/* It is a range. */
unsigned char cend = *p++;
if (!(flags & FNM_NOESCAPE) && cend == '\\')
cend = *p++;
if (cend == '\0')
return FNM_NOMATCH;
if (cold <= fn && fn <= FOLD (cend))
goto matched;
c = *p++;
}
}
if (c == ']')
break;
}
if (!not)
return FNM_NOMATCH;
break;
matched:
/* Skip the rest of the [...] that already matched. */
while (c != ']')
{
if (c == '\0')
/* [... (unterminated) loses. */
return FNM_NOMATCH;
c = *p++;
if (!(flags & FNM_NOESCAPE) && c == '\\')
{
if (*p == '\0')
return FNM_NOMATCH;
/* XXX 1003.2d11 is unclear if this is right. */
++p;
}
else if (c == '[' && *p == ':')
{
do
if (*++p == '\0')
return FNM_NOMATCH;
while (*p != ':' || p[1] == ']');
p += 2;
c = *p;
}
}
if (not)
return FNM_NOMATCH;
}
break;
default:
if (c != FOLD ((unsigned char) *n))
return FNM_NOMATCH;
}
++n;
}
if (*n == '\0')
return 0;
if ((flags & FNM_LEADING_DIR) && *n == '/')
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
return 0;
return FNM_NOMATCH;
# undef FOLD
}
int
fnmatch (pattern, string, flags)
const char *pattern;
const char *string;
int flags;
{
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
/* ----- END glibc-2.1.2 posix/fnmatch.c */
#else /* HAVE_FNMATCH */
void fnmatch_dummy(void) {}
#endif

View File

@@ -1,88 +0,0 @@
/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef _FNMATCH_H
#define _FNMATCH_H 1
#ifdef __cplusplus
extern "C" {
#endif
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
# if !defined __GLIBC__ || !defined __P
# undef __P
# define __P(protos) protos
# endif
#else /* Not C++ or ANSI C. */
# undef __P
# define __P(protos) ()
/* We can get away without defining `const' here only because in this file
it is used only inside the prototype for `fnmatch', which is elided in
non-ANSI C where `const' is problematical. */
#endif /* C++ or ANSI C. */
#ifndef const
# if (defined __STDC__ && __STDC__) || defined __cplusplus
# define __const const
# else
# define __const
# endif
#endif
/* We #undef these before defining them because some losing systems
(HP-UX A.08.07 for example) define these in <unistd.h>. */
#undef FNM_PATHNAME
#undef FNM_NOESCAPE
#undef FNM_PERIOD
/* Bits set in the FLAGS argument to `fnmatch'. */
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
#ifndef FNM_FILE_NAME
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
#endif
#ifndef FNM_LEADING_DIR
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
#endif
#ifndef FNM_CASEFOLD
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
#endif
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
#define FNM_NOMATCH 1
/* This value is returned if the implementation does not support
`fnmatch'. Since this is not the case here it will never be
returned but the conformance test suites still require the symbol
to be defined. */
#ifdef _XOPEN_SOURCE
# define FNM_NOSYS (-1)
#endif
/* Match STRING against the filename pattern PATTERN,
returning zero if it matches, FNM_NOMATCH if not. */
extern int fnmatch __P ((__const char *__pattern, __const char *__string,
int __flags));
#ifdef __cplusplus
}
#endif
#endif /* fnmatch.h */

View File

@@ -27,10 +27,12 @@
*/
static int inet_pton4(const char *src, unsigned char *dst);
#ifdef INET6
static int inet_pton6(const char *src, unsigned char *dst);
#endif
/* int
* isc_net_pton(af, src, dst)
* inet_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:

View File

@@ -109,29 +109,53 @@ void mdfour_begin(struct mdfour *md)
md->C = 0x98badcfe;
md->D = 0x10325476;
md->totalN = 0;
md->totalN2 = 0;
}
static void mdfour_tail(unsigned char *in, int n)
static void mdfour_tail(unsigned char *in, uint32 n)
{
unsigned char buf[128];
uint32 M[16];
uint32 b;
extern int protocol_version;
m->totalN += n;
b = m->totalN * 8;
/*
* Count total number of bits, modulo 2^64
*/
m->totalN += n << 3;
if (m->totalN < (n << 3)) {
m->totalN2++;
}
m->totalN2 += n >> 29;
memset(buf, 0, 128);
if (n) memcpy(buf, in, n);
buf[n] = 0x80;
if (n <= 55) {
copy4(buf+56, b);
copy4(buf+56, m->totalN);
/*
* Prior to protocol version 27 only the number of bits
* modulo 2^32 was included. MD4 requires the number
* of bits modulo 2^64, which was fixed starting with
* protocol version 27.
*/
if (protocol_version >= 27) {
copy4(buf+60, m->totalN2);
}
copy64(M, buf);
mdfour64(M);
} else {
copy4(buf+120, b);
copy4(buf+120, m->totalN);
/*
* Prior to protocol version 27 only the number of bits
* modulo 2^32 was included. MD4 requires the number
* of bits modulo 2^64, which was fixed starting with
* protocol version 27.
*/
if (protocol_version >= 27) {
copy4(buf+124, m->totalN2);
}
copy64(M, buf);
mdfour64(M);
copy64(M, buf+64);
@@ -139,20 +163,23 @@ static void mdfour_tail(unsigned char *in, int n)
}
}
void mdfour_update(struct mdfour *md, unsigned char *in, int n)
void mdfour_update(struct mdfour *md, unsigned char *in, uint32 n)
{
uint32 M[16];
if (n == 0) mdfour_tail(in, n);
m = md;
if (n == 0) mdfour_tail(in, n);
while (n >= 64) {
copy64(M, in);
mdfour64(M);
in += 64;
n -= 64;
m->totalN += 64;
m->totalN += 64 << 3;
if (m->totalN < 64 << 3) {
m->totalN2++;
}
}
if (n) mdfour_tail(in, n);

View File

@@ -21,11 +21,12 @@
struct mdfour {
uint32 A, B, C, D;
uint32 totalN;
uint32 totalN; /* bit count, lower 32 bits */
uint32 totalN2; /* bit count, upper 32 bits */
};
void mdfour_begin(struct mdfour *md);
void mdfour_update(struct mdfour *md, unsigned char *in, int n);
void mdfour_update(struct mdfour *md, unsigned char *in, uint32 n);
void mdfour_result(struct mdfour *md, unsigned char *out);
void mdfour(unsigned char *out, unsigned char *in, int n);

View File

@@ -47,8 +47,10 @@ void permstring(char *perms,
if (mode & S_ISGID)
perms[6] = (mode & S_IXGRP) ? 's' : 'S';
#ifdef S_ISVTX
if (mode & S_ISVTX)
perms[9] = (mode & S_IXOTH) ? 't' : 'T';
#endif
if (S_ISLNK(mode)) perms[0] = 'l';
if (S_ISDIR(mode)) perms[0] = 'd';

199
lib/pool_alloc.3 Normal file
View File

@@ -0,0 +1,199 @@
.ds d \-\^\-
.ds o \fR[\fP
.ds c \fR]\fP
.ds | \fR|\fP
.de D
\\.B \*d\\$1
..
.de DI
\\.BI \*d\\$1 \\$2
..
.de DR
\\.BR \*d\\$1 \\$2
..
.de Di
\\.BI \*d\\$1 " \\$2"
..
.de Db
\\.B \*d\\$1 " \\$2"
..
.de Df
\\.B \*d\*ono\*c\\$1
..
.de See
See \fB\\$1\fP for details.
..
.de SeeIn
See \fB\\$1\fP in \fB\\$2\fP for details.
..
.TH POOL_ALLOC 3
.SH NAME
pool_alloc, pool_free, pool_talloc, pool_tfree, pool_create, pool_destroy
\- Allocate and free memory in managed allocation pools.
.SH SYNOPSIS
.B #include "pool_alloc.h"
\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char *), int \fIflags\fB);
\fBvoid pool_destroy(struct alloc_pool *\fIpool\fB);
\fBvoid *pool_alloc(struct alloc_pool *\fIpool\fB, size_t \fIsize\fB, char *\fImsg\fB);
\fBvoid pool_free(struct alloc_pool *\fIpool\fB, sise_t \fIsize\fB, void *\fIaddr\fB);
\fBvoid *pool_talloc(struct alloc_pool *\fIpool\fB, \fItype\fB), int \fIcount\fB, char *\fImsg\fB);
\fBvoid pool_tfree(struct alloc_pool *\fIpool\fB, \fItype\fB, int \fIcount\fB, void *\fIaddr\fB);
.SH DESCRIPTION
.P
The pool allocation routines use
.B malloc()
for underlying memory management.
What allocation pools do is cause
memory within a given pool to be in large contigious blocks
(called extents) that when freed will be reusable. Unlike
.B malloc()
the allocations are not managed individually.
Instead each extent tracks the total free memory within the
extent. Each extent can either be used to allocate memory
or to manage the freeing of memory within that extent.
When an extent has less free memory than a given
allocation request or when the first request to free
memory within that extent is received the extent ceases to
be used for allocation.
.P
This form of memory management is suited to large numbers of small
related allocations that are held for a while
and then freed as a group.
Because the
underlying allocations are done in large contigious extents
when an extent is freed it releases a large enough
contigious block of memory to be useful to subsequent
.B malloc()
and
.B pool_alloc()
calls even if allocations from other pools or from
.B malloc()
are made between allocations from a given pool.
.P
.B pool_create()
Creates an allocation pool for subsequent calls to the pool
allocation functions.
When an extent is created for allocations it will be
.I size
bytes.
Allocations from the pool have their sizes rounded up to a
multiple of
.I quantum
bytes in length.
Specifying
.B 0
for
.I quantum
Will produce a quantum that should meet maximal allignment
on most platforms.
If the
.B POOL_QALIGN
.I flag
is set allocations will be aligned to addresses that are a
multiple of
.IR quantum .
If the
.B POOL_CLEAR
.I flag
is set all allocations from the pool will be zero filled.
.P
.B pool_destroy()
destroys an allocation pool and frees all memory allocated
in that pool.
.P
.B pool_alloc()
allocates
.I size
bytes from the specified
.IR pool .
If
.I size
is
.B 0
.I quantum
bytes will be freed.
If the requested memory cannot be allocated
.B pool_alloc()
will call
.I bomb()
function, if defined, with
.I msg
as it's sole argument and
.B NULL
will be returned.
.P
.B pool_free()
frees
.I size
bytes pointed to by
.I addr
previously allocated in the specified
.IR pool .
The memory freed within an extent will not be reusable until
all of the memory in that extent has been freed but
depending on the order in which the
allocations are freed some extents may be released for reuse
while others are still in use.
If
.I size
is
.B 0
.I quantum
bytes will be freed.
If
.I addr
is
.B 0
no memory will be freed but subsequent allocations will come
from a new extent.
.P
.B pool_talloc()
is a macro that take a
.I type
and
.I count
instead of
.I size
and will cast the return value to the correct type.
.P
.B pool_tfree
is a macro to free memory previously allocated in the
specified
.IR pool .
.SH RETURN VALUE
.B pool_create()
returns a pointer to
.BR "struct alloc_pool" .
.P
.B pool_alloc()
and
.B pool_talloc()
return pointers to the allocated memory,
or NULL if the request fails.
For each extent so long as no allocations are smaller than varaible
allignment requirements this pointer will be suitably
alligned for any kind of variable.
The return type of
.B pool_alloc()
will normally require casting to the desired type but
.B pool_talloc()
will returns a pointer of the requested
.IR type .
.P
.BR pool_free() ,
.B pool_tfree()
and
.B pool_destroy()
return no value.
.SH SEE ALSO
.nf
malloc(3)
.SH AUTHOR
pool_alloc was created by J.W. Schultz of Pegasystems Technologies.
.SH BUGS AND ISSUES

304
lib/pool_alloc.c Normal file
View File

@@ -0,0 +1,304 @@
#include "rsync.h"
#define POOL_DEF_EXTENT (32 * 1024)
struct alloc_pool
{
size_t size; /* extent size */
size_t quantum; /* allocation quantum */
struct pool_extent *live; /* current extent for
* allocations */
struct pool_extent *free; /* unfreed extent list */
void (*bomb)();
/* function to call if
* malloc fails */
int flags;
/* statistical data */
unsigned long e_created; /* extents created */
unsigned long e_freed; /* extents detroyed */
uint64 n_allocated; /* calls to alloc */
uint64 n_freed; /* calls to free */
uint64 b_allocated; /* cum. bytes allocated */
uint64 b_freed; /* cum. bytes freed */
};
struct pool_extent
{
void *start; /* starting address */
size_t free; /* free bytecount */
size_t bound; /* bytes bound by padding,
* overhead and freed */
struct pool_extent *next;
};
struct align_test {
void *foo;
uint64 bar;
};
#define MINALIGN offsetof(struct align_test, bar)
/* Temporarily cast a void* var into a char* var when adding an offset (to
* keep some compilers from complaining about the pointer arithmetic). */
#define PTR_ADD(b,o) ( (void*) ((char*)(b) + (o)) )
alloc_pool_t
pool_create(size_t size, size_t quantum,
void (*bomb)(char *), int flags)
{
struct alloc_pool *pool;
if (!(pool = (struct alloc_pool*) malloc(sizeof (struct alloc_pool))))
return pool;
memset(pool, 0, sizeof (struct alloc_pool));
pool->size = size /* round extent size to min alignment reqs */
? (size + MINALIGN - 1) & ~(MINALIGN - 1)
: POOL_DEF_EXTENT;
if (pool->flags & POOL_INTERN)
{
pool->size -= sizeof (struct pool_extent);
flags |= POOL_APPEND;
}
pool->quantum = quantum ? quantum : MINALIGN;
pool->bomb = bomb;
pool->flags = flags;
return pool;
}
void
pool_destroy(alloc_pool_t p)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
struct pool_extent *cur, *next;
if (!pool)
return;
if (pool->live)
{
cur = pool->live;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
}
for (cur = pool->free; cur; cur = next)
{
next = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
}
free(pool);
}
void *
pool_alloc(alloc_pool_t p, size_t len, char *bomb)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
if (!pool)
return NULL;
if (!len)
len = pool->quantum;
else if (pool->quantum > 1 && len % pool->quantum)
len += pool->quantum - len % pool->quantum;
if (len > pool->size)
goto bomb;
if (!pool->live || len > pool->live->free)
{
void *start;
size_t free;
size_t bound;
size_t sqew;
size_t asize;
if (pool->live)
{
pool->live->next = pool->free;
pool->free = pool->live;
}
free = pool->size;
bound = 0;
asize = pool->size;
if (pool->flags & POOL_APPEND)
asize += sizeof (struct pool_extent);
if (!(start = (void *) malloc(asize)))
goto bomb;
if (pool->flags & POOL_CLEAR)
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))
{
bound += sqew;
free -= sqew;
}
pool->live->start = start;
pool->live->free = free;
pool->live->bound = bound;
pool->live->next = NULL;
pool->e_created++;
}
pool->n_allocated++;
pool->b_allocated += len;
pool->live->free -= len;
return PTR_ADD(pool->live->start, pool->live->free);
bomb:
if (pool->bomb)
(*pool->bomb)(bomb);
return NULL;
}
void
pool_free(alloc_pool_t p, size_t len, void *addr)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
struct pool_extent *cur;
struct pool_extent *prev;
if (!pool)
return;
if (!len)
len = pool->quantum;
else if (pool->quantum > 1 && len % pool->quantum)
len += pool->quantum - len % pool->quantum;
if (!addr && pool->live)
{
pool->live->next = pool->free;
pool->free = pool->live;
pool->live = NULL;
return;
}
pool->n_freed++;
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 (pool->flags & POOL_CLEAR)
memset(addr, 0, len);
pool->b_freed += len;
} else {
cur->bound += len;
}
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))
{
cur->bound += sqew;
cur->free -= sqew;
}
}
return;
}
for (prev = NULL, cur = pool->free; cur; prev = cur, cur = cur->next)
{
if (addr >= cur->start
&& addr < PTR_ADD(cur->start, pool->size))
break;
}
if (!cur)
return;
if (prev)
{
prev->next = cur->next;
cur->next = pool->free;
pool->free = cur;
}
cur->bound += len;
if (cur->free + cur->bound >= pool->size)
{
pool->free = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
pool->e_freed++;
}
return;
}
#define FDPRINT(label, value) \
snprintf(buf, BUFSIZ, label, value), \
write(fd, buf, strlen(buf));
#define FDEXTSTAT(ext) \
snprintf(buf, BUFSIZ, " %12ld %5ld\n", \
(long) ext->free, \
(long) ext->bound), \
write(fd, buf, strlen(buf))
void
pool_stats(alloc_pool_t p, int fd, int summarize)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
struct pool_extent *cur;
char buf[BUFSIZ];
if (!pool)
return;
FDPRINT(" Extent size: %12ld\n", (long) pool->size);
FDPRINT(" Alloc quantum: %12ld\n", (long) pool->quantum);
FDPRINT(" Extents created: %12ld\n", pool->e_created);
FDPRINT(" Extents freed: %12ld\n", pool->e_freed);
FDPRINT(" Alloc count: %12.0f\n", (double) pool->n_allocated);
FDPRINT(" Free Count: %12.0f\n", (double) pool->n_freed);
FDPRINT(" Alloc bytes: %12.0f\n", (double) pool->b_allocated);
FDPRINT(" Free bytes: %12.0f\n", (double) pool->b_freed);
if (summarize)
return;
if (!pool->live && !pool->free)
return;
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);
}
}

20
lib/pool_alloc.h Normal file
View File

@@ -0,0 +1,20 @@
#include <stddef.h>
#define POOL_CLEAR (1<<0) /* zero fill allocations */
#define POOL_QALIGN (1<<1) /* align data to quanta */
#define POOL_INTERN (1<<2) /* Allocate extent structures */
#define POOL_APPEND (1<<3) /* or appended to extent data */
typedef void *alloc_pool_t;
alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(char *), int flags);
void pool_destroy(alloc_pool_t pool);
void *pool_alloc(alloc_pool_t pool, size_t size, char *bomb);
void pool_free(alloc_pool_t pool, size_t size, void *addr);
#define pool_talloc(pool, type, count, bomb) \
((type *)pool_alloc(pool, sizeof(type) * count, bomb))
#define pool_tfree(pool, type, count, addr) \
(pool_free(pool, sizeof(type) * count, addr))

View File

@@ -53,6 +53,9 @@
* got rid of fcvt code (twas buggy and made testing harder)
* added C99 semantics
*
* Paul Green (paulg@samba.org) April 9, 2003
* fixed handling of %f when converting fractions with leading zeros.
* (e.g., 0.025).
**************************************************************/
#ifndef NO_CONFIG_H /* for some tests */
@@ -725,15 +728,15 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
if (max > 0) {
dopr_outch (buffer, currlen, maxlen, '.');
while (zpadlen > 0) {
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
}
while (zpadlen > 0) {
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
while (padlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
++padlen;
@@ -749,13 +752,15 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
}
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
#define vsnprintf rsync_vsnprintf
int vsnprintf(char *str, size_t count, const char *fmt, va_list args)
{
return dopr(str, count, fmt, args);
}
#endif
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
#define snprintf rsync_snprintf
int snprintf(char *str,size_t count,const char *fmt,...)
{
size_t ret;

229
lib/wildmatch.c Normal file
View File

@@ -0,0 +1,229 @@
/*
** Do shell-style pattern matching for ?, \, [], and * characters.
** It is 8bit clean.
**
** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
** Rich $alz is now <rsalz@bbn.com>.
**
** Modified by Wayne Davison to special-case '/' matching, to make '**'
** work differently than '*', and to fix the character-class code.
*/
#include "rsync.h"
/* What character marks an inverted character class? */
#define NEGATE_CLASS '!'
#define NEGATE_CLASS2 '^'
#define FALSE 0
#define TRUE 1
#define ABORT_ALL -1
#define ABORT_TO_STARSTAR -2
#define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 \
&& *(class) == *(litmatch) \
&& strncmp((char*)class, litmatch, len) == 0)
#if defined STDC_HEADERS || !defined isascii
# define ISASCII(c) 1
#else
# define ISASCII(c) isascii(c)
#endif
#ifdef isblank
# define ISBLANK(c) (ISASCII(c) && isblank(c))
#else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef isgraph
# define ISGRAPH(c) (ISASCII(c) && isgraph(c))
#else
# define ISGRAPH(c) (ISASCII(c) && isprint(c) && !isspace(c))
#endif
#define ISPRINT(c) (ISASCII(c) && isprint(c))
#define ISDIGIT(c) (ISASCII(c) && isdigit(c))
#define ISALNUM(c) (ISASCII(c) && isalnum(c))
#define ISALPHA(c) (ISASCII(c) && isalpha(c))
#define ISCNTRL(c) (ISASCII(c) && iscntrl(c))
#define ISLOWER(c) (ISASCII(c) && islower(c))
#define ISPUNCT(c) (ISASCII(c) && ispunct(c))
#define ISSPACE(c) (ISASCII(c) && isspace(c))
#define ISUPPER(c) (ISASCII(c) && isupper(c))
#define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))
#ifdef WILD_TEST_ITERATIONS
int wildmatch_iteration_count;
#endif
static int domatch(const unsigned char *p, const unsigned char *text)
{
int matched, special;
unsigned char ch, prev;
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count++;
#endif
for ( ; (ch = *p) != '\0'; text++, p++) {
if (*text == '\0' && ch != '*')
return FALSE;
switch (ch) {
case '\\':
/* Literal match with following character. Note that the test
* in "default" handles the p[1] == '\0' failure case. */
ch = *++p;
/* FALLTHROUGH */
default:
if (*text != ch)
return FALSE;
continue;
case '?':
/* Match anything but '/'. */
if (*text == '/')
return FALSE;
continue;
case '*':
if (*++p == '*') {
while (*++p == '*') {}
special = TRUE;
}
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;
}
for ( ; *text; text++) {
if ((matched = domatch(p, text)) != FALSE) {
if (!special || matched != ABORT_TO_STARSTAR)
return matched;
}
else if (!special && *text == '/')
return ABORT_TO_STARSTAR;
}
return ABORT_ALL;
case '[':
ch = *++p;
#ifdef NEGATE_CLASS2
if (ch == NEGATE_CLASS2)
ch = NEGATE_CLASS;
#endif
/* Assign literal TRUE/FALSE because of "matched" comparison. */
special = ch == NEGATE_CLASS? TRUE : FALSE;
if (special) {
/* Inverted character class. */
ch = *++p;
}
prev = 0;
matched = FALSE;
do {
if (!ch)
return ABORT_ALL;
if (ch == '\\') {
ch = *++p;
if (!ch)
return ABORT_ALL;
if (*text == ch)
matched = TRUE;
}
else if (ch == '-' && prev && p[1] && p[1] != ']') {
ch = *++p;
if (ch == '\\') {
ch = *++p;
if (!ch)
return ABORT_ALL;
}
if (*text <= ch && *text >= prev)
matched = TRUE;
ch = 0; /* This makes "prev" get set to 0. */
}
else if (ch == '[' && p[1] == ':') {
const unsigned char *s = p += 2;
int i;
while ((ch = *p) && ch != ']') p++;
if (!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)
matched = TRUE;
continue;
}
if (CC_EQ(s,i, "alnum")) {
if (ISALNUM(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "alpha")) {
if (ISALPHA(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "blank")) {
if (ISBLANK(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "cntrl")) {
if (ISCNTRL(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "digit")) {
if (ISDIGIT(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "graph")) {
if (ISGRAPH(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "lower")) {
if (ISLOWER(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "print")) {
if (ISPRINT(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "punct")) {
if (ISPUNCT(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "space")) {
if (ISSPACE(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "upper")) {
if (ISUPPER(*text))
matched = TRUE;
}
else if (CC_EQ(s,i, "xdigit")) {
if (ISXDIGIT(*text))
matched = TRUE;
}
else /* malformed [:class:] string */
return ABORT_ALL;
ch = 0; /* This makes "prev" get set to 0. */
}
else if (*text == ch)
matched = TRUE;
} while (prev = ch, (ch = *++p) != ']');
if (matched == special || *text == '/')
return FALSE;
continue;
}
}
return *text == '\0';
}
/* Find the pattern (p) in the text string (t). */
int wildmatch(const char *p, const char *t)
{
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count = 0;
#endif
return domatch((const unsigned char*)p, (const unsigned char*)t) == TRUE;
}

3
lib/wildmatch.h Normal file
View File

@@ -0,0 +1,3 @@
/* wildmatch.h */
int wildmatch(const char *p, const char *text);

View File

@@ -3,20 +3,20 @@
/* some fixes
*
* Copyright (C) 2001 by Martin Pool <mbp@samba.org>
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
*/
/*
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -36,7 +36,7 @@
* 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
* 4) If it's a global then initialise it in init_globals. If a local
* (ie. service) parameter then initialise it in the sDefault structure
*
*
*
* Notes:
* The configuration file is processed sequentially for speed. It is NOT
@@ -48,6 +48,8 @@
*
*/
/* TODO: Parameter to set debug level on server. */
#include "rsync.h"
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
#define strequal(a,b) (strcasecmp(a,b)==0)
@@ -59,7 +61,7 @@ typedef char pstring[1024];
typedef enum
{
P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
P_STRING,P_GSTRING,P_ENUM,P_SEP
P_PATH,P_STRING,P_GSTRING,P_ENUM,P_SEP
} parm_type;
typedef enum
@@ -91,7 +93,7 @@ struct parm_struct
#define iSERVICE(i) (*pSERVICE(i))
#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices))
/*
/*
* This structure describes global (ie., server-wide) parameters.
*/
typedef struct
@@ -99,16 +101,16 @@ typedef struct
char *motd_file;
char *log_file;
char *pid_file;
int syslog_facility;
char *socket_options;
int syslog_facility;
int max_verbosity;
} global;
static global Globals;
/*
* This structure describes a single service.
/*
* This structure describes a single service.
*/
typedef struct
{
@@ -117,6 +119,7 @@ typedef struct
char *comment;
char *lock_file;
BOOL read_only;
BOOL write_only;
BOOL list;
BOOL use_chroot;
BOOL transfer_logging;
@@ -142,19 +145,29 @@ typedef struct
/* This is a default service used to prime a services structure */
static service sDefault =
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 */
/* 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 */
NULL, /* hosts allow */
NULL, /* hosts deny */
NULL, /* auth users */
@@ -211,7 +224,7 @@ static struct enum_list enum_facilities[] = {
{ LOG_NEWS, "news" },
#endif
#ifdef LOG_AUTH
{ LOG_AUTH, "security" },
{ LOG_AUTH, "security" },
#endif
#ifdef LOG_SYSLOG
{ LOG_SYSLOG, "syslog" },
@@ -257,14 +270,16 @@ static struct parm_struct parm_table[] =
{"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},
{"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_STRING, P_LOCAL, &sDefault.path, 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},
@@ -293,10 +308,11 @@ Initialise the global parameter structure.
***************************************************************************/
static void init_globals(void)
{
memset(&Globals, 0, sizeof(Globals));
memset(&Globals, 0, sizeof Globals);
#ifdef LOG_DAEMON
Globals.syslog_facility = LOG_DAEMON;
#endif
Globals.max_verbosity = 1;
}
/***************************************************************************
@@ -308,8 +324,8 @@ static void init_locals(void)
/*
In this section all the functions that are used to access the
parameters from the rest of the program are defined
In this section all the functions that are used to access the
parameters from the rest of the program are defined
*/
#define FN_GLOBAL_STRING(fn_name,ptr) \
@@ -336,12 +352,14 @@ FN_GLOBAL_STRING(lp_log_file, &Globals.log_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_LOCAL_STRING(lp_name, name)
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)
@@ -365,12 +383,11 @@ FN_LOCAL_INTEGER(lp_timeout, timeout)
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
/* local prototypes */
static int strwicmp( char *psz1, char *psz2 );
static int map_parameter( char *parmname);
static BOOL set_boolean( BOOL *pb, char *parmvalue );
static int strwicmp(char *psz1, char *psz2);
static int map_parameter(char *parmname);
static BOOL set_boolean(BOOL *pb, char *parmvalue);
static int getservicebyname(char *name, service *pserviceDest);
static void copy_service( service *pserviceDest,
service *pserviceSource);
static void copy_service(service *pserviceDest, service *pserviceSource);
static BOOL do_parameter(char *parmname, char *parmvalue);
static BOOL do_section(char *sectionname);
@@ -410,7 +427,7 @@ static void string_set(char **s, const char *v)
/***************************************************************************
add a new service to the services array initialising it with the given
add a new service to the services array initialising it with the given
service
***************************************************************************/
static int add_a_service(service *pservice, char *name)
@@ -422,7 +439,7 @@ static int add_a_service(service *pservice, char *name)
tservice = *pservice;
/* it might already exist */
if (name)
if (name)
{
i = getservicebyname(name,NULL);
if (i >= 0)
@@ -431,10 +448,10 @@ static int add_a_service(service *pservice, char *name)
i = iNumServices;
ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
ServicePtrs = realloc_array(ServicePtrs, service *, num_to_alloc);
if (ServicePtrs)
pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
pSERVICE(iNumServices) = new(service);
if (!ServicePtrs || !pSERVICE(iNumServices))
return(-1);
@@ -444,7 +461,7 @@ static int add_a_service(service *pservice, char *name)
init_service(pSERVICE(i));
copy_service(pSERVICE(i),&tservice);
if (name)
string_set(&iSERVICE(i).name,name);
string_set(&iSERVICE(i).name,name);
return(i);
}
@@ -468,11 +485,12 @@ static int strwicmp(char *psz1, char *psz2)
/* sync the strings on first non-whitespace */
while (1)
{
while (isspace(*psz1))
while (isspace(* (unsigned char *) psz1))
psz1++;
while (isspace(*psz2))
while (isspace(* (unsigned char *) psz2))
psz2++;
if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
if (toupper(* (unsigned char *) psz1) != toupper(* (unsigned char *) psz2)
|| *psz1 == '\0' || *psz2 == '\0')
break;
psz1++;
psz2++;
@@ -481,7 +499,7 @@ static int strwicmp(char *psz1, char *psz2)
}
/***************************************************************************
Map a parameter's string representation to something we can use.
Map a parameter's string representation to something we can use.
Returns False if the parameter string is not recognised, else TRUE.
***************************************************************************/
static int map_parameter(char *parmname)
@@ -491,7 +509,7 @@ static int map_parameter(char *parmname)
if (*parmname == '-')
return(-1);
for (iIndex = 0; parm_table[iIndex].label; iIndex++)
for (iIndex = 0; parm_table[iIndex].label; iIndex++)
if (strwicmp(parm_table[iIndex].label, parmname) == 0)
return(iIndex);
@@ -502,7 +520,7 @@ static int map_parameter(char *parmname)
/***************************************************************************
Set a boolean variable from the text value stored in the passed string.
Returns True in success, False if the passed string does not correctly
Returns True in success, False if the passed string does not correctly
represent a boolean.
***************************************************************************/
static BOOL set_boolean(BOOL *pb, char *parmvalue)
@@ -536,7 +554,7 @@ static int getservicebyname(char *name, service *pserviceDest)
int iService;
for (iService = iNumServices - 1; iService >= 0; iService--)
if (strwicmp(iSERVICE(iService).name, name) == 0)
if (strwicmp(iSERVICE(iService).name, name) == 0)
{
if (pserviceDest != NULL)
copy_service(pserviceDest, pSERVICE(iService));
@@ -552,7 +570,7 @@ static int getservicebyname(char *name, service *pserviceDest)
Copy a service structure to another
***************************************************************************/
static void copy_service(service *pserviceDest,
static void copy_service(service *pserviceDest,
service *pserviceSource)
{
int i;
@@ -560,9 +578,9 @@ static void copy_service(service *pserviceDest,
for (i=0;parm_table[i].label;i++)
if (parm_table[i].ptr && parm_table[i].class == P_LOCAL) {
void *def_ptr = parm_table[i].ptr;
void *src_ptr =
void *src_ptr =
((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
void *dest_ptr =
void *dest_ptr =
((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
switch (parm_table[i].type)
@@ -582,6 +600,7 @@ static void copy_service(service *pserviceDest,
*(char *)dest_ptr = *(char *)src_ptr;
break;
case P_PATH:
case P_STRING:
string_set(dest_ptr,*(char **)src_ptr);
break;
@@ -602,6 +621,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
int parmnum, i;
void *parm_ptr=NULL; /* where we are going to store the result */
void *def_ptr=NULL;
char *cp;
parmnum = map_parameter(parmname);
@@ -648,6 +668,15 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
sscanf(parmvalue,"%o",(int *)parm_ptr);
break;
case P_PATH:
string_set(parm_ptr,parmvalue);
if ((cp = *(char**)parm_ptr) != NULL) {
int len = strlen(cp);
while (len > 1 && cp[len-1] == '/') len--;
cp[len] = '\0';
}
break;
case P_STRING:
string_set(parm_ptr,parmvalue);
break;
@@ -699,7 +728,7 @@ static BOOL do_section(char *sectionname)
init_locals();
/* if we've just struck a global section, note the fact. */
bInGlobalSection = isglobal;
bInGlobalSection = isglobal;
/* check for multiple global sections */
if (bInGlobalSection)
@@ -731,26 +760,34 @@ static BOOL do_section(char *sectionname)
/***************************************************************************
Load the services array from the services file. Return True on success,
Load the services array from the services file. Return True on success,
False on failure.
***************************************************************************/
BOOL lp_load(char *pszFname, int globals_only)
{
extern int am_server;
extern int am_daemon;
extern int am_root;
pstring n2;
BOOL bRetval;
bRetval = False;
bInGlobalSection = True;
init_globals();
pstrcpy(n2,pszFname);
if (pszFname)
pstrcpy(n2,pszFname);
else if (am_server && am_daemon && !am_root)
pstrcpy(n2,RSYNCD_USERCONF);
else
pstrcpy(n2,RSYNCD_SYSCONF);
/* We get sections first, so have to start 'behind' to make up */
iServiceIndex = -1;
bRetval = pm_process(n2, globals_only?NULL:do_section, do_parameter);
return (bRetval);
}
@@ -774,7 +811,7 @@ int lp_number(char *name)
int iService;
for (iService = iNumServices - 1; iService >= 0; iService--)
if (strequal(lp_name(iService), name))
if (strcmp(lp_name(iService), name) == 0)
break;
return (iService);

385
log.c
View File

@@ -1,18 +1,18 @@
/* -*- c-file-style: "linux"; -*-
Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 2000-2001 by Martin Pool <mbp@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -27,36 +27,47 @@
*/
#include "rsync.h"
extern int am_daemon;
extern int am_server;
extern int am_sender;
extern int quiet;
extern int module_id;
extern int msg_fd_out;
extern char *auth_user;
extern char *log_format;
static int log_initialised;
static char *logfname;
static FILE *logfile;
static int log_error_fd = -1;
struct stats stats;
int log_got_error=0;
int log_got_error = 0;
struct {
int code;
char const *name;
} const rerr_names[] = {
{ RERR_SYNTAX , "syntax or usage error" },
{ RERR_PROTOCOL , "protocol incompatibility" },
{ RERR_FILESELECT , "errors selecting input/output files, dirs" },
{ RERR_UNSUPPORTED, "requested action not supported" },
{ RERR_STARTCLIENT, "error starting client-server protocol" },
{ 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_MALLOC , "error allocating core memory buffers" },
{ RERR_PARTIAL , "partial transfer" },
{ RERR_TIMEOUT , "timeout in data send/receive" },
{ RERR_SYNTAX , "syntax or usage error" },
{ RERR_PROTOCOL , "protocol incompatibility" },
{ RERR_FILESELECT , "errors selecting input/output files, dirs" },
{ RERR_UNSUPPORTED, "requested action not supported" },
{ RERR_STARTCLIENT, "error starting client-server protocol" },
{ 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_MALLOC , "error allocating core memory buffers" },
{ RERR_PARTIAL , "some files could not be transferred" },
{ RERR_VANISHED , "some files vanished before they could be transferred" },
{ RERR_TIMEOUT , "timeout in data send/receive" },
{ RERR_CMD_FAILED , "remote shell failed" },
{ RERR_CMD_KILLED , "remote shell killed" },
{ RERR_CMD_RUN, "remote command could not be run" },
{ RERR_CMD_NOTFOUND, "remote command not found" },
{ 0, NULL }
{ RERR_CMD_NOTFOUND, "remote command not found" },
{ 0, NULL }
};
@@ -66,67 +77,12 @@ struct {
*/
static char const *rerr_name(int code)
{
int i;
for (i = 0; rerr_names[i].name; i++) {
if (rerr_names[i].code == code)
return rerr_names[i].name;
}
return NULL;
}
struct err_list {
struct err_list *next;
char *buf;
int len;
int written; /* how many bytes we have written so far */
};
static struct err_list *err_list_head;
static struct err_list *err_list_tail;
/* add an error message to the pending error list */
static void err_list_add(int code, char *buf, int len)
{
struct err_list *el;
el = (struct err_list *)malloc(sizeof(*el));
if (!el) exit_cleanup(RERR_MALLOC);
el->next = NULL;
el->buf = malloc(len+4);
if (!el->buf) exit_cleanup(RERR_MALLOC);
memcpy(el->buf+4, buf, len);
SIVAL(el->buf, 0, ((code+MPLEX_BASE)<<24) | len);
el->len = len+4;
el->written = 0;
if (err_list_tail) {
err_list_tail->next = el;
} else {
err_list_head = el;
}
err_list_tail = el;
}
/* try to push errors off the error list onto the wire */
void err_list_push(void)
{
if (log_error_fd == -1) return;
while (err_list_head) {
struct err_list *el = err_list_head;
int n = write(log_error_fd, el->buf+el->written, el->len - el->written);
/* don't check for an error if the best way of handling the error is
to ignore it */
if (n == -1) break;
if (n > 0) {
el->written += n;
}
if (el->written == el->len) {
free(el->buf);
err_list_head = el->next;
if (!err_list_head) err_list_tail = NULL;
free(el);
}
int i;
for (i = 0; rerr_names[i].name; i++) {
if (rerr_names[i].code == code)
return rerr_names[i].name;
}
return NULL;
}
@@ -135,7 +91,7 @@ static void logit(int priority, char *buf)
if (logfname) {
if (!logfile)
log_open();
fprintf(logfile,"%s [%d] %s",
fprintf(logfile,"%s [%d] %s",
timestring(time(NULL)), (int)getpid(), buf);
fflush(logfile);
} else {
@@ -145,16 +101,16 @@ static void logit(int priority, char *buf)
void log_init(void)
{
static int initialised;
int options = LOG_PID;
time_t t;
if (initialised) return;
initialised = 1;
if (log_initialised)
return;
log_initialised = 1;
/* this looks pointless, but it is needed in order for the
C library on some systems to fetch the timezone info
before the chroot */
* C library on some systems to fetch the timezone info
* before the chroot */
t = time(NULL);
localtime(&t);
@@ -183,7 +139,7 @@ void log_init(void)
#endif
}
void log_open()
void log_open(void)
{
if (logfname && !logfile) {
extern int orig_umask;
@@ -193,7 +149,7 @@ void log_open()
}
}
void log_close()
void log_close(void)
{
if (logfile) {
fclose(logfile);
@@ -201,84 +157,72 @@ void log_close()
}
}
/* setup the error file descriptor - used when we are a server
that is receiving files */
void set_error_fd(int fd)
{
log_error_fd = fd;
set_nonblocking(log_error_fd);
}
/* this is the underlying (unformatted) rsync debugging function. Call
it with FINFO, FERROR or FLOG */
* it with FINFO, FERROR or FLOG */
void rwrite(enum logcode code, char *buf, int len)
{
FILE *f=NULL;
extern int am_daemon;
extern int am_server;
extern int quiet;
FILE *f = NULL;
/* recursion can happen with certain fatal conditions */
if (quiet && code == FINFO) return;
if (quiet && code == FINFO)
return;
if (len < 0) exit_cleanup(RERR_MESSAGEIO);
if (len < 0)
exit_cleanup(RERR_MESSAGEIO);
buf[len] = 0;
if (code == FLOG) {
if (am_daemon) logit(LOG_INFO, buf);
return;
}
/* first try to pass it off to our sibling */
if (am_server && log_error_fd != -1) {
err_list_add(code, buf, len);
err_list_push();
return;
}
/* If that fails, try to pass it to the other end.
*
* io_multiplex_write can fail if we do not have a multiplexed
* connection at the moment, in which case we fall through and
* log locally instead. */
if (am_server && io_multiplex_write(code, buf, len)) {
if (am_server && msg_fd_out >= 0) {
/* Pass the message to our sibling. */
send_msg((enum msgcode)code, buf, len);
return;
}
if (am_daemon) {
static int depth;
int priority = LOG_INFO;
if (code == FERROR) priority = LOG_WARNING;
static int in_block;
char msg[2048];
int priority = code == FERROR ? LOG_WARNING : LOG_INFO;
if (depth) return;
if (in_block)
return;
in_block = 1;
if (!log_initialised)
log_init();
strlcpy(msg, buf, MIN((int)sizeof msg, len + 1));
logit(priority, msg);
in_block = 0;
depth++;
log_init();
logit(priority, buf);
depth--;
if (code == FLOG || !am_server)
return;
} else if (code == FLOG)
return;
if (am_server) {
/* Pass the message to the non-server side. */
if (io_multiplex_write((enum msgcode)code, buf, len))
return;
if (am_daemon) {
/* TODO: can we send the error to the user somehow? */
return;
}
}
if (code == FERROR) {
log_got_error = 1;
f = stderr;
}
}
if (code == FINFO) {
if (am_server)
f = stderr;
else
f = stdout;
}
if (code == FINFO)
f = am_server ? stderr : stdout;
if (!f) exit_cleanup(RERR_MESSAGEIO);
if (!f)
exit_cleanup(RERR_MESSAGEIO);
if (fwrite(buf, len, 1, f) != 1) exit_cleanup(RERR_MESSAGEIO);
if (fwrite(buf, len, 1, f) != 1)
exit_cleanup(RERR_MESSAGEIO);
if (buf[len-1] == '\r' || buf[len-1] == '\n') fflush(f);
if (buf[len-1] == '\r' || buf[len-1] == '\n')
fflush(f);
}
@@ -286,19 +230,18 @@ void rwrite(enum logcode code, char *buf, int len)
* FLOG. */
void rprintf(enum logcode code, const char *format, ...)
{
va_list ap;
char buf[1024];
int len;
va_list ap;
char buf[MAXPATHLEN+512];
size_t len;
va_start(ap, format);
/* Note: might return -1 */
len = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
/* Deal with buffer overruns. Instead of panicking, just
* truncate the resulting string. Note that some vsnprintf()s
* return -1 on truncation, e.g., glibc 2.0.6 and earlier. */
if ((size_t) len > sizeof(buf)-1 || len < 0) {
* 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[] = "[...]";
/* Reset length, and zero-terminate the end of our buffer */
@@ -335,34 +278,24 @@ void rprintf(enum logcode code, const char *format, ...)
* message catalog we need to call it once before chroot-ing. */
void rsyserr(enum logcode code, int errcode, const char *format, ...)
{
va_list ap;
char buf[1024];
int len;
size_t sys_len;
char *sysmsg;
va_list ap;
char buf[MAXPATHLEN+512];
size_t len;
strcpy(buf, RSYNC_NAME ": ");
len = (sizeof RSYNC_NAME ": ") - 1;
va_start(ap, format);
/* Note: might return <0 */
len = vsnprintf(buf, sizeof(buf), format, ap);
len += vsnprintf(buf + len, sizeof buf - len, format, ap);
va_end(ap);
/* TODO: Put in RSYNC_NAME at the start. */
if ((size_t) len > sizeof(buf)-1)
if (len < sizeof buf) {
len += snprintf(buf + len, sizeof buf - len,
": %s (%d)\n", strerror(errcode), errcode);
}
if (len >= sizeof buf)
exit_cleanup(RERR_MESSAGEIO);
sysmsg = strerror(errcode);
sys_len = strlen(sysmsg);
if ((size_t) len + 3 + sys_len > sizeof(buf) - 1)
exit_cleanup(RERR_MESSAGEIO);
strcpy(buf + len, ": ");
len += 2;
strcpy(buf + len, sysmsg);
len += sys_len;
strcpy(buf + len, "\n");
len++;
rwrite(code, buf, len);
}
@@ -371,7 +304,6 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
void rflush(enum logcode code)
{
FILE *f = NULL;
extern int am_daemon;
if (am_daemon) {
return;
@@ -379,19 +311,18 @@ void rflush(enum logcode code)
if (code == FLOG) {
return;
}
}
if (code == FERROR) {
f = stderr;
}
}
if (code == FINFO) {
extern int am_server;
if (am_server)
if (am_server)
f = stderr;
else
f = stdout;
}
}
if (!f) exit_cleanup(RERR_MESSAGEIO);
fflush(f);
@@ -400,20 +331,15 @@ void rflush(enum logcode code)
/* a generic logging routine for send/recv, with parameter
substitiution */
* substitiution */
static void log_formatted(enum logcode code,
char *format, char *op, struct file_struct *file,
struct stats *initial_stats)
{
extern int module_id;
extern char *auth_user;
char buf[1024];
char buf2[1024];
char *p, *s, *n;
size_t l;
extern struct stats stats;
extern int am_sender;
extern int am_daemon;
int64 b;
/* We expand % codes one by one in place in buf. We don't
@@ -421,60 +347,60 @@ static void log_formatted(enum logcode code,
* rather keep going until we reach the nul of the format.
* Just to make sure we don't clobber that nul and therefore
* accidentally keep going, we zero the buffer now. */
memset(buf, 0, sizeof buf);
strlcpy(buf, format, sizeof(buf));
l = strlcpy(buf, format, sizeof buf);
if (l < sizeof buf)
memset(buf + l, 0, sizeof buf - l);
for (s=&buf[0];
s && (p=strchr(s,'%')); ) {
for (s = &buf[0]; s && (p = strchr(s,'%')); ) {
n = NULL;
s = p + 1;
switch (p[1]) {
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",
(double)file->length);
case 'l':
snprintf(buf2,sizeof(buf2),"%.0f",
(double)file->length);
n = buf2;
break;
case 'p':
snprintf(buf2,sizeof(buf2),"%d",
(int)getpid());
case 'p':
snprintf(buf2,sizeof(buf2),"%d",
(int)getpid());
n = buf2;
break;
case 'o': n = op; break;
case 'f':
snprintf(buf2, sizeof(buf2), "%s/%s",
file->basedir?file->basedir:"",
case 'f':
pathjoin(buf2, sizeof buf2,
file->basedir ? file->basedir : "",
f_name(file));
clean_fname(buf2);
n = buf2;
clean_fname(buf2, 0);
n = buf2;
if (*n == '/') n++;
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':
case 'b':
if (am_sender) {
b = stats.total_written -
b = stats.total_written -
initial_stats->total_written;
} else {
b = stats.total_read -
b = stats.total_read -
initial_stats->total_read;
}
snprintf(buf2,sizeof(buf2),"%.0f", (double)b);
snprintf(buf2,sizeof(buf2),"%.0f", (double)b);
n = buf2;
break;
case 'c':
case 'c':
if (!am_sender) {
b = stats.total_written -
b = stats.total_written -
initial_stats->total_written;
} else {
b = stats.total_read -
b = stats.total_read -
initial_stats->total_read;
}
snprintf(buf2,sizeof(buf2),"%.0f", (double)b);
snprintf(buf2,sizeof(buf2),"%.0f", (double)b);
n = buf2;
break;
}
@@ -512,10 +438,6 @@ static void log_formatted(enum logcode code,
/* log the outgoing transfer of a file */
void log_send(struct file_struct *file, struct stats *initial_stats)
{
extern int module_id;
extern int am_server;
extern char *log_format;
if (lp_transfer_logging(module_id)) {
log_formatted(FLOG, lp_log_format(module_id), "send", file, initial_stats);
} else if (log_format && !am_server) {
@@ -526,10 +448,6 @@ void log_send(struct file_struct *file, struct stats *initial_stats)
/* log the incoming transfer of a file */
void log_recv(struct file_struct *file, struct stats *initial_stats)
{
extern int module_id;
extern int am_server;
extern char *log_format;
if (lp_transfer_logging(module_id)) {
log_formatted(FLOG, lp_log_format(module_id), "recv", file, initial_stats);
} else if (log_format && !am_server) {
@@ -549,33 +467,24 @@ void log_recv(struct file_struct *file, struct stats *initial_stats)
void log_exit(int code, const char *file, int line)
{
if (code == 0) {
extern struct stats stats;
rprintf(FLOG,"wrote %.0f bytes read %.0f bytes total size %.0f\n",
(double)stats.total_written,
(double)stats.total_read,
(double)stats.total_size);
} else {
const char *name;
const char *name;
name = rerr_name(code);
if (!name)
name = "unexplained error";
rprintf(FERROR,"rsync error: %s (code %d) at %s(%d)\n",
name, code, file, line);
name = rerr_name(code);
if (!name)
name = "unexplained error";
/* 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);
} else {
rprintf(FERROR, "rsync error: %s (code %d) at %s(%d)\n",
name, code, file, line);
}
}
}
/*
* Log the incoming transfer of a file for interactive use,
* this will be called at the end where the client was run.
* Called when a file starts to be transferred.
*/
void log_transfer(struct file_struct *file, const char *fname)
{
extern int verbose;
if (!verbose) return;
rprintf(FINFO, "%s\n", fname);
}

999
main.c
View File

File diff suppressed because it is too large Load Diff

305
match.c
View File

@@ -1,17 +1,17 @@
/*
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -19,17 +19,17 @@
#include "rsync.h"
extern int csum_length;
extern int verbose;
extern int am_server;
extern int remote_version;
extern int do_progress;
extern int checksum_seed;
extern int inplace;
extern int make_backups;
typedef unsigned short tag;
#define TABLESIZE (1<<16)
#define NULL_TAG (-1)
#define NULL_TAG ((size_t)-1)
static int false_alarms;
static int tag_hits;
@@ -43,53 +43,64 @@ static int total_matches;
extern struct stats stats;
struct target {
tag t;
int i;
tag t;
size_t i;
};
static struct target *targets;
static int *tag_table;
static size_t *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);
return (int)t1->t - (int)t2->t;
}
static void build_hash_table(struct sum_struct *s)
{
int i;
size_t i;
if (!tag_table)
tag_table = (int *)malloc(sizeof(tag_table[0])*TABLESIZE);
if (!tag_table)
tag_table = new_array(size_t, TABLESIZE);
targets = (struct target *)malloc(sizeof(targets[0])*s->count);
if (!tag_table || !targets)
out_of_memory("build_hash_table");
targets = new_array(struct target, s->count);
if (!tag_table || !targets)
out_of_memory("build_hash_table");
for (i=0;i<(int) s->count;i++) {
targets[i].i = i;
targets[i].t = gettag(s->sums[i].sum1);
}
for (i = 0; i < s->count; i++) {
targets[i].i = i;
targets[i].t = gettag(s->sums[i].sum1);
}
qsort(targets,s->count,sizeof(targets[0]),(int (*)())compare_targets);
qsort(targets,s->count,sizeof(targets[0]),(int (*)())compare_targets);
for (i=0;i<TABLESIZE;i++)
tag_table[i] = NULL_TAG;
for (i = 0; i < TABLESIZE; i++)
tag_table[i] = NULL_TAG;
for (i=s->count-1;i>=0;i--) {
tag_table[targets[i].t] = i;
}
for (i = s->count; i-- > 0; )
tag_table[targets[i].t] = i;
}
static OFF_T last_match;
/**
* Transmit a literal and/or match token.
*
* This delightfully-named function is called either when we find a
* match and need to transmit all the unmatched data leading up to it,
* or when we get bored of accumulating literal data and just need to
* transmit it. As a result of this second case, it is called even if
* we have not matched at all!
*
* @param i If >0, the number of a matched token. If 0, indicates we
* have only literal data.
**/
static void matched(int f,struct sum_struct *s,struct map_struct *buf,
OFF_T offset,int i)
{
@@ -97,7 +108,7 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
OFF_T j;
if (verbose > 2 && i >= 0)
rprintf(FINFO,"match at %.0f last_match=%.0f j=%d len=%d n=%.0f\n",
rprintf(FINFO,"match at %.0f last_match=%.0f j=%d len=%u n=%.0f\n",
(double)offset,(double)last_match,i,s->sums[i].len,(double)n);
send_token(f,i,buf,last_match,n,i<0?0:s->sums[i].len);
@@ -107,8 +118,8 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
stats.matched_data += s->sums[i].len;
n += s->sums[i].len;
}
for (j=0;j<n;j+=CHUNK_SIZE) {
for (j = 0; j < n; j += CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,n-j);
sum_update(map_ptr(buf,last_match+j,n1),n1);
}
@@ -119,126 +130,167 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
else
last_match = offset;
if (buf) {
if (buf && do_progress) {
show_progress(last_match, buf->file_size);
if (i == -1) end_progress(buf->file_size);
if (i == -1)
end_progress(buf->file_size);
}
}
static void hash_search(int f,struct sum_struct *s,
struct map_struct *buf,OFF_T len)
struct map_struct *buf, OFF_T len)
{
OFF_T offset, end;
int j,k, last_i;
OFF_T offset, end, backup;
unsigned int k;
size_t want_i;
char sum2[SUM_LENGTH];
uint32 s1, s2, sum;
uint32 s1, s2, sum;
int more;
schar *map;
/* last_i is used to encourage adjacent matches, allowing the RLL coding of the
output to work more efficiently */
last_i = -1;
/* want_i is used to encourage adjacent matches, allowing the RLL
* coding of the output to work more efficiently. */
want_i = 0;
if (verbose > 2)
rprintf(FINFO,"hash search b=%d len=%.0f\n",s->n,(double)len);
if (verbose > 2) {
rprintf(FINFO,"hash search b=%u len=%.0f\n",
s->blength, (double)len);
}
k = MIN(len, s->blength);
map = (schar *)map_ptr(buf, 0, k);
k = MIN(len, s->n);
map = (schar *)map_ptr(buf,0,k);
sum = get_checksum1((char *)map, k);
s1 = sum & 0xFFFF;
s2 = sum >> 16;
if (verbose > 3)
rprintf(FINFO, "sum=%.8x k=%d\n", sum, k);
rprintf(FINFO, "sum=%.8x k=%u\n", sum, k);
offset = 0;
end = len + 1 - s->sums[s->count-1].len;
if (verbose > 3)
rprintf(FINFO,"hash search s->n=%d len=%.0f count=%d\n",
s->n,(double)len,s->count);
if (verbose > 3) {
rprintf(FINFO, "hash search s->blength=%u len=%.0f count=%.0f\n",
s->blength, (double)len, (double)s->count);
}
do {
tag t = gettag2(s1,s2);
int done_csum2 = 0;
j = tag_table[t];
size_t j = tag_table[t];
if (verbose > 4)
rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
if (j == NULL_TAG) {
if (j == NULL_TAG)
goto null_tag;
}
sum = (s1 & 0xffff) | (s2 << 16);
tag_hits++;
for (; j < (int) s->count && targets[j].t == t; j++) {
int l, i = targets[j].i;
if (sum != s->sums[i].sum1) continue;
do {
unsigned int l;
size_t i = targets[j].i;
if (sum != s->sums[i].sum1)
continue;
/* also make sure the two blocks are the same length */
l = MIN(s->n,len-offset);
if (l != s->sums[i].len) continue;
l = MIN((OFF_T)s->blength, len-offset);
if (l != s->sums[i].len)
continue;
/* inplace: ensure chunk's offset is either >= our
* offset or that the data didn't move. */
if (inplace && !make_backups && s->sums[i].offset < offset
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET))
continue;
if (verbose > 3)
rprintf(FINFO,"potential match at %.0f target=%d %d sum=%08x\n",
(double)offset,j,i,sum);
rprintf(FINFO,"potential match at %.0f target=%.0f %.0f sum=%08x\n",
(double)offset,(double)j,(double)i,sum);
if (!done_csum2) {
map = (schar *)map_ptr(buf,offset,l);
get_checksum2((char *)map,l,sum2);
done_csum2 = 1;
}
if (memcmp(sum2,s->sums[i].sum2,csum_length) != 0) {
if (memcmp(sum2,s->sums[i].sum2,s->s2length) != 0) {
false_alarms++;
continue;
}
/* we've found a match, but now check to see
if last_i can hint at a better match */
for (j++; j < (int) s->count && targets[j].t == t; j++) {
int i2 = targets[j].i;
if (i2 == last_i + 1) {
if (sum != s->sums[i2].sum1) break;
if (memcmp(sum2,s->sums[i2].sum2,csum_length) != 0) break;
/* we've found an adjacent match - the RLL coder
will be happy */
i = i2;
break;
}
/* If inplace is enabled, the best possible match is
* one with an identical offset, so we prefer that over
* the following want_i optimization. */
if (inplace && !make_backups) {
do {
size_t i2 = targets[j].i;
if (s->sums[i2].offset != offset)
continue;
if (i2 != i) {
if (sum != s->sums[i2].sum1)
break;
if (memcmp(sum2, s->sums[i2].sum2,
s->s2length) != 0)
break;
i = i2;
}
/* This chunk was at the same offset on
* 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);
}
last_i = i;
/* we've found a match, but now check to see
* if want_i can hint at a better match. */
if (i != want_i && want_i < s->count
&& (!inplace || make_backups || s->sums[want_i].offset >= offset
|| s->sums[want_i].flags & SUMFLG_SAME_OFFSET)
&& sum == s->sums[want_i].sum1
&& memcmp(sum2, s->sums[want_i].sum2, s->s2length) == 0) {
/* we've found an adjacent match - the RLL coder
* will be happy */
i = want_i;
}
set_want_i:
want_i = i + 1;
matched(f,s,buf,offset,i);
offset += s->sums[i].len - 1;
k = MIN((len-offset), s->n);
map = (schar *)map_ptr(buf,offset,k);
k = MIN(s->blength, len-offset);
map = (schar *)map_ptr(buf, offset, k);
sum = get_checksum1((char *)map, k);
s1 = sum & 0xFFFF;
s2 = sum >> 16;
matches++;
break;
}
} while (++j < s->count && targets[j].t == t);
null_tag:
backup = offset - last_match;
/* We sometimes read 1 byte prior to last_match... */
if (backup < 0)
backup = 0;
/* Trim off the first byte from the checksum */
map = (schar *)map_ptr(buf,offset,k+1);
more = offset + k < len;
map = (schar *)map_ptr(buf, offset - backup, k + more + backup)
+ backup;
s1 -= map[0] + CHAR_OFFSET;
s2 -= k * (map[0]+CHAR_OFFSET);
/* Add on the next byte (if there is one) to the checksum */
if (k < (len-offset)) {
s1 += (map[k]+CHAR_OFFSET);
if (more) {
s1 += map[k] + CHAR_OFFSET;
s2 += s1;
} else {
} else
--k;
}
/* By matching early we avoid re-reading the
data 3 times in the case where a token
@@ -246,45 +298,57 @@ static void hash_search(int f,struct sum_struct *s,
match. The 3 reads are caused by the
running match, the checksum update and the
literal send. */
if (offset > last_match &&
offset-last_match >= CHUNK_SIZE+s->n &&
(end-offset > CHUNK_SIZE)) {
matched(f,s,buf,offset - s->n, -2);
if (backup >= CHUNK_SIZE + s->blength
&& end - offset > CHUNK_SIZE) {
matched(f,s,buf,offset - s->blength, -2);
}
} while (++offset < end);
matched(f,s,buf,len,-1);
map_ptr(buf,len-1,1);
}
void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
/**
* Scan through a origin file, looking for sections that match
* checksums from the generator, and transmit either literal or token
* data.
*
* Also calculates the MD4 checksum of the whole file, using the md
* accumulator. This is transmitted with the file as protection
* against corruption on the wire.
*
* @param s Checksums received from the generator. If <tt>s->count ==
* 0</tt>, then there are actually no checksums for this file.
*
* @param len Length of the file to send.
**/
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
{
char file_sum[MD4_SUM_LENGTH];
extern int write_batch; /* dw */
last_match = 0;
false_alarms = 0;
tag_hits = 0;
matches=0;
data_transfer=0;
matches = 0;
data_transfer = 0;
sum_init();
sum_init(checksum_seed);
if (len > 0 && s->count>0) {
build_hash_table(s);
if (verbose > 2)
if (verbose > 2)
rprintf(FINFO,"built hash table\n");
hash_search(f,s,buf,len);
if (verbose > 2)
if (verbose > 2)
rprintf(FINFO,"done hash search\n");
} else {
OFF_T j;
/* by doing this in pieces we avoid too many seeks */
for (j=0;j<(len-CHUNK_SIZE);j+=CHUNK_SIZE) {
for (j = 0; j < len-CHUNK_SIZE; j += CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,(len-CHUNK_SIZE)-j);
matched(f,s,buf,j+n1,-2);
}
@@ -292,24 +356,23 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
}
sum_end(file_sum);
/* If we had a read error, send a bad checksum. */
if (buf && buf->status != 0)
file_sum[0]++;
if (remote_version >= 14) {
if (verbose > 2)
rprintf(FINFO,"sending file_sum\n");
write_buf(f,file_sum,MD4_SUM_LENGTH);
if (write_batch) /* dw */
write_batch_delta_file(file_sum, MD4_SUM_LENGTH);
}
if (verbose > 2)
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);
total_tag_hits += tag_hits;
total_false_alarms += false_alarms;
total_matches += matches;

View File

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

1132
options.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.1
Version: 2.6.3pre2
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-%{version}.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
@@ -21,11 +21,18 @@ A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
* Thu Jan 30 2003 Horst von Brand <vonbrand@inf.utfsm.cl>
Fixed "Sept" date in %changelog here
Use %{_mandir} to point to manpages
Support for compressed manpages (* at end catches them in %files)
Add doc/README-SGML and doc/rsync.sgml to %doc
* Mon Sep 11 2000 John H Terpstra <jht@turbolinux.com>
Changed target paths to be Linux Standards Base compliant
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
@@ -62,23 +69,25 @@ previous package(s).)
%setup
%build
./configure --prefix=/usr --mandir=/usr/share/man
./configure --prefix=/usr --mandir=%{_mandir}
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
mkdir -p $RPM_BUILD_ROOT/usr/bin
mkdir -p $RPM_BUILD_ROOT/%{_mandir}/man{1,5}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
install -m644 rsync.1 $RPM_BUILD_ROOT/%{_mandir}/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/%{_mandir}/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/share/man/man1/rsync.1
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
%attr(-,root,root) %{_mandir}/man1/rsync.1*
%attr(-,root,root) %{_mandir}/man5/rsyncd.conf.5*
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING
%attr(-,root,root) %doc doc/README-SGML doc/rsync.sgml

View File

@@ -1,84 +0,0 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: PVERSION
Release: PRELEASE
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
Changed target paths to be Linux Standards Base compliant
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr --mandir=/usr/share/man
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/share/man/man1/rsync.1
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -1,81 +0,0 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.1
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -1,81 +0,0 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: PVERSION
Release: PRELEASE
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -1,81 +0,0 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.1
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1*
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -1,81 +0,0 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: PVERSION
Release: PRELEASE
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1*
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -0,0 +1,94 @@
#!/bin/sh
# Shell script for building Solaris package of rsync
# Author: Jens Apel <jens.apel@web.de>
# License: GPL
#
# BASEDIR is /usr/local and should be the same as the
# --prefix parameter of configure
#
# this script should be copied under
# packaging/solaris/5.8/build_pkg.sh
# Definitions start here
# you can edit this, if you like
# The Package name under which rsync will b installed
PKGNAME=SMBrsync
# Extract common info requires for the 'info' part of the package.
# This should be made generic and generated by the configure script
# but for now it is hard coded
BASEDIR=/usr/local
VERSION="2.5.5"
ARCH=`uname -p`
NAME=rsync
# Definitions end here
# Please do not edit below this line or you know what you do.
## Start by faking root install
echo "Creating install directory (fake $BASEDIR)..."
START=`pwd`
FAKE_ROOT=$START/${PKGNAME}
mkdir $FAKE_ROOT
# copy the binary and the man page to their places
mkdir $FAKE_ROOT/bin
mkdir -p $FAKE_ROOT/doc/rsync
mkdir -p $FAKE_ROOT/man/man1
mkdir -p $FAKE_ROOT/man/man5
cp ../../../rsync $FAKE_ROOT/bin/rsync
cp ../../../rsync.1 $FAKE_ROOT/man/man1/rsync.1
cp ../../../rsyncd.conf.5 $FAKE_ROOT/man/man5/rsyncd.conf.5
cp ../../../README $FAKE_ROOT/doc/rsync/README
cp ../../../COPYING $FAKE_ROOT/doc/rsync/COPYING
cp ../../../tech_report.pdf $FAKE_ROOT/doc/rsync/tech_report.pdf
cp ../../../COPYING $FAKE_ROOT/COPYING
## Build info file
echo "Building pkginfo file..."
cat > $FAKE_ROOT/pkginfo << EOF_INFO
PKG=$PKGNAME
NAME=$NAME
DESC="Program for efficient remote updates of files."
VENDOR="Samba Team URL: http://samba.anu.edu.au/rsync/"
BASEDIR=$BASEDIR
ARCH=$ARCH
VERSION=$VERSION
CATEGORY=application
CLASSES=none
EOF_INFO
## Build prototype file
cat > $FAKE_ROOT/prototype << EOFPROTO
i copyright=COPYING
i pkginfo=pkginfo
d none bin 0755 bin bin
f none bin/rsync 0755 bin bin
d none doc 0755 bin bin
d none doc/$NAME 0755 bin bin
f none doc/$NAME/README 0644 bin bin
f none doc/$NAME/COPYING 0644 bin bin
f none doc/$NAME/tech_report.pdf 0644 bin bin
d none man 0755 bin bin
d none man/man1 0755 bin bin
f none man/man1/rsync.1 0644 bin bin
d none man/man5 0755 bin bin
f none man/man5/rsyncd.conf.5 0644 bin bin
EOFPROTO
## And now build the package.
OUTPUTFILE=$PKGNAME-$VERSION-sol8-$ARCH-local.pkg
echo "Building package.."
echo FAKE_ROOT = $FAKE_ROOT
cd $FAKE_ROOT
pkgmk -d . -r . -f ./prototype -o
pkgtrans -os . $OUTPUTFILE $PKGNAME
mv $OUTPUTFILE ..
cd ..
# Comment this out if you want to see, which file structure has been created
rm -rf $FAKE_ROOT

View File

@@ -164,7 +164,7 @@ static int Continuation( char *line, int pos )
*/
{
pos--;
while( (pos >= 0) && isspace(line[pos]) )
while( (pos >= 0) && isspace(((unsigned char *)line)[pos]) )
pos--;
return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
@@ -207,7 +207,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
if( i > (bSize - 2) )
{
bSize += BUFR_INC;
bufr = Realloc( bufr, bSize );
bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FERROR, "%s Memory re-allocation failure.", func);
@@ -301,7 +301,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i > (bSize - 2) ) /* Ensure there's space for next char. */
{
bSize += BUFR_INC;
bufr = Realloc( bufr, bSize );
bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
@@ -366,7 +366,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i > (bSize - 2) ) /* Make sure there's enough room. */
{
bSize += BUFR_INC;
bufr = Realloc( bufr, bSize );
bufr = realloc_array( bufr, char, bSize );
if( NULL == bufr )
{
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
@@ -386,7 +386,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
c = 0;
else
{
for( end = i; (end >= 0) && isspace(bufr[end]); end-- )
for( end = i; (end >= 0) && isspace(((unsigned char *) bufr)[end]); end-- )
;
c = getc( InFile );
}
@@ -491,8 +491,8 @@ static FILE *OpenConfFile( char *FileName )
OpenedFile = fopen( FileName, "r" );
if( NULL == OpenedFile )
{
rprintf(FERROR,"%s Unable to open configuration file \"%s\":\n\t%s\n",
func, FileName, strerror(errno));
rsyserr(FERROR, errno, "rsync: unable to open configuration file \"%s\"",
FileName);
}
return( OpenedFile );
@@ -530,7 +530,7 @@ BOOL pm_process( char *FileName,
else /* If we don't have a buffer */
{ /* allocate one, then parse, */
bSize = BUFR_INC; /* then free. */
bufr = (char *)malloc( bSize );
bufr = new_array( char, bSize );
if( NULL == bufr )
{
rprintf(FERROR,"%s memory allocation failure.\n", func);

164
pipe.c Normal file
View File

@@ -0,0 +1,164 @@
/* -*- c-file-style: "linux" -*-
*
* Copyright (C) 1996-2000 by Andrew Tridgell
* Copyright (C) Paul Mackerras 1996
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rsync.h"
extern int am_sender;
extern int am_server;
extern int blocking_io;
extern int orig_umask;
extern int write_batch;
extern int filesfrom_fd;
/**
* Create a child connected to use on stdin/stdout.
*
* This is derived from CVS code
*
* Note that in the child STDIN is set to blocking and STDOUT
* is set to non-blocking. This is necessary as rsh relies on stdin being blocking
* and ssh relies on stdout being non-blocking
*
* If blocking_io is set then use blocking io on both fds. That can be
* used to cope with badly broken rsh implementations like the one on
* Solaris.
**/
pid_t piped_child(char **command, int *f_in, int *f_out)
{
pid_t pid;
int to_child_pipe[2];
int from_child_pipe[2];
if (verbose >= 2) {
print_child_argv(command);
}
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
rsyserr(FERROR, errno, "pipe");
exit_cleanup(RERR_IPC);
}
pid = do_fork();
if (pid == -1) {
rsyserr(FERROR, errno, "fork");
exit_cleanup(RERR_IPC);
}
if (pid == 0) {
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
rsyserr(FERROR, errno, "Failed to dup/close");
exit_cleanup(RERR_IPC);
}
if (to_child_pipe[0] != STDIN_FILENO)
close(to_child_pipe[0]);
if (from_child_pipe[1] != STDOUT_FILENO)
close(from_child_pipe[1]);
umask(orig_umask);
set_blocking(STDIN_FILENO);
if (blocking_io > 0)
set_blocking(STDOUT_FILENO);
execvp(command[0], command);
rsyserr(FERROR, errno, "Failed to exec %s", command[0]);
exit_cleanup(RERR_IPC);
}
if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
rsyserr(FERROR, errno, "Failed to close");
exit_cleanup(RERR_IPC);
}
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
return pid;
}
/* This function forks a child which calls child_main(). First,
* however, it has to establish communication paths to and from the
* newborn child. It creates two socket pairs -- one for writing to
* the child (from the parent) and one for reading from the child
* (writing to the parent). Since that's four socket ends, each
* process has to close the two ends it doesn't need. The remaining
* two socket ends are retained for reading and writing. In the
* child, the STDIN and STDOUT file descriptors refer to these
* sockets. In the parent, the function arguments f_in and f_out are
* set to refer to these sockets. */
pid_t local_child(int argc, char **argv, int *f_in, int *f_out,
int (*child_main)(int, char*[]))
{
pid_t pid;
int to_child_pipe[2];
int from_child_pipe[2];
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rsyserr(FERROR, errno, "pipe");
exit_cleanup(RERR_IPC);
}
pid = do_fork();
if (pid == -1) {
rsyserr(FERROR, errno, "fork");
exit_cleanup(RERR_IPC);
}
if (pid == 0) {
am_sender = !am_sender;
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;
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
close(to_child_pipe[1]) < 0 ||
close(from_child_pipe[0]) < 0 ||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
rsyserr(FERROR, errno, "Failed to dup/close");
exit_cleanup(RERR_IPC);
}
if (to_child_pipe[0] != STDIN_FILENO)
close(to_child_pipe[0]);
if (from_child_pipe[1] != STDOUT_FILENO)
close(from_child_pipe[1]);
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");
exit_cleanup(RERR_IPC);
}
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
return pid;
}

View File

@@ -5,5 +5,3 @@ config.h
config.log
config.status
dummy
rsync
zlib/dummy

View File

@@ -1,4 +1,7 @@
1.3 ->
1.5 -> 1.6
- add ability to perform callbacks for every, not just first, match.
1.3 -> 1.5
- heavy dose of const's
- poptParseArgvString() now NULL terminates the list

View File

@@ -5,7 +5,7 @@ to getopt(3), it contains a number of enhancements, including:
2) popt can parse arbitrary argv[] style arrays while
getopt(2) makes this quite difficult
3) popt allows users to alias command line arguments
4) popt provides convience functions for parsting strings
4) popt provides convience functions for parsing strings
into argv[] style arrays
popt is used by rpm, the Red Hat install program, and many other Red Hat

4
popt/README.rsync Normal file
View File

@@ -0,0 +1,4 @@
This is a perfectly ordinary copy of libpopt. It is only used on platforms
that do not have a sufficiently up-to-date copy of their own. If you build
rsync on a platform which has popt, this directory should not be used. (You
can control that using the --with-included-popt configure flag.)

View File

@@ -1,104 +0,0 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
configure:592: checking host system type
configure:613: checking target system type
configure:631: checking build system type
configure:665: checking for a BSD compatible install
configure:718: checking whether build environment is sane
configure:775: checking whether make sets ${MAKE}
configure:821: checking for working aclocal
configure:834: checking for working autoconf
configure:847: checking for working automake
configure:860: checking for working autoheader
configure:873: checking for working makeinfo
configure:891: checking for gcc
configure:1004: checking whether the C compiler (gcc ) works
configure:1020: gcc -o conftest conftest.c 1>&5
configure:1046: checking whether the C compiler (gcc ) is a cross-compiler
configure:1051: checking whether we are using GNU C
configure:1079: checking whether gcc accepts -g
configure:1111: checking for POSIXized ISC
configure:1135: checking for gcc
configure:1248: checking whether the C compiler (gcc -g -O2 ) works
configure:1264: gcc -o conftest -g -O2 conftest.c 1>&5
configure:1290: checking whether the C compiler (gcc -g -O2 ) is a cross-compiler
configure:1295: checking whether we are using GNU C
configure:1323: checking whether gcc accepts -g
configure:1355: checking how to run the C preprocessor
configure:1436: checking whether gcc needs -traditional
configure:1485: checking for gcc option to accept ANSI C
configure:1564: checking for function prototypes
configure:1795: checking for ranlib
configure:1834: checking for ld used by GCC
configure:1896: checking if the linker (/usr/bin/ld) is GNU ld
configure:1912: checking for BSD-compatible nm
configure:1948: checking whether ln -s works
ltconfig:603: checking for object suffix
ltconfig:604: gcc -c -g -O2 conftest.c 1>&5
ltconfig:629: checking for executable suffix
ltconfig:630: gcc -o conftest -g -O2 conftest.c 1>&5
ltconfig:776: checking if gcc PIC flag -fPIC works
ltconfig:777: gcc -c -g -O2 -fPIC -DPIC conftest.c 1>&5
ltconfig:829: checking if gcc supports -c -o file.o
ltconfig:830: gcc -c -g -O2 -o out/conftest2.o conftest.c 1>&5
ltconfig:862: checking if gcc supports -c -o file.lo
ltconfig:863: gcc -c -g -O2 -c -o conftest.lo conftest.c 1>&5
ltconfig:914: checking if gcc supports -fno-rtti -fno-exceptions
ltconfig:915: gcc -c -g -O2 -fno-rtti -fno-exceptions -c conftest.c conftest.c 1>&5
ltconfig:958: checking if gcc static flag -static works
ltconfig:959: gcc -o conftest -g -O2 -static conftest.c 1>&5
GNU ld version 2.10.91 (with BFD 2.10.91.0.2)
ltconfig:1635: checking if global_symbol_pipe works
ltconfig:1636: gcc -c -g -O2 conftest.c 1>&5
ltconfig:1639: eval "/usr/bin/nm -B conftest.o | sed -n -e 's/^.*[ ]\([ABCDGISTW]\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p' > conftest.nm"
ltconfig:1691: gcc -o conftest -g -O2 -fno-builtin -fno-rtti -fno-exceptions conftest.c conftstm.o 1>&5
configure:2150: checking for a BSD compatible install
configure:2231: checking for alloca.h
configure:2231: checking for libintl.h
configure:2231: checking for mcheck.h
configure:2231: checking for unistd.h
configure:2268: checking for /usr/ucblib in LIBS
configure:2284: checking for GNU xgettext
configure:2294: checking for strerror
configure:2294: checking for mtrace
configure:2347: checking for setreuid
configure:2438: checking for working const
configure:2513: checking for inline
configure:2553: checking for off_t
configure:2586: checking for size_t
configure:2621: checking for working alloca.h
configure:2654: checking for alloca
configure:2856: checking for unistd.h
configure:2895: checking for getpagesize
configure:2948: checking for working mmap
configure:3124: checking for argz.h
configure:3124: checking for limits.h
configure:3124: checking for locale.h
configure:3124: checking for nl_types.h
configure:3124: checking for malloc.h
configure:3124: checking for string.h
configure:3124: checking for unistd.h
configure:3124: checking for sys/param.h
configure:3164: checking for getcwd
configure:3164: checking for munmap
configure:3164: checking for putenv
configure:3164: checking for setenv
configure:3164: checking for setlocale
configure:3164: checking for strchr
configure:3164: checking for strcasecmp
configure:3164: checking for strdup
configure:3164: checking for __argz_count
configure:3164: checking for __argz_stringify
configure:3164: checking for __argz_next
configure:3283: checking for LC_MESSAGES
configure:3316: checking whether NLS is requested
configure:3336: checking whether included gettext is requested
configure:3355: checking for libintl.h
configure:3382: checking for gettext in libc
configure:3508: checking for msgfmt
configure:3542: checking for dcgettext
configure:3597: checking for gmsgfmt
configure:3633: checking for xgettext
configure:3673: gcc -o conftest -Wall -g -O2 conftest.c 1>&5
configure:4131: checking for catalogs to be installed

View File

@@ -1,6 +1,10 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/findme.c
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
#include "findme.h"
@@ -9,38 +13,38 @@ const char * findProgramPath(const char * argv0) {
char * path = getenv("PATH");
char * pathbuf;
char * start, * chptr;
char * buf, *local = NULL;
char * buf;
/* If there is a / in the argv[0], it has to be an absolute
path */
if (argv0 == NULL) return NULL; /* XXX can't happen */
/* If there is a / in the argv[0], it has to be an absolute path */
if (strchr(argv0, '/'))
return xstrdup(argv0);
if (!path) return NULL;
if (path == NULL) return NULL;
local = start = pathbuf = malloc(strlen(path) + 1);
buf = malloc(strlen(path) + strlen(argv0) + 2);
start = pathbuf = alloca(strlen(path) + 1);
buf = malloc(strlen(path) + strlen(argv0) + sizeof("/"));
if (buf == NULL) return NULL; /* XXX can't happen */
strcpy(pathbuf, path);
chptr = NULL;
/*@-branchstate@*/
do {
if ((chptr = strchr(start, ':')))
*chptr = '\0';
sprintf(buf, "%s/%s", start, argv0);
if (!access(buf, X_OK)) {
if (local) free(local);
return buf;
}
if (!access(buf, X_OK))
return buf;
if (chptr)
start = chptr + 1;
else
start = NULL;
} while (start && *start);
/*@=branchstate@*/
free(buf);
if (local) free(local);
return NULL;
}

View File

@@ -1,10 +1,20 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/findme.h
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
ftp://ftp.rpm.org/pub/rpm/dist. */
#ifndef H_FINDME
#define H_FINDME
const char * findProgramPath(const char * argv0);
/**
* Return absolute path to executable by searching PATH.
* @param argv0 name of executable
* @return (malloc'd) absolute path to executable (or NULL)
*/
/*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0)
/*@*/;
#endif

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,128 +1,444 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \file popt/popt.h
* \ingroup popt
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
ftp://ftp.rpm.org/pub/rpm/dist. */
#ifndef H_POPT
#define H_POPT
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h> /* for FILE * */
#define POPT_OPTION_DEPTH 10
#define POPT_ARG_NONE 0
#define POPT_ARG_STRING 1
#define POPT_ARG_INT 2
#define POPT_ARG_LONG 3
#define POPT_ARG_INCLUDE_TABLE 4 /* arg points to table */
#define POPT_ARG_CALLBACK 5 /* table-wide callback... must be
/** \ingroup popt
* \name Arg type identifiers
*/
/*@{*/
#define POPT_ARG_NONE 0 /*!< no arg */
#define POPT_ARG_STRING 1 /*!< arg will be saved as string */
#define POPT_ARG_INT 2 /*!< arg will be converted to int */
#define POPT_ARG_LONG 3 /*!< arg will be converted to long */
#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */
#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be
set first in table; arg points
to callback, descrip points to
callback data to pass */
#define POPT_ARG_INTL_DOMAIN 6 /* set the translation domain
#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain
for this table and any
included tables; arg points
to the domain string */
#define POPT_ARG_VAL 7 /* arg should take value val */
#define POPT_ARG_VAL 7 /*!< arg should take value val */
#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */
#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */
#define POPT_ARG_MASK 0x0000FFFF
#define POPT_ARGFLAG_ONEDASH 0x80000000 /* allow -longoption */
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /* don't show in help/usage */
#define POPT_ARGFLAG_STRIP 0x20000000 /* strip this arg from argv (only applies to long args) */
#define POPT_CBFLAG_PRE 0x80000000 /* call the callback before parse */
#define POPT_CBFLAG_POST 0x40000000 /* call the callback after parse */
#define POPT_CBFLAG_INC_DATA 0x20000000 /* use data from the include line,
/*@}*/
/** \ingroup popt
* \name Arg modifiers
*/
/*@{*/
#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */
#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */
#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */
#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */
#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */
#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */
#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */
#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */
#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */
#define POPT_ARGFLAG_LOGICALOPS \
(POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR)
#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR)
/*!< set arg bit(s) */
#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND)
/*!< clear arg bit(s) */
#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */
/*@}*/
/** \ingroup popt
* \name Callback modifiers
*/
/*@{*/
#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */
#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */
#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line,
not the subtable */
#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */
#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */
/*@}*/
#define POPT_ERROR_NOARG -10
#define POPT_ERROR_BADOPT -11
#define POPT_ERROR_OPTSTOODEEP -13
#define POPT_ERROR_BADQUOTE -15 /* only from poptParseArgString() */
#define POPT_ERROR_ERRNO -16 /* only from poptParseArgString() */
#define POPT_ERROR_BADNUMBER -17
#define POPT_ERROR_OVERFLOW -18
/** \ingroup popt
* \name Error return values
*/
/*@{*/
#define POPT_ERROR_NOARG -10 /*!< missing argument */
#define POPT_ERROR_BADOPT -11 /*!< unknown option */
#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */
#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */
#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */
#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */
#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */
#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */
#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */
#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */
/*@}*/
/* poptBadOption() flags */
#define POPT_BADOPTION_NOALIAS (1 << 0) /* don't go into an alias */
/** \ingroup popt
* \name poptBadOption() flags
*/
/*@{*/
#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */
/*@}*/
/* poptGetContext() flags */
#define POPT_CONTEXT_NO_EXEC (1 << 0) /* ignore exec expansions */
#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /* pay attention to argv[0] */
#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /* options can't follow args */
/** \ingroup popt
* \name poptGetContext() flags
*/
/*@{*/
#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */
#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */
#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */
#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */
/*@}*/
/** \ingroup popt
*/
struct poptOption {
/*@observer@*/ /*@null@*/ const char * longName; /* may be NULL */
char shortName; /* may be '\0' */
/*@observer@*/ /*@null@*/ const char * longName; /*!< may be NULL */
char shortName; /*!< may be '\0' */
int argInfo;
/*@shared@*/ /*@null@*/ void * arg; /* depends on argInfo */
int val; /* 0 means don't return, just update flag */
/*@shared@*/ /*@null@*/ const char * descrip; /* description for autohelp -- may be NULL */
/*@shared@*/ /*@null@*/ const char * argDescrip; /* argument description for autohelp */
/*@shared@*/ /*@null@*/ void * arg; /*!< depends on argInfo */
int val; /*!< 0 means don't return, just update flag */
/*@observer@*/ /*@null@*/ const char * descrip; /*!< description for autohelp -- may be NULL */
/*@observer@*/ /*@null@*/ const char * argDescrip; /*!< argument description for autohelp */
};
/** \ingroup popt
* A popt alias argument for poptAddAlias().
*/
struct poptAlias {
/*@owned@*/ /*@null@*/ const char * longName; /* may be NULL */
char shortName; /* may be '\0' */
/*@owned@*/ /*@null@*/ const char * longName; /*!< may be NULL */
char shortName; /*!< may be '\0' */
int argc;
/*@owned@*/ const char ** argv; /* must be free()able */
/*@owned@*/ const char ** argv; /*!< must be free()able */
};
/** \ingroup popt
* A popt alias or exec argument for poptAddItem().
*/
typedef struct poptItem_s {
struct poptOption option; /*!< alias/exec name(s) and description. */
int argc; /*!< (alias) no. of args. */
/*@owned@*/ const char ** argv; /*!< (alias) args, must be free()able. */
} * poptItem;
/** \ingroup popt
* \name Auto-generated help/usage
*/
/*@{*/
/**
* Empty table marker to enable displaying popt alias/exec options.
*/
/*@observer@*/ /*@checked@*/
extern struct poptOption poptAliasOptions[];
#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \
0, "Options implemented via popt alias/exec:", NULL },
/**
* Auto help table options.
*/
/*@observer@*/ /*@checked@*/
extern struct poptOption poptHelpOptions[];
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
0, "Help options", NULL },
0, "Help options:", NULL },
typedef struct poptContext_s * poptContext;
#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
/*@}*/
/** \ingroup popt
*/
typedef /*@abstract@*/ struct poptContext_s * poptContext;
/** \ingroup popt
*/
#ifndef __cplusplus
/*@-typeuse@*/
typedef struct poptOption * poptOption;
/*@=typeuse@*/
#endif
enum poptCallbackReason { POPT_CALLBACK_REASON_PRE,
POPT_CALLBACK_REASON_POST,
POPT_CALLBACK_REASON_OPTION };
typedef void (*poptCallbackType)(poptContext con,
enum poptCallbackReason reason,
const struct poptOption * opt,
const char * arg, const void * data);
/*@only@*/ poptContext poptGetContext(/*@keep@*/ const char * name,
int argc, /*@keep@*/ const char ** argv,
/*@keep@*/ const struct poptOption * options, int flags);
void poptResetContext(poptContext con);
#ifdef __cplusplus
extern "C" {
#endif
/*@-type@*/
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
int poptGetNextOpt(poptContext con);
/* returns NULL if no argument is available */
/*@observer@*/ /*@null@*/ const char * poptGetOptArg(poptContext con);
/* returns NULL if no more options are available */
/*@observer@*/ /*@null@*/ const char * poptGetArg(poptContext con);
/*@observer@*/ /*@null@*/ const char * poptPeekArg(poptContext con);
/*@observer@*/ /*@null@*/ const char ** poptGetArgs(poptContext con);
/* returns the option which caused the most recent error */
/*@observer@*/ const char * poptBadOption(poptContext con, int flags);
void poptFreeContext( /*@only@*/ poptContext con);
int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv);
int poptAddAlias(poptContext con, struct poptAlias alias, int flags);
int poptReadConfigFile(poptContext con, const char * fn);
/* like above, but reads /etc/popt and $HOME/.popt along with environment
vars */
int poptReadDefaultConfig(poptContext con, int useEnv);
/* argv should be freed -- this allows ', ", and \ quoting, but ' is treated
the same as " and both may include \ quotes */
int poptDupArgv(int argc, const char **argv,
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr);
int poptParseArgvString(const char * s,
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr);
/*@observer@*/ const char *const poptStrerror(const int error);
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute);
void poptPrintHelp(poptContext con, FILE * f, int flags);
void poptPrintUsage(poptContext con, FILE * f, int flags);
void poptSetOtherOptionHelp(poptContext con, const char * text);
/*@observer@*/ const char * poptGetInvocationName(poptContext con);
/* shuffles argv pointers to remove stripped args, returns new argc */
int poptStrippedArgv(poptContext con, int argc, char **argv);
/** \ingroup popt
* Table callback prototype.
* @param con context
* @param reason reason for callback
* @param opt option that triggered callback
* @param arg @todo Document.
* @param data @todo Document.
*/
typedef void (*poptCallbackType) (poptContext con,
enum poptCallbackReason reason,
/*@null@*/ const struct poptOption * opt,
/*@null@*/ const char * arg,
/*@null@*/ const void * data)
/*@*/;
/** \ingroup popt
* Initialize popt context.
* @param name
* @param argc no. of arguments
* @param argv argument array
* @param options address of popt option table
* @param flags or'd POPT_CONTEXT_* bits
* @return initialized popt context
*/
/*@only@*/ /*@null@*/ poptContext poptGetContext(
/*@dependent@*/ /*@keep@*/ const char * name,
int argc, /*@dependent@*/ /*@keep@*/ const char ** argv,
/*@dependent@*/ /*@keep@*/ const struct poptOption * options,
int flags)
/*@*/;
/** \ingroup popt
* Reinitialize popt context.
* @param con context
*/
void poptResetContext(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
* Return value of next option found.
* @param con context
* @return next option val, -1 on last item, POPT_ERROR_* on error
*/
int poptGetNextOpt(/*@null@*/poptContext con)
/*@globals fileSystem@*/
/*@modifies con, fileSystem @*/;
/*@-redecl@*/
/** \ingroup popt
* Return next option argument (if any).
* @param con context
* @return option argument, NULL if no more options are available
*/
/*@observer@*/ /*@null@*/ const char * poptGetOptArg(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
* Return current option's argument.
* @param con context
* @return option argument, NULL if no more options are available
*/
/*@observer@*/ /*@null@*/ const char * poptGetArg(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
* Peek at current option's argument.
* @param con context
* @return option argument
*/
/*@observer@*/ /*@null@*/ const char * poptPeekArg(/*@null@*/poptContext con)
/*@*/;
/** \ingroup popt
* Return remaining arguments.
* @param con context
* @return argument array, terminated with NULL
*/
/*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
* Return the option which caused the most recent error.
* @param con context
* @return offending option
*/
/*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, int flags)
/*@*/;
/*@=redecl@*/
/** \ingroup popt
* Destroy context.
* @param con context
* @return NULL always
*/
/*@null@*/ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con)
/*@modifies con @*/;
/** \ingroup popt
* Add arguments to context.
* @param con context
* @param argv argument array, NULL terminated
* @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure
*/
int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv)
/*@modifies con @*/;
/** \ingroup popt
* Add alias to context.
* @todo Pass alias by reference, not value.
* @deprecated Use poptAddItem instead.
* @param con context
* @param alias alias to add
* @param flags (unused)
* @return 0 on success
*/
/*@unused@*/
int poptAddAlias(poptContext con, struct poptAlias alias, int flags)
/*@modifies con @*/;
/** \ingroup popt
* Add alias/exec item to context.
* @param con context
* @param item alias/exec item to add
* @param flags 0 for alias, 1 for exec
* @return 0 on success
*/
int poptAddItem(poptContext con, poptItem newItem, int flags)
/*@modifies con @*/;
/** \ingroup popt
* Read configuration file.
* @param con context
* @param fn file name to read
* @return 0 on success, POPT_ERROR_ERRNO on failure
*/
int poptReadConfigFile(poptContext con, const char * fn)
/*@globals fileSystem@*/
/*@modifies fileSystem,
con->execs, con->numExecs @*/;
/** \ingroup popt
* Read default configuration from /etc/popt and $HOME/.popt.
* @param con context
* @param useEnv (unused)
* @return 0 on success, POPT_ERROR_ERRNO on failure
*/
int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
/*@globals fileSystem@*/
/*@modifies fileSystem,
con->execs, con->numExecs @*/;
/** \ingroup popt
* Duplicate an argument array.
* @note: The argument array is malloc'd as a single area, so only argv must
* be free'd.
*
* @param argc no. of arguments
* @param argv argument array
* @retval argcPtr address of returned no. of arguments
* @retval argvPtr address of returned argument array
* @return 0 on success, POPT_ERROR_NOARG on failure
*/
int poptDupArgv(int argc, /*@null@*/ const char **argv,
/*@null@*/ /*@out@*/ int * argcPtr,
/*@null@*/ /*@out@*/ const char *** argvPtr)
/*@modifies *argcPtr, *argvPtr @*/;
/** \ingroup popt
* Parse a string into an argument array.
* The parse allows ', ", and \ quoting, but ' is treated the same as " and
* both may include \ quotes.
* @note: The argument array is malloc'd as a single area, so only argv must
* be free'd.
*
* @param s string to parse
* @retval argcPtr address of returned no. of arguments
* @retval argvPtr address of returned argument array
*/
int poptParseArgvString(const unsigned char * s,
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr)
/*@modifies *argcPtr, *argvPtr @*/;
/** \ingroup popt
* Return formatted error string for popt failure.
* @param error popt error
* @return error string
*/
/*@-redecl@*/
/*@observer@*/ const char *const poptStrerror(const int error)
/*@*/;
/*@=redecl@*/
/** \ingroup popt
* Limit search for executables.
* @param con context
* @param path single path to search for executables
* @param allowAbsolute absolute paths only?
*/
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
/*@modifies con @*/;
/** \ingroup popt
* Print detailed description of options.
* @param con context
* @param fp ouput file handle
* @param flags (unused)
*/
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/;
/** \ingroup popt
* Print terse description of options.
* @param con context
* @param fp ouput file handle
* @param flags (unused)
*/
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/;
/** \ingroup popt
* Provide text to replace default "[OPTION...]" in help/usage output.
* @param con context
* @param text replacement text
*/
/*@-fcnuse@*/
void poptSetOtherOptionHelp(poptContext con, const char * text)
/*@modifies con @*/;
/*@=fcnuse@*/
/** \ingroup popt
* Return argv[0] from context.
* @param con context
* @return argv[0]
*/
/*@-redecl -fcnuse@*/
/*@observer@*/ const char * poptGetInvocationName(poptContext con)
/*@*/;
/*@=redecl =fcnuse@*/
/** \ingroup popt
* Shuffle argv pointers to remove stripped args, returns new argc.
* @param con context
* @param argc no. of args
* @param argv arg vector
* @return new argc
*/
/*@-fcnuse@*/
int poptStrippedArgv(poptContext con, int argc, char ** argv)
/*@modifies *argv @*/;
/*@=fcnuse@*/
/*@=type@*/
#ifdef __cplusplus
}
#endif

View File

@@ -1,101 +1,144 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/poptconfig.c
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
#include "poptint.h"
static void configLine(poptContext con, char * line) {
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
static void configLine(poptContext con, unsigned char * line)
/*@modifies con @*/
{
/*@-type@*/
int nameLength = strlen(con->appName);
char * opt;
struct poptAlias alias;
char * entryType;
char * longName = NULL;
char shortName = '\0';
/*@=type@*/
const char * entryType;
const char * opt;
poptItem item = (poptItem) alloca(sizeof(*item));
int i, j;
memset(item, 0, sizeof(*item));
/*@-type@*/
if (strncmp(line, con->appName, nameLength)) return;
/*@=type@*/
line += nameLength;
if (!*line || !isspace(*line)) return;
while (*line && isspace(*line)) line++;
if (*line == '\0' || !isspace(*line)) return;
while (*line != '\0' && isspace(*line)) line++;
entryType = line;
while (!*line || !isspace(*line)) line++;
while (*line == '\0' || !isspace(*line)) line++;
*line++ = '\0';
while (*line && isspace(*line)) line++;
if (!*line) return;
while (*line != '\0' && isspace(*line)) line++;
if (*line == '\0') return;
opt = line;
while (!*line || !isspace(*line)) line++;
while (*line == '\0' || !isspace(*line)) line++;
*line++ = '\0';
while (*line && isspace(*line)) line++;
if (!*line) return;
while (*line != '\0' && isspace(*line)) line++;
if (*line == '\0') return;
/*@-temptrans@*/ /* FIX: line alias is saved */
if (opt[0] == '-' && opt[1] == '-')
longName = opt + 2;
else if (opt[0] == '-' && !opt[2])
shortName = opt[1];
item->option.longName = opt + 2;
else if (opt[0] == '-' && opt[2] == '\0')
item->option.shortName = opt[1];
/*@=temptrans@*/
if (!strcmp(entryType, "alias")) {
if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
alias.longName = longName, alias.shortName = shortName;
poptAddAlias(con, alias, 0);
} else if (!strcmp(entryType, "exec")) {
con->execs = realloc(con->execs,
sizeof(*con->execs) * (con->numExecs + 1));
if (longName)
con->execs[con->numExecs].longName = xstrdup(longName);
else
con->execs[con->numExecs].longName = NULL;
if (poptParseArgvString(line, &item->argc, &item->argv)) return;
con->execs[con->numExecs].shortName = shortName;
con->execs[con->numExecs].script = xstrdup(line);
con->numExecs++;
/*@-modobserver@*/
item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
for (i = 0, j = 0; i < item->argc; i++, j++) {
const char * f;
if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
f = item->argv[i] + sizeof("--POPTdesc=");
if (f[0] == '$' && f[1] == '"') f++;
item->option.descrip = f;
item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
j--;
} else
if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
f = item->argv[i] + sizeof("--POPTargs=");
if (f[0] == '$' && f[1] == '"') f++;
item->option.argDescrip = f;
item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
item->option.argInfo |= POPT_ARG_STRING;
j--;
} else
if (j != i)
item->argv[j] = item->argv[i];
}
if (j != i) {
item->argv[j] = NULL;
item->argc = j;
}
/*@=modobserver@*/
/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
if (!strcmp(entryType, "alias"))
(void) poptAddItem(con, item, 0);
else if (!strcmp(entryType, "exec"))
(void) poptAddItem(con, item, 1);
/*@=nullstate@*/
}
/*@=compmempass@*/
int poptReadConfigFile(poptContext con, const char * fn) {
char * file=NULL, * chptr, * end;
char * buf=NULL, * dst;
int poptReadConfigFile(poptContext con, const char * fn)
{
const unsigned char * file, * chptr, * end;
unsigned char * buf;
/*@dependent@*/ unsigned char * dst;
int fd, rc;
int fileLength;
off_t fileLength;
fd = open(fn, O_RDONLY);
if (fd < 0) {
if (errno == ENOENT)
return 0;
else
return POPT_ERROR_ERRNO;
}
if (fd < 0)
return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
fileLength = lseek(fd, 0, SEEK_END);
(void) lseek(fd, 0, 0);
file = malloc(fileLength + 1);
if (read(fd, file, fileLength) != fileLength) {
if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
rc = errno;
close(fd);
(void) close(fd);
/*@-mods@*/
errno = rc;
if (file) free(file);
/*@=mods@*/
return POPT_ERROR_ERRNO;
}
close(fd);
dst = buf = malloc(fileLength + 1);
file = alloca(fileLength + 1);
if (read(fd, (char *)file, fileLength) != fileLength) {
rc = errno;
(void) close(fd);
/*@-mods@*/
errno = rc;
/*@=mods@*/
return POPT_ERROR_ERRNO;
}
if (close(fd) == -1)
return POPT_ERROR_ERRNO;
dst = buf = alloca(fileLength + 1);
chptr = file;
end = (file + fileLength);
/*@-infloops@*/ /* LCL: can't detect chptr++ */
while (chptr < end) {
switch (*chptr) {
case '\n':
*dst = '\0';
dst = buf;
while (*dst && isspace(*dst)) dst++;
if (*dst && *dst != '#') {
if (*dst && *dst != '#')
configLine(con, dst);
}
chptr++;
break;
/*@switchbreak@*/ break;
case '\\':
*dst++ = *chptr++;
if (chptr < end) {
@@ -105,38 +148,37 @@ int poptReadConfigFile(poptContext con, const char * fn) {
else
*dst++ = *chptr++;
}
break;
/*@switchbreak@*/ break;
default:
*dst++ = *chptr++;
break;
/*@switchbreak@*/ break;
}
}
free(file);
free(buf);
/*@=infloops@*/
return 0;
}
int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) {
int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv))
{
char * fn, * home;
int rc;
/*@-type@*/
if (!con->appName) return 0;
/*@=type@*/
rc = poptReadConfigFile(con, "/etc/popt");
if (rc) return rc;
if (getuid() != geteuid()) return 0;
if ((home = getenv("HOME"))) {
fn = malloc(strlen(home) + 20);
fn = alloca(strlen(home) + 20);
strcpy(fn, home);
strcat(fn, "/.popt");
rc = poptReadConfigFile(con, fn);
free(fn);
if (rc) return rc;
}
return 0;
}

View File

@@ -1,48 +1,92 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/*@-type@*/
/** \ingroup popt
* \file popt/popthelp.c
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
#include "poptint.h"
/**
* @param con context
* @param key option(s)
*/
static void displayArgs(poptContext con,
/*@unused@*/ enum poptCallbackReason foo,
/*@unused@*/ UNUSED(enum poptCallbackReason foo),
struct poptOption * key,
/*@unused@*/ const char * arg, /*@unused@*/ void * data) {
if (key->shortName== '?')
/*@unused@*/ UNUSED(const char * arg), /*@unused@*/ UNUSED(void * data))
/*@globals fileSystem@*/
/*@modifies fileSystem@*/
{
if (key->shortName == '?')
poptPrintHelp(con, stdout, 0);
else
poptPrintUsage(con, stdout, 0);
exit(0);
}
#ifdef NOTYET
/*@unchecked@*/
static int show_option_defaults = 0;
#endif
/**
* Empty table marker to enable displaying popt alias/exec options.
*/
/*@observer@*/ /*@unchecked@*/
struct poptOption poptAliasOptions[] = {
POPT_TABLEEND
};
/**
* Auto help table options.
*/
/*@-castfcnptr@*/
/*@observer@*/ /*@unchecked@*/
struct poptOption poptHelpOptions[] = {
{ NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
{ "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
{ "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
{ NULL, '\0', 0, NULL, 0, NULL, NULL }
{ NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
{ "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
{ "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
#ifdef NOTYET
{ "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
N_("Display option defaults in message"), NULL },
#endif
POPT_TABLEEND
} ;
/*@=castfcnptr@*/
/*@observer@*/ /*@null@*/ static const char *const
getTableTranslationDomain(const struct poptOption *table)
/**
* @param table option(s)
*/
/*@observer@*/ /*@null@*/ static const char *
getTableTranslationDomain(/*@null@*/ const struct poptOption *table)
/*@*/
{
const struct poptOption *opt;
const struct poptOption *opt;
for(opt = table;
opt->longName || opt->shortName || opt->arg;
opt++) {
if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
return opt->arg;
}
return NULL;
if (table != NULL)
for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
return opt->arg;
}
return NULL;
}
/*@observer@*/ /*@null@*/ static const char *const
getArgDescrip(const struct poptOption * opt, const char *translation_domain)
/**
* @param opt option(s)
* @param translation_domain translation domain
*/
/*@observer@*/ /*@null@*/ static const char *
getArgDescrip(const struct poptOption * opt,
/*@-paramuse@*/ /* FIX: wazzup? */
/*@null@*/ const char * translation_domain)
/*@=paramuse@*/
/*@*/
{
if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
@@ -50,45 +94,229 @@ getArgDescrip(const struct poptOption * opt, const char *translation_domain)
if (opt->argDescrip) return POPT_(opt->argDescrip);
if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
return POPT_("ARG");
switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_NONE: return POPT_("NONE");
case POPT_ARG_VAL: return POPT_("VAL");
case POPT_ARG_INT: return POPT_("INT");
case POPT_ARG_LONG: return POPT_("LONG");
case POPT_ARG_STRING: return POPT_("STRING");
case POPT_ARG_FLOAT: return POPT_("FLOAT");
case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
default: return POPT_("ARG");
}
}
static void singleOptionHelp(FILE * f, int maxLeftCol,
const struct poptOption * opt,
const char *translation_domain) {
/**
* @param opt option(s)
* @param translation_domain translation domain
*/
static /*@only@*/ /*@null@*/ char *
singleOptionDefaultValue(int lineLength,
const struct poptOption * opt,
/*@-paramuse@*/ /* FIX: i18n macros disable with lclint */
/*@null@*/ const char * translation_domain)
/*@=paramuse@*/
/*@*/
{
const char * defstr = D_(translation_domain, "default");
char * le = malloc(4*lineLength + 1);
char * l = le;
if (le == NULL) return NULL; /* XXX can't happen */
*le = '\0';
*le++ = '(';
strcpy(le, defstr); le += strlen(le);
*le++ = ':';
*le++ = ' ';
if (opt->arg) /* XXX programmer error */
switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_VAL:
case POPT_ARG_INT:
{ long aLong = *((int *)opt->arg);
sprintf(le, "%ld", aLong);
le += strlen(le);
} break;
case POPT_ARG_LONG:
{ long aLong = *((long *)opt->arg);
sprintf(le, "%ld", aLong);
le += strlen(le);
} break;
case POPT_ARG_FLOAT:
{ double aDouble = *((float *)opt->arg);
sprintf(le, "%g", aDouble);
le += strlen(le);
} break;
case POPT_ARG_DOUBLE:
{ double aDouble = *((double *)opt->arg);
sprintf(le, "%g", aDouble);
le += strlen(le);
} break;
case POPT_ARG_STRING:
{ const char * s = *(const char **)opt->arg;
if (s == NULL) {
strcpy(le, "null"); le += strlen(le);
} else {
size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
*le++ = '"';
strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le);
if (slen < strlen(s)) {
strcpy(le, "..."); le += strlen(le);
}
*le++ = '"';
}
} break;
case POPT_ARG_NONE:
default:
l = _free(l);
return NULL;
/*@notreached@*/ break;
}
*le++ = ')';
*le = '\0';
return l;
}
/**
* @param fp output file handle
* @param opt option(s)
* @param translation_domain translation domain
*/
static void singleOptionHelp(FILE * fp, int maxLeftCol,
const struct poptOption * opt,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
int indentLength = maxLeftCol + 5;
int lineLength = 79 - indentLength;
const char * help = D_(translation_domain, opt->descrip);
int helpLength;
const char * ch;
char format[10];
char * left;
const unsigned char * help = D_(translation_domain, opt->descrip);
const char * argDescrip = getArgDescrip(opt, translation_domain);
int helpLength;
unsigned char * defs = NULL;
unsigned char * left;
int nb = maxLeftCol + 1;
left = malloc(maxLeftCol + 1);
*left = '\0';
/* Make sure there's more than enough room in target buffer. */
if (opt->longName) nb += strlen(opt->longName);
if (argDescrip) nb += strlen(argDescrip);
left = malloc(nb);
if (left == NULL) return; /* XXX can't happen */
left[0] = '\0';
left[maxLeftCol] = '\0';
if (opt->longName && opt->shortName)
sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
else if (opt->shortName)
sprintf(left, "-%c, %s%s", opt->shortName,
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
opt->longName);
else if (opt->shortName != '\0')
sprintf(left, "-%c", opt->shortName);
else if (opt->longName)
sprintf(left, "--%s", opt->longName);
if (!*left) return ;
sprintf(left, "%s%s",
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
opt->longName);
if (!*left) goto out;
if (argDescrip) {
strcat(left, "=");
strcat(left, argDescrip);
char * le = left + strlen(left);
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
*le++ = '[';
/* Choose type of output */
/*@-branchstate@*/
if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) {
defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
if (defs) {
char * t = malloc((help ? strlen(help) : 0) +
strlen(defs) + sizeof(" "));
if (t) {
char * te = t;
*te = '\0';
if (help) {
strcpy(te, help); te += strlen(te);
}
*te++ = ' ';
strcpy(te, defs);
defs = _free(defs);
}
defs = t;
}
}
/*@=branchstate@*/
if (opt->argDescrip == NULL) {
switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_NONE:
break;
case POPT_ARG_VAL:
{ long aLong = opt->val;
int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS);
int negate = (opt->argInfo & POPT_ARGFLAG_NOT);
/* Don't bother displaying typical values */
if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
break;
*le++ = '[';
switch (ops) {
case POPT_ARGFLAG_OR:
*le++ = '|';
/*@innerbreak@*/ break;
case POPT_ARGFLAG_AND:
*le++ = '&';
/*@innerbreak@*/ break;
case POPT_ARGFLAG_XOR:
*le++ = '^';
/*@innerbreak@*/ break;
default:
/*@innerbreak@*/ break;
}
*le++ = '=';
if (negate) *le++ = '~';
/*@-formatconst@*/
sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
le += strlen(le);
/*@=formatconst@*/
*le++ = ']';
} break;
case POPT_ARG_INT:
case POPT_ARG_LONG:
case POPT_ARG_FLOAT:
case POPT_ARG_DOUBLE:
case POPT_ARG_STRING:
*le++ = '=';
strcpy(le, argDescrip); le += strlen(le);
break;
default:
break;
}
} else {
*le++ = '=';
strcpy(le, argDescrip); le += strlen(le);
}
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
*le++ = ']';
*le = '\0';
}
if (help)
fprintf(f," %-*s ", maxLeftCol, left);
fprintf(fp," %-*s ", maxLeftCol, left);
else {
fprintf(f," %s\n", left);
fprintf(fp," %s\n", left);
goto out;
}
left = _free(left);
if (defs) {
help = defs; defs = NULL;
}
helpLength = strlen(help);
while (helpLength > lineLength) {
const unsigned char * ch;
char format[10];
ch = help + lineLength - 1;
while (ch > help && !isspace(*ch)) ch--;
if (ch == help) break; /* give up */
@@ -96,39 +324,56 @@ static void singleOptionHelp(FILE * f, int maxLeftCol,
ch++;
sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
fprintf(f, format, help, " ");
/*@-formatconst@*/
fprintf(fp, format, help, " ");
/*@=formatconst@*/
help = ch;
while (isspace(*help) && *help) help++;
helpLength = strlen(help);
}
if (helpLength) fprintf(f, "%s\n", help);
if (helpLength) fprintf(fp, "%s\n", help);
out:
free(left);
/*@-dependenttrans@*/
defs = _free(defs);
/*@=dependenttrans@*/
left = _free(left);
}
/**
* @param opt option(s)
* @param translation_domain translation domain
*/
static int maxArgWidth(const struct poptOption * opt,
const char * translation_domain) {
/*@null@*/ const char * translation_domain)
/*@*/
{
int max = 0;
int this;
int len = 0;
const char * s;
if (opt != NULL)
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
this = maxArgWidth(opt->arg, translation_domain);
if (this > max) max = this;
if (opt->arg) /* XXX program error */
len = maxArgWidth(opt->arg, translation_domain);
if (len > max) max = len;
} else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
this = opt->shortName ? 2 : 0;
len = sizeof(" ")-1;
if (opt->shortName != '\0') len += sizeof("-X")-1;
if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1;
if (opt->longName) {
if (this) this += 2;
this += strlen(opt->longName) + 2;
len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH)
? sizeof("-")-1 : sizeof("--")-1);
len += strlen(opt->longName);
}
s = getArgDescrip(opt, translation_domain);
if (s)
this += strlen(s) + 1;
if (this > max) max = this;
len += sizeof("=")-1 + strlen(s);
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1;
if (len > max) max = len;
}
opt++;
@@ -137,77 +382,134 @@ static int maxArgWidth(const struct poptOption * opt,
return max;
}
static void singleTableHelp(FILE * f, const struct poptOption * table,
int left,
const char *translation_domain) {
const struct poptOption * opt;
const char *sub_transdom;
/**
* Display popt alias and exec help.
* @param fp output file handle
* @param items alias/exec array
* @param nitems no. of alias/exec entries
* @param translation_domain translation domain
*/
static void itemHelp(FILE * fp,
/*@null@*/ poptItem items, int nitems, int left,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
poptItem item;
int i;
opt = table;
while (opt->longName || opt->shortName || opt->arg) {
if (items != NULL)
for (i = 0, item = items; i < nitems; i++, item++) {
const struct poptOption * opt;
opt = &item->option;
if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
singleOptionHelp(f, left, opt, translation_domain);
opt++;
}
opt = table;
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
sub_transdom = getTableTranslationDomain(opt->arg);
if(!sub_transdom)
sub_transdom = translation_domain;
if (opt->descrip)
fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
singleTableHelp(f, opt->arg, left, sub_transdom);
}
opt++;
singleOptionHelp(fp, left, opt, translation_domain);
}
}
static int showHelpIntro(poptContext con, FILE * f) {
/**
* @param fp output file handle
* @param table option(s)
* @param translation_domain translation domain
*/
static void singleTableHelp(poptContext con, FILE * fp,
/*@null@*/ const struct poptOption * table, int left,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
const struct poptOption * opt;
const char *sub_transdom;
if (table == poptAliasOptions) {
itemHelp(fp, con->aliases, con->numAliases, left, NULL);
itemHelp(fp, con->execs, con->numExecs, left, NULL);
return;
}
if (table != NULL)
for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
singleOptionHelp(fp, left, opt, translation_domain);
}
if (table != NULL)
for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE)
continue;
sub_transdom = getTableTranslationDomain(opt->arg);
if (sub_transdom == NULL)
sub_transdom = translation_domain;
if (opt->descrip)
fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
singleTableHelp(con, fp, opt->arg, left, sub_transdom);
}
}
/**
* @param con context
* @param fp output file handle
*/
static int showHelpIntro(poptContext con, FILE * fp)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
int len = 6;
const char * fn;
fprintf(f, POPT_("Usage:"));
fprintf(fp, POPT_("Usage:"));
if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
/*@-nullderef@*/ /* LCL: wazzup? */
fn = con->optionStack->argv[0];
if (strchr(fn, '/')) fn = strchr(fn, '/') + 1;
fprintf(f, " %s", fn);
/*@=nullderef@*/
if (fn == NULL) return len;
if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
fprintf(fp, " %s", fn);
len += strlen(fn) + 1;
}
return len;
}
void poptPrintHelp(poptContext con, FILE * f, /*@unused@*/ int flags) {
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags))
{
int leftColWidth;
showHelpIntro(con, f);
(void) showHelpIntro(con, fp);
if (con->otherHelp)
fprintf(f, " %s\n", con->otherHelp);
fprintf(fp, " %s\n", con->otherHelp);
else
fprintf(f, " %s\n", POPT_("[OPTION...]"));
fprintf(fp, " %s\n", POPT_("[OPTION...]"));
leftColWidth = maxArgWidth(con->options, NULL);
singleTableHelp(f, con->options, leftColWidth, NULL);
singleTableHelp(con, fp, con->options, leftColWidth, NULL);
}
static int singleOptionUsage(FILE * f, int cursor,
const struct poptOption * opt,
const char *translation_domain) {
/**
* @param fp output file handle
* @param opt option(s)
* @param translation_domain translation domain
*/
static int singleOptionUsage(FILE * fp, int cursor,
const struct poptOption * opt,
/*@null@*/ const char *translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
int len = 3;
char shortStr[2] = { '\0', '\0' };
const char * item = shortStr;
const char * argDescrip = getArgDescrip(opt, translation_domain);
if (opt->shortName) {
if (opt->shortName!= '\0' ) {
if (!(opt->argInfo & POPT_ARG_MASK))
return cursor; /* we did these already */
len++;
*shortStr = opt->shortName;
shortStr[0] = opt->shortName;
shortStr[1] = '\0';
} else if (opt->longName) {
len += 1 + strlen(opt->longName);
@@ -220,82 +522,140 @@ static int singleOptionUsage(FILE * f, int cursor,
len += strlen(argDescrip) + 1;
if ((cursor + len) > 79) {
fprintf(f, "\n ");
fprintf(fp, "\n ");
cursor = 7;
}
fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
argDescrip ? (opt->shortName ? " " : "=") : "",
argDescrip ? argDescrip : "");
fprintf(fp, " [-%s%s%s%s]",
((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
item,
(argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
(argDescrip ? argDescrip : ""));
return cursor + len + 1;
}
static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
const char *translation_domain) {
const struct poptOption * opt;
opt = table;
while (opt->longName || opt->shortName || opt->arg) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
translation_domain = (const char *)opt->arg;
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
cursor = singleTableUsage(f, cursor, opt->arg,
translation_domain);
else if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
cursor = singleOptionUsage(f, cursor, opt, translation_domain);
/**
* Display popt alias and exec usage.
* @param fp output file handle
* @param item alias/exec array
* @param nitems no. of ara/exec entries
* @param translation_domain translation domain
*/
static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
int i;
opt++;
/*@-branchstate@*/ /* FIX: W2DO? */
if (item != NULL)
for (i = 0; i < nitems; i++, item++) {
const struct poptOption * opt;
opt = &item->option;
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
translation_domain = (const char *)opt->arg;
} else if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
}
}
/*@=branchstate@*/
return cursor;
}
static int showShortOptions(const struct poptOption * opt, FILE * f,
char * str) {
char s[300]; /* this is larger then the ascii set, so
it should do just fine */
/**
* @param fp output file handle
* @param opt option(s)
* @param translation_domain translation domain
*/
static int singleTableUsage(poptContext con, FILE * fp,
int cursor, const struct poptOption * opt,
/*@null@*/ const char * translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
/*@-branchstate@*/ /* FIX: W2DO? */
if (opt != NULL)
for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
translation_domain = (const char *)opt->arg;
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
if (opt->arg) /* XXX program error */
cursor = singleTableUsage(con, fp, cursor, opt->arg,
translation_domain);
} else if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
}
}
/*@=branchstate@*/
return cursor;
}
/**
* Return concatenated short options for display.
* @param opt option(s)
* @param fp output file handle
* @retval str concatenation of short options
* @return length of display string
*/
static int showShortOptions(const struct poptOption * opt, FILE * fp,
/*@null@*/ char * str)
/*@globals fileSystem @*/
/*@modifies *str, *fp, fileSystem @*/
{
char * s = alloca(300); /* larger then the ascii set */
s[0] = '\0';
/*@-branchstate@*/ /* FIX: W2DO? */
if (str == NULL) {
memset(s, 0, sizeof(s));
str = s;
}
/*@=branchstate@*/
while (opt->longName || opt->shortName || opt->arg) {
if (opt != NULL)
for (; (opt->longName || opt->shortName || opt->arg); opt++) {
if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
str[strlen(str)] = opt->shortName;
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
showShortOptions(opt->arg, f, str);
opt++;
if (opt->arg) /* XXX program error */
(void) showShortOptions(opt->arg, fp, str);
}
if (s != str || !*s)
if (s != str || *s != '\0')
return 0;
fprintf(f, " [-%s]", s);
fprintf(fp, " [-%s]", s);
return strlen(s) + 4;
}
void poptPrintUsage(poptContext con, FILE * f, /*@unused@*/ int flags) {
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags))
{
int cursor;
cursor = showHelpIntro(con, f);
cursor += showShortOptions(con->options, f, NULL);
singleTableUsage(f, cursor, con->options, NULL);
cursor = showHelpIntro(con, fp);
cursor += showShortOptions(con->options, fp, NULL);
(void) singleTableUsage(con, fp, cursor, con->options, NULL);
(void) itemUsage(fp, cursor, con->aliases, con->numAliases, NULL);
(void) itemUsage(fp, cursor, con->execs, con->numExecs, NULL);
if (con->otherHelp) {
cursor += strlen(con->otherHelp) + 1;
if (cursor > 79) fprintf(f, "\n ");
fprintf(f, " %s", con->otherHelp);
if (cursor > 79) fprintf(fp, "\n ");
fprintf(fp, " %s", con->otherHelp);
}
fprintf(f, "\n");
fprintf(fp, "\n");
}
void poptSetOtherOptionHelp(poptContext con, const char * text) {
if (con->otherHelp) xfree(con->otherHelp);
void poptSetOtherOptionHelp(poptContext con, const char * text)
{
con->otherHelp = _free(con->otherHelp);
con->otherHelp = xstrdup(text);
}
/*@=type@*/

View File

@@ -1,69 +1,78 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/poptint.h
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
ftp://ftp.rpm.org/pub/rpm/dist. */
#ifndef H_POPTINT
#define H_POPTINT
/**
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
* @param p memory to free
* @retval NULL always
*/
/*@unused@*/ static inline /*@null@*/ void *
_free(/*@only@*/ /*@null@*/ const void * p)
/*@modifies p @*/
{
if (p != NULL) free((void *)p);
return NULL;
}
/* Bit mask macros. */
typedef unsigned int __pbm_bits;
#define __PBM_NBITS (8 * sizeof (__pbm_bits))
#define __PBM_IX(d) ((d) / __PBM_NBITS)
#define __PBM_MASK(d) ((__pbm_bits) 1 << ((d) % __PBM_NBITS))
#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS))
typedef struct {
__pbm_bits bits[1];
} pbm_set;
#define __PBM_BITS(set) ((set)->bits)
#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits))
#define PBM_FREE(s) free(s);
#define PBM_FREE(s) _free(s);
#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d))
#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d))
#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0)
struct optionStackEntry {
int argc;
/*@only@*/ const char ** argv;
/*@only@*/ pbm_set * argb;
/*@only@*/ /*@null@*/ const char ** argv;
/*@only@*/ /*@null@*/ pbm_set * argb;
int next;
/*@only@*/ const char * nextArg;
/*@keep@*/ const char * nextCharArg;
/*@dependent@*/ struct poptAlias * currAlias;
/*@only@*/ /*@null@*/ const char * nextArg;
/*@keep@*/ /*@null@*/ const char * nextCharArg;
/*@dependent@*/ /*@null@*/ poptItem currAlias;
int stuffed;
};
struct execEntry {
const char * longName;
char shortName;
const char * script;
};
struct poptContext_s {
struct optionStackEntry optionStack[POPT_OPTION_DEPTH];
/*@dependent@*/ struct optionStackEntry * os;
/*@owned@*/ const char ** leftovers;
/*@dependent@*/ struct optionStackEntry * os;
/*@owned@*/ /*@null@*/ const char ** leftovers;
int numLeftovers;
int nextLeftover;
/*@keep@*/ const struct poptOption * options;
/*@keep@*/ const struct poptOption * options;
int restLeftover;
/*@only@*/ const char * appName;
/*@only@*/ struct poptAlias * aliases;
/*@only@*/ /*@null@*/ const char * appName;
/*@only@*/ /*@null@*/ poptItem aliases;
int numAliases;
int flags;
struct execEntry * execs;
/*@owned@*/ /*@null@*/ poptItem execs;
int numExecs;
/*@only@*/ const char ** finalArgv;
/*@only@*/ /*@null@*/ const char ** finalArgv;
int finalArgvCount;
int finalArgvAlloced;
/*@dependent@*/ struct execEntry * doExec;
/*@only@*/ const char * execPath;
/*@dependent@*/ /*@null@*/ poptItem doExec;
/*@only@*/ const char * execPath;
int execAbsolute;
/*@only@*/ const char * otherHelp;
pbm_set * arg_strip;
/*@only@*/ const char * otherHelp;
/*@null@*/ pbm_set * arg_strip;
};
#define xfree(_a) free((void *)_a)
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
#endif
@@ -71,17 +80,17 @@ struct poptContext_s {
#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
#define _(foo) gettext(foo)
#else
#define _(foo) (foo)
#define _(foo) foo
#endif
#if defined(HAVE_DGETTEXT) && !defined(__LCLINT__)
#define D_(dom, str) dgettext(dom, str)
#define POPT_(foo) D_("popt", foo)
#else
#define POPT_(foo) (foo)
#define D_(dom, str) (str)
#define D_(dom, str) str
#define POPT_(foo) foo
#endif
#define N_(foo) (foo)
#define N_(foo) foo
#endif

View File

@@ -1,6 +1,10 @@
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
/** \ingroup popt
* \file popt/poptparse.c
*/
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.redhat.com/pub/code/popt */
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
@@ -14,6 +18,8 @@ int poptDupArgv(int argc, const char **argv,
char * dst;
int i;
if (argc <= 0 || argv == NULL) /* XXX can't happen */
return POPT_ERROR_NOARG;
for (i = 0; i < argc; i++) {
if (argv[i] == NULL)
return POPT_ERROR_NOARG;
@@ -21,53 +27,64 @@ int poptDupArgv(int argc, const char **argv,
}
dst = malloc(nb);
if (dst == NULL) /* XXX can't happen */
return POPT_ERROR_MALLOC;
argv2 = (void *) dst;
dst += (argc + 1) * sizeof(*argv);
/*@-branchstate@*/
for (i = 0; i < argc; i++) {
argv2[i] = dst;
dst += strlen(strcpy(dst, argv[i])) + 1;
}
/*@=branchstate@*/
argv2[argc] = NULL;
*argvPtr = argv2;
*argcPtr = argc;
if (argvPtr) {
*argvPtr = argv2;
} else {
free(argv2);
argv2 = NULL;
}
if (argcPtr)
*argcPtr = argc;
return 0;
}
int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
int poptParseArgvString(const unsigned char * s, int * argcPtr, const char *** argvPtr)
{
const char * src;
char quote = '\0';
const unsigned char * src;
unsigned char quote = '\0';
int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
const char ** argv = malloc(sizeof(*argv) * argvAlloced);
int argc = 0;
int buflen = strlen(s) + 1;
char *buf0 = calloc(buflen, 1);
char *buf = buf0;
char * buf = memset(alloca(buflen), 0, buflen);
int rc = POPT_ERROR_MALLOC;
if (argv == NULL) return rc;
argv[argc] = buf;
for (src = s; *src; src++) {
for (src = s; *src != '\0'; src++) {
if (quote == *src) {
quote = '\0';
} else if (quote) {
} else if (quote != '\0') {
if (*src == '\\') {
src++;
if (!*src) {
free(argv);
free(buf0);
return POPT_ERROR_BADQUOTE;
rc = POPT_ERROR_BADQUOTE;
goto exit;
}
if (*src != quote) *buf++ = '\\';
}
*buf++ = *src;
} else if (isspace(*src)) {
if (*argv[argc]) {
if (*argv[argc] != '\0') {
buf++, argc++;
if (argc == argvAlloced) {
argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
argv = realloc(argv, sizeof(*argv) * argvAlloced);
if (argv == NULL) goto exit;
}
argv[argc] = buf;
}
@@ -75,18 +92,17 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
case '"':
case '\'':
quote = *src;
break;
/*@switchbreak@*/ break;
case '\\':
src++;
if (!*src) {
free(argv);
free(buf0);
return POPT_ERROR_BADQUOTE;
rc = POPT_ERROR_BADQUOTE;
goto exit;
}
/*@fallthrough@*/
default:
*buf++ = *src;
break;
/*@switchbreak@*/ break;
}
}
@@ -94,9 +110,9 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
argc++, buf++;
}
(void) poptDupArgv(argc, argv, argcPtr, argvPtr);
rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
free(argv);
free(buf0);
return 0;
exit:
if (argv) free(argv);
return rc;
}

View File

@@ -19,12 +19,28 @@
#include <unistd.h>
#endif
#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
#ifdef __NeXT
/* access macros are not declared in non posix mode in unistd.h -
don't try to use posix on NeXTstep 3.3 ! */
#include <libc.h>
#endif
#if defined(__LCLINT__)
/*@-declundef -incondefs -redecl@*/ /* LCL: missing annotation */
/*@only@*/ void * alloca (size_t __size)
/*@ensures MaxSet(result) == (__size - 1) @*/
/*@*/;
/*@=declundef =incondefs =redecl@*/
#endif
/* AIX requires this to be the first thing in the file. */
#ifndef __GNUC__
# if HAVE_ALLOCA_H
@@ -33,8 +49,15 @@
# ifdef _AIX
#pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
# if HAVE_ALLOCA
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# else
# ifdef alloca
# undef alloca
# endif
# define alloca(sz) malloc(sz) /* Kludge this for now */
# endif
# endif
# endif
@@ -42,7 +65,10 @@ char *alloca ();
#define alloca __builtin_alloca
#endif
/*@only@*/ char * xstrdup (const char *str);
/*@-redecl -redef@*/
/*@mayexit@*/ /*@only@*/ char * xstrdup (const char *str)
/*@*/;
/*@=redecl =redef@*/
#if HAVE_MCHECK_H && defined(__GNUC__)
#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL)
@@ -51,5 +77,6 @@ char *alloca ();
#define xstrdup(_str) strdup(_str)
#endif /* HAVE_MCHECK_H && defined(__GNUC__) */
#define UNUSED(x) x __attribute__((__unused__))
#include "popt.h"

154
progress.c Normal file
View File

@@ -0,0 +1,154 @@
/* -*- c-file-style: "linux" -*-
*
* Copyright (C) 1996-2000 by Andrew Tridgell
* Copyright (C) Paul Mackerras 1996
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rsync.h"
extern struct stats stats;
extern int am_server;
#define PROGRESS_HISTORY_SECS 5
struct progress_history {
struct timeval time;
OFF_T ofs;
};
static struct progress_history ph_start;
static struct progress_history ph_list[PROGRESS_HISTORY_SECS];
static int newest_hpos, oldest_hpos;
static unsigned long msdiff(struct timeval *t1, struct timeval *t2)
{
return (t2->tv_sec - t1->tv_sec) * 1000L
+ (t2->tv_usec - t1->tv_usec) / 1000;
}
/**
* @param ofs Current position in file
* @param size Total size of file
* @param is_last True if this is the last time progress will be
* printed for this file, so we should output a newline. (Not
* necessarily the same as all bytes being received.)
**/
static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
int is_last)
{
char eol[256];
const char *units;
int pct = ofs == size ? 100 : (int) (100.0 * ofs / size);
unsigned long diff;
double rate, remain;
int remain_h, remain_m, remain_s;
if (is_last) {
/* Compute stats based on the starting info. */
diff = msdiff(&ph_start.time, now);
if (!diff)
diff = 1;
rate = (double) (ofs - ph_start.ofs) * 1000.0 / diff / 1024.0;
/* Switch to total time taken for our last update. */
remain = (double) diff / 1000.0;
} else {
/* Compute stats based on recent progress. */
diff = msdiff(&ph_list[oldest_hpos].time, now);
rate = diff ? (double) (ofs - ph_list[oldest_hpos].ofs) * 1000.0
/ diff / 1024.0 : 0;
remain = rate ? (double) (size - ofs) / rate / 1000.0 : 0.0;
}
if (rate > 1024*1024) {
rate /= 1024.0 * 1024.0;
units = "GB/s";
} else if (rate > 1024) {
rate /= 1024.0;
units = "MB/s";
} else {
units = "kB/s";
}
remain_s = (int) remain % 60;
remain_m = (int) (remain / 60.0) % 60;
remain_h = (int) (remain / 3600.0);
if (is_last) {
snprintf(eol, sizeof eol, " (%d, %.1f%% of %d)\n",
stats.num_transferred_files,
(float)((stats.current_file_index+1) * 100)
/ stats.num_files,
stats.num_files);
} else
strcpy(eol, "\r");
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s",
(double) ofs, pct, rate, units,
remain_h, remain_m, remain_s, eol);
}
void end_progress(OFF_T size)
{
if (!am_server) {
struct timeval now;
gettimeofday(&now, NULL);
rprint_progress(size, size, &now, True);
}
memset(&ph_start, 0, sizeof ph_start);
}
void show_progress(OFF_T ofs, OFF_T size)
{
struct timeval now;
if (am_server)
return;
gettimeofday(&now, NULL);
if (!ph_start.time.tv_sec) {
int i;
/* Try to guess the real starting time when the sender started
* to send us data by using the time we last received some data
* in the last file (if it was recent enough). */
if (msdiff(&ph_list[newest_hpos].time, &now) <= 1500) {
ph_start.time = ph_list[newest_hpos].time;
ph_start.ofs = 0;
} else {
ph_start.time.tv_sec = now.tv_sec;
ph_start.time.tv_usec = now.tv_usec;
ph_start.ofs = ofs;
}
for (i = 0; i < PROGRESS_HISTORY_SECS; i++)
ph_list[i] = ph_start;
}
else {
if (msdiff(&ph_list[newest_hpos].time, &now) < 1000)
return;
newest_hpos = oldest_hpos;
oldest_hpos = (oldest_hpos + 1) % PROGRESS_HISTORY_SECS;
ph_list[newest_hpos].time.tv_sec = now.tv_sec;
ph_list[newest_hpos].time.tv_usec = now.tv_usec;
ph_list[newest_hpos].ofs = ofs;
}
rprint_progress(ofs, size, &now, False);
}

View File

@@ -1,18 +1,18 @@
/* -*- c-file-style: "linux" -*-
Copyright (C) 1996-2000 by Andrew Tridgell
Copyright (C) Paul Mackerras 1996
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -22,96 +22,76 @@
extern int verbose;
extern int recurse;
extern int delete_mode;
extern int remote_version;
extern int delete_after;
extern int max_delete;
extern int csum_length;
extern struct stats stats;
extern int dry_run;
extern int read_batch;
extern int batch_gen_fd;
extern int am_server;
extern int relative_paths;
extern int keep_dirlinks;
extern int preserve_hard_links;
extern int preserve_perms;
extern int cvs_exclude;
extern int io_error;
extern char *tmpdir;
extern char *partial_dir;
extern char *compare_dest;
extern int make_backups;
extern int do_progress;
extern char *backup_dir;
extern char *backup_suffix;
extern int backup_suffix_len;
extern int cleanup_got_literal;
extern int module_id;
extern int ignore_errors;
extern int orig_umask;
extern int keep_partial;
extern int checksum_seed;
extern int inplace;
static struct delete_list {
DEV64_T dev;
INO64_T inode;
} *delete_list;
static int dlist_len, dlist_alloc_len;
extern struct exclude_list_struct server_exclude_list;
/* yuck! This function wouldn't have been necessary if I had the sorting
algorithm right. Unfortunately fixing the sorting algorithm would introduce
a backward incompatibility as file list indexes are sent over the link.
*/
static int delete_already_done(struct file_list *flist,int j)
static void delete_one(char *fn, int is_dir)
{
int i;
STRUCT_STAT st;
if (link_stat(f_name(flist->files[j]), &st)) return 1;
for (i=0;i<dlist_len;i++) {
if (st.st_ino == delete_list[i].inode &&
st.st_dev == delete_list[i].dev)
return 1;
}
return 0;
}
static void add_delete_entry(struct file_struct *file)
{
if (dlist_len == dlist_alloc_len) {
dlist_alloc_len += 1024;
delete_list = (struct delete_list *)Realloc(delete_list, sizeof(delete_list[0])*dlist_alloc_len);
if (!delete_list) out_of_memory("add_delete_entry");
}
delete_list[dlist_len].dev = file->dev;
delete_list[dlist_len].inode = file->inode;
dlist_len++;
if (verbose > 3)
rprintf(FINFO,"added %s to delete list\n", f_name(file));
}
static void delete_one(struct file_struct *f)
{
if (!S_ISDIR(f->mode)) {
if (robust_unlink(f_name(f)) != 0) {
rprintf(FERROR,"delete_one: unlink %s: %s\n",f_name(f),strerror(errno));
if (!is_dir) {
if (robust_unlink(fn) != 0) {
rsyserr(FERROR, errno, "delete_one: unlink %s failed",
full_fname(fn));
} else if (verbose)
rprintf(FINFO, "deleting %s\n", safe_fname(fn));
} else {
if (do_rmdir(fn) != 0) {
if (errno != ENOTEMPTY && errno != EEXIST) {
rsyserr(FERROR, errno,
"delete_one: rmdir %s failed",
full_fname(fn));
}
} else if (verbose) {
rprintf(FINFO,"deleting %s\n",f_name(f));
}
} else {
if (do_rmdir(f_name(f)) != 0) {
if (errno != ENOTEMPTY && errno != EEXIST)
rprintf(FERROR,"delete_one: rmdir %s: %s\n",
f_name(f), strerror(errno));
} else if (verbose) {
rprintf(FINFO,"deleting directory %s\n",f_name(f));
rprintf(FINFO, "deleting directory %s\n",
safe_fname(fn));
}
}
}
static int is_backup_file(char *fn)
{
int k = strlen(fn) - backup_suffix_len;
return k > 0 && strcmp(fn+k, backup_suffix) == 0;
}
/* this deletes any files on the receiving side that are not present
on the sending side. For version 1.6.4 I have changed the behaviour
to match more closely what most people seem to expect of this option */
/* This deletes any files on the receiving side that are not present
* on the sending side. */
void delete_files(struct file_list *flist)
{
struct file_list *local_file_list;
int i, j;
char *name;
extern int module_id;
extern int ignore_errors;
extern int max_delete;
char *argv[1], fbuf[MAXPATHLEN];
static int deletion_count;
if (cvs_exclude)
@@ -122,112 +102,138 @@ void delete_files(struct file_list *flist)
return;
}
for (j=0;j<flist->count;j++) {
if (!S_ISDIR(flist->files[j]->mode) ||
!(flist->files[j]->flags & FLAG_DELETE)) continue;
if (remote_version < 19 &&
delete_already_done(flist, j)) continue;
name = strdup(f_name(flist->files[j]));
if (!(local_file_list = send_file_list(-1,1,&name))) {
free(name);
for (j = 0; j < flist->count; j++) {
if (!(flist->files[j]->flags & FLAG_TOP_DIR)
|| !S_ISDIR(flist->files[j]->mode))
continue;
argv[0] = f_name_to(flist->files[j], fbuf);
if (!(local_file_list = send_file_list(-1, 1, argv)))
continue;
}
if (verbose > 1)
rprintf(FINFO,"deleting in %s\n", name);
rprintf(FINFO, "deleting in %s\n", safe_fname(fbuf));
for (i=local_file_list->count-1;i>=0;i--) {
if (max_delete && deletion_count > max_delete) break;
if (!local_file_list->files[i]->basename) continue;
if (remote_version < 19 &&
S_ISDIR(local_file_list->files[i]->mode))
add_delete_entry(local_file_list->files[i]);
if (-1 == flist_find(flist,local_file_list->files[i])) {
for (i = local_file_list->count-1; i >= 0; i--) {
if (max_delete && deletion_count > max_delete)
break;
if (!local_file_list->files[i]->basename)
continue;
if (flist_find(flist,local_file_list->files[i]) < 0) {
char *f = f_name(local_file_list->files[i]);
int k = strlen(f) - strlen(backup_suffix);
/* Hi Andrew, do we really need to play with backup_suffix here? */
if (make_backups && ((k <= 0) ||
(strcmp(f+k,backup_suffix) != 0))) {
(void) make_backup(f);
if (make_backups && (backup_dir || !is_backup_file(f))) {
make_backup(f);
if (verbose) {
rprintf(FINFO, "deleting %s\n",
safe_fname(f));
}
} else {
deletion_count++;
delete_one(local_file_list->files[i]);
int mode = local_file_list->files[i]->mode;
delete_one(f, S_ISDIR(mode) != 0);
}
deletion_count++;
}
}
flist_free(local_file_list);
free(name);
}
}
/*
* get_tmpname() - create a tmp filename for a given filename
*
* If a tmpdir is defined, use that as the directory to
* put it in. Otherwise, the tmp filename is in the same
* directory as the given name. Note that there may be no
* directory at all in the given name!
*
* The tmp filename is basically the given filename with a
* dot prepended, and .XXXXXX appended (for mkstemp() to
* put its unique gunk in). Take care to not exceed
* either the MAXPATHLEN or NAME_MAX, esp. the last, as
* the basename basically becomes 8 chars longer. In that
* case, the original name is shortened sufficiently to
* make it all fit.
*
* Of course, there's no real reason for the tmp name to
* look like the original, except to satisfy us humans.
* As long as it's unique, rsync will work.
*/
static int get_tmpname(char *fnametmp, char *fname)
{
char *f;
int length = 0;
int maxname;
/* open tmp file */
if (tmpdir) {
f = strrchr(fname,'/');
if (f == NULL)
f = fname;
else
f++;
if (strlen(tmpdir)+strlen(f)+10 > MAXPATHLEN) {
rprintf(FERROR,"filename too long\n");
return 0;
/* Note: this can't overflow, so the return value is safe */
length = strlcpy(fnametmp, tmpdir, MAXPATHLEN - 2);
fnametmp[length++] = '/';
fnametmp[length] = '\0'; /* always NULL terminated */
}
if ((f = strrchr(fname, '/')) != NULL) {
++f;
if (!tmpdir) {
length = f - fname;
/* copy up to and including the slash */
strlcpy(fnametmp, fname, length + 1);
}
snprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f);
return 1;
}
} else
f = fname;
fnametmp[length++] = '.';
fnametmp[length] = '\0'; /* always NULL terminated */
f = strrchr(fname,'/');
maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8);
if (strlen(fname)+9 > MAXPATHLEN) {
rprintf(FERROR,"filename too long\n");
if (maxname < 1) {
rprintf(FERROR, "temporary filename too long: %s\n", fname);
fnametmp[0] = '\0';
return 0;
}
if (f) {
*f = 0;
snprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX",
fname,f+1);
*f = '/';
} else {
snprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname);
}
strlcpy(fnametmp + length, f, maxname);
strcat(fnametmp + length, ".XXXXXX");
return 1;
}
static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
OFF_T total_size)
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
char *fname, int fd, OFF_T total_size)
{
int i;
unsigned int n,remainder,len,count;
static char file_sum1[MD4_SUM_LENGTH];
static char file_sum2[MD4_SUM_LENGTH];
struct map_struct *mapbuf;
struct sum_struct sum;
unsigned int len;
OFF_T offset = 0;
OFF_T offset2;
char *data;
static char file_sum1[MD4_SUM_LENGTH];
static char file_sum2[MD4_SUM_LENGTH];
char *map=NULL;
count = read_int(f_in);
n = read_int(f_in);
remainder = read_int(f_in);
sum_init();
for (i=recv_token(f_in,&data); i != 0; i=recv_token(f_in,&data)) {
int i;
char *map = NULL;
show_progress(offset, total_size);
read_sum_head(f_in, &sum);
if (fd_r >= 0 && size_r > 0) {
OFF_T map_size = MAX(sum.blength * 2, 16*1024);
mapbuf = map_file(fd_r, size_r, map_size, sum.blength);
if (verbose > 2) {
rprintf(FINFO, "recv mapped %s of size %.0f\n",
safe_fname(fname_r), (double)size_r);
}
} else
mapbuf = NULL;
sum_init(checksum_seed);
while ((i = recv_token(f_in, &data)) != 0) {
if (do_progress)
show_progress(offset, total_size);
if (i > 0) {
extern int cleanup_got_literal;
if (verbose > 3) {
rprintf(FINFO,"data recv %d at %.0f\n",
i,(double)offset);
@@ -235,273 +241,374 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
stats.literal_data += i;
cleanup_got_literal = 1;
sum_update(data,i);
if (fd != -1 && write_file(fd,data,i) != i) {
rprintf(FERROR,"write failed on %s : %s\n",fname,strerror(errno));
exit_cleanup(RERR_FILEIO);
}
if (fd != -1 && write_file(fd,data,i) != i)
goto report_write_error;
offset += i;
continue;
}
}
i = -(i+1);
offset2 = i*(OFF_T)n;
len = n;
if (i == (int) count-1 && remainder != 0)
len = remainder;
offset2 = i*(OFF_T)sum.blength;
len = sum.blength;
if (i == (int)sum.count-1 && sum.remainder != 0)
len = sum.remainder;
stats.matched_data += len;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] of size %d at %.0f offset=%.0f\n",
i,len,(double)offset2,(double)offset);
if (buf) {
map = map_ptr(buf,offset2,len);
if (mapbuf) {
map = map_ptr(mapbuf,offset2,len);
see_token(map, len);
sum_update(map,len);
}
if (fd != -1 && write_file(fd,map,len) != (int) len) {
rprintf(FERROR,"write failed on %s : %s\n",
fname,strerror(errno));
exit_cleanup(RERR_FILEIO);
if (inplace) {
if (offset == offset2 && fd != -1) {
if (flush_write_file(fd) < 0)
goto report_write_error;
offset += len;
if (do_lseek(fd, len, SEEK_CUR) != offset) {
rsyserr(FERROR, errno,
"lseek failed on %s",
full_fname(fname));
exit_cleanup(RERR_FILEIO);
}
continue;
}
}
if (fd != -1 && write_file(fd, map, len) != (int)len)
goto report_write_error;
offset += len;
}
end_progress(total_size);
flush_write_file(fd);
#ifdef HAVE_FTRUNCATE
if (inplace && fd != -1)
ftruncate(fd, offset);
#endif
if (do_progress)
end_progress(total_size);
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
rprintf(FERROR,"write failed on %s : %s\n",
fname,strerror(errno));
report_write_error:
rsyserr(FERROR, errno, "write failed on %s",
full_fname(fname));
exit_cleanup(RERR_FILEIO);
}
sum_end(file_sum1);
if (remote_version >= 14) {
read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
if (verbose > 2) {
rprintf(FINFO,"got file_sum\n");
}
if (fd != -1 &&
memcmp(file_sum1,file_sum2,MD4_SUM_LENGTH) != 0) {
return 0;
}
}
if (mapbuf)
unmap_file(mapbuf);
read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
if (verbose > 2)
rprintf(FINFO,"got file_sum\n");
if (fd != -1 && memcmp(file_sum1, file_sum2, MD4_SUM_LENGTH) != 0)
return 0;
return 1;
}
/* main routine for receiver process. Receiver process runs on the
same host as the generator process. */
static void discard_receive_data(int f_in, OFF_T length)
{
receive_data(f_in, NULL, -1, 0, NULL, -1, length);
}
int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
{
/**
* main routine for receiver process.
*
* Receiver process runs on the same host as the generator process. */
int recv_files(int f_in, struct file_list *flist, char *local_name)
{
int next_gen_i = -1;
int fd1,fd2;
STRUCT_STAT st;
char *fname;
char *fname, fbuf[MAXPATHLEN];
char template[MAXPATHLEN];
char fnametmp[MAXPATHLEN];
char *fnamecmp;
char *fnamecmp, *partialptr;
char fnamecmpbuf[MAXPATHLEN];
struct map_struct *buf;
int i;
struct file_struct *file;
int phase=0;
int recv_ok;
extern struct stats stats;
extern int preserve_perms;
extern int delete_after;
struct stats initial_stats;
int save_make_backups = make_backups;
int i, recv_ok, phase = 0;
if (verbose > 2) {
if (verbose > 2)
rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
if (flist->hlink_pool) {
pool_destroy(flist->hlink_pool);
flist->hlink_pool = NULL;
}
while (1) {
while (1) {
cleanup_disable();
i = read_int(f_in);
if (i == -1) {
if (phase==0 && remote_version >= 13) {
phase++;
csum_length = SUM_LENGTH;
if (verbose > 2)
rprintf(FINFO,"recv_files phase=%d\n",phase);
write_int(f_gen,-1);
continue;
if (read_batch) {
if (next_gen_i != flist->count)
while (read_int(batch_gen_fd) != -1) {}
next_gen_i = -1;
}
break;
if (phase)
break;
phase = 1;
csum_length = SUM_LENGTH;
if (verbose > 2)
rprintf(FINFO, "recv_files phase=%d\n", phase);
send_msg(MSG_DONE, "", 0);
if (keep_partial)
make_backups = 0; /* prevents double backup */
continue;
}
if (i < 0 || i >= flist->count) {
rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n",
rprintf(FERROR,"Invalid file index %d in recv_files (count=%d)\n",
i, flist->count);
exit_cleanup(RERR_PROTOCOL);
}
file = flist->files[i];
fname = f_name(file);
stats.current_file_index = i;
stats.num_transferred_files++;
stats.total_transferred_size += file->length;
cleanup_got_literal = 0;
if (local_name)
fname = local_name;
else
fname = f_name_to(file, fbuf);
if (dry_run) {
if (!am_server) {
log_transfer(file, fname);
}
if (!am_server && verbose) /* log the transfer */
rprintf(FINFO, "%s\n", safe_fname(fname));
continue;
}
initial_stats = stats;
if (verbose > 2)
rprintf(FINFO,"recv_files(%s)\n",fname);
rprintf(FINFO, "recv_files(%s)\n", safe_fname(fname));
fnamecmp = fname;
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;
}
if (i < next_gen_i) {
rprintf(FINFO, "skipping update for \"%s\"\n",
safe_fname(fname));
discard_receive_data(f_in, file->length);
continue;
}
}
/* open the file */
if (server_exclude_list.head
&& check_exclude(&server_exclude_list, fname,
S_ISDIR(file->mode)) < 0) {
rprintf(FERROR, "attempt to hack rsync failed.\n");
exit_cleanup(RERR_PROTOCOL);
}
if (partial_dir) {
if ((partialptr = partial_dir_fname(fname)) != NULL)
fnamecmp = partialptr;
else
fnamecmp = fname;
} else
fnamecmp = partialptr = fname;
if (inplace && make_backups) {
if (!(fnamecmp = get_backup_name(fname)))
fnamecmp = partialptr;
}
/* open the file */
fd1 = do_open(fnamecmp, O_RDONLY, 0);
if ((fd1 == -1) && (compare_dest != NULL)) {
if (fd1 == -1 && fnamecmp != fname) {
fnamecmp = fname;
fd1 = do_open(fnamecmp, O_RDONLY, 0);
}
if (fd1 == -1 && compare_dest != NULL) {
/* try the file at compare_dest instead */
snprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",
compare_dest,fname);
pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
compare_dest, fname);
fnamecmp = fnamecmpbuf;
fd1 = do_open(fnamecmp, O_RDONLY, 0);
}
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
rprintf(FERROR,"fstat %s : %s\n",fnamecmp,strerror(errno));
receive_data(f_in,NULL,-1,NULL,file->length);
rsyserr(FERROR, errno, "fstat %s failed",
full_fname(fnamecmp));
discard_receive_data(f_in, file->length);
close(fd1);
continue;
}
if (fd1 != -1 && S_ISDIR(st.st_mode) && fnamecmp == fname) {
/* this special handling for directories
* wouldn't be necessary if robust_rename()
* and the underlying robust_unlink could cope
* with directories
*/
rprintf(FERROR,"recv_files: %s is a directory\n",
full_fname(fnamecmp));
discard_receive_data(f_in, file->length);
close(fd1);
continue;
}
if (fd1 != -1 && !S_ISREG(st.st_mode)) {
rprintf(FERROR,"%s : not a regular file (recv_files)\n",fnamecmp);
receive_data(f_in,NULL,-1,NULL,file->length);
close(fd1);
continue;
fd1 = -1;
}
if (fd1 != -1 && !preserve_perms) {
/* if the file exists already and we aren't perserving
presmissions then act as though the remote end sent
us the file permissions we already have */
/* 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 (fd1 != -1 && st.st_size > 0) {
buf = map_file(fd1,st.st_size);
if (verbose > 2)
rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
/* We now check to see if we are writing file "inplace" */
if (inplace) {
fd2 = do_open(fname, O_WRONLY|O_CREAT, 0);
if (fd2 == -1) {
rsyserr(FERROR, errno, "open %s failed",
full_fname(fname));
discard_receive_data(f_in, file->length);
if (fd1 != -1)
close(fd1);
continue;
}
} else {
buf = NULL;
}
if (!get_tmpname(fnametmp,fname)) {
discard_receive_data(f_in, file->length);
if (fd1 != -1)
close(fd1);
continue;
}
if (!get_tmpname(fnametmp,fname)) {
if (buf) unmap_file(buf);
if (fd1 != -1) close(fd1);
continue;
}
strlcpy(template, fnametmp, sizeof template);
strlcpy(template, fnametmp, sizeof(template));
/* we initially set the perms without the
setuid/setgid bits to ensure that there is no race
condition. They are then correctly updated after
the lchown. Thanks to snabb@epipe.fi for pointing
this out. We also set it initially without group
access because of a similar race condition. */
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
if (fd2 == -1) {
rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno));
receive_data(f_in,buf,-1,NULL,file->length);
if (buf) unmap_file(buf);
continue;
}
/* in most cases parent directories will already exist
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) == 0) {
strlcpy(fnametmp, template, sizeof(fnametmp));
/* we initially set the perms without the
* setuid/setgid bits to ensure that there is no race
* condition. They are then correctly updated after
* the lchown. Thanks to snabb@epipe.fi for pointing
* this out. We also set it initially without group
* access because of a similar race condition. */
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
}
if (fd2 == -1) {
rprintf(FERROR,"cannot create %s : %s\n",fnametmp,strerror(errno));
receive_data(f_in,buf,-1,NULL,file->length);
if (buf) unmap_file(buf);
if (fd1 != -1) close(fd1);
continue;
}
cleanup_set(fnametmp, fname, file, buf, fd1, fd2);
if (!am_server) {
log_transfer(file, fname);
/* in most cases parent directories will already exist
* 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) {
strlcpy(fnametmp, template, sizeof fnametmp);
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
}
if (fd2 == -1) {
rsyserr(FERROR, errno, "mkstemp %s failed",
full_fname(fnametmp));
discard_receive_data(f_in, file->length);
if (fd1 != -1)
close(fd1);
continue;
}
if (partialptr)
cleanup_set(fnametmp, partialptr, file, fd1, fd2);
}
if (!am_server && verbose) /* log the transfer */
rprintf(FINFO, "%s\n", safe_fname(fname));
/* recv file data */
recv_ok = receive_data(f_in,buf,fd2,fname,file->length);
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
fname, fd2, file->length);
log_recv(file, &initial_stats);
if (buf) unmap_file(buf);
if (fd1 != -1) {
close(fd1);
}
close(fd2);
if (verbose > 2)
rprintf(FINFO,"renaming %s to %s\n",fnametmp,fname);
finish_transfer(fname, fnametmp, file);
if (fd1 != -1)
close(fd1);
if (close(fd2) < 0) {
rsyserr(FERROR, errno, "close failed on %s",
full_fname(fnametmp));
exit_cleanup(RERR_FILEIO);
}
if (recv_ok || inplace)
finish_transfer(fname, fnametmp, file, recv_ok);
else if (keep_partial && partialptr
&& handle_partial_dir(partialptr, PDIR_CREATE))
finish_transfer(partialptr, fnametmp, file, 0);
else {
partialptr = NULL;
do_unlink(fnametmp);
}
if (partialptr != fname && fnamecmp == partialptr && recv_ok) {
do_unlink(partialptr);
handle_partial_dir(partialptr, PDIR_DELETE);
}
cleanup_disable();
if (!recv_ok) {
if (csum_length == SUM_LENGTH) {
rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
fname);
} else {
if (verbose > 1)
rprintf(FINFO,"redoing %s(%d)\n",fname,i);
write_int(f_gen,i);
int msgtype = csum_length == SUM_LENGTH || read_batch ?
FERROR : FINFO;
if (msgtype == FERROR || verbose) {
char *errstr, *redostr, *keptstr;
if (!(keep_partial && partialptr) && !inplace)
keptstr = "discarded";
else if (partial_dir)
keptstr = "put into partial-dir";
else
keptstr = "retained";
if (msgtype == FERROR) {
errstr = "ERROR";
redostr = "";
} else {
errstr = "WARNING";
redostr = " (will try again)";
}
rprintf(msgtype,
"%s: %s failed verification -- update %s%s.\n",
errstr, safe_fname(fname),
keptstr, redostr);
}
if (csum_length != SUM_LENGTH) {
char buf[4];
SIVAL(buf, 0, i);
send_msg(MSG_REDO, buf, 4);
}
}
}
make_backups = save_make_backups;
if (delete_after) {
if (recurse && delete_mode && !local_name && flist->count>0) {
delete_files(flist);
}
}
if (preserve_hard_links)
do_hard_links();
/* now we need to fix any directory permissions that were
modified during the transfer */
for (i = 0; i < flist->count; i++) {
file = flist->files[i];
if (!file->basename || !S_ISDIR(file->mode)) continue;
recv_generator(local_name?local_name:f_name(file),flist,i,-1);
}
if (delete_after && recurse && !local_name && flist->count > 0)
delete_files(flist);
if (verbose > 2)
rprintf(FINFO,"recv_files finished\n");
return 0;
}

239
rsync.c
View File

@@ -1,17 +1,17 @@
/*
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -26,10 +26,16 @@ extern int verbose;
extern int dry_run;
extern int preserve_times;
extern int am_root;
extern int am_sender;
extern int am_generator;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_perms;
extern int force_delete;
extern int recurse;
extern int keep_dirlinks;
extern int make_backups;
extern char *backup_dir;
extern int inplace;
/*
@@ -43,178 +49,165 @@ void free_sums(struct sum_struct *s)
/*
* delete a file or directory. If force_delete is set then delete
* recursively
* delete a file or directory. If force_delete is set then delete
* recursively
*/
int delete_file(char *fname)
{
DIR *d;
struct dirent *di;
char buf[MAXPATHLEN];
extern int force_delete;
STRUCT_STAT st;
int ret;
extern int recurse;
#if SUPPORT_LINKS
ret = do_lstat(fname, &st);
#else
ret = do_stat(fname, &st);
#endif
if (ret) {
if (ret)
return -1;
}
if (!S_ISDIR(st.st_mode)) {
if (robust_unlink(fname) == 0 || errno == ENOENT) return 0;
rprintf(FERROR,"delete_file: unlink(%s) : %s\n", fname, strerror(errno));
if (robust_unlink(fname) == 0 || errno == ENOENT)
return 0;
rsyserr(FERROR, errno, "delete_file: unlink %s failed",
full_fname(fname));
return -1;
}
if (do_rmdir(fname) == 0 || errno == ENOENT) return 0;
if (!force_delete || !recurse ||
(errno != ENOTEMPTY && errno != EEXIST)) {
rprintf(FERROR,"delete_file: rmdir(%s) : %s\n", fname, strerror(errno));
if (do_rmdir(fname) == 0 || errno == ENOENT)
return 0;
if (!force_delete || !recurse
|| (errno != ENOTEMPTY && errno != EEXIST)) {
rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
full_fname(fname));
return -1;
}
/* now we do a recsursive delete on the directory ... */
d = opendir(fname);
if (!d) {
rprintf(FERROR,"delete_file: opendir(%s): %s\n",
fname,strerror(errno));
if (!(d = opendir(fname))) {
rsyserr(FERROR, errno, "delete_file: opendir %s failed",
full_fname(fname));
return -1;
}
for (di=readdir(d); di; di=readdir(d)) {
for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
char *dname = d_name(di);
if (strcmp(dname,".")==0 ||
strcmp(dname,"..")==0)
if (dname[0] == '.' && (dname[1] == '\0'
|| (dname[1] == '.' && dname[2] == '\0')))
continue;
snprintf(buf, sizeof(buf), "%s/%s", fname, dname);
pathjoin(buf, sizeof buf, fname, dname);
if (verbose > 0)
rprintf(FINFO,"deleting %s\n", buf);
rprintf(FINFO, "deleting %s\n", safe_fname(buf));
if (delete_file(buf) != 0) {
closedir(d);
return -1;
}
}
}
if (errno) {
rsyserr(FERROR, errno, "delete_file: readdir %s failed",
full_fname(fname));
closedir(d);
return -1;
}
closedir(d);
if (do_rmdir(fname) != 0) {
rprintf(FERROR,"delete_file: rmdir(%s) : %s\n", fname, strerror(errno));
rsyserr(FERROR, errno, "delete_file: rmdir %s failed",
full_fname(fname));
return -1;
}
return 0;
}
static int is_in_group(gid_t gid)
{
#ifdef GETGROUPS_T
static gid_t last_in = (gid_t) -2, last_out;
static int ngroups = -2;
static GETGROUPS_T *gidset;
int n;
if (gid == last_in)
return last_out;
if (ngroups < -1) {
/* treat failure (-1) as if not member of any group */
ngroups = getgroups(0, 0);
if (ngroups > 0) {
gidset = (GETGROUPS_T *) malloc(ngroups * sizeof(GETGROUPS_T));
ngroups = getgroups(ngroups, gidset);
}
}
last_in = gid;
last_out = 0;
for (n = 0; n < ngroups; n++) {
if (gidset[n] == gid) {
last_out = 1;
break;
}
}
return last_out;
#else
return 0;
#endif
}
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
int report)
int flags)
{
int updated = 0;
STRUCT_STAT st2;
int change_uid, change_gid;
if (dry_run) return 0;
if (dry_run)
return 0;
if (!st) {
if (link_stat(fname,&st2) != 0) {
rprintf(FERROR,"stat %s : %s\n",fname,strerror(errno));
if (link_stat(fname, &st2, 0) < 0) {
rsyserr(FERROR, errno, "stat %s failed",
full_fname(fname));
return 0;
}
st = &st2;
}
if (preserve_times && !S_ISLNK(st->st_mode) &&
cmp_modtime(st->st_mtime, file->modtime) != 0) {
if (!preserve_times || S_ISLNK(st->st_mode)
|| (make_backups && !backup_dir && S_ISDIR(st->st_mode)))
flags |= PERMS_SKIP_MTIME;
if (!(flags & PERMS_SKIP_MTIME)
&& cmp_modtime(st->st_mtime, file->modtime) != 0) {
/* don't complain about not setting times on directories
because some filesystems can't do it */
* because some filesystems can't do it */
if (set_modtime(fname,file->modtime) != 0 &&
!S_ISDIR(st->st_mode)) {
rprintf(FERROR,"failed to set times on %s : %s\n",
fname,strerror(errno));
rsyserr(FERROR, errno, "failed to set times on %s",
full_fname(fname));
return 0;
} else {
updated = 1;
}
updated = 1;
}
change_uid = am_root && preserve_uid && st->st_uid != file->uid;
change_gid = preserve_gid && file->gid != (gid_t) -1 && \
st->st_gid != file->gid;
if (change_gid && !am_root) {
/* enforce bsd-style group semantics: non-root can only
change to groups that the user is a member of */
change_gid = is_in_group(file->gid);
}
change_gid = preserve_gid && file->gid != GID_NONE
&& st->st_gid != file->gid;
if (change_uid || change_gid) {
if (verbose > 2) {
if (change_uid) {
rprintf(FINFO,
"set uid of %s from %ld to %ld\n",
fname, (long)st->st_uid, (long)file->uid);
}
if (change_gid) {
rprintf(FINFO,
"set gid of %s from %ld to %ld\n",
fname, (long)st->st_gid, (long)file->gid);
}
}
if (do_lchown(fname,
change_uid?file->uid:st->st_uid,
change_gid?file->gid:st->st_gid) != 0) {
change_uid ? file->uid : st->st_uid,
change_gid ? file->gid : st->st_gid) != 0) {
/* shouldn't have attempted to change uid or gid
unless have the privilege */
rprintf(FERROR,"chown %s : %s\n", fname,strerror(errno));
* unless have the privilege */
rsyserr(FERROR, errno, "%s %s failed",
change_uid ? "chown" : "chgrp",
full_fname(fname));
return 0;
}
/* a lchown had been done - we have to re-stat if the
destination had the setuid or setgid bits set due
to the side effect of the chown call */
* destination had the setuid or setgid bits set due
* to the side effect of the chown call */
if (st->st_mode & (S_ISUID | S_ISGID)) {
link_stat(fname, st);
link_stat(fname, st,
keep_dirlinks && S_ISDIR(st->st_mode));
}
updated = 1;
}
#ifdef HAVE_CHMOD
if (!S_ISLNK(st->st_mode)) {
if (st->st_mode != file->mode) {
if ((st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS)) {
updated = 1;
if (do_chmod(fname,file->mode) != 0) {
rprintf(FERROR,"failed to set permissions on %s : %s\n",
fname,strerror(errno));
if (do_chmod(fname,(file->mode & CHMOD_BITS)) != 0) {
rsyserr(FERROR, errno, "failed to set permissions on %s",
full_fname(fname));
return 0;
}
}
}
#endif
if (verbose > 1 && report) {
if (verbose > 1 && flags & PERMS_REPORT) {
if (updated)
rprintf(FINFO,"%s\n",fname);
else
@@ -226,34 +219,58 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
void sig_int(void)
{
/* KLUGE: if the user hits Ctrl-C while ssh is prompting
* for a password, then our cleanup's sending of a SIGUSR1
* signal to all our children may kill ssh before it has a
* chance to restore the tty settings (i.e. turn echo back
* on). By sleeping for a short time, ssh gets a bigger
* chance to do the right thing. If child processes are
* not ssh waiting for a password, then this tiny delay
* shouldn't hurt anything. */
msleep(400);
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)
void finish_transfer(char *fname, char *fnametmp, struct file_struct *file,
int ok_to_set_time)
{
int ret;
if (inplace) {
if (verbose > 2)
rprintf(FINFO, "finishing %s\n", fname);
goto do_set_perms;
}
if (make_backups && !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);
/* move tmp file over real file */
if (robust_rename(fnametmp,fname) != 0) {
if (errno == EXDEV) {
/* rename failed on cross-filesystem link.
Copy the file instead. */
if (copy_file(fnametmp,fname, file->mode & INITACCESSPERMS)) {
rprintf(FERROR,"copy %s -> %s : %s\n",
fnametmp,fname,strerror(errno));
} else {
set_perms(fname,file,NULL,0);
}
} else {
rprintf(FERROR,"rename %s -> %s : %s\n",
fnametmp,fname,strerror(errno));
}
if (verbose > 2)
rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
if (ret < 0) {
rsyserr(FERROR, errno, "%s %s -> \"%s\"",
ret == -2 ? "copy" : "rename",
full_fname(fnametmp), fname);
do_unlink(fnametmp);
} else {
set_perms(fname,file,NULL,0);
return;
}
if (ret == 0) {
/* 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);
}
const char *who_am_i(void)
{
return am_sender ? "sender" : am_generator ? "generator" : "receiver";
}

372
rsync.h
View File

@@ -24,9 +24,11 @@
#define BLOCK_SIZE 700
#define RSYNC_RSH_ENV "RSYNC_RSH"
#define RSYNC_RSH_IO_ENV "RSYNC_RSH_IO"
#define RSYNC_NAME "rsync"
#define RSYNCD_CONF "/etc/rsyncd.conf"
/* RSYNCD_SYSCONF is now set in config.h */
#define RSYNCD_USERCONF "rsyncd.conf"
#define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock"
#define URL_PREFIX "rsync://"
@@ -37,32 +39,51 @@
incompatible with older versions :-( */
#define CHAR_OFFSET 0
/* These flags are only used during the flist transfer. */
#define FLAG_DELETE (1<<0)
#define SAME_MODE (1<<1)
#define SAME_RDEV (1<<2)
#define SAME_UID (1<<3)
#define SAME_GID (1<<4)
#define SAME_DIR (1<<5)
#define SAME_NAME SAME_DIR
#define LONG_NAME (1<<6)
#define SAME_TIME (1<<7)
#define XMIT_TOP_DIR (1<<0)
#define XMIT_SAME_MODE (1<<1)
#define XMIT_EXTENDED_FLAGS (1<<2)
#define XMIT_SAME_RDEV_pre28 XMIT_EXTENDED_FLAGS /* Only in protocols < 28 */
#define XMIT_SAME_UID (1<<3)
#define XMIT_SAME_GID (1<<4)
#define XMIT_SAME_NAME (1<<5)
#define XMIT_LONG_NAME (1<<6)
#define XMIT_SAME_TIME (1<<7)
#define XMIT_SAME_RDEV_MAJOR (1<<8)
#define XMIT_HAS_IDEV_DATA (1<<9)
#define XMIT_SAME_DEV (1<<10)
#define XMIT_RDEV_MINOR_IS_SMALL (1<<11)
/* These flags are used in the live flist data. */
#define FLAG_TOP_DIR (1<<0)
#define FLAG_HLINK_EOL (1<<1) /* generator only */
#define FLAG_MOUNT_POINT (1<<2) /* sender only */
/* update this if you make incompatible changes */
#define PROTOCOL_VERSION 26
#define PROTOCOL_VERSION 28
/* We refuse to interoperate with versions that are not in this range.
* Note that we assume we'll work with later versions: the onus is on
* people writing them to make sure that they don't send us anything
* we won't understand.
*
* There are two possible explanations for the limit at thirty: either
* to allow new major-rev versions that do not interoperate with us,
* and (more likely) so that we can detect an attempt to connect rsync
* to a non-rsync server, which is unlikely to begin by sending a byte
* between 15 and 30. */
#define MIN_PROTOCOL_VERSION 15
#define MAX_PROTOCOL_VERSION 30
* Interoperation with old but supported protocol versions
* should cause a warning to be printed. At a future date
* the old protocol will become the minimum and
* compatibility code removed.
*
* There are two possible explanations for the limit at
* MAX_PROTOCOL_VERSION: either to allow new major-rev versions that
* do not interoperate with us, and (more likely) so that we can
* detect an attempt to connect rsync to a non-rsync server, which is
* unlikely to begin by sending a byte between MIN_PROTOCL_VERSION and
* MAX_PROTOCOL_VERSION. */
#define MIN_PROTOCOL_VERSION 20
#define OLD_PROTOCOL_VERSION 25
#define MAX_PROTOCOL_VERSION 40
#define RSYNC_PORT 873
@@ -72,22 +93,50 @@
#define MAX_MAP_SIZE (256*1024)
#define IO_BUFFER_SIZE (4092)
#define IOERR_GENERAL (1<<0) /* For backward compatibility, this must == 1 */
#define IOERR_VANISHED (1<<1)
#define MAX_ARGS 1000
#define MPLEX_BASE 7
/* Log values. I *think* what these mean is: FLOG goes to the server
* logfile; FERROR and FINFO try to end up on the client, with
* different levels of filtering. */
enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#define NO_EXCLUDES 0
#define SERVER_EXCLUDES 1
#define ALL_EXCLUDES 2
#define XFLG_FATAL_ERRORS (1<<0)
#define XFLG_DEF_INCLUDE (1<<1)
#define XFLG_WORDS_ONLY (1<<2)
#define XFLG_WORD_SPLIT (1<<3)
#define PERMS_REPORT (1<<0)
#define PERMS_SKIP_MTIME (1<<1)
#define FULL_FLUSH 1
#define NORMAL_FLUSH 0
#define PDIR_CREATE 1
#define PDIR_DELETE 0
/* Log-message categories. FLOG is only used on the daemon side to
* output messages to the log file. */
enum logcode { FERROR=1, FINFO=2, FLOG=3 };
/* Messages types that are sent over the message channel. The logcode
* values must all be present here with identical numbers. */
enum msgcode {
MSG_DONE=5, /* current phase is done */
MSG_REDO=4, /* reprocess indicated flist index */
MSG_ERROR=FERROR, MSG_INFO=FINFO, MSG_LOG=FLOG, /* remote logging */
MSG_DATA=0 /* raw data on the multiplexed stream */
};
#include "errcode.h"
#include "config.h"
/* The default RSYNC_RSH is always set in config.h, either to "remsh",
* "rsh", or otherwise something specified by the user. HAVE_REMSH
* controls parameter munging for HP/UX, etc. */
/* The default RSYNC_RSH is always set in config.h. */
#include <sys/types.h>
@@ -105,6 +154,10 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#include <stdlib.h>
#endif
#if defined(HAVE_MALLOC_H) && (defined(HAVE_MALLINFO) || !defined(HAVE_STDLIB_H))
#include <malloc.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
@@ -113,10 +166,6 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#include <string.h>
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
@@ -173,20 +222,10 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#endif
#endif
#ifdef HAVE_FNMATCH
#include <fnmatch.h>
#else
#include "lib/fnmatch.h"
#endif
#ifdef HAVE_GLOB_H
#include <glob.h>
#endif
#ifdef HAVE_MALLOC_H
# include <malloc.h>
#endif
/* these are needed for the uid/gid mapping code */
#include <pwd.h>
#include <grp.h>
@@ -213,10 +252,19 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
# endif
#endif
#if MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#elif MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#endif
#ifdef HAVE_COMPAT_H
#include <compat.h>
#endif
#include <assert.h>
#include "lib/pool_alloc.h"
#define BOOL int
@@ -267,7 +315,18 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#else
/* As long as it gets... */
#define int64 off_t
#define NO_INT64
#define INT64_IS_OFF_T
#endif
#if (SIZEOF_LONG == 8)
#define uint64 unsigned long
#elif (SIZEOF_INT == 8)
#define uint64 unsigned int
#elif HAVE_LONGLONG
#define uint64 unsigned long long
#else
/* As long as it gets... */
#define uint64 unsigned off_t
#endif
/* Starting from protocol version 26, we always use 64-bit
@@ -292,17 +351,14 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
* device numbers will be truncated. But it's a kind of silly thing
* to do anyhow.
*
* FIXME: In future, we should probable split the device number into
* major/minor, and transfer the two parts as 32-bit ints. That gives
* you somewhat more of a chance that they'll come from a big machine
* to a little one in a useful way.
*
* FIXME: Really we need an unsigned type, and we perhaps ought to
* cope with platforms on which this is an unsigned int or even a
* struct. Later.
* FIXME: I don't think the code in flist.c has ever worked on a system
* where dev_t is a struct.
*/
#define INO64_T int64
#define DEV64_T int64
struct idev {
uint64 inode;
uint64 dev;
};
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@@ -319,82 +375,141 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
/* the length of the md4 checksum */
#define MD4_SUM_LENGTH 16
#define SUM_LENGTH 16
#define SHORT_SUM_LENGTH 2
#define BLOCKSUM_BIAS 10
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
#ifndef NAME_MAX
#define NAME_MAX 255
#endif
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif
#ifndef IN_LOOPBACKNET
#define IN_LOOPBACKNET 127
#endif
#define GID_NONE ((gid_t)-1)
#define HL_CHECK_MASTER 0
#define HL_SKIP 1
struct hlink {
int hlindex;
struct file_struct *next;
};
#define F_DEV link_u.idev->dev
#define F_INODE link_u.idev->inode
#define F_HLINDEX link_u.links->hlindex
#define F_NEXT link_u.links->next
struct file_struct {
unsigned flags;
time_t modtime;
union {
dev_t rdev; /* The device number, if this is a device */
char *sum; /* Only a normal file can have a checksum */
char *link; /* Points to symlink string, if a symlink */
} u;
OFF_T length;
mode_t mode;
INO64_T inode;
/** Device this file lives upon */
DEV64_T dev;
/** If this is a device node, the device number. */
DEV64_T rdev;
uid_t uid;
gid_t gid;
char *basename;
char *dirname;
char *basedir;
char *link;
char *sum;
union {
struct idev *idev;
struct hlink *links;
} link_u;
time_t modtime;
uid_t uid;
gid_t gid;
mode_t mode;
uchar flags; /* this item MUST remain last */
};
/*
* Start the flist array at FLIST_START entries and grow it
* by doubling until FLIST_LINEAR then grow by FLIST_LINEAR
*/
#define FLIST_START (32 * 1024)
#define FLIST_LINEAR (FLIST_START * 512)
#define ARENA_SIZE (32 * 1024)
/*
* Extent size for allocation pools A minimum size of 128KB
* is needed to mmap them so that freeing will release the
* space to the OS.
*
* Larger sizes reduce leftover fragments and speed free calls
* (when they happen) Smaller sizes increase the chance of
* freed allocations freeing whole extents.
*/
#define FILE_EXTENT (256 * 1024)
#define HLINK_EXTENT (128 * 1024)
struct string_area {
char *base;
char *end;
char *current;
struct string_area *next;
};
#define WITH_HLINK 1
#define WITHOUT_HLINK 0
struct file_list {
int count;
int malloced;
alloc_pool_t file_pool;
alloc_pool_t hlink_pool;
struct file_struct **files;
struct string_area *string_area;
};
#define SUMFLG_SAME_OFFSET (1<<0)
struct sum_buf {
OFF_T offset; /* offset in file of this chunk */
int len; /* length of chunk of file */
int i; /* index of this chunk */
uint32 sum1; /* simple checksum */
char sum2[SUM_LENGTH]; /* checksum */
OFF_T offset; /**< offset in file of this chunk */
unsigned int len; /**< length of chunk of file */
uint32 sum1; /**< simple checksum */
short flags; /**< flag bits */
char sum2[SUM_LENGTH]; /**< checksum */
};
struct sum_struct {
OFF_T flength; /* total file length */
size_t count; /* how many chunks */
size_t remainder; /* flength % block_length */
size_t n; /* block_length */
struct sum_buf *sums; /* points to info for each chunk */
OFF_T flength; /**< total file length */
size_t count; /**< how many chunks */
unsigned int blength; /**< block_length */
unsigned int remainder; /**< flength % block_length */
int s2length; /**< sum2_length */
struct sum_buf *sums; /**< points to info for each chunk */
};
struct map_struct {
char *p;
int fd,p_size,p_len;
OFF_T file_size, p_offset, p_fd_offset;
char *p; /* Window pointer */
int fd; /* File Descriptor */
int p_size; /* Largest window size we allocated */
int p_len; /* Latest (rounded) window size */
int def_window_size; /* Default window size */
int status; /* first errno from read errors */
OFF_T file_size; /* File size (from stat) */
OFF_T p_offset; /* Window start */
OFF_T p_fd_offset; /* offset of cursor in fd ala lseek */
};
#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 */
struct exclude_struct {
struct exclude_struct *next;
char *pattern;
int regular_exp;
int fnmatch_flags;
int include;
int directory;
int local;
unsigned int match_flags;
int slash_cnt;
};
struct exclude_list_struct {
struct exclude_struct *head;
struct exclude_struct *tail;
char *debug_type;
};
struct stats {
@@ -407,6 +522,7 @@ struct stats {
int flist_size;
int num_files;
int num_transferred_files;
int current_file_index;
};
@@ -421,6 +537,7 @@ static inline int flist_up(struct file_list *flist, int i)
#include "byteorder.h"
#include "lib/mdfour.h"
#include "lib/wildmatch.h"
#include "lib/permstring.h"
#include "lib/addrinfo.h"
@@ -435,11 +552,13 @@ int asprintf(char **ptr, const char *format, ...);
int vasprintf(char **ptr, const char *format, va_list ap);
#endif
#if !defined(HAVE_VSNPRINTF) && !defined(HAVE_C99_VSNPRINTF)
int vsnprintf (char *str, size_t count, const char *fmt, va_list args);
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
#define vsnprintf rsync_vsnprintf
int vsnprintf(char *str, size_t count, const char *fmt, va_list args);
#endif
#if !defined(HAVE_SNPRINTF) && !defined(HAVE_C99_VSNPRINTF)
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
#define snprintf rsync_snprintf
int snprintf(char *str,size_t count,const char *fmt,...);
#endif
@@ -486,10 +605,24 @@ extern int errno;
#define STDERR_FILENO 2
#endif
#ifndef S_IRUSR
#define S_IRUSR 0400
#endif
#ifndef S_IWUSR
#define S_IWUSR 0200
#endif
#ifndef ACCESSPERMS
#define ACCESSPERMS 0777
#endif
#ifndef S_ISVTX
#define S_ISVTX 0
#endif
#define CHMOD_BITS (S_ISUID | S_ISGID | S_ISVTX | ACCESSPERMS)
#ifndef _S_IFMT
#define _S_IFMT 0170000
#endif
@@ -553,9 +686,6 @@ extern int errno;
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
#ifndef ACCESSPERMS
#define ACCESSPERMS 0777
#endif
/* Initial mask on permissions given to temporary files. Mask off setuid
bits and group access because of potential race-condition security
holes, and mask other access because mode 707 is bizarre */
@@ -564,25 +694,38 @@ extern int errno;
/* handler for null strings in printf format */
#define NS(s) ((s)?(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
/* Convenient wrappers for malloc and realloc. Use them. */
#define new(type) ((type *)malloc(sizeof(type)))
#define new_array(type, num) ((type *)_new_array(sizeof(type), (num)))
#define realloc_array(ptr, type, num) ((type *)_realloc_array((ptr), sizeof(type), (num)))
/* use magic gcc attributes to catch format errors */
void rprintf(enum logcode , const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
__attribute__((format (printf, 2, 3)))
;
/* This is just like rprintf, but it also tries to print some
* representation of the error code. Normally errcode = errno. */
void rsyserr(enum logcode, int, const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 3, 4)))
#endif
__attribute__((format (printf, 3, 4)))
;
#ifdef REPLACE_INET_NTOA
#define inet_ntoa rep_inet_ntoa
#endif
/* Make sure that the O_BINARY flag is defined. */
#ifndef O_BINARY
#define O_BINARY 0
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char *d, const char *s, size_t bufsize);
@@ -598,6 +741,17 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
#define exit_cleanup(code) _exit_cleanup(code, __FILE__, __LINE__)
#ifdef HAVE_GETEUID
#define MY_UID() geteuid()
#else
#define MY_UID() getuid()
#endif
#ifdef HAVE_GETEGID
#define MY_GID() getegid()
#else
#define MY_GID() getgid()
#endif
extern int verbose;
@@ -607,11 +761,13 @@ inet_ntop(int af, const void *src, char *dst, size_t size);
#endif /* !HAVE_INET_NTOP */
#ifndef HAVE_INET_PTON
int isc_net_pton(int af, const char *src, void *dst);
int inet_pton(int af, const char *src, void *dst);
#endif
#ifdef __GNUC__
# define UNUSED(x) x __attribute__((__unused__))
#else
# define UNUSED(x) x
#endif /* ndef __GNUC__ */
#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;

1009
rsync.yo
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsyncd.conf)(5)(12 Feb 1999)()()
manpage(rsyncd.conf)(5)(21 Sep 2004)()()
manpagename(rsyncd.conf)(configuration file for rsync server)
manpagesynopsis()
@@ -8,9 +8,7 @@ rsyncd.conf
manpagedescription()
The rsyncd.conf file is the runtime configuration file for rsync when
run with the --daemon option. When run in this way rsync becomes a
rsync server listening on TCP port 873. Connections from rsync clients
are accepted for either anonymous or authenticated rsync sessions.
run as an rsync server.
The rsyncd.conf file controls authentication, access, logging and
available modules.
@@ -51,9 +49,12 @@ bind to a port numbered under 1024 (as is the default 873), or to set
file ownership. Otherwise, it must just have permission to read and
write the appropriate data, log, and lock files.
You can launch it either via inetd or as a stand-alone daemon. If run
as a daemon then just run the command "rsync --daemon" from a suitable
startup script.
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 "rsync --daemon" from a suitable startup script.
If run from an rsync client via a remote shell (by specifying both the
"-e/--rsh" option and server mode with "::" or "rsync://"), the --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 +69,7 @@ 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
it to reread the tt(/etc/rsyncd.conf). The file is re-read on each client
it to reread the tt(rsyncd.conf) file. The file is re-read on each client
connection.
manpagesection(GLOBAL OPTIONS)
@@ -92,7 +93,7 @@ useful on systems (such as AIX) where syslog() doesn't work for
chrooted programs.
dit(bf(pid file)) The "pid file" option tells the rsync daemon to write
its process id to that file.
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
@@ -127,28 +128,49 @@ of available modules. The default is no comment.
dit(bf(path)) The "path" option specifies the directory in the servers
filesystem to make available in this module. You must specify this option
for each module in tt(/etc/rsyncd.conf).
for each module in tt(rsyncd.conf).
dit(bf(use chroot)) If "use chroot" is true, the rsync server 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 and
of not being able to follow symbolic links outside of the new root path
when reading. When "use chroot" is false, for security reasons
symlinks may only be relative paths pointing to other files within the
root path, and leading slashes are removed from absolute paths. The
default for "use chroot" is true.
holes, but it has the disadvantages of requiring super-user privileges,
of not being able to follow symbolic links that are either absolute or outside
of the new root path, and of complicating the preservation of usernames and groups
(see below). When "use chroot" is false, for security reasons,
symlinks may only be relative paths pointing to other files within the root
path, and leading slashes are removed from most absolute paths (options
such as --backup-dir, --compare-dest, etc. interpret an absolute path as
rooted in the module's "path" dir, just as if chroot was specified).
The default for "use chroot" is true.
In order to preserve usernames and groupnames, rsync needs to be able to
use the standard library functions for looking up names and IDs (i.e.
getpwuid(), getgrgid(), getpwname(), and getgrnam()). This means a
process in the chroot namespace will need to have access to the resources
used by these library functions (traditionally /etc/passwd and
/etc/group). If these resources are not available, rsync will only be
able to copy the IDs, just as if the --numeric-ids option had been
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
(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
at least 2.6.3 to effect this.
dit(bf(max connections)) The "max connections" option allows you to
specify the maximum number of simultaneous connections you will allow
to this module of your rsync server. Any clients connecting when the
maximum has been reached will receive a message telling them to try
later. The default is 0 which means no limit.
specify the maximum number of simultaneous connections you will allow.
Any clients connecting when the maximum has been reached will receive a
message telling them to try later. The default is 0 which means no limit.
See also the "lock file" option.
dit(bf(lock file)) The "lock file" option specifies the file to use to
support the "max connections" option. The rsync server uses record
locking on this file to ensure that the max connections limit is not
exceeded. The default is tt(/var/run/rsyncd.lock).
exceeded for the modules sharing the lock file.
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
@@ -156,60 +178,64 @@ attempted uploads will fail. If "read only" is false then uploads will
be possible if file permissions on the server 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
default is for this option to be disabled.
dit(bf(list)) The "list" option determines if this module should be
listed when the client asks for a listing of available modules. By
setting this to false you can create hidden modules. The default is
for modules to be listable.
dit(bf(uid)) The "uid" option specifies the user name or user id that
dit(bf(uid)) The "uid" option specifies the user name or user ID that
file transfers to and from that module should take place as when the daemon
was run as root. In combination with the "gid" option this determines what
file permissions are available. The default is uid -2, which is normally
the user "nobody".
dit(bf(gid)) The "gid" option specifies the group name or group id that
dit(bf(gid)) The "gid" option specifies the group name or group ID that
file transfers to and from that module should take place as when the daemon
was run as root. This complements the "uid" option. The default is gid -2,
which is normally the group "nobody".
dit(bf(exclude)) The "exclude" option allows you to specify a space
separated list of patterns to add to the exclude list. This is
equivalent to the client specifying these patterns with the --exclude
option except that the exclude list is not passed to the client and
thus only apply on the server. Only one "exclude" option may be
specified, but you can use "-" and "+" before patterns to specify
exclude/include.
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
or written. This is only superficially equivalent to the client
specifying these patterns with the --exclude option. Only one "exclude"
option may be specified, but you can use "-" and "+" before patterns to
specify exclude/include.
Note that this option is not designed with strong security in
mind, it is quite possible that a client may find a way to bypass this
exclude list. If you want to absolutely ensure that certain files
cannot be accessed then use the uid/gid options in combination with
file permissions.
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
it doesn't exclude files from being deleted on a client when receiving
from a server.
dit(bf(exclude from)) The "exclude from" option specifies a filename
on the server that contains exclude patterns, one per line. This is
equivalent to the client specifying the --exclude-from option with a
equivalent file except that the resulting exclude patterns are not
passed to the client and thus only apply on the server. See also the
note about security for the exclude option above.
on the server that contains exclude patterns, one per line.
This is only superficially equivalent
to the client specifying the --exclude-from option with an equivalent file.
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
equivalent to the client specifying these patterns with the --include
option. 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 section of exclude patterns in the rsync man page for information
on the syntax of this option.
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 --include option because it applies only on the server. 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
equivalent to the client specifying the --include-from option with a
equivalent file.
only superficially equivalent to the client specifying the
--include-from option with a equivalent file.
See the "exclude" option above.
dit(bf(auth users)) The "auth users" option specifies a comma and
space separated list of usernames that will be allowed to connect to
space-separated list of usernames that will be allowed to connect to
this module. The usernames do not need to exist on the local
system. The usernames may also contain shell wildcard characters. If
"auth users" is set then the client will be challenged to supply a
@@ -219,6 +245,11 @@ usernames are 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
rsyncd.conf-level username that differs from the remote-shell-level
username when using a remote shell to connect to an rsync server.
dit(bf(secrets file)) The "secrets file" option specifies the name of
a file that contains the username:password pairs used for
authenticating this module. This file is only consulted if the "auth
@@ -235,7 +266,7 @@ by "other"; see "strict modes".
dit(bf(strict modes)) The "strict modes" option determines whether or not
the permissions on the secrets file will be checked. If "strict modes" is
true, then the secrets file must not be readable by any user id other
true, then the secrets file must not be readable by any user ID other
than the one that the rsync daemon is running under. If "strict modes" is
false, the check is not performed. The default is true. This option
was added to accommodate rsync running on the Windows operating system.
@@ -248,16 +279,18 @@ connection is rejected.
Each pattern can be in one of five forms:
itemize(
it() a dotted decimal IP address. In this case the incoming machines
IP address must match exactly.
it() a dotted decimal IPv4 address of the form a.b.c.d, or an IPv6 address
of the form a:b:c::d:e:f. In this case the incoming machine's IP address
must match exactly.
it() a address/mask in the form a.b.c.d/n were n is the number of
one bits in in the netmask. All IP addresses which match the masked
IP address will be allowed in.
it() an address/mask in the form ipaddr/n where ipaddr is the IP address
and n is the number of one bits in the netmask. All IP addresses which
match the masked IP address will be allowed in.
it() a address/mask in the form a.b.c.d/e.f.g.h where e.f.g.h is a
netmask in dotted decimal notation. All IP addresses which match the masked
IP address will be allowed in.
it() an address/mask in the form ipaddr/maskaddr where ipaddr is the
IP address and maskaddr is the netmask in dotted decimal notation for IPv4,
or similar for IPv6, e.g. ffff:ffff:ffff:ffff:: instead of /64. All IP
addresses which match the masked IP address will be allowed in.
it() a hostname. The hostname as determined by a reverse lookup will
be matched (case insensitive) against the pattern. Only an exact
@@ -268,6 +301,12 @@ itemize(
then the client is allowed in.
)
Note IPv6 link-local addresses can have a scope in the address specification:
quote(fe80::1%link1)
quote(fe80::%link1/64)
quote(fe80::%link1/ffff:ffff:ffff:ffff::)
You can also combine "hosts allow" with a separate "hosts deny"
option. If both options are specified then the "hosts allow" option s
checked first and a match results in the client being able to
@@ -286,10 +325,10 @@ 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 IO errors on the server when deciding whether to run the delete
ignore I/O errors on the server when deciding whether to run the delete
phase of the transfer. Normally rsync skips the --delete step if any
IO errors have occurred in order to prevent disasterous deletion due
to a temporary resource shortage or other IO error. In some cases this
I/O errors have occurred in order to prevent disasterous 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
behaviour.
@@ -314,7 +353,7 @@ 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() %p for the process ID of this rsync session
it() %o for the operation, which is either "send" or "recv"
it() %f for the filename
it() %P for the module path
@@ -333,16 +372,22 @@ A perl script called rsyncstats to summarize this format is included
in the rsync source code distribution.
dit(bf(timeout)) The "timeout" option allows you to override the
clients choice for IO timeout for this module. Using this option you
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
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. The full names of the options must be
used (i.e., you must use "checksum" not "c" to disable checksumming).
specify a space-separated list of rsync command line options that will
be refused by your rsync server.
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 --checksum (-c) and all the options that
start with "delete":
quote(refuse options = c delete*)
When an option is refused, the server 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
@@ -354,7 +399,7 @@ during transfer. Compression is expensive in terms of CPU usage so it
is usually good to not try to compress files that won't compress well,
such as already compressed files.
The "dont compress" option takes a space separated list of
The "dont compress" option takes a space-separated list of
case-insensitive wildcard patterns. Any source filename matching one
of the patterns will not be compressed during transfer.
@@ -372,13 +417,39 @@ 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.
Also note that the rsync server protocol does not currently provide any
encryption of the data that is transferred over the link. Only
encryption of the data that is transferred over the connection. Only
authentication is provided. Use ssh as the transport if you want
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 --daemon and --rsh (-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(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
--config option to the em(command):
quote(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 --server option under normal circumstances.
manpagesection(EXAMPLES)
A simple rsyncd.conf file that allow anonymous rsync to a ftp area at
@@ -430,7 +501,7 @@ susan:herpass
manpagefiles()
/etc/rsyncd.conf
/etc/rsyncd.conf or rsyncd.conf
manpageseealso()
@@ -448,7 +519,7 @@ 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.0 of rsync
This man page is current for version 2.x of rsync.
manpagesection(CREDITS)

View File

@@ -125,6 +125,9 @@ set -e
RUNSHFLAGS='-e'
# for Solaris
PATH="/usr/xpg4/bin/:$PATH"
if [ -n "$loglevel" ] && [ "$loglevel" -gt 8 ]
then
if set -x
@@ -139,6 +142,20 @@ echo "$0 running in `pwd`"
echo " rsync_bin=$rsync_bin"
echo " srcdir=$srcdir"
testuser=`id -un || whoami || echo UNKNOWN`
echo " testuser=$testuser"
echo " os=`uname -a`"
# It must be "yes", not just nonnull
if test "x$preserve_scratch" = xyes
then
echo " preserve_scratch=yes"
else
echo " preserve_scratch=no"
fi
if test ! -f $rsync_bin
then
echo "rsync_bin $rsync_bin is not a file" >&2
@@ -203,6 +220,11 @@ do
echo "----- $testbase log follows"
cat "$scratchdir/test.log"
echo "----- $testbase log ends"
if [ -f "$scratchdir/rsyncd.log" ]; then
echo "----- $testbase rsyncd.log follows"
cat "$scratchdir/rsyncd.log"
echo "----- $testbase rsyncd.log ends"
fi
fi
case $result in
@@ -212,7 +234,9 @@ do
maybe_discard_scratch
;;
77)
echo "SKIP $testbase"
# backticks will fill the whole file onto one line, which is a feature
whyskipped=`cat "$scratchdir/whyskipped"`
echo "SKIP $testbase ($whyskipped)"
skipped=`expr $skipped + 1`
maybe_discard_scratch
;;

338
sender.c
View File

@@ -1,17 +1,17 @@
/*
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -20,58 +20,87 @@
#include "rsync.h"
extern int verbose;
extern int remote_version;
extern int csum_length;
extern struct stats stats;
extern int io_error;
extern int dry_run;
extern int am_server;
extern int am_daemon;
extern int protocol_version;
extern int make_backups;
extern struct stats stats;
/*
receive the checksums for a buffer
*/
/**
* @file
*
* The sender gets checksums from the generator, calculates deltas,
* and transmits them to the receiver. The sender process runs on the
* machine holding the source files.
**/
void read_sum_head(int f, struct sum_struct *sum)
{
sum->count = read_int(f);
sum->blength = read_int(f);
if (protocol_version < 27) {
sum->s2length = csum_length;
} else {
sum->s2length = read_int(f);
if (sum->s2length > MD4_SUM_LENGTH) {
rprintf(FERROR, "Invalid checksum length %ld\n",
(long)sum->s2length);
exit_cleanup(RERR_PROTOCOL);
}
}
sum->remainder = read_int(f);
}
/**
* Receive the checksums for a buffer
**/
static struct sum_struct *receive_sums(int f)
{
struct sum_struct *s;
int i;
OFF_T offset = 0;
s = (struct sum_struct *)malloc(sizeof(*s));
if (!s) out_of_memory("receive_sums");
if (!(s = new(struct sum_struct)))
out_of_memory("receive_sums");
read_sum_head(f, s);
s->count = read_int(f);
s->n = read_int(f);
s->remainder = read_int(f);
s->sums = NULL;
if (verbose > 3)
rprintf(FINFO,"count=%d n=%d rem=%d\n",
s->count,s->n,s->remainder);
if (verbose > 3) {
rprintf(FINFO, "count=%ld n=%u rem=%u\n",
(long)s->count, s->blength, s->remainder);
}
if (s->count == 0)
if (s->count == 0)
return(s);
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
if (!s->sums) out_of_memory("receive_sums");
if (!(s->sums = new_array(struct sum_buf, s->count)))
out_of_memory("receive_sums");
for (i=0; i < (int) s->count;i++) {
for (i = 0; i < (int)s->count; i++) {
s->sums[i].sum1 = read_int(f);
read_buf(f,s->sums[i].sum2,csum_length);
read_buf(f, s->sums[i].sum2, s->s2length);
s->sums[i].offset = offset;
s->sums[i].i = i;
s->sums[i].flags = 0;
if (i == (int) s->count-1 && s->remainder != 0) {
if (i == (int)s->count-1 && s->remainder != 0)
s->sums[i].len = s->remainder;
} else {
s->sums[i].len = s->n;
}
else
s->sums[i].len = s->blength;
offset += s->sums[i].len;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
i,s->sums[i].len,(double)s->sums[i].offset,s->sums[i].sum1);
if (verbose > 3) {
rprintf(FINFO,
"chunk[%d] len=%d offset=%.0f sum1=%08x\n",
i, s->sums[i].len, (double)s->sums[i].offset,
s->sums[i].sum1);
}
}
s->flength = offset;
@@ -81,213 +110,160 @@ static struct sum_struct *receive_sums(int f)
void send_files(struct file_list *flist,int f_out,int f_in)
{
void send_files(struct file_list *flist, int f_out, int f_in)
{
int fd = -1;
struct sum_struct *s;
struct map_struct *buf = NULL;
struct map_struct *mbuf = NULL;
STRUCT_STAT st;
char fname[MAXPATHLEN];
char *fname2, fname[MAXPATHLEN];
int i;
struct file_struct *file;
int phase = 0;
extern struct stats stats;
struct stats initial_stats;
extern int write_batch; /* dw */
extern int read_batch; /* dw */
int checksums_match; /* dw */
int buff_len; /* dw */
char buff[CHUNK_SIZE]; /* dw */
int j; /* dw */
int done; /* dw */
int save_make_backups = make_backups;
int j;
if (verbose > 2)
rprintf(FINFO,"send_files starting\n");
rprintf(FINFO, "send_files starting\n");
while (1) {
int offset=0;
unsigned int offset;
i = read_int(f_in);
if (i == -1) {
if (phase==0 && remote_version >= 13) {
if (phase == 0) {
phase++;
csum_length = SUM_LENGTH;
write_int(f_out,-1);
write_int(f_out, -1);
if (verbose > 2)
rprintf(FINFO,"send_files phase=%d\n",phase);
rprintf(FINFO, "send_files phase=%d\n", phase);
/* For inplace: redo phase turns off the backup
* flag so that we do a regular inplace send. */
make_backups = 0;
continue;
}
break;
}
if (i < 0 || i >= flist->count) {
rprintf(FERROR,"Invalid file index %d (count=%d)\n",
rprintf(FERROR, "Invalid file index %d (count=%d)\n",
i, flist->count);
exit_cleanup(RERR_PROTOCOL);
}
file = flist->files[i];
stats.current_file_index = i;
stats.num_transferred_files++;
stats.total_transferred_size += file->length;
fname[0] = 0;
if (file->basedir) {
strlcpy(fname,file->basedir,MAXPATHLEN);
if (strlen(fname) == MAXPATHLEN-1) {
io_error = 1;
rprintf(FERROR, "send_files failed on long-named directory %s\n",
fname);
return;
}
strlcat(fname,"/",MAXPATHLEN);
offset = strlen(file->basedir)+1;
}
strlcat(fname,f_name(file),MAXPATHLEN);
if (verbose > 2)
rprintf(FINFO,"send_files(%d,%s)\n",i,fname);
if (dry_run) {
if (!am_server) {
log_transfer(file, fname+offset);
}
write_int(f_out,i);
/* N.B. We're sure that this fits, so offset is OK. */
offset = strlcpy(fname, file->basedir, sizeof fname);
if (!offset || fname[offset-1] != '/')
fname[offset++] = '/';
} else
offset = 0;
fname2 = f_name_to(file, fname + offset);
if (verbose > 2)
rprintf(FINFO, "send_files(%d, %s)\n", i, fname);
if (dry_run) {
if (!am_server && verbose) /* log the transfer */
rprintf(FINFO, "%s\n", safe_fname(fname2));
write_int(f_out, i);
continue;
}
initial_stats = stats;
s = receive_sums(f_in);
if (!s) {
io_error = 1;
rprintf(FERROR,"receive_sums failed\n");
if (!(s = receive_sums(f_in))) {
io_error |= IOERR_GENERAL;
rprintf(FERROR, "receive_sums failed\n");
return;
}
if (write_batch)
write_batch_csum_info(&i,flist->count,s);
if (!read_batch) {
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) {
io_error = 1;
rprintf(FERROR,"send_files failed to open %s: %s\n",
fname,strerror(errno));
free_sums(s);
continue;
}
/* map the local file */
if (do_fstat(fd,&st) != 0) {
io_error = 1;
rprintf(FERROR,"fstat failed : %s\n",strerror(errno));
free_sums(s);
close(fd);
return;
}
if (st.st_size > 0) {
buf = map_file(fd,st.st_size);
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) {
if (errno == ENOENT) {
enum logcode c = am_daemon
&& protocol_version < 28 ? FERROR
: FINFO;
io_error |= IOERR_VANISHED;
rprintf(c, "file has vanished: %s\n",
full_fname(fname));
} else {
buf = NULL;
io_error |= IOERR_GENERAL;
rsyserr(FERROR, errno,
"send_files failed to open %s",
full_fname(fname));
}
if (verbose > 2)
rprintf(FINFO,"send_files mapped %s of size %.0f\n",
fname,(double)st.st_size);
write_int(f_out,i);
if (write_batch)
write_batch_delta_file((char *)&i,sizeof(i));
write_int(f_out,s->count);
write_int(f_out,s->n);
write_int(f_out,s->remainder);
free_sums(s);
continue;
}
if (verbose > 2)
if (!read_batch)
rprintf(FINFO,"calling match_sums %s\n",fname);
if (!am_server) {
log_transfer(file, fname+offset);
/* map the local file */
if (do_fstat(fd, &st) != 0) {
io_error |= IOERR_GENERAL;
rsyserr(FERROR, errno, "fstat failed");
free_sums(s);
close(fd);
return;
}
if (st.st_size) {
OFF_T map_size = MAX(s->blength * 3, MAX_MAP_SIZE);
mbuf = map_file(fd, st.st_size, map_size, s->blength);
} else
mbuf = NULL;
if (verbose > 2) {
rprintf(FINFO, "send_files mapped %s of size %.0f\n",
safe_fname(fname), (double)st.st_size);
}
write_int(f_out, i);
write_sum_head(f_out, s);
if (verbose > 2) {
rprintf(FINFO, "calling match_sums %s\n",
safe_fname(fname));
}
if (!am_server && verbose) /* log the transfer */
rprintf(FINFO, "%s\n", safe_fname(fname2));
set_compression(fname);
if (read_batch) { /* dw */
/* read checksums originally computed on sender side */
read_batch_csum_info(i, s, &checksums_match);
if (checksums_match) {
read_batch_delta_file( (char *) &j, sizeof(int) );
if (j != i) { /* if flist index entries don't match*/
rprintf(FINFO,"index mismatch in send_files\n");
rprintf(FINFO,"read index = %d flist ndx = %d\n",j,i);
close_batch_delta_file();
close_batch_csums_file();
exit_cleanup(1);
}
else {
write_int(f_out,j);
write_int(f_out,s->count);
write_int(f_out,s->n);
write_int(f_out,s->remainder);
done=0;
while (!done) {
read_batch_delta_file( (char *) &buff_len, sizeof(int) );
write_int(f_out,buff_len);
if (buff_len == 0) {
done = 1;
}
else {
if (buff_len > 0) {
read_batch_delta_file(buff, buff_len);
write_buf(f_out,buff,buff_len);
}
}
} /* end while */
read_batch_delta_file( buff, MD4_SUM_LENGTH);
write_buf(f_out, buff, MD4_SUM_LENGTH);
match_sums(f_out, s, mbuf, st.st_size);
log_send(file, &initial_stats);
} /* j=i */
} else { /* not checksum match */
rprintf (FINFO,"readbatch & checksums don't match\n");
rprintf (FINFO,"filename=%s is being skipped\n",
fname);
continue;
}
} else {
match_sums(f_out,s,buf,st.st_size);
log_send(file, &initial_stats);
}
if (!read_batch) { /* dw */
if (buf) unmap_file(buf);
close(fd);
if (mbuf) {
j = unmap_file(mbuf);
if (j) {
io_error |= IOERR_GENERAL;
rsyserr(FERROR, j,
"read errors mapping %s",
full_fname(fname));
}
}
close(fd);
free_sums(s);
if (verbose > 2)
rprintf(FINFO,"sender finished %s\n",fname);
if (verbose > 2) {
rprintf(FINFO, "sender finished %s\n",
safe_fname(fname));
}
}
make_backups = save_make_backups;
if (verbose > 2)
rprintf(FINFO,"send files finished\n");
rprintf(FINFO, "send files finished\n");
match_report();
write_int(f_out,-1);
if (write_batch || read_batch) { /* dw */
close_batch_csums_file();
close_batch_delta_file();
}
write_int(f_out, -1);
}

550
socket.c
View File

@@ -1,20 +1,20 @@
/* -*- c-file-style: "linux" -*-
rsync -- fast file replication program
Copyright (C) 1992-2001 by Andrew Tridgell <tridge@samba.org>
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -22,7 +22,7 @@
/**
* @file socket.c
*
*
* Socket functions used in rsync.
*
* This file is now converted to use the new-style getaddrinfo()
@@ -33,25 +33,51 @@
#include "rsync.h"
extern char *bind_address;
extern int default_af_hint;
/* Establish a proxy connection on an open socket to a web roxy by
* using the CONNECT method. */
static int establish_proxy_connection(int fd, char *host, int port)
/**
* 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,
* they are used to authenticate to the proxy using the "Basic"
* proxy-authorization protocol
**/
static int establish_proxy_connection(int fd, char *host, int port,
char *proxy_user, char *proxy_pass)
{
char buffer[1024];
char *cp;
char *cp, buffer[1024];
char *authhdr, authbuf[1024];
int len;
snprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
if (write(fd, buffer, strlen(buffer)) != (int) strlen(buffer)) {
rprintf(FERROR, "failed to write to proxy: %s\n",
strerror(errno));
if (proxy_user && proxy_pass) {
stringjoin(buffer, sizeof buffer,
proxy_user, ":", proxy_pass, NULL);
len = strlen(buffer);
if ((len*8 + 5) / 6 >= (int)sizeof authbuf) {
rprintf(FERROR,
"authentication information is too long\n");
return -1;
}
base64_encode(buffer, len, authbuf);
authhdr = "\r\nProxy-Authorization: Basic ";
} else {
*authbuf = '\0';
authhdr = "";
}
snprintf(buffer, sizeof buffer, "CONNECT %s:%d HTTP/1.0%s%s\r\n\r\n",
host, port, authhdr, authbuf);
len = strlen(buffer);
if (write(fd, buffer, len) != len) {
rsyserr(FERROR, errno, "failed to write to proxy");
return -1;
}
for (cp = buffer; cp < &buffer[sizeof(buffer) - 1]; cp++) {
for (cp = buffer; cp < &buffer[sizeof buffer - 1]; cp++) {
if (read(fd, cp, 1) != 1) {
rprintf(FERROR, "failed to read from proxy: %s\n",
strerror(errno));
rsyserr(FERROR, errno, "failed to read from proxy");
return -1;
}
if (*cp == '\n')
@@ -68,8 +94,7 @@ static int establish_proxy_connection(int fd, char *host, int port)
buffer);
return -1;
}
for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
;
for (cp = &buffer[5]; isdigit(*(uchar*)cp) || *cp == '.'; cp++) {}
while (*cp == ' ')
cp++;
if (*cp != '2') {
@@ -79,19 +104,18 @@ static int establish_proxy_connection(int fd, char *host, int port)
}
/* throw away the rest of the HTTP header */
while (1) {
for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
cp++) {
for (cp = buffer; cp < &buffer[sizeof buffer - 1]; cp++) {
if (read(fd, cp, 1) != 1) {
rprintf(FERROR, "failed to read from proxy: %s\n",
strerror(errno));
rsyserr(FERROR, errno,
"failed to read from proxy");
return -1;
}
if (*cp == '\n')
break;
}
if ((cp > buffer) && (*cp == '\n'))
if (cp > buffer && *cp == '\n')
cp--;
if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
if (cp == buffer && (*cp == '\n' || *cp == '\r'))
break;
}
return 0;
@@ -102,14 +126,13 @@ static int establish_proxy_connection(int fd, char *host, int port)
* Try to set the local address for a newly-created socket. Return -1
* if this fails.
**/
int try_bind_local(int s,
int ai_family, int ai_socktype,
int try_bind_local(int s, int ai_family, int ai_socktype,
const char *bind_address)
{
int error;
struct addrinfo bhints, *bres_all, *r;
memset(&bhints, 0, sizeof(bhints));
memset(&bhints, 0, sizeof bhints);
bhints.ai_family = ai_family;
bhints.ai_socktype = ai_socktype;
bhints.ai_flags = AI_PASSIVE;
@@ -122,12 +145,14 @@ int try_bind_local(int s,
for (r = bres_all; r; r = r->ai_next) {
if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
continue;
freeaddrinfo(bres_all);
return s;
}
/* no error message; there might be some problem that allows
* creation of the socket but not binding, perhaps if the
* machine has no ipv6 address of this name. */
freeaddrinfo(bres_all);
return -1;
}
@@ -156,42 +181,59 @@ int open_socket_out(char *host, int port, const char *bind_address,
int af_hint)
{
int type = SOCK_STREAM;
int error;
int s;
int error, s;
struct addrinfo hints, *res0, *res;
char portbuf[10];
char *h;
char *h, *cp;
int proxied = 0;
char buffer[1024];
char *cp;
char *proxy_user = NULL, *proxy_pass = NULL;
/* if we have a RSYNC_PROXY env variable then redirect our
* connetcion via a web proxy at the given address. The format
* is hostname:port */
* connetcion via a web proxy at the given address. */
h = getenv("RSYNC_PROXY");
proxied = (h != NULL) && (*h != '\0');
proxied = h != NULL && *h != '\0';
if (proxied) {
strlcpy(buffer, h, sizeof(buffer));
cp = strchr(buffer, ':');
if (cp == NULL) {
strlcpy(buffer, h, sizeof buffer);
/* Is the USER:PASS@ prefix present? */
if ((cp = strchr(buffer, '@')) != NULL) {
*cp++ = '\0';
/* The remainder is the HOST:PORT part. */
h = cp;
if ((cp = strchr(buffer, ':')) == NULL) {
rprintf(FERROR,
"invalid proxy specification: should be USER:PASS@HOST:PORT\n");
return -1;
}
*cp++ = '\0';
proxy_user = buffer;
proxy_pass = cp;
} else {
/* The whole buffer is the HOST:PORT part. */
h = buffer;
}
if ((cp = strchr(h, ':')) == NULL) {
rprintf(FERROR,
"invalid proxy specification: should be HOST:PORT\n");
return -1;
}
*cp++ = '\0';
strcpy(portbuf, cp);
h = buffer;
strlcpy(portbuf, cp, sizeof portbuf);
if (verbose >= 2) {
rprintf(FINFO, "connection via http proxy %s port %s\n",
h, portbuf);
}
} else {
snprintf(portbuf, sizeof(portbuf), "%d", port);
snprintf(portbuf, sizeof portbuf, "%d", port);
h = host;
}
memset(&hints, 0, sizeof(hints));
memset(&hints, 0, sizeof hints);
hints.ai_family = af_hint;
hints.ai_socktype = type;
error = getaddrinfo(h, portbuf, &hints, &res0);
@@ -211,31 +253,30 @@ int open_socket_out(char *host, int port, const char *bind_address,
if (s < 0)
continue;
if (bind_address)
if (try_bind_local(s, res->ai_family, type,
bind_address) == -1) {
close(s);
s = -1;
continue;
}
if (bind_address
&& try_bind_local(s, res->ai_family, type,
bind_address) == -1) {
close(s);
s = -1;
continue;
}
if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
close(s);
s = -1;
continue;
}
if (proxied &&
establish_proxy_connection(s, host, port) != 0) {
if (proxied
&& establish_proxy_connection(s, host, port,
proxy_user, proxy_pass) != 0) {
close(s);
s = -1;
continue;
} else
break;
}
break;
}
freeaddrinfo(res0);
if (s < 0) {
rprintf(FERROR, RSYNC_NAME ": failed to connect to %s: %s\n",
h, strerror(errno));
rsyserr(FERROR, errno, "failed to connect to %s", h);
return -1;
}
return s;
@@ -254,92 +295,111 @@ int open_socket_out(char *host, int port, const char *bind_address,
*
* @param bind_address 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 af_hint)
int open_socket_out_wrapped(char *host, int port, const char *bind_address,
int af_hint)
{
char *prog;
char *prog = getenv("RSYNC_CONNECT_PROG");
if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
return sock_exec (prog);
else
return open_socket_out (host, port, bind_address,
af_hint);
if (verbose >= 2) {
rprintf(FINFO, "%sopening tcp connection to %s port %d\n",
prog ? "Using RSYNC_CONNECT_PROG instead of " : "",
host, port);
}
if (prog)
return sock_exec(prog);
return open_socket_out(host, port, bind_address, af_hint);
}
/**
* Open a socket of the specified type, port and address for incoming data
* Open one or more sockets for incoming data using the specified type,
* port, and address.
*
* The getaddrinfo() call may return several address results, e.g. for
* the machine's IPv4 and IPv6 name.
*
* We return an array of file-descriptors to the sockets, with a trailing
* -1 value to indicate the end of the list.
*
* Try to be better about handling the results of getaddrinfo(): when
* opening an inbound socket, we might get several address results,
* e.g. for the machine's ipv4 and ipv6 name.
*
* If binding a wildcard, then any one of them should do. If an address
* was specified but it's insufficiently specific then that's not our
* fault.
*
* However, some of the advertized addresses may not work because e.g. we
* don't have IPv6 support in the kernel. In that case go on and try all
* addresses until one succeeds.
*
* @param bind_address Local address to bind, or NULL to allow it to
* default.
**/
static int open_socket_in(int type, int port, const char *bind_address,
int af_hint)
static int *open_socket_in(int type, int port, const char *bind_address,
int af_hint)
{
int one=1;
int s;
int one = 1;
int s, *socks, maxs, i;
struct addrinfo hints, *all_ai, *resp;
char portbuf[10];
int error;
memset(&hints, 0, sizeof(hints));
memset(&hints, 0, sizeof hints);
hints.ai_family = af_hint;
hints.ai_socktype = type;
hints.ai_flags = AI_PASSIVE;
snprintf(portbuf, sizeof(portbuf), "%d", port);
snprintf(portbuf, sizeof portbuf, "%d", port);
error = getaddrinfo(bind_address, portbuf, &hints, &all_ai);
if (error) {
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
bind_address, gai_strerror(error));
return -1;
return NULL;
}
/* Count max number of sockets we might open. */
for (maxs = 0, resp = all_ai; resp; resp = resp->ai_next, maxs++) {}
if (!(socks = new_array(int, maxs + 1)))
out_of_memory("open_socket_in");
/* We may not be able to create the socket, if for example the
* machine knows about IPv6 in the C library, but not in the
* kernel. */
for (resp = all_ai; resp; resp = resp->ai_next) {
for (resp = all_ai, i = 0; resp; resp = resp->ai_next) {
s = socket(resp->ai_family, resp->ai_socktype,
resp->ai_protocol);
if (s == -1)
if (s == -1) {
/* See if there's another address that will work... */
continue;
}
setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(char *)&one, sizeof one);
/* now we've got a socket - we need to bind it */
if (bind(s, all_ai->ai_addr, all_ai->ai_addrlen) < 0) {
#ifdef IPV6_V6ONLY
if (resp->ai_family == AF_INET6) {
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
(char *)&one, sizeof one) < 0
&& default_af_hint != AF_INET6) {
close(s);
continue;
}
}
#endif
/* Now we've got a socket - we need to bind it. */
if (bind(s, resp->ai_addr, resp->ai_addrlen) < 0) {
/* Nope, try another */
close(s);
continue;
}
return s;
socks[i++] = s;
}
socks[i] = -1;
rprintf(FERROR, RSYNC_NAME ": open inbound socket on port %d failed: "
"%s\n",
port,
strerror(errno));
if (all_ai)
freeaddrinfo(all_ai);
freeaddrinfo(all_ai);
return -1;
if (!i) {
rprintf(FERROR,
"unable to bind any inbound sockets on port %d\n",
port);
free(socks);
return NULL;
}
return socks;
}
@@ -349,46 +409,65 @@ static int open_socket_in(int type, int port, const char *bind_address,
int is_a_socket(int fd)
{
int v;
socklen_t l;
l = sizeof(int);
socklen_t l = sizeof (int);
/* Parameters to getsockopt, setsockopt etc are very
* unstandardized across platforms, so don't be surprised if
* there are compiler warnings on e.g. SCO OpenSwerver or AIX.
* It seems they all eventually get the right idea.
*
* Debian says: ``The fifth argument of getsockopt and
* setsockopt is in reality an int [*] (and this is what BSD
* 4.* and libc4 and libc5 have). Some POSIX confusion
* resulted in the present socklen_t. The draft standard has
* not been adopted yet, but glibc2 already follows it and
* also has socklen_t [*]. See also accept(2).''
*
* We now return to your regularly scheduled programming. */
return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
/* Parameters to getsockopt, setsockopt etc are very
* unstandardized across platforms, so don't be surprised if
* there are compiler warnings on e.g. SCO OpenSwerver or AIX.
* It seems they all eventually get the right idea.
*
* Debian says: ``The fifth argument of getsockopt and
* setsockopt is in reality an int [*] (and this is what BSD
* 4.* and libc4 and libc5 have). Some POSIX confusion
* resulted in the present socklen_t. The draft standard has
* not been adopted yet, but glibc2 already follows it and
* also has socklen_t [*]. See also accept(2).''
*
* We now return to your regularly scheduled programming. */
return getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0;
}
void start_accept_loop(int port, int (*fn)(int ))
static RETSIGTYPE sigchld_handler(UNUSED(int val))
{
int s;
extern char *bind_address;
extern int default_af_hint;
#ifdef WNOHANG
while (waitpid(-1, NULL, WNOHANG) > 0) {}
#endif
signal(SIGCHLD, sigchld_handler);
}
void start_accept_loop(int port, int (*fn)(int, int))
{
fd_set deffds;
int *sp, maxfd, i;
/* open an incoming socket */
s = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
if (s == -1)
sp = open_socket_in(SOCK_STREAM, port, bind_address, default_af_hint);
if (sp == NULL)
exit_cleanup(RERR_SOCKETIO);
/* ready to listen */
if (listen(s, 5) == -1) {
close(s);
exit_cleanup(RERR_SOCKETIO);
FD_ZERO(&deffds);
for (i = 0, maxfd = -1; sp[i] >= 0; i++) {
if (listen(sp[i], 5) < 0) {
rsyserr(FERROR, errno, "listen() on socket failed");
#ifdef INET6
if (errno == EADDRINUSE && i > 0) {
rprintf(FINFO,
"Try using --ipv4 or --ipv6 to avoid this listen() error.");
}
#endif
exit_cleanup(RERR_SOCKETIO);
}
FD_SET(sp[i], &deffds);
if (maxfd < sp[i])
maxfd = sp[i];
}
/* now accept incoming connections - forking a new process
for each incoming connection */
* for each incoming connection */
while (1) {
fd_set fds;
pid_t pid;
@@ -397,43 +476,45 @@ void start_accept_loop(int port, int (*fn)(int ))
socklen_t addrlen = sizeof addr;
/* close log file before the potentially very long select so
file can be trimmed by another process instead of growing
forever */
* file can be trimmed by another process instead of growing
* forever */
log_close();
FD_ZERO(&fds);
FD_SET(s, &fds);
if (select(s+1, &fds, NULL, NULL, NULL) != 1) {
continue;
}
if(!FD_ISSET(s, &fds)) continue;
fd = accept(s,(struct sockaddr *)&addr,&addrlen);
if (fd == -1) continue;
signal(SIGCHLD, SIG_IGN);
/* we shouldn't have any children left hanging around
but I have had reports that on Digital Unix zombies
are produced, so this ensures that they are reaped */
#ifdef WNOHANG
while (waitpid(-1, NULL, WNOHANG) > 0);
#ifdef FD_COPY
FD_COPY(&deffds, &fds);
#else
fds = deffds;
#endif
if (select(maxfd + 1, &fds, NULL, NULL, NULL) != 1)
continue;
for (i = 0, fd = -1; sp[i] >= 0; i++) {
if (FD_ISSET(sp[i], &fds)) {
fd = accept(sp[i], (struct sockaddr *)&addr,
&addrlen);
break;
}
}
if (fd < 0)
continue;
signal(SIGCHLD, sigchld_handler);
if ((pid = fork()) == 0) {
close(s);
int ret;
for (i = 0; sp[i] >= 0; i++)
close(sp[i]);
/* open log file in child before possibly giving
up privileges */
* up privileges */
log_open();
_exit(fn(fd));
ret = fn(fd, fd);
close_all();
_exit(ret);
} else if (pid < 0) {
rprintf(FERROR,
RSYNC_NAME
": could not create child server process: %s\n",
strerror(errno));
rsyserr(FERROR, errno,
"could not create child server process");
close(fd);
/* This might have happened because we're
* overloaded. Sleep briefly before trying to
@@ -444,6 +525,7 @@ void start_accept_loop(int port, int (*fn)(int ))
close(fd);
}
}
free(sp);
}
@@ -489,21 +571,24 @@ struct
#endif
{NULL,0,0,0,0}};
/****************************************************************************
set user socket options
****************************************************************************/
/**
* Set user socket options
**/
void set_socket_options(int fd, char *options)
{
char *tok;
if (!options || !*options) return;
if (!options || !*options)
return;
options = strdup(options);
if (!options) out_of_memory("set_socket_options");
for (tok=strtok(options, " \t,"); tok; tok=strtok(NULL," \t,")) {
if (!options)
out_of_memory("set_socket_options");
for (tok = strtok(options, " \t,"); tok; tok = strtok(NULL," \t,")) {
int ret=0,i;
int value = 1;
char *p;
@@ -515,9 +600,10 @@ void set_socket_options(int fd, char *options)
got_value = 1;
}
for (i=0;socket_options[i].name;i++)
for (i = 0; socket_options[i].name; i++) {
if (strcmp(socket_options[i].name,tok)==0)
break;
}
if (!socket_options[i].name) {
rprintf(FERROR,"Unknown socket option %s\n",tok);
@@ -528,9 +614,10 @@ void set_socket_options(int fd, char *options)
case OPT_BOOL:
case OPT_INT:
ret = setsockopt(fd,socket_options[i].level,
socket_options[i].option,(char *)&value,sizeof(int));
socket_options[i].option,
(char *)&value, sizeof (int));
break;
case OPT_ON:
if (got_value)
rprintf(FERROR,"syntax error - %s does not take a value\n",tok);
@@ -538,22 +625,24 @@ void set_socket_options(int fd, char *options)
{
int on = socket_options[i].value;
ret = setsockopt(fd,socket_options[i].level,
socket_options[i].option,(char *)&on,sizeof(int));
socket_options[i].option,
(char *)&on, sizeof (int));
}
break;
break;
}
if (ret != 0) {
rsyserr(FERROR, errno,
"failed to set socket option %s", tok);
}
if (ret != 0)
rprintf(FERROR, "failed to set socket option %s: %s\n", tok,
strerror(errno));
}
free(options);
}
/****************************************************************************
become a daemon, discarding the controlling terminal
****************************************************************************/
/**
* Become a daemon, discarding the controlling terminal
**/
void become_daemon(void)
{
int i;
@@ -569,83 +658,95 @@ void become_daemon(void)
#ifdef TIOCNOTTY
i = open("/dev/tty", O_RDWR);
if (i >= 0) {
ioctl(i, (int) TIOCNOTTY, (char *)0);
ioctl(i, (int)TIOCNOTTY, (char *)0);
close(i);
}
#endif /* TIOCNOTTY */
#endif
/* make sure that stdin, stdout an stderr don't stuff things
up (library functions, for example) */
for (i=0;i<3;i++) {
close(i);
* up (library functions, for example) */
for (i = 0; i < 3; i++) {
close(i);
open("/dev/null", O_RDWR);
}
}
/*******************************************************************
this is like socketpair but uses tcp. It is used by the Samba
regression test code
The function guarantees that nobody else can attach to the socket,
or if they do that this function fails and the socket gets closed
returns 0 on success, -1 on failure
the resulting file descriptors are symmetrical
******************************************************************/
/**
* This is like socketpair but uses tcp. It is used by the Samba
* regression test code.
*
* The function guarantees that nobody else can attach to the socket,
* or if they do that this function fails and the socket gets closed
* returns 0 on success, -1 on failure the resulting file descriptors
* are symmetrical.
**/
static int socketpair_tcp(int fd[2])
{
int listener;
struct sockaddr_in sock;
struct sockaddr_in sock2;
socklen_t socklen = sizeof(sock);
socklen_t socklen = sizeof sock;
int connect_done = 0;
fd[0] = fd[1] = listener = -1;
memset(&sock, 0, sizeof(sock));
if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
memset(&sock, 0, sizeof sock);
memset(&sock2, 0, sizeof(sock2));
#ifdef HAVE_SOCKADDR_LEN
sock2.sin_len = sizeof(sock2);
if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1)
goto failed;
memset(&sock2, 0, sizeof sock2);
#if HAVE_SOCKADDR_IN_LEN
sock2.sin_len = sizeof sock2;
#endif
sock2.sin_family = PF_INET;
sock2.sin_family = PF_INET;
bind(listener, (struct sockaddr *)&sock2, sizeof(sock2));
bind(listener, (struct sockaddr *)&sock2, sizeof sock2);
if (listen(listener, 1) != 0) goto failed;
if (listen(listener, 1) != 0)
goto failed;
if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0) goto failed;
if (getsockname(listener, (struct sockaddr *)&sock, &socklen) != 0)
goto failed;
if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
if ((fd[1] = socket(PF_INET, SOCK_STREAM, 0)) == -1)
goto failed;
set_nonblocking(fd[1]);
sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
if (errno != EINPROGRESS) goto failed;
} else {
if (connect(fd[1], (struct sockaddr *)&sock, sizeof sock) == -1) {
if (errno != EINPROGRESS)
goto failed;
} else
connect_done = 1;
}
if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1) goto failed;
if ((fd[0] = accept(listener, (struct sockaddr *)&sock, &socklen)) == -1)
goto failed;
close(listener);
if (connect_done == 0) {
if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
&& errno != EISCONN) goto failed;
}
listener = -1;
set_blocking (fd[1]);
set_blocking(fd[1]);
if (connect_done == 0) {
if (connect(fd[1], (struct sockaddr *)&sock, sizeof sock) != 0
&& errno != EISCONN)
goto failed;
}
/* all OK! */
return 0;
failed:
if (fd[0] != -1) close(fd[0]);
if (fd[1] != -1) close(fd[1]);
if (listener != -1) close(listener);
if (fd[0] != -1)
close(fd[0]);
if (fd[1] != -1)
close(fd[1]);
if (listener != -1)
close(listener);
return -1;
}
@@ -663,30 +764,21 @@ static int socketpair_tcp(int fd[2])
int sock_exec(const char *prog)
{
int fd[2];
if (socketpair_tcp(fd) != 0) {
rprintf (FERROR, RSYNC_NAME
": socketpair_tcp failed (%s)\n",
strerror(errno));
rsyserr(FERROR, errno, "socketpair_tcp failed");
return -1;
}
if (verbose >= 2)
rprintf(FINFO, "Running socket program: \"%s\"\n", prog);
if (fork() == 0) {
close(fd[0]);
close(0);
close(1);
dup(fd[1]);
dup(fd[1]);
if (verbose > 3) {
/* Can't use rprintf because we've forked. */
fprintf (stderr,
RSYNC_NAME ": execute socket program \"%s\"\n",
prog);
}
exit (system (prog));
exit(system(prog));
}
close (fd[1]);
close(fd[1]);
return fd[0];
}

View File

@@ -29,20 +29,29 @@
extern int dry_run;
extern int read_only;
extern int list_only;
extern int preserve_perms;
#define CHECK_RO if (read_only || list_only) {errno = EROFS; return -1;}
#define RETURN_ERROR_IF(x,e) \
do { \
if (x) { \
errno = (e); \
return -1; \
} \
} while (0)
#define RETURN_ERROR_IF_RO_OR_LO RETURN_ERROR_IF(read_only || list_only, EROFS)
int do_unlink(char *fname)
{
if (dry_run) return 0;
CHECK_RO
RETURN_ERROR_IF_RO_OR_LO;
return unlink(fname);
}
int do_symlink(char *fname1, char *fname2)
{
if (dry_run) return 0;
CHECK_RO
RETURN_ERROR_IF_RO_OR_LO;
return symlink(fname1, fname2);
}
@@ -50,7 +59,7 @@ int do_symlink(char *fname1, char *fname2)
int do_link(char *fname1, char *fname2)
{
if (dry_run) return 0;
CHECK_RO
RETURN_ERROR_IF_RO_OR_LO;
return link(fname1, fname2);
}
#endif
@@ -58,7 +67,7 @@ int do_link(char *fname1, char *fname2)
int do_lchown(const char *path, uid_t owner, gid_t group)
{
if (dry_run) return 0;
CHECK_RO
RETURN_ERROR_IF_RO_OR_LO;
return lchown(path, owner, group);
}
@@ -66,7 +75,7 @@ int do_lchown(const char *path, uid_t owner, gid_t group)
int do_mknod(char *pathname, mode_t mode, dev_t dev)
{
if (dry_run) return 0;
CHECK_RO
RETURN_ERROR_IF_RO_OR_LO;
return mknod(pathname, mode, dev);
}
#endif
@@ -74,56 +83,65 @@ int do_mknod(char *pathname, mode_t mode, dev_t dev)
int do_rmdir(char *pathname)
{
if (dry_run) return 0;
CHECK_RO
RETURN_ERROR_IF_RO_OR_LO;
return rmdir(pathname);
}
int do_open(char *pathname, int flags, mode_t mode)
{
if (flags != O_RDONLY) {
if (dry_run) return -1;
CHECK_RO
RETURN_ERROR_IF(dry_run, 0);
RETURN_ERROR_IF_RO_OR_LO;
}
#ifdef O_BINARY
/* for Windows */
flags |= O_BINARY;
#endif
/* some systems can't handle a double / */
if (pathname[0] == '/' && pathname[1] == '/') pathname++;
return open(pathname, flags, mode);
return open(pathname, flags | O_BINARY, mode);
}
#if HAVE_CHMOD
int do_chmod(const char *path, mode_t mode)
{
int code;
if (dry_run) return 0;
CHECK_RO
return chmod(path, mode);
RETURN_ERROR_IF_RO_OR_LO;
code = chmod(path, mode);
if (code != 0 && preserve_perms)
return code;
return 0;
}
#endif
int do_rename(char *fname1, char *fname2)
{
if (dry_run) return 0;
CHECK_RO
RETURN_ERROR_IF_RO_OR_LO;
return rename(fname1, fname2);
}
void trim_trailing_slashes(char *name)
{
int l;
/* Some BSD systems cannot make a directory if the name
* contains a trailing slash.
* <http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html> */
/* Don't change empty string; and also we can't improve on
* "/" */
l = strlen(name);
while (l > 1) {
if (name[--l] != '/')
break;
name[l] = '\0';
}
}
int do_mkdir(char *fname, mode_t mode)
{
int l;
if (dry_run)
return 0;
CHECK_RO;
/* Some BSD systems cannot make a directory if the name
* contains a trailing slash.
* <http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html> */
if ((l = strlen(fname)) && (fname[l-1] == '/'))
fname[l-1] = '/';
if (dry_run) return 0;
RETURN_ERROR_IF_RO_OR_LO;
trim_trailing_slashes(fname);
return mkdir(fname, mode);
}
@@ -131,22 +149,26 @@ int do_mkdir(char *fname, mode_t mode)
/* like mkstemp but forces permissions */
int do_mkstemp(char *template, mode_t perms)
{
if (dry_run) return -1;
if (read_only) {errno = EROFS; return -1;}
RETURN_ERROR_IF(dry_run, 0);
RETURN_ERROR_IF(read_only, EROFS);
#if defined(HAVE_SECURE_MKSTEMP) && defined(HAVE_FCHMOD)
#if HAVE_SECURE_MKSTEMP && HAVE_FCHMOD && (!HAVE_OPEN64 || HAVE_MKSTEMP64)
{
int fd = mkstemp(template);
if (fd == -1) return -1;
if (fchmod(fd, perms) != 0) {
if (fd == -1)
return -1;
if (fchmod(fd, perms) != 0 && preserve_perms) {
int errno_save = errno;
close(fd);
unlink(template);
errno = errno_save;
return -1;
}
return fd;
}
#else
if (!mktemp(template)) return -1;
if (!mktemp(template))
return -1;
return do_open(template, O_RDWR|O_EXCL|O_CREAT, perms);
#endif
}

81
t_stub.c Normal file
View File

@@ -0,0 +1,81 @@
/* -*- c-file-style: "linux" -*-
*
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
*
* This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "rsync.h"
/**
* @file t_stub.c
*
* This file contains really simple implementations for rsync global
* functions, so that module test harnesses can run standalone.
**/
int modify_window = 0;
int module_id = -1;
char *partial_dir;
struct exclude_list_struct server_exclude_list;
void rprintf(UNUSED(enum logcode code), const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
}
void rsyserr(UNUSED(enum logcode code), int errcode, const char *format, ...)
{
va_list ap;
fputs(RSYNC_NAME ": ", stderr);
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fprintf(stderr, ": %s (%d)\n", strerror(errcode), errcode);
}
void _exit_cleanup(int code, const char *file, int line)
{
fprintf(stderr, "exit(%d): %s(%d)\n",
code, file, line);
exit(code);
}
int check_exclude(UNUSED(struct exclude_list_struct *listp), UNUSED(char *name),
UNUSED(int name_is_dir))
{
/* This function doesn't really get called in this test context, so
* just return 0. */
return 0;
}
char *lp_name(UNUSED(int mod))
{
return NULL;
}
BOOL lp_use_chroot(UNUSED(int mod))
{
return 0;
}
char *lp_path(UNUSED(int mod))
{
return NULL;
}

46
t_unsafe.c Normal file
View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2002 by Martin Pool
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/**
* @file
*
* Test harness for unsafe_symlink(). Not linked into @c rsync itself.
*
* Prints either "safe" or "unsafe" depending on the two arguments.
* Always returns 0 unless something extraordinary happens.
**/
#include "rsync.h"
int dry_run, read_only, list_only, verbose;
int preserve_perms = 0;
int
main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "usage: t_unsafe LINKDEST SRCDIR\n");
return 1;
}
printf("%s\n",
unsafe_symlink(argv[1], argv[2]) ? "unsafe" : "safe");
return 0;
}

173
test.sh
View File

@@ -1,173 +0,0 @@
#!/bin/sh
# Copyright (C) 1998,1999 Philip Hands <phil@hands.com>
#
# This program is distributable under the terms of the GNU GPL (see COPYING)
#
# This is a simple test script that tests a few rsync
# features to make sure I haven't broken them before a release.
#
#
# check if we are running under debian-test, and change behaviour to suit
if test -n "${DEBIANTEST_LIB}" ; then
# make sure rsync is installed
test -e /usr/bin/rsync || exit 0
. ${DEBIANTEST_LIB}/functions.sh
Debian=1
else
cat <<EOF
This set of tests is not completely portable. It is intended for developers
not for end users. You may experience failures on some platforms that
do not indicate a problem with rsync.
EOF
RSYNC=`pwd`/rsync
runtest() {
echo -n "Test $1: "
eval "$2"
}
printmsg() {
echo ""
echo "**** ${1}^G ****"
echo ""
}
fi
TMP=/tmp/rsync-test.$$
FROM=${TMP}/from
TO=${TMP}/to
F1=text1
LOG=${TMP}/log
mkdir $TMP
mkdir $FROM
mkdir $TO
# set up test data
touch ${FROM}/empty
mkdir ${FROM}/emptydir
ps ax > ${FROM}/pslist
echo -n "This file has no trailing lf" > ${FROM}/nolf
ln -s nolf ${FROM}/nolf-symlink
# Gather some random text. We need files that will exist and be
# publicly readable on all platforms: hopefully this will work.
cat /etc/*tab /etc/services /etc/*.conf /etc/*rc > ${FROM}/${F1}
mkdir ${FROM}/dir
cp ${FROM}/${F1} ${FROM}/dir/
mkdir ${FROM}/dir/subdir
mkdir ${FROM}/dir/subdir/subsubdir
ls -ltr /etc > ${FROM}/dir/subdir/subsubdir/etc-ltr-list
mkdir ${FROM}/dir/subdir/subsubdir2
ls -lt /bin > ${FROM}/dir/subdir/subsubdir2/bin-lt-list
checkit() {
testnum=`expr 0${testnum} + 1`
log=${LOG}.${testnum}
failed=
echo "Running: \"$1\"" >${log}
echo "">>${log}
eval "$1" >>${log} 2>&1
status=$?
if [ $status != 0 ]; then
failed="YES";
fi
echo "-------------">>${log}
echo "check how the files compare with diff:">>${log}
echo "">>${log}
diff -ur $2 $3 >>${log} 2>&1 || failed=YES
echo "-------------">>${log}
echo "check how the directory listings compare with diff:">>${log}
echo "">>${log}
( cd $2 ; ls -laR ) > ${TMP}/ls-from 2>>${log}
( cd $3 ; ls -laR ) > ${TMP}/ls-to 2>>${log}
diff -u ${TMP}/ls-from ${TMP}/ls-to >>${log} 2>&1 || failed=YES
if [ -z "${failed}" ] ; then
test -z "${Debian}" && echo " done."
rm $log
return 0
else
if test -n "${Debian}" ; then
cat ${log}
rm ${log}
else
echo " FAILED (test # ${testnum} status=$status)."
fi
return 1
fi
}
checkforlogs() {
# skip it if we're under debian-test
if test -n "${Debian}" ; then return 0 ; fi
if [ -f $1 ] ; then
cat <<EOF
Failures have occured.
You can find the output of the tests in these files:
$@
Please hit <RETURN>
EOF
read input
else
rm -rf ${TMP}
echo ""
echo "Tests Completed Successfully :-)"
fi
}
# Main script starts here
runtest "basic operation" 'checkit "$RSYNC -av ${FROM}/ ${TO}" ${FROM}/ ${TO}'
ln ${FROM}/pslist ${FROM}/dir
runtest "hard links" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
rm ${TO}/${F1}
runtest "one file" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
echo "extra line" >> ${TO}/${F1}
runtest "extra data" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
cp ${FROM}/${F1} ${TO}/ThisShouldGo
runtest " --delete" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
LONGDIR=${FROM}/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/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/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
mkdir -p ${LONGDIR}
date > ${LONGDIR}/1
ls -la / > ${LONGDIR}/2
runtest "long paths" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
if type ssh >/dev/null 2>&1; then
if [ "`ssh -o'BatchMode yes' localhost echo yes 2>/dev/null`" = "yes" ]; then
rm -rf ${TO}
runtest "ssh: basic test" 'checkit "$RSYNC -avH -e ssh --rsync-path=$RSYNC ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
mv ${TO}/${F1} ${TO}/ThisShouldGo
runtest "ssh: renamed file" 'checkit "$RSYNC --delete -avH -e ssh --rsync-path=$RSYNC ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
else
printmsg "Skipping SSH tests because ssh conection to localhost not authorised"
fi
else
printmsg "Skipping SSH tests because ssh is not in the path"
fi
rm -rf ${TO}
mkdir -p ${FROM}2/dir/subdir
cp -a ${FROM}/dir/subdir/subsubdir ${FROM}2/dir/subdir
cp ${FROM}/dir/* ${FROM}2/dir 2>/dev/null
runtest "excludes" 'checkit "$RSYNC -vv -Hlrt --delete --include /dir/ --include /dir/\* --include /dir/\*/subsubdir --include /dir/\*/subsubdir/\*\* --exclude \*\* ${FROM}/dir ${TO}" ${FROM}2/ ${TO}'
rm -r ${FROM}2
checkforlogs ${LOG}.?

View File

@@ -2,4 +2,4 @@
echo $0 running
"$rsync_bin" --version || exit 1
$RSYNC --version || exit 1

View File

@@ -17,8 +17,8 @@ with the GNU Standards, installcheck does not look for rsync on the
path.
If the tests pass, you should see a report to that effect. Some tests
require being root or some other precondition, and so will normally be
checked -- look at the test scripts for more information.
require being root or some other precondition, and so will normally not
be checked -- look at the test scripts for more information.
If the tests fail, you will see rather more output. The scratch
directory will remain in the build directory. It would be useful if

61
testsuite/backup.test Normal file
View File

@@ -0,0 +1,61 @@
#! /bin/sh
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that the --backup option works right.
. "$suitedir/rsync.fns"
bakdir="$tmpdir/bak"
mkdir "$fromdir" "$bakdir"
name1="$fromdir/name1"
name2="$fromdir/name2"
outfile="$scratchdir/rsync.out"
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"
$RSYNC -avv --no-whole-file --backup "$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"
diff $diffopt "$fromdir/$fn" "$todir" || test_fail "copy of $fn failed"
diff $diffopt "$chkdir/$fn" "$todir/$fn~" || test_fail "backup of $fn to $fn~ failed"
mv "$todir/$fn~" "$todir/$fn"
done
checkit "$RSYNC -avv --no-whole-file --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"
checkit "$RSYNC -avv \"$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"
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"
checkit "$RSYNC -avv --inplace --no-whole-file \"$fromdir/\" \"$bakdir/\"" "$fromdir" "$bakdir"
# The script would have aborted on error, so getting here means we've won.
exit 0

45
testsuite/batch-mode.test Normal file
View File

@@ -0,0 +1,45 @@
#! /bin/sh
# Copyright (C) 2004 by Chris Shoemaker <c.shoemaker@cox.net>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync's --write-batch and --read-batch options
. "$suitedir/rsync.fns"
set -x
hands_setup
cd "$tmpdir"
# Build chkdir for the daemon tests using a normal rsync and an --exclude.
$RSYNC -av --exclude=foobar.baz "$fromdir/" "$chkdir/"
runtest "local --write-batch" 'checkit "$RSYNC -av --write-batch=BATCH \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"'
rm -rf "$todir"
runtest "--read-batch" 'checkit "$RSYNC -av --read-batch=BATCH \"$todir\"" "$fromdir" "$todir"'
build_rsyncd_conf
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
export RSYNC_CONNECT_PROG
rm -rf "$todir"
runtest "daemon sender --write-batch" 'checkit "$RSYNC -av --write-batch=BATCH rsync://localhost/test-from/ \"$todir\"" "$chkdir" "$todir"'
rm -rf "$todir"
runtest "--read-batch from daemon" 'checkit "$RSYNC -av --read-batch=BATCH \"$todir\"" "$chkdir" "$todir"'
rm -rf "$todir"
runtest "BATCH.sh use of --read-batch" 'checkit "./BATCH.sh" "$chkdir" "$todir"'
rm -rf "$todir"
mkdir "$todir" || test_fail "failed to restore empty destination directory"
runtest "daemon recv --write-batch" 'checkit "$RSYNC -av --write-batch=BATCH \"$fromdir/\" rsync://localhost/test-to" "$chkdir" "$todir"'
# The script would have aborted on error, so getting here means we pass.
exit 0

View File

@@ -9,16 +9,13 @@
# the test is a member of them. Hopefully they're in at least one
# test.
. $srcdir/testsuite/rsync.fns
. "$suitedir/rsync.fns"
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
mygrps="`groups`" || fail "Can't get groups"
mygrps="`rsync_getgroups`" || fail "Can't get groups"
mkdir "$fromdir"
for g in $mygrps
@@ -29,8 +26,7 @@ do
done
sleep 2
checkit "rsync -rtgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
checkit "$RSYNC -rtgpvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
# The script would have aborted on error, so getting here means we've won.
exit 0
# last [] may have failed but if we get here then we've won

View File

@@ -0,0 +1,41 @@
#! /bin/sh
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
# 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,
# even when using a --temp-dir option (which we try to point at a
# different filesystem than the destination dir).
. "$suitedir/rsync.fns"
set -x
hands_setup
tmpdir2=/tmp
sdev=`$TOOLDIR/getfsdev $scratchdir`
tdev=`$TOOLDIR/getfsdev $tmpdir2`
if [ x$sdev = x$tdev ]; then
tmpdir2=/var/tmp
tdev=`$TOOLDIR/getfsdev $tmpdir2`
[ x$sdev = x$tdev ] && test_skipped "Can't find a tmp dir on a different file system"
fi
chmod 440 "$fromdir/text"
chmod 500 "$fromdir/dir/text"
e="$fromdir/dir/subdir/foobar.baz"
chmod 6450 "$e" || chmod 2450 "$e" || chmod 1450 "$e" || chmod 450 "$e"
e="$fromdir/dir/subdir/subsubdir/etc-ltr-list"
chmod 2670 "$e" || chmod 1670 "$e" || chmod 670 "$e"
# First a normal copy.
runtest "normal copy" 'checkit "$RSYNC -avv --temp-dir=\"$tmpdir2\" \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"'
# Then we update all the files.
runtest "update copy" 'checkit "$RSYNC -avvI --no-whole-file --temp-dir=\"$tmpdir2\" \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"'
# The script would have aborted on error, so getting here means we've won.
exit 0

32
testsuite/chmod.test Normal file
View File

@@ -0,0 +1,32 @@
#! /bin/sh
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
# 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,
# even when using a --temp-dir option (which we try to point at a
# different filesystem than the destination dir).
. "$suitedir/rsync.fns"
set -x
hands_setup
chmod 440 "$fromdir/text"
chmod 500 "$fromdir/dir/text"
e="$fromdir/dir/subdir/foobar.baz"
chmod 6450 "$e" || chmod 2450 "$e" || chmod 1450 "$e" || chmod 450 "$e"
e="$fromdir/dir/subdir/subsubdir/etc-ltr-list"
chmod 2670 "$e" || chmod 1670 "$e" || chmod 670 "$e"
# First a normal copy.
runtest "normal copy" 'checkit "$RSYNC -avv \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"'
# Then we update all the files.
runtest "update copy" 'checkit "$RSYNC -avvI --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"'
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -11,28 +11,24 @@
# We don't know what users will be present on this system, so we just
# use random numeric uids and gids.
. $srcdir/testsuite/rsync.fns
. "$suitedir/rsync.fns"
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
mkdir "$fromdir"
name1="$fromdir/name1"
name2="$fromdir/name2"
echo "This is the file" > "$name1"
echo "This is the other file" > "$name2"
chown 5000 "$name1" || test_skipped "Can't chown"
chown 5001 "$name2" || test_skipped "Can't chown"
chgrp 5002 "$name1" || test_skipped "Can't chgrp"
chgrp 5003 "$name2" || test_skipped "Can't chgrp"
chown 5000 "$name1" || test_skipped "Can't chown (probably need root)"
chown 5001 "$name2" || test_skipped "Can't chown (probably need root)"
chgrp 5002 "$name1" || test_skipped "Can't chgrp (probably need root)"
chgrp 5003 "$name2" || test_skipped "Can't chgrp (probably need root)"
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
# The script would have aborted on error, so getting here means we've won.
exit 0
# last [] may have failed but if we get here then we've won

View File

@@ -0,0 +1,33 @@
#! /bin/sh
# Copyright (C) 2004 by Wayne Davison <wayned@samba.org>
# This program is distributable under the terms of the GNU GPL see
# COPYING).
# Test rsync handling of the --compare-dest option.
. "$suitedir/rsync.fns"
set -x
altdir="$tmpdir/alt"
# Build some files/dirs/links to copy
hands_setup
# Setup the alt and chk dirs
$RSYNC -av --include=text --include='*/' --exclude='*' "$fromdir/" "$altdir/"
sleep 1
touch "$fromdir/dir/text"
$RSYNC -av --exclude=/text "$fromdir/" "$chkdir/"
# Let's do it!
checkit "$RSYNC -avv --no-whole-file --compare-dest=\"$altdir\" \
\"$fromdir/\" \"$todir/\"" "$chkdir" "$todir"
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -23,9 +23,15 @@
build_rsyncd_conf
RSYNC_CONNECT_PROG="$rsync_bin --config=$conf --daemon"
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
export RSYNC_CONNECT_PROG
hands_setup
checkit "$rsync_bin -avvz localhost::test-from/ \"$TO/\"" "$FROM" "$TO"
# Build chkdir with a normal rsync and an --exclude.
$RSYNC -av --exclude=foobar.baz "$fromdir/" "$chkdir/"
checkit "$RSYNC -avvvvz localhost::test-from/ \"$todir/\"" "$chkdir" "$todir"
# The script would have aborted on error, so getting here means we've won.
exit 0

View File

@@ -17,9 +17,15 @@
build_rsyncd_conf
RSYNC_CONNECT_PROG="$rsync_bin --config=$conf --daemon"
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
export RSYNC_CONNECT_PROG
hands_setup
checkit "$rsync_bin -avvz \"$FROM/\" localhost::test-to/" "$FROM" "$TO"
# Build chkdir with a normal rsync and an --exclude.
$RSYNC -av --exclude=foobar.baz "$fromdir/" "$chkdir/"
checkit "$RSYNC -avvvvz \"$fromdir/\" localhost::test-to/" "$chkdir" "$todir"
# The script would have aborted on error, so getting here means we've won.
exit 0

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