Compare commits

...

183 Commits

Author SHA1 Message Date
rsync-bugs
5783c065ba preparing for release of 2.4.4 2000-07-29 05:05:38 +00:00
Andrew Tridgell
adc19c987b fix from T.J.Adye@rl.ac.uk for final goodbye message with new protocol 2000-07-29 04:58:24 +00:00
Andrew Tridgell
3d38277706 optimisations from Rich Salz <rsalz@caveosystems.com> 2000-07-29 04:52:05 +00:00
Andrew Tridgell
64c704f0b9 added blocking-io docs 2000-07-29 04:41:19 +00:00
Andrew Tridgell
69c6522734 added *.bz2 and *.tbz to default dont compress list 2000-06-24 13:20:21 +00:00
Andrew Tridgell
0f8f98c8ff added insure debug support 2000-06-24 13:19:53 +00:00
Andrew Tridgell
e384bfbdcb if the remote shell is rsh then use blocking IO 2000-06-24 13:19:25 +00:00
Andrew Tridgell
08e5094d7f added some comments on blocking-io 2000-06-23 13:54:29 +00:00
Andrew Tridgell
4b3977bf00 get rid of annoying symlink error messages 2000-06-23 13:54:08 +00:00
Andrew Tridgell
c80ccabb0c added --blocking-io option 2000-06-23 13:50:18 +00:00
David Dykstra
ef5d23ebcd Add --bwlimit option contributed by Matthew Demicco and Jamie Gritton. 2000-06-06 21:13:05 +00:00
David Dykstra
27b9a19be0 Do better job at describing exclude/include in man page. Based on suggestions
from Harry Putnam <reader@newsguy.com>.
2000-05-19 14:58:28 +00:00
Andrew Tridgell
14175f1e77 fixed bug in replacement inet_aton() 2000-04-19 05:49:15 +00:00
Andrew Tridgell
269833af78 test was the wrong way around 2000-04-19 05:44:43 +00:00
Andrew Tridgell
fca3ef06cd autoconf test for broken solaris inet_aton() 2000-04-19 05:33:39 +00:00
Andrew Tridgell
07a14ef8b2 by default don't gzip .iso images 2000-04-19 05:33:06 +00:00
rsync-bugs
21cde2888c preparing for release of 2.4.3 2000-04-09 02:53:57 +00:00
Andrew Tridgell
4a7481889c use 1 second sleeps in the sleep loop as some OSes (NT for example)
don't get interrupted during a sleep.
2000-04-09 02:32:57 +00:00
Andrew Tridgell
0adb99b9dc don't pprint the IO timeout message if we are a server or daemon (can
cause recursive error messages)
2000-04-09 02:32:18 +00:00
Andrew Tridgell
36349ea0be a very simple fix - if I'd only thought if it last week :)
rsh relies on stdin being blocking
ssh relies on stdout being non-blocking

what we've done before is to set both stdin and stdout to either
blocking or non-blocking. Now I set stdin to blocking and stdout to
non-blocking. This seems to fix all cases I've tested.
2000-04-09 02:16:42 +00:00
rsync-bugs
ec3f7d1b61 preparing for release of 2.4.2 2000-03-30 14:24:37 +00:00
Andrew Tridgell
f0359dd00d went back to non-blokcing IO
it looks like ssh is willing to accept a non-blocking fd when used as
a transport, this seems to avoid the Solaris socketpair bug
2000-03-30 14:15:00 +00:00
Andrew Tridgell
ef55c686bc add a --ignore-errors option 2000-03-21 04:06:04 +00:00
David Dykstra
5f7ce2041c Describe symbolic link handling when writing to a "use chroot = no" module. 2000-02-25 17:02:45 +00:00
David Dykstra
328fcf113a Somebody was confused into thinking that "Here are some examples" in the
section on exclude/include was supposed to be about "+/-" so I changed
the statement to "Here are some exclude/include examples".
2000-02-22 19:47:44 +00:00
David Dykstra
24c857f1de Change socketpair test to verify that it works rather than just exists,
because I have an obscure system (Amdahl's UTS 2.1.2) in which socketpair()
exists but is broken.
2000-02-22 15:55:40 +00:00
David Dykstra
a784e10d00 Move the checking for -lsocket -lnsl ahead of the checking for most of
the functions, especially "socketpair" so that socket-related functions will
be properly discovered on SVR4-based systems such as Solaris.  Problem
discovered by Kenji Miyake <kenji@miyake.org>
2000-02-15 22:44:18 +00:00
rsync-bugs
7eb6bf0397 preparing for release of 2.4.1 2000-01-30 01:02:59 +00:00
Andrew Tridgell
49d6fdc036 patch from Jim Delahanty <mail_us@swbell.net> to ensure files are
deleted after being backed up in a rename operation
2000-01-30 00:56:43 +00:00
Andrew Tridgell
8b35435f7c another hang-at-end fix. It looks like we are more sensiitive to
these with socketpairs. The receiver now sleeps until it gets a signal
to tell it to exit

also fixed test.sh to use the current version remotely
2000-01-30 00:50:19 +00:00
Andrew Tridgell
8ada751890 damn.
with the new error handling code it is possible for rsync to get stuck
on the final transaction, leaving it hung.

looks like 2.4.1 will be pretty soon
2000-01-29 23:49:36 +00:00
rsync-bugs
1a52e84874 preparing for release of 2.4.0 2000-01-29 11:35:39 +00:00
Andrew Tridgell
53c5cbed23 change version to 2.4.0pre2 2000-01-29 05:25:53 +00:00
Andrew Tridgell
4a81463880 use full buffer length, not strlen 2000-01-29 05:16:13 +00:00
Andrew Tridgell
09b7f5dbb1 move the read only daemon test to after the protocol setup 2000-01-29 05:02:23 +00:00
Andrew Tridgell
6d7b6081ac damn!
the last pre-release had a bug that didn't setup the multiplexing
correctly. This means that pre-release will get "unexpected tag -7"
whenm talking to the fixed code.
2000-01-29 04:50:01 +00:00
Andrew Tridgell
31b7d79afe I've decided that this release will be 2.4.0, updated version to 2.4.0pre1 2000-01-29 03:11:07 +00:00
Andrew Tridgell
b2999e457f don't need PIPE_BUF any more 2000-01-29 02:56:36 +00:00
Andrew Tridgell
0f3203c312 fixed some logcode warnings 2000-01-29 02:49:03 +00:00
Andrew Tridgell
a2edb26cd6 fixed a bug in test suite that I introduced yesterday 2000-01-29 02:39:52 +00:00
Andrew Tridgell
9bec528606 runtime detect fnmatch() bug if ** is used.
its all too common to compile with a working libc and run on a broken
one.
2000-01-29 02:35:01 +00:00
Andrew Tridgell
2f0e3b30a9 changed version to 2.3.3pre2 2000-01-28 15:35:08 +00:00
Andrew Tridgell
ff41a59f58 - switched on multiplexing for all connections, not just daemon
connections (this fixes the stderr/stdout problem). Upped
  protocol version for backward compat
- use multiplexing on error fd
- upped minimal protocol version
- got rid of some ugly code in the write buffering
2000-01-28 15:29:59 +00:00
Andrew Tridgell
08f15335b5 switch to using socketpair instead of pipe if possible. This fixes the
ssh clag problems as long as you also fix the same problem in sshd

removed all the old read buffering code from io.c as this was only
there to try to reduce the chance of clagging up sshd.
2000-01-28 12:37:58 +00:00
Andrew Tridgell
bd36966bed report exit code when failing a test 2000-01-27 04:54:02 +00:00
Andrew Tridgell
f76933b149 fixed the error code problem with test.sh
(was a minor bug in send_file_list)
2000-01-27 04:53:39 +00:00
Andrew Tridgell
378a074c82 patch from James Delahanty <jimd@gie.com> to make --backup-dir work
cross-filesystem
2000-01-27 02:45:56 +00:00
Andrew Tridgell
c36cd31713 the convoluted nest of #ifdefs that is fnmatch.c caught us again. On
my system the LIBC tests meant it never compiled and we used the
broken system one.

hacked it so it does compile
2000-01-25 14:17:21 +00:00
Andrew Tridgell
5e12ce1186 fix segv bug in --progress handling 2000-01-25 13:16:42 +00:00
Andrew Tridgell
166aa72332 patch from David Murn to make sure the final 100% is always printed
when using --progress
2000-01-25 06:39:33 +00:00
Andrew Tridgell
f9f6184f38 updated version.h 2000-01-25 01:33:05 +00:00
Andrew Tridgell
f625af9400 updated config.guess from latest autoconf CVS tree 2000-01-24 13:12:20 +00:00
Andrew Tridgell
fc7952e7f3 updated --password-file docs 2000-01-24 12:28:45 +00:00
Andrew Tridgell
cbce490e13 reinstated the MAX_READ_BUFFER code. Its a nasty tradeoff - using lots
of memory vs. ssh bugs. uggh.
2000-01-24 12:23:39 +00:00
Andrew Tridgell
74a7f81d57 updated a debug message 2000-01-24 12:22:58 +00:00
Andrew Tridgell
5b5591d8a8 make the replacement inet_aton() function independent of
inet_addr(). Some systems were detecting a missing inet_aton(), but
actually had it and inet_addr() called it, causing infinite recursion
2000-01-24 12:02:44 +00:00
Andrew Tridgell
c55f70218c fixed a rare SEGV that can happen when a file disappears (due to
another program) during an update
2000-01-24 11:41:08 +00:00
Andrew Tridgell
6957ae33a9 moved file deletion to before the fork() to prevent a race condition
pointed out by byrnes@curl.com
2000-01-24 11:20:25 +00:00
Andrew Tridgell
8a5d6bba09 don't use stderr after we become a daemon 2000-01-24 09:19:44 +00:00
Andrew Tridgell
1d2c275fff I can't believe it - solaris allows unlink of a non-empty directory as
root, leaving a corrupt filesystem. Are those guys on drugs?

try to avoid the problem as best we can.
2000-01-24 09:13:39 +00:00
Andrew Tridgell
d0fd26aa16 added some more debug info to the "buffer overflow in
receive_file_entry" message
2000-01-24 08:16:57 +00:00
Andrew Tridgell
e20c5e9521 -a now implies -o and -D whether you are root or not 2000-01-24 05:52:44 +00:00
Andrew Tridgell
66203a982b added --backup-dir option from Bob Edwards
this is very useful for incremental backups
2000-01-24 04:58:53 +00:00
Andrew Tridgell
b315601ce0 removed Daves include-only optimisation. One of the bug reports turned
out to be caused by it and it seems rather a lot of extra effort for
what must really be a minor optimisation in most cases
2000-01-23 13:16:30 +00:00
Andrew Tridgell
5f808dfbd7 fix a problem with files > 2GB
(thanks to T.J.Adye@rl.ac.uk)
2000-01-23 12:30:34 +00:00
Andrew Tridgell
0b73ca12fa added --max-delete option 2000-01-23 11:43:04 +00:00
Andrew Tridgell
03e2d0e329 fixed mdfour code on Cray (64 bit problems)
Thanks to roebel@kgw.tu-berlin.de
2000-01-23 11:26:10 +00:00
Andrew Tridgell
182517e692 removed u_sleep() as it is no longer used anywhere 2000-01-23 07:38:20 +00:00
Andrew Tridgell
554e0a8dd0 added some really ugly code to allow errors to propogate to
clients when writing to a rsync server

it works like this:

- we have an extra pipe from the receiver to the generator
- the server always runs with multiplexing on
- errors from the generator go down the multiplexed connection
- errors from the receiver go over the pipe, and from there to
  the multiplexed conn

it required some incredibly ugly code. damn.
2000-01-23 07:36:56 +00:00
Andrew Tridgell
b0f3f5784c open on paths starting with // fails on win32 2000-01-23 03:00:27 +00:00
Andrew Tridgell
3060d4aa1d handle systems that don't take a 2nd argument to gettimeofday() 2000-01-23 02:16:51 +00:00
Andrew Tridgell
1347d5126a added --existing option, similar to one suggested by Gildas Quiniou <gildas@stip.fr> 2000-01-23 01:53:18 +00:00
Andrew Tridgell
5d1e1dcf4b don't try to write errors to a dead socket 2000-01-23 01:11:43 +00:00
David Dykstra
74f5442401 Make all the rsync objects dependent on all the header files except the
zlib header fiels in Makefile.in.  I've been burned several times because
objects did not get rebuilt when header files changed.
2000-01-10 22:39:45 +00:00
David Dykstra
c08bb0fb73 Needed to comment out the inclusion of headers in fnmatch.c because it
couldn't find some of them (especially <fnmatch.h>, because it wasn't
looking in the current directory).  The header files are included better
from ../rsync.h.
2000-01-10 20:36:20 +00:00
Andrew Tridgell
e30f065766 make --address work for a client connecting to a server 2000-01-10 04:49:51 +00:00
David Dykstra
9dce9b45b3 Upgrade lib/fnmatch.[ch] to the latest from glibc-2.1.2 because the
FNM_PATHNAME flag (to stop at slashes in path names) was not working.

Ironically, the bug in glibc's fnmatch was reported on the rsync mailing
list in late October, and rsync's configure.in was changed to detect the
bad glibc and use the internal fnmatch, but the internal fnmatch was based
on the same buggy glibc!
2000-01-07 17:58:44 +00:00
David Dykstra
60be6acf46 If a destination file cannot be opened, pretend it doesn't exist rather
than skipping it and thus not updating it.  For example, the ownership or
mode on a file may prevent opening it, but the directory may still be
writable so the file could be completely replaced.
2000-01-06 16:15:36 +00:00
Andrew Tridgell
a5827a28d2 when we do a lchown() on a file we have to flush the cached perms on
the file if the file has the setuid or setgid bits set as the chown
has a side effect of removing the setuid and setgid bits.
we re-do the stat in this case
2000-01-06 00:26:00 +00:00
David Dykstra
dcc875e41e Define the WEXITSTATUS macro for systems that don't have it. 1999-12-29 21:11:57 +00:00
David Dykstra
128cf58433 When writing to a daemon with read only = false and uid = root and -g,
was not preserving group permisions.  Bug was introduced March 1 in
version 1.100 of rsync.c with an error in re-ordering of the boolean
expressions.  In order to completely preserve the earlier semantics,
change_gid should depend on "(am_root || !am_daemon)", but I don't see why
group ownership should behave differently in a non-root daemon.
1999-12-29 20:50:48 +00:00
David Dykstra
7e0ca8e2f0 When not using -p and file being copied to already existed, was mistakenly
using all the mode bits of the existing file rather than just the permissions,
including the file type.
1999-12-29 20:45:23 +00:00
Andrew Tridgell
d79d1c69f7 fixed a bug with waitpid() - I'd forgotten about WEXITSTATUS ! 1999-12-09 06:46:11 +00:00
Andrew Tridgell
a7d068abff fixed man page typo 1999-12-03 04:24:25 +00:00
Andrew Tridgell
7f931a0002 fixed a segv bug when handling symlinks.
thanks to taver@otenet.gr
1999-12-02 05:50:09 +00:00
Andrew Tridgell
07b7c86c06 don't write more than PIPE_BUF bytes in any one write() in io.c
this makes sure that the write never blocks.
1999-11-23 08:43:16 +00:00
Andrew Tridgell
1f5c6343e6 removed old non-blocking fd code (a hangover from a earlier version of
io.c). Thanks to Theo for pointing out this brokenness.
1999-11-15 01:32:20 +00:00
rsync-bugs
290b615a16 preparing for release of 2.3.2 1999-11-08 13:15:48 +00:00
Andrew Tridgell
57df171bc0 added --delete-after option (suggested by Jason) 1999-11-08 13:03:05 +00:00
Andrew Tridgell
f08baea3dd removed ACCESSPERMS mask when transferring a file without perms
copy. This makes us match GNU cp more closely.
1999-11-08 10:47:14 +00:00
Andrew Tridgell
2fb139c11b fixed passing of directory exclude options to remote side (thanks to
andrewdagger@xerox.gbr.com)

added note about multiple excludes per exclude option
1999-11-08 09:12:42 +00:00
David Dykstra
3420c8e6e0 Fixed bug introduced by calling do_open() for O_RDONLY files. Changed it
so the check for dry_run and CHECK_RO are not done when flags is O_RDONLY.
Only do the adding of O_BINARY, which was the intention.
1999-11-04 15:43:38 +00:00
Andrew Tridgell
b17bc22bb3 added a replacement inet_aton() for systems that don't have it.
thanks to Dave for pointing this out.
1999-11-01 21:35:15 +00:00
Andrew Tridgell
3adffb52e6 forgot to commit the fnmatch.h changes 1999-11-01 21:25:39 +00:00
Andrew Tridgell
4df9f36841 solved the problem of not using the right permissions when
preserve_perms is off.
1999-10-31 04:28:03 +00:00
Andrew Tridgell
5c9730a46c added --address option for virtual hosting 1999-10-31 03:21:02 +00:00
Andrew Tridgell
d9fcc198cf added -P option
it is equivalent to --partial --progress
1999-10-31 02:47:30 +00:00
Andrew Tridgell
c831379436 updated test suite from Phil. 1999-10-31 02:39:34 +00:00
Andrew Tridgell
d73ee7b70e updated rsync-path man page entry 1999-10-31 02:37:21 +00:00
Andrew Tridgell
cda2ae84b3 added "ignore errors" option in rsyncd.conf 1999-10-31 02:19:24 +00:00
Andrew Tridgell
e7d6e0aa0c updated the configure test for fnmatch() to see if FNM_PATHNAME is
working correctly.
1999-10-27 13:17:16 +00:00
Andrew Tridgell
8c9fd200f9 use do_open() instead of open() in several places to help the WinXX port
and O_BINARY
1999-10-25 22:04:09 +00:00
David Dykstra
79f118d859 Minor change suggesting people put in the right path in inetd.conf.
Suggested by Roger Price <rprice@cs.uml.edu>
1999-10-19 17:50:39 +00:00
Andrew Tridgell
7b10f91d8f added a note about using -v with --progress 1999-09-06 02:04:20 +00:00
Andrew Tridgell
3d19b4c83e separated out the make_backup code in preparation for some patches
from Bob Edwards
1999-08-30 08:19:47 +00:00
David Dykstra
79452d4693 Add a couple clarifying points to the sanitize_path() comments.
One is a note that a leading "/" in a symlink target will not behave
exactly as if a chroot had occurred, but I decided it wasn't worth the
making it the same.

The other is note about an extra harmless trailing "." that is added under
some rare circumstances.
1999-07-09 17:07:59 +00:00
David Dykstra
cb13abfed0 Fix significant security holes with "use chroot = no" in an rsync daemon:
1. The file paths being sent and received were not "sanitized" to
	ensure that there weren't any ".." components that would escape the
	top level directory.  This can't happen with the standard rsync
	client, but it could be exploited on both read and write if someone
	modified an rsync client.  This fix sanitizes all incoming and
	outgoing paths when "use chroot = no".

    2. If a module is also "read only = no", clients could have created
	symbolic links with ".." components that would allow writing
	outside of the module.  This could happen with the standard rsync
	client.  This fix sanitizes all incoming symbolic link targets
	when "use chroot = no".

Previously, only top-level paths (anything passed in command line arguments)
were sanitized.  Sorry, I didn't think about the individual file paths
before now.
1999-07-09 15:49:46 +00:00
Andrew Tridgell
0503f06089 continue calling waitpid() while still reapingchildren (patch from
Matti Aarnio)
1999-06-27 04:12:12 +00:00
Andrew Tridgell
f855a7d01a fixed a bug that made us use only 16 bits of the file checksum when
comparing checksums for the --checksum (-c) option.
1999-06-26 01:06:38 +00:00
Andrew Tridgell
4c3b4b2557 added RSYNC_PROXY support from Stephen Rothwell. This allows access to
rsync servers via a web proxy (useful for getting through firewalls)
1999-04-13 03:53:30 +00:00
rsync-bugs
79b5aa09a0 preparing for release of 2.3.1 1999-04-06 15:09:28 +00:00
Andrew Tridgell
9bd6597666 set the exit code to RERR_FILEIO is io_error is set when we exit. This
catches most sorts of io errors and ensures we report a error in our
exit status.
1999-04-06 14:52:32 +00:00
Andrew Tridgell
6fe076b3d7 these aren't used any more 1999-04-06 14:17:44 +00:00
Andrew Tridgell
cec8aa7724 handle the case of an empty file list in get_local_name 1999-04-06 12:30:36 +00:00
Andrew Tridgell
4c36a13ef2 don't abort the server side if the file list is empty (perhaps because
all files have been excluded).
1999-04-06 12:28:54 +00:00
Andrew Tridgell
24986abd07 note in the man page that:
1) rsync won't copy directories at all if recursion isn't selected
2) --delete won't do anything if recursion isn't selected
1999-04-06 11:52:45 +00:00
Andrew Tridgell
8dfac376b5 fix the man page to reflect the fact that exclude options in
rsyncd.conf are not passed to the client and thus only affect the file
lists on the server.
1999-04-06 11:34:06 +00:00
Andrew Tridgell
e78733d975 fixed a nasty bug in the handling of "local_name" when setting the
permissions on directories after a transfer.
1999-04-06 10:56:18 +00:00
Andrew Tridgell
dffba35e01 quote RPM_OPT_FLAGS
patch from racke@linuxia.de
1999-04-06 10:27:34 +00:00
David Dykstra
bd4ed7f719 Small bug fix for the --compare-dest option: when a file's contents
hadn't changed but its permissions had, the file wasn't copied but
its permissions were attempted to be set anyway.  Made a change to
skip setting the permissions in that case.
1999-04-02 18:24:27 +00:00
David Dykstra
752eaba41f Backed out the change to create missing parent directories when using
--compare-dest.  It was due to an incomplete analysis of the problem,
sorry.  I left a comment in its place indicating that normally the
parent directories should already have been created.

It turned out to actually be a bug in nsbd in which it was not always
including all the parent directories in the include list like it was
supposed to.  The files themselves were still being sent but that was only
because my exclude_the_rest optimization was kicking in; if it weren't,
excluding the parent directories would have had the side effect of
excluding the files too.  So it really had nothing to do with the
--compare-dest option after all, just with the requirement that if you use
--exclude '*' you need to explicitly include all parent directories of
files you include.
1999-03-24 19:28:03 +00:00
David Dykstra
ad517ce5b3 The "pid file" was getting created mode 666, not applying the umask
because at that point in the program the umask is set to 0.  Now creating
the file with mode (666 & ~orig_umask).
1999-03-24 16:39:07 +00:00
David Dykstra
1f8413449d Fix bug with --compare-dest option where missing parent directories in the
target destination were not getting created.  There was a case in
receiver.c to do that but it was only getting invoked when the -R option is
specified, although I don't know why it was limited to that.

It's too bad I didn't get a chance to more fully test the use of
--compare-dest by my nsbd program before releasing rsync 2.3.0.  I'll
probably need to put a workaround in nsbd too until the next release
of rsync.
1999-03-23 22:20:10 +00:00
rsync-bugs
d0a7c8a487 preparing for release of 2.3.0 1999-03-15 21:23:26 +00:00
David Dykstra
ebb00c8e29 Changed the protocol version to 20 so that --stats will work without -v in
both directions.
1999-03-15 21:17:58 +00:00
David Dykstra
6543dc0c4c Fix typo in comment in rsync.h, suggested by bje@cygnus.com 1999-03-15 17:04:22 +00:00
David Dykstra
e459239d27 Make a special version number 2.3.0-beta for a short period because
I'll be encouraging extra testing before the release.
1999-03-12 21:45:37 +00:00
David Dykstra
651443a7ff Allow + and - in the "include" and "exclude" directives in rsyncd.conf.
Patch submitted by Damian A Ivereigh <damian@cisco.com>
1999-03-12 21:42:51 +00:00
David Dykstra
79fc6bdb45 Include a test for a working getopt_long because the one on some versions
of cygwin doesn't work.  Thanks to Martin Krumpolec <krumpo@pobox.sk> for
the patch.  At the same time, include cache checks in configure.in for a few
items that were missing the checks.
1999-03-12 18:21:53 +00:00
David Dykstra
245fbb5129 When -R is used, send the permissions of the original top directories to
the receiver even when not combined with -r.  Without this, the directories
were getting created mode 777 because the default umask on receivers is
often 00.
1999-03-12 17:36:52 +00:00
David Dykstra
c7c11a0d4c When a file cannot be deleted because of ETXTBSY (in particular, when an
executable is busy on HPUX), rename it instead to .rsyncNNN.  Most of
the code was submitted by Ketil Kristiansen <ketil-k@osc.no>
1999-03-11 22:17:42 +00:00
David Dykstra
c27f25922e Check for EINVAL from a rename error call in addition to ENOENT because
David Campbell <david@pastornet.net.au> reported that that helps data
be received onto a windows box running cygwin b19.
1999-03-09 21:55:16 +00:00
David Dykstra
af21c12fbc Add distclean target to Makefile.in. 1999-03-09 21:47:18 +00:00
David Dykstra
32b1f1de0e Update config.sub to the latest from automake in addition to config.guess. 1999-03-09 21:46:15 +00:00
David Dykstra
529e60864f Update config.guess from a new official GNU version.
I believe this is the latest, which comes with automake 1.4 (somebody
else is in charge of installing the GNU stuff on my system so I'm not
100% sure it's the absolute latest, but it was updated just a couple
weeks ago).
1999-03-05 16:37:44 +00:00
David Dykstra
972a3619c4 The change a couple days ago to create files initially without group and
other access resulted in group and other access being left off when the
'-p' option was not used.  This fixes it by reintroducing the ACCESSPERMS
mask and setting permissions to (file->mode & ACCESSPERMS) if preserve_perms
is off.  I decided to change the mask INITPERMMASK to INITACCESSPERMS at
the same time.  When preserve_perms is off, rsync is restored to the
previous behavior of having the permissions of the original file with the
umask and setuid/setgid bits shut off.

Also, I decided that a check for "(updated && (file->mode & ~ACCESSPERMS))"
is no longer needed since as far as I can tell that would have only affected
permissions when not running as root and when a chgrp was done to a group
the user was not a member of, using system V chgrp semantics.  This is no
longer allowed.
1999-03-04 21:48:52 +00:00
David Dykstra
8458724d25 Disable the optimization that treats include-only files as a special case
whenever delete_mode is on.  People reported problems when it kicked in
while using --delete and while using --delete-excluded.
1999-03-02 20:56:17 +00:00
David Dykstra
9422bb3fdf Change getgroups to use GETGROUPS_T as the type of the group array returned,
as calculated by the configure macro AC_TYPE_GETGROUPS.  Without that, it
doesn't work properly on systems like sunos 4 where gid_t is defined to
be an unsigned short but getgroups is defined to return an array of integers.
1999-03-02 16:42:46 +00:00
David Dykstra
5afd8aedce Change the mask used when creating temporary files from 777 to 700, to prevent
an obscure race-condition security hole where a file may for a short time
have the wrong group.  Could have used 707 instead but that's just too weird
of a permission.  The define name used to be ACCESSPERMS but that is defined
as 777 on Linux, so changed the name to INITPERMMASK.
1999-03-01 21:22:54 +00:00
David Dykstra
86692050b5 When comparing -1 to a group id, cast -1 with gid_t because on some systems
such as sunos4 gid_t is an unsigned short.  This prevented the just-added
non-mapped group test from working on sunos4.
1999-03-01 21:16:49 +00:00
David Dykstra
460f6b990a Prevent the -g option from preserving groups that a non-root receiver
does not belong to, in these two ways:
    1. If a group mapping doesn't exist for a group name, do not preserve
	it for a non-root receiver.  This is especially evident with the
	sender is a daemon using chroot because then no mappings are
	available.
    2. Before setting the group on a file make sure that it is in the list
	of groups returned by getgroups().  The same thing is done by chgrp
	on systems that support bsd-style chown/chgrp, and this enforces
	that it happens the same way on all systems.  Overhead is very
	little, especially since most systems don't allow more then 16
	groups per user.
1999-03-01 19:24:39 +00:00
David Dykstra
896bd482c0 Removed am_client variable. It was being set in one place, when a client
of a socket (that is, a --daemon) server, but never looked at.  The way to
test whether or not on a client is (!am_server).
1999-02-25 17:58:31 +00:00
David Dykstra
53f821f1e6 Fix a bug with rsync -R --delete from ./ as reported in PR#1532 1999-02-24 22:38:36 +00:00
David Dykstra
b33b791e6b Add --delete-excluded option to delete files on the receiving side that
are excluded.  Implies --delete.
1999-02-22 19:55:57 +00:00
David Dykstra
17d31b380b Changed --stats implementation to work without -v in only these two
situations:
    1. the client is the receiver of files.  Can't do it otherwise yet
	because without -v the bytes written from the sender's generator
	process will not be counted.
    2. both the remote and local protocol versions are >=20.  I did not
	change the protocol version yet because it is such a minor change
	that it isn't worth it, although I did test it with the protocol
	version set to 20.
If neither of the situations hold, it prints a message saying to use -v.
1999-02-18 17:23:44 +00:00
David Dykstra
a8b9d4edec Changed exclude/include matching so that normally wildcards will stop at
slashes.  The old behavior of crossing slashes can be achieved by using a
double-asterisk ('**') anywhere in a pattern.  Note that this can change
some existing exclude patterns in a subtle way.  Also note that if the
remote side is an older release the processing on the two sides might not
be exactly the same when there's no double-asterisk, which can affect which
files are excluded from deletion, but they're close enough that people will
probably not notice.  I considered changing the protocol version and
checking the remote_version number to ensure the same processing on both
sides, but the exclude patterns are pre-processed before the remote version
number is known and it's just not worth going through extraordinary efforts.
Suggested by Cameron Simpson <cs@zip.com.au>
1999-02-18 16:27:36 +00:00
Andrew Tridgell
f83f054875 added --size-only option. Useful when starting to use rsync after a
ftp based mirror system so that timestamps may not be right.
1999-02-18 03:48:24 +00:00
David Dykstra
15800c7e89 Changed man page documentation of --force to say it is hardly ever needed
any more except in very obscure cases.
1999-02-17 21:39:45 +00:00
David Dykstra
b531360763 Added --copy-unsafe-links option which is like --copy-links except it is
only for symlinks that point outside the source tree.  Suggested by Charles
Hines <chuck_hines@VNET.IBM.COM> in PR#1376.  Also apply the option to any
symbolic links in the source portion of a path when --relative is used,
as suggested by Francis Montagnac <Francis.Montagnac@sophia.inria.fr> on
the rsync mailing list in a message titled "New option: --copy-parent-links".
1999-02-17 19:34:40 +00:00
David Dykstra
b567933566 Be consistent on use of '=' on options that take a parameter. 1999-02-15 17:48:06 +00:00
David Dykstra
52d7d78865 Change the implementation of memmove in lib/compat.c to call bcopy instead
of memcpy because bcopy is guaranteed to work with overlapping memory and
memcpy is not.  Bug fix for PR#1584 in which log entries in the rsync
daemon log on Sunos 4.1.4 were garbled.
1999-02-12 17:27:22 +00:00
David Dykstra
23c5aef18e A slight compensation I had just added for total bytes read when using -v
was incorrect.  It's hard to tell how many bytes are actually read because
transferring the value changes it and depending on its value it may
transfer 4 or 12 bytes so instead change the sender side to not include the
length of the counters it sends at all (it had been including one but three
are sent).
1999-02-10 22:16:32 +00:00
David Dykstra
e19452a96c Allow --stats to work without -v. 1999-02-10 21:54:12 +00:00
David Dykstra
9ef5390714 Changed Usage in the rsync --help message to indicate how there can be
multiple SRCs.  Also moved the --suffix option to show up right after
--backup and included the default backup suffix and block size along with
their corresponding options rather than at the end.  Copied the new help
message to rsync.yo and README and used the Usage also in the SYNOPSIS
section at the top of rsync.yo rather than the different one that used
"path" instead of SRC and DEST.  That last change was inspired by a
suggestion from Michael Bleyer in PR #1523.
1999-02-10 19:33:05 +00:00
David Dykstra
fd0abefa43 Changed error message that just said "open %s: %s" to "cannot create %s: %s"
in receiver.c because it confuses people when they do something like
    rsync /etc/passwd /tmp/nonexistentdir/passwd
and it printed out something like
    open /tmp/noniexistentdir/.passwd.a004d5 : No such file or directory
Reported by kurt_granroth@pobox.com in PR #1253.
1999-02-10 18:44:25 +00:00
David Dykstra
19c14f987e Changed the optimized include mode (which kicks in when there are a series
of non-wildcard includes followed by an exclude of *) so that it will silently
ignore included files that don't exist rather than saying "No such file or
directory".  This is more like the behavior of the non-optimized include mode.
1999-02-10 18:03:59 +00:00
David Dykstra
122f19a615 Support '#' and ';' comments in exclude files. It would actually not
probably cause any harm if they were treated as normal exclude or include
patterns because they just wouldn't match anything, but it's better to
explicitly ignore them.  Suggested by David Holland <uholld1@lexis-nexis.com>
1999-02-09 22:31:52 +00:00
David Dykstra
3ca8e68f58 Added "strict modes" option. When set false (default is true), it allows
the secrets file to be readable by other users.  Added to support the Windows
port under cygwin.  Problem reported by Martin Krumpolec krumpo@pobox.sk
1999-02-09 19:27:15 +00:00
David Dykstra
d41c7d025c Use MAXHOSTNAMELEN (256) for the array holding the host_name in socket.c
instead of 200.  Move the defines of True and False to rsync.h.  Eliminate
the defines of BOOL in loadparm.c and params.c because it is already
defined in rsync.h.  Changes suggested by Roman Gollent roman.gollent@wdr.com
1999-02-09 18:35:29 +00:00
David Dykstra
b86f0cefa2 Add --quiet/-q option. Contributed by Rich Salz salzr@certco.com. 1999-02-09 17:25:35 +00:00
David Dykstra
c226b7c2fd Move the initialization of push_dir, which calls getcwd, to early in main.
The reason for that is that on SVR2-based UTS 2.1.2 (which along with many
other old systems implements getcwd by forking "pwd") getcwd hangs when
called when other child processes are running.

I also added a quick return from push_dir if name == NULL so it doesn't
actually have to chdir anywhere when just initializing.

An initializing call to push_dir("/",0) had previously been put in at the
beginning of daemon_main() to avoid calling getcwd after a chroot, but
since that is no longer I needed I removed it and changed the call to
chdir("/") after chroot into a push_dir("/",0) so it will remember the
correct current directory.
1999-02-03 15:38:06 +00:00
David Dykstra
5865fcdd63 When calling lchown, pass the current known uid and gid rather than -1
to not change it, since the old SVR2-based UTS 2.1.2 does not support
leaving uid and gid alone when the value is -1.
1999-02-03 15:15:56 +00:00
David Dykstra
e68f34816f Add alternate implementation of waitpid() for systems that have wait4 but
not wait3, in particular Amdahl's SVR2-based UTS 2.1.2.  The code comes
from apache, but I contributed it to apache in the first place.
1999-02-03 15:11:40 +00:00
David Dykstra
716baed7ff Fix serious bug with "use chroot = no" option which caused "uid =" and "gid ="
to be ignored.  At the same time, change the "uid =" and "gid =" options to
be ignored when not running the daemon as super-user, to make it more
convenient for those people and to make it portable to systems such as
cygwin which don't support the uid/gid notions.
1999-01-21 17:10:32 +00:00
David Dykstra
b882b49747 Document the fact that the %t log format option includes the date, and
that the "log file" option always prepends "%t [%p] ".
1999-01-20 21:32:46 +00:00
David Dykstra
1f0610ef82 Fix segmentation fault when using -vvv. Suggested by assar@sics.se. 1999-01-11 17:07:27 +00:00
Andrew Tridgell
379e689dac fixed bug where strtok() could return NULL in getpassf(). 1999-01-08 10:42:29 +00:00
Andrew Tridgell
65575e9670 added --password-file patch from Alex Schlessinger <alex@inconnect.com>
(yes, I know I'm not supposed to be doing rsync work at the moment!
only four weeks to go ...)
1999-01-08 10:32:56 +00:00
Andrew Tridgell
5e71c4446e made the "max connections" and "lock file" local rather than global
options so you can set them on a per-module basis (requested by
kernel.org mirror maintiner)
1999-01-08 07:51:25 +00:00
David Dykstra
94a7fce217 Ran yodl2man on rsync.yo, and updated modification date. 1999-01-07 16:27:38 +00:00
Andrew Tridgell
3bc67f0c4f add warning about using RSYNC_PASSWORD on systems where env varibables
are visible to all users.
1999-01-07 07:19:03 +00:00
David Dykstra
117af10225 Change the receive log message from "send" to "recv". Fix from
Rick Smith <rick@rbsmith.com>.
1999-01-05 20:08:45 +00:00
Andrew Tridgell
536541d52b moved the block length mismatch code to another part of the loop. 1999-01-05 06:43:59 +00:00
Andrew Tridgell
496d9272c1 don't try to match checksums of two blocks which are of unequal
size. This explains the high false_alarms rate that I saw for one of
the sample data files used in my thesis.

The bug was harmless as the strong checksum easily caught all the
false matches but it's been bugging me as I couldn't explain it :)
1999-01-05 06:31:58 +00:00
Andrew Tridgell
34d3eed462 fixed a bug in the adjacent target optimisation 1999-01-05 01:57:13 +00:00
Andrew Tridgell
923fa97808 an optimization that tries to make rsync choose adjacent matches if
multiple matching blocks are available. This make the run-length
coding of the output more efficient.
1999-01-05 01:15:32 +00:00
Andrew Tridgell
4440b8aa3f no longer use mmap() in rsync because of the risk of a SIGBUS when
another program (such as a mailer) truncates a file.

To offset the speed loss I have rewritten the map_ptr() code to make
much better use of read().
1998-12-30 14:48:45 +00:00
David Dykstra
5a554d5b14 steve.ingram@icl-gis.com noticed several mistakes in rsync.1. Some of
them had already been fixed but yodl2man hadn't been run, and a couple
others were new.
1998-12-07 18:48:46 +00:00
David Dykstra
2cfeab21ce Fix minor man page typo, suggested by jbm@jbm.org. 1998-12-07 14:51:32 +00:00
Andrew Tridgell
2b086e033c paranoia change - treat list_only like read_only and refuse all
syscalls that might change the filesystem. This shouldn't be needed,
but I like paranoid coding :)
1998-12-05 01:56:45 +00:00
Andrew Tridgell
241fc706a9 - slprintf() takes sizeof(buf) not sizeof(buf)-1
- fixed incorrect format string in rename error
1998-12-05 01:55:37 +00:00
David Dykstra
7fadb4bc58 Support newer rpm's which define $RPM_OPT_FLAGS as a set of options
separated by spaces.  Suggested by pavel_roskin@geocities.com.
1998-12-01 16:13:25 +00:00
David Dykstra
6c7c2ef372 Minor documentation change suggested by pavel_roskin@geocities.com. 1998-12-01 16:11:40 +00:00
44 changed files with 3748 additions and 1823 deletions

View File

@@ -20,11 +20,13 @@ SHELL=/bin/sh
.SUFFIXES:
.SUFFIXES: .c .o
HEADS=byteorder.h config.h errcode.h proto.h rsync.h version.h \
lib/fnmatch.h lib/getopt.h lib/mdfour.h
LIBOBJ=lib/getopt.o lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o
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
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
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ)
@@ -53,6 +55,8 @@ install-strip:
rsync: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
$(OBJS): $(HEADS)
rsync.1: rsync.yo
yodl2man -o rsync.1 rsync.yo
@@ -60,11 +64,14 @@ rsyncd.conf.5: rsyncd.conf.yo
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
proto:
cat *.c | awk -f mkproto.awk > proto.h
cat *.c lib/compat.c | awk -f mkproto.awk > proto.h
clean:
rm -f *~ $(OBJS) rsync
distclean: clean
rm -f config.h config.cache config.status Makefile
# 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

21
README
View File

@@ -22,23 +22,29 @@ Basically you use rsync just like rcp, but rsync has many additional options.
Here is a brief description of rsync usage:
Usage: rsync [OPTION]... SRC [USER@]HOST:DEST
Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
or rsync [OPTION]... [USER@]HOST:SRC DEST
or rsync [OPTION]... SRC DEST
or rsync [OPTION]... SRC [SRC]... DEST
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
or rsync [OPTION]... SRC [USER@]HOST::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 ~ extension)
-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
@@ -50,16 +56,18 @@ Options
-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
-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
@@ -67,7 +75,6 @@ Options
--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
--suffix=SUFFIX override backup suffix
--version print version number
--daemon run as a rsync daemon
--config=FILE specify alternate rsyncd.conf file
@@ -75,9 +82,11 @@ Options
--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
SETUP
-----

View File

@@ -8,4 +8,8 @@
#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 HAVE_SOCKETPAIR

View File

@@ -56,7 +56,7 @@ static void gen_challenge(char *addr, char *challenge)
memset(input, 0, sizeof(input));
strlcpy((char *)input, addr, 17);
gettimeofday(&tv, NULL);
sys_gettimeofday(&tv);
SIVAL(input, 16, tv.tv_sec);
SIVAL(input, 20, tv.tv_usec);
SIVAL(input, 24, getpid());
@@ -87,12 +87,14 @@ static int get_secret(int module, char *user, char *secret, int len)
if (do_stat(fname, &st) == -1) {
rprintf(FERROR,"stat(%s) : %s\n", fname, strerror(errno));
ok = 0;
} else if ((st.st_mode & 06) != 0) {
rprintf(FERROR,"secrets file must not be other-accessible\n");
ok = 0;
} else if (am_root && (st.st_uid != 0)) {
rprintf(FERROR,"secrets file must be owned by root when running as root\n");
ok = 0;
} else if (lp_strict_modes(module)) {
if ((st.st_mode & 06) != 0) {
rprintf(FERROR,"secrets file must not be other-accessible (see strict modes option)\n");
ok = 0;
} else if (am_root && (st.st_uid != 0)) {
rprintf(FERROR,"secrets file must be owned by root when running as root (see strict modes)\n");
ok = 0;
}
}
if (!ok) {
rprintf(FERROR,"continuing without secrets file\n");
@@ -130,6 +132,55 @@ static int get_secret(int module, char *user, char *secret, int len)
return 1;
}
static char *getpassf(char *filename)
{
char buffer[100];
int len=0;
int fd=0;
STRUCT_STAT st;
int ok = 1;
extern int am_root;
char *envpw=getenv("RSYNC_PASSWORD");
if (!filename) return NULL;
if ( (fd=open(filename,O_RDONLY)) == -1) {
rprintf(FERROR,"could not open password file \"%s\"\n",filename);
if (envpw) rprintf(FERROR,"falling back to RSYNC_PASSWORD environment variable.\n");
return NULL;
}
if (do_stat(filename, &st) == -1) {
rprintf(FERROR,"stat(%s) : %s\n", filename, strerror(errno));
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)) {
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");
close(fd);
return NULL;
}
if (envpw) rprintf(FERROR,"RSYNC_PASSWORD environment variable ignored\n");
buffer[sizeof(buffer)-1]='\0';
if ( (len=read(fd,buffer,sizeof(buffer)-1)) > 0)
{
char *p = strtok(buffer,"\n\r");
close(fd);
if (p) p = strdup(p);
return p;
}
return NULL;
}
/* generate a 16 byte hash from a password and challenge */
static void generate_hash(char *in, char *challenge, char *out)
{
@@ -216,10 +267,11 @@ void auth_client(int fd, char *user, char *challenge)
{
char *pass;
char pass2[30];
extern char *password_file;
if (!user || !*user) return;
if (!(pass=getenv("RSYNC_PASSWORD"))) {
if (!(pass=getpassf(password_file)) && !(pass=getenv("RSYNC_PASSWORD"))) {
pass = getpass("Password: ");
}
@@ -228,7 +280,7 @@ void auth_client(int fd, char *user, char *challenge)
}
generate_hash(pass, challenge, pass2);
io_printf(fd, "%s %s\n", user, pass2);
}

288
backup.c Normal file
View File

@@ -0,0 +1,288 @@
/*
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.
*/
/* backup handling code */
#include "rsync.h"
extern int verbose;
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;
/* 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;
}
slprintf(fnamebak,sizeof(fnamebak),"%s%s",fname,backup_suffix);
if (do_rename(fname,fnamebak) != 0) {
/* cygwin (at least version b19) reports EINVAL */
if (errno != ENOENT && errno != EINVAL) {
rprintf(FERROR,"rename %s %s : %s\n",fname,fnamebak,strerror(errno));
return 0;
}
} else if (verbose > 1) {
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)
{
STRUCT_STAT st;
STRUCT_STAT *st2;
char fullpath[MAXPATHLEN];
extern int orig_umask;
char *p;
char *q;
while(strncmp(bak_path,"./",2)==0) bak_path += 2;
if(bak_path[strlen(bak_path)-1]!='/') {
slprintf(fullpath,sizeof(fullpath),"%s/",bak_path);
} else {
slprintf(fullpath,sizeof(fullpath),"%s",bak_path);
}
p=fullpath;
q=&fullpath[strlen(fullpath)]; /* End of bak_path string */
strcat(fullpath,fname);
/* 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;
}
/* 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 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;
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;
#else
if (do_stat (fname, &st)) return 1;
#endif
file = make_file (0, fname, 0);
/* 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;
}
slprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname);
#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);
};
#endif
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 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;
};
#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);
}
/* 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 (verbose > 1)
rprintf (FINFO, "keep_backup %s -> %s\n", fname, keep_name);
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));
}

View File

@@ -91,9 +91,9 @@ void file_checksum(char *fname,char *sum,OFF_T size)
char tmpchunk[CSUM_CHUNK];
struct mdfour m;
memset(sum,0,csum_length);
memset(sum,0,MD4_SUM_LENGTH);
fd = open(fname,O_RDONLY);
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) return;
buf = map_file(fd,size);

View File

@@ -30,12 +30,16 @@ 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;
void _exit_cleanup(int code, const char *file, int line)
{
extern int keep_partial;
if (code == 0 && io_error) code = RERR_FILEIO;
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
if (cleanup_got_literal && cleanup_fname && keep_partial) {
char *fname = cleanup_fname;

View File

@@ -25,6 +25,7 @@ extern int read_only;
extern int verbose;
extern int rsync_port;
char *auth_user;
int sanitize_paths = 0;
int start_socket_client(char *host, char *path, int argc, char *argv[])
{
@@ -34,8 +35,8 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
char line[MAXPATHLEN];
char *p, *user=NULL;
extern int remote_version;
extern int am_client;
extern int am_sender;
extern struct in_addr socket_address;
if (*path == '/') {
rprintf(FERROR,"ERROR: The remote path must start with a module name\n");
@@ -52,9 +53,7 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
if (!user) user = getenv("USER");
if (!user) user = getenv("LOGNAME");
am_client = 1;
fd = open_socket_out(host, rsync_port);
fd = open_socket_out(host, rsync_port, &socket_address);
if (fd == -1) {
exit_cleanup(RERR_SOCKETIO);
}
@@ -102,8 +101,10 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
}
io_printf(fd,"\n");
if (remote_version > 17 && !am_sender)
io_start_multiplex_in(fd);
if (remote_version < 23) {
if (remote_version == 22 || (remote_version > 17 && !am_sender))
io_start_multiplex_in(fd);
}
return client_run(fd, fd, -1, argc, argv);
}
@@ -138,16 +139,16 @@ static int rsync_module(int fd, int i)
return -1;
}
if (!claim_connection(lp_lock_file(), lp_max_connections())) {
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(), strerror(errno));
lp_lock_file(i), strerror(errno));
io_printf(fd,"@ERROR: failed to open lock file %s : %s\n",
lp_lock_file(), strerror(errno));
lp_lock_file(i), strerror(errno));
} else {
rprintf(FERROR,"max connections (%d) reached\n",
lp_max_connections());
io_printf(fd,"@ERROR: max connections (%d) reached - try again later\n", lp_max_connections());
lp_max_connections(i));
io_printf(fd,"@ERROR: max connections (%d) reached - try again later\n", lp_max_connections(i));
}
return -1;
}
@@ -164,27 +165,28 @@ static int rsync_module(int fd, int i)
module_id = i;
if (lp_read_only(i))
read_only = 1;
am_root = (getuid() == 0);
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\n");
return -1;
}
uid = atoi(p);
}
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\n");
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\n");
return -1;
}
gid = 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\n");
return -1;
}
gid = atoi(p);
}
}
p = lp_include_from(i);
@@ -208,33 +210,36 @@ static int rsync_module(int fd, int i)
return -1;
}
if (chdir("/")) {
if (!push_dir("/", 0)) {
rprintf(FERROR,"chdir %s failed\n", lp_path(i));
io_printf(fd,"@ERROR: chdir failed\n");
return -1;
}
if (setgid(gid) || getgid() != gid) {
rprintf(FERROR,"setgid %d failed\n", gid);
io_printf(fd,"@ERROR: setgid failed\n");
return -1;
}
if (setuid(uid) || getuid() != uid) {
rprintf(FERROR,"setuid %d failed\n", uid);
io_printf(fd,"@ERROR: setuid failed\n");
return -1;
}
} else {
if (!push_dir(lp_path(i), 0)) {
rprintf(FERROR,"chdir %s failed\n", lp_path(i));
io_printf(fd,"@ERROR: chdir failed\n");
return -1;
}
sanitize_paths = 1;
}
am_root = (getuid() == 0);
if (am_root) {
if (setgid(gid)) {
rprintf(FERROR,"setgid %d failed\n", gid);
io_printf(fd,"@ERROR: setgid failed\n");
return -1;
}
if (setuid(uid)) {
rprintf(FERROR,"setuid %d failed\n", uid);
io_printf(fd,"@ERROR: setuid failed\n");
return -1;
}
am_root = (getuid() == 0);
}
io_printf(fd,"@RSYNCD: OK\n");
@@ -259,7 +264,7 @@ static int rsync_module(int fd, int i)
request = strdup(p);
start_glob++;
}
glob_expand(name, argv, &argc, MAX_ARGS, !use_chroot);
glob_expand(name, argv, &argc, MAX_ARGS);
} else {
argc++;
}
@@ -273,7 +278,7 @@ static int rsync_module(int fd, int i)
}
}
if (!use_chroot) {
if (sanitize_paths) {
/*
* Note that this is applied to all parameters, whether or not
* they are filenames, but no other legal parameters contain
@@ -282,11 +287,11 @@ static int rsync_module(int fd, int i)
* and which aren't.
*/
for (i = 1; i < argc; i++) {
sanitize_path(argv[i]);
sanitize_path(argv[i], NULL);
}
}
ret = parse_arguments(argc, argv);
ret = parse_arguments(argc, argv, 0);
if (request) {
if (*auth_user) {
@@ -310,8 +315,10 @@ static int rsync_module(int fd, int i)
argp = argv + optind;
optind = 0;
if (remote_version > 17 && am_sender)
io_start_multiplex_out(fd);
if (remote_version < 23) {
if (remote_version == 22 || (remote_version > 17 && am_sender))
io_start_multiplex_out(fd);
}
if (!ret) {
option_error();
@@ -356,7 +363,7 @@ static int start_daemon(int fd)
set_socket_options(fd,"SO_KEEPALIVE");
set_socket_options(fd,lp_socket_options());
set_nonblocking(fd);
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
@@ -414,13 +421,9 @@ static int start_daemon(int fd)
int daemon_main(void)
{
extern char *config_file;
extern int orig_umask;
char *pid_file;
/* this ensures that we don't call getcwd after the chroot,
which doesn't work on platforms that use popen("pwd","r")
for getcwd */
push_dir("/", 0);
if (is_a_socket(STDIN_FILENO)) {
int i;
@@ -432,15 +435,12 @@ int daemon_main(void)
open("/dev/null", O_RDWR);
}
set_nonblocking(STDIN_FILENO);
return start_daemon(STDIN_FILENO);
}
become_daemon();
if (!lp_load(config_file, 1)) {
fprintf(stderr,"failed to load config file %s\n", config_file);
exit_cleanup(RERR_SYNTAX);
}
@@ -449,16 +449,19 @@ int daemon_main(void)
rprintf(FINFO,"rsyncd version %s starting\n",VERSION);
if (((pid_file = lp_pid_file()) != NULL) && (*pid_file != '\0')) {
FILE *f;
char pidbuf[16];
int fd;
int pid = (int) getpid();
cleanup_set_pid(pid);
if ((f = fopen(lp_pid_file(), "w")) == NULL) {
if ((fd = do_open(lp_pid_file(), O_WRONLY|O_CREAT|O_TRUNC,
0666 & ~orig_umask)) == -1) {
cleanup_set_pid(0);
fprintf(stderr,"failed to create pid file %s\n", pid_file);
rprintf(FLOG,"failed to create pid file %s\n", pid_file);
exit_cleanup(RERR_FILEIO);
}
fprintf(f, "%d\n", pid);
fclose(f);
slprintf(pidbuf, sizeof(pidbuf), "%d\n", pid);
write(fd, pidbuf, strlen(pidbuf));
close(fd);
}
start_accept_loop(rsync_port, start_daemon);

View File

@@ -23,8 +23,6 @@
extern int am_server;
extern int csum_length;
extern int preserve_links;
extern int preserve_perms;
extern int preserve_devices;

702
config.guess vendored
View File

@@ -1,6 +1,7 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
# Free Software Foundation, Inc.
#
# 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
@@ -23,6 +24,7 @@
# Written by Per Bothner <bothner@cygnus.com>.
# The master version of this file is at the FSF in /home/gd/gnu/lib.
# Please send patches to <autoconf-patches@gnu.org>.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -35,6 +37,20 @@
# (but try to keep the structure clean).
#
# Use $HOST_CC if defined. $CC may point to a cross-compiler
if test x"$CC_FOR_BUILD" = x; then
if test x"$HOST_CC" != x; then
CC_FOR_BUILD="$HOST_CC"
else
if test x"$CC" != x; then
CC_FOR_BUILD="$CC"
else
CC_FOR_BUILD=cc
fi
fi
fi
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
@@ -46,20 +62,66 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
dummy=dummy-$$
trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
news*:NEWS-OS:6.*:*)
echo mips-sony-newsos6
exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
fi
# 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.
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
cat <<EOF >$dummy.s
.globl main
.ent main
main:
.frame \$30,0,\$26,0
.prologue 0
.long 0x47e03d80 # implver $0
lda \$2,259
.long 0x47e20c21 # amask $2,$1
srl \$1,8,\$2
sll \$2,2,\$2
sll \$0,3,\$0
addl \$1,\$0,\$0
addl \$2,\$0,\$0
ret \$31,(\$26),1
.end main
EOF
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./$dummy
case "$?" in
7)
UNAME_MACHINE="alpha"
;;
15)
UNAME_MACHINE="alphaev5"
;;
14)
UNAME_MACHINE="alphaev56"
;;
10)
UNAME_MACHINE="alphapca56"
;;
16)
UNAME_MACHINE="alphaev6"
;;
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\ *: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
# of the specific Alpha model?
echo alpha-pc-interix
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
@@ -71,23 +133,60 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-cbm-openbsd${UNAME_RELEASE}
exit 0 ;;
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}
exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
Pyramid*:OSx*:*:*)
arm32:NetBSD:*:*)
echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
SR2?01:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit 0;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0 ;;
sun4*:SunOS:5.*:*)
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -107,23 +206,79 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun3*:SunOS:*:*)
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`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit 0 ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-atari-openbsd${UNAME_RELEASE}
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
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit 0 ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit 0 ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
echo m68k-sun-openbsd${UNAME_RELEASE}
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-apple-openbsd${UNAME_RELEASE}
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 ;;
macppc:NetBSD:*:*)
echo powerpc-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
@@ -131,10 +286,34 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
mips:*:4*:UMIPS)
echo mips-mips-riscos4sysv
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:5*:RISCos)
mips:*:*:UMIPS | mips:*:*:RISCos)
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy \
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
@@ -152,15 +331,18 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
else echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
@@ -178,15 +360,15 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i[34]86:AIX:*:*)
i?86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
sed 's/^ //' << EOF >dummy.c
sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
main()
@@ -197,8 +379,8 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit(0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
@@ -207,7 +389,8 @@ EOF
fi
exit 0 ;;
*:AIX:*:4)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
@@ -226,7 +409,7 @@ EOF
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
@@ -240,18 +423,50 @@ EOF
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
9000/[3478]??:HP-UX:*:*)
9000/[34678]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
9000/8?? ) HP_ARCH=hppa1.0 ;;
9000/[678][0-9][0-9])
sed 's/^ //' << EOF >$dummy.c
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
rm -f $dummy.c $dummy
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
sed 's/^ //' << EOF >dummy.c
sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
main ()
@@ -276,8 +491,8 @@ EOF
exit (0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
@@ -286,15 +501,28 @@ EOF
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
*9??*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
i?86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit 0 ;;
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 ;;
@@ -313,120 +541,332 @@ EOF
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
CRAY*T3E:*:*:*)
echo t3e-cray-unicos_mk
exit 0 ;;
CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY*C90:*:*:*)
echo c90-cray-unicos${UNAME_RELEASE}
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY*T3E:*:*:*)
echo alpha-cray-unicosmk${UNAME_RELEASE}
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
F300:UNIX_System_V:*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
F301:UNIX_System_V:*:*)
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
exit 0 ;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
hp3[0-9][05]:OpenBSD:*:*)
echo m68k-hp-openbsd${UNAME_RELEASE}
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
if test -x /usr/bin/objformat; then
if test "elf" = "`/usr/bin/objformat`"; then
echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
exit 0
fi
fi
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
i*:CYGWIN*:*)
echo i386-unknown-cygwin32
echo ${UNAME_MACHINE}-pc-cygwin
exit 0 ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
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
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32
echo powerpcle-unknown-cygwin
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
elif test "${UNAME_MACHINE}" = "alpha" ; then
echo alpha-unknown-linux ; exit 0
else
# Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
# useful --help. Gcc wants to distinguish between linuxoldld and linuxaout.
test ! -d /usr/lib/ldscripts/. \
&& echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
# Determine whether the default compiler is a.out or elf
cat >dummy.c <<EOF
# 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_help_string=`cd /; ld --help 2>&1`
ld_supported_emulations=`echo $ld_help_string \
| sed -ne '/supported emulations:/!d
s/[ ][ ]*/ /g
s/.*supported emulations: *//
s/ .*//
p'`
case "$ld_supported_emulations" in
*ia64)
echo "${UNAME_MACHINE}-unknown-linux"
exit 0
;;
i?86linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0
;;
i?86coff)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0
;;
sparclinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
armlinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
elf32arm*)
echo "${UNAME_MACHINE}-unknown-linux-gnu"
exit 0
;;
armelf_linux*)
echo "${UNAME_MACHINE}-unknown-linux-gnu"
exit 0
;;
m68klinux)
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
exit 0
;;
elf32ppc)
# Determine Lib Version
cat >$dummy.c <<EOF
#include <features.h>
#if defined(__GLIBC__)
extern char __libc_version[];
extern char __libc_release[];
#endif
main(argc, argv)
int argc;
char *argv[];
int argc;
char *argv[];
{
#ifdef __ELF__
printf ("%s-unknown-linux\n", argv[1]);
#if defined(__GLIBC__)
printf("%s %s\n", __libc_version, __libc_release);
#else
printf ("%s-unknown-linuxaout\n", argv[1]);
printf("unkown\n");
#endif
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
LIBC=""
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./$dummy | grep 1\.99 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
rm -f $dummy.c $dummy
echo powerpc-unknown-linux-gnu${LIBC}
exit 0
;;
esac
if test "${UNAME_MACHINE}" = "alpha" ; then
sed 's/^ //' <<EOF >$dummy.s
.globl main
.ent main
main:
.frame \$30,0,\$26,0
.prologue 0
.long 0x47e03d80 # implver $0
lda \$2,259
.long 0x47e20c21 # amask $2,$1
srl \$1,8,\$2
sll \$2,2,\$2
sll \$0,3,\$0
addl \$1,\$0,\$0
addl \$2,\$0,\$0
ret \$31,(\$26),1
.end main
EOF
LIBC=""
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
if test "$?" = 0 ; then
./$dummy
case "$?" in
7)
UNAME_MACHINE="alpha"
;;
15)
UNAME_MACHINE="alphaev5"
;;
14)
UNAME_MACHINE="alphaev56"
;;
10)
UNAME_MACHINE="alphapca56"
;;
16)
UNAME_MACHINE="alphaev6"
;;
esac
objdump --private-headers $dummy | \
grep ld.so.1 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
rm -f $dummy.s $dummy
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
elif test "${UNAME_MACHINE}" = "mips" ; then
cat >$dummy.c <<EOF
#ifdef __cplusplus
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#ifdef __MIPSEB__
printf ("%s-unknown-linux-gnu\n", argv[1]);
#endif
#ifdef __MIPSEL__
printf ("%sel-unknown-linux-gnu\n", argv[1]);
#endif
return 0;
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
else
# Either a pre-BFD a.out linker (linux-gnuoldld)
# or one that does not give us useful --help.
# GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
# If ld does not provide *any* "supported emulations:"
# that means it is gnuoldld.
echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
case "${UNAME_MACHINE}" in
i?86)
VENDOR=pc;
;;
*)
VENDOR=unknown;
;;
esac
# Determine whether the default compiler is a.out or elf
cat >$dummy.c <<EOF
#include <features.h>
#ifdef __cplusplus
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-${VENDOR}-linux-gnu\n", argv[1]);
# else
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
# endif
# else
printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
# endif
#else
printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
#endif
return 0;
}
EOF
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
i[34]86:DYNIX/ptx:4*:*)
i?86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4
exit 0 ;;
i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
i?86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
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
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit 0 ;;
i[34]86:*:3.2:*)
i?86:*:5:7*)
# Fixed at (any) Pentium or better
UNAME_MACHINE=i586
if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
i?86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
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_MACHINE=i586
echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-unknown-sysv32
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
pc:*:*:*)
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
exit 0 ;;
Intel:Mach:3*:*)
echo i386-unknown-mach3
echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
@@ -442,28 +882,39 @@ EOF
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
M680[234]0:*:R3V[567]*:*)
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3 && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
uname -p 2>/dev/null | grep 86 >/dev/null \
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
m680[234]0:LynxOS:2.[23]*:*)
echo m68k-lynx-lynxos${UNAME_RELEASE}
m68*:LynxOS:2.*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i[34]86:LynxOS:2.[23]*:*)
echo i386-lynx-lynxos${UNAME_RELEASE}
i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.[23]*:*)
echo sparc-lynx-lynxos${UNAME_RELEASE}
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
rs6000:LynxOS:2.[23]*:*)
echo rs6000-lynx-lynxos${UNAME_RELEASE}
rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
@@ -476,22 +927,62 @@ 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>
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit 0 ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
R3000:*System_V*:*:*)
news*:NEWS-OS:*:6*)
echo mips-sony-newsos6
exit 0 ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit 0 ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit 0 ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit 0 ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit 0 ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit 0 ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:QNX:*:4*)
echo i386-qnx-qnx${UNAME_VERSION}
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
cat >dummy.c <<EOF
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
@@ -529,7 +1020,10 @@ main ()
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
@@ -546,7 +1040,7 @@ main ()
#endif
#if defined (__386BSD__)
printf ("i386-unknown-bsd\n"); exit (0);
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
@@ -589,8 +1083,8 @@ main ()
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
rm -f $dummy.c $dummy
# Apollos put the system type in the environment.

453
config.sub vendored
View File

@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
# can handle that machine. It does not imply ALL GNU software can.
#
# 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
@@ -41,6 +41,8 @@
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
@@ -62,11 +64,21 @@ case $1 in
;;
esac
# Separate what the user gave into CPU-COMPANY and OS (if any).
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
linux-gnu*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
@@ -81,52 +93,43 @@ case $os in
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp )
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple)
os=
basic_machine=$1
;;
-sim | -cisco | -oki | -wec | -winbond ) # CYGNUS LOCAL
os=
basic_machine=$1
;;
-apple*) # CYGNUS LOCAL
os=
basic_machine=$1
;;
-scout) # CYGNUS LOCAL
;;
-wrs) # CYGNUS LOCAL
os=vxworks
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco5)
os=sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
@@ -137,67 +140,58 @@ case $os in
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm | armeb \
| armel | pyramid \
| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
| alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
| powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
| pdp11 | mips64el | mips64orion | mips64orionel \
| sparc | sparc8 | supersparc | microsparc | ultrasparc)
basic_machine=$basic_machine-unknown
;;
m88110 | m680[012346]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL
basic_machine=$basic_machine-unknown
;;
mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith
tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
| 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
| mipstx39 | mipstx39el \
| sparc | sparclet | sparclite | sparc64 | v850)
basic_machine=$basic_machine-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i[34567]86)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
| sparc-* | ns32k-* | fx80-* | arm-* | arme[lb]-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
| hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
| pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
| pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* \
| mips64-* | mipsel-* | mips64el-* | mips64orion-* \
| mips64orionel-* | sparc8-* | supersparc-* | microsparc-* | ultrasparc-*)
;;
m88110-* | m680[012346]0-* | m683?2-* | m68360-* | z8k-* | h8500-*) # CYGNUS LOCAL
;;
mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith
vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
| xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \
| alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mipstx39-* | mipstx39el-* \
| f301-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd) # CYGNUS LOCAL
basic_machine=i386-unknown
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
a29khif) # CYGNUS LOCAL
basic_machine=a29k-amd
os=-udi
;;
adobe68k) # CYGNUS LOCAL
basic_machine=m68010-adobe
os=-scout
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
@@ -215,9 +209,9 @@ case $basic_machine in
amiga | amiga-*)
basic_machine=m68k-cbm
;;
amigados)
amigaos | amigados)
basic_machine=m68k-cbm
os=-amigados
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-cbm
@@ -227,26 +221,14 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-sysv
;;
apollo68bsd) # CYGNUS LOCAL
basic_machine=m68k-apollo
os=-bsd
;;
arm | armel | armeb)
basic_machine=arm-arm
os=-aout
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
[ctj]90-cray)
basic_machine=c90-cray
os=-unicos
;;
t3e-cray)
basic_machine=t3e-cray
os=-unicos_mk
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -275,6 +257,10 @@ case $basic_machine in
basic_machine=cray2-cray
os=-unicos
;;
[ctj]90-cray)
basic_machine=c90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
@@ -311,10 +297,6 @@ case $basic_machine in
encore | umax | mmax)
basic_machine=ns32k-encore
;;
es1800 | OSE68k | ose68k | ose | OSE) # CYGNUS LOCAL
basic_machine=m68k-ericsson
os=-ose
;;
fx2800)
basic_machine=i860-alliant
;;
@@ -333,14 +315,6 @@ case $basic_machine in
basic_machine=h8300-hitachi
os=-hms
;;
h8300xray) # CYGNUS LOCAL
basic_machine=h8300-hitachi
os=-xray
;;
h8500hms) # CYGNUS LOCAL
basic_machine=h8500-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
@@ -356,22 +330,6 @@ case $basic_machine in
basic_machine=m68k-hp
os=-hpux
;;
w89k-*) # CYGNUS LOCAL
basic_machine=hppa1.1-winbond
os=-proelf
;;
op50n-*) # CYGNUS LOCAL
basic_machine=hppa1.1-oki
os=-proelf
;;
op60c-*) # CYGNUS LOCAL
basic_machine=hppa1.1-oki
os=-proelf
;;
hppro) # CYGNUS LOCAL
basic_machine=hppa1.1-hp
os=-proelf
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
@@ -384,43 +342,30 @@ case $basic_machine in
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppaosf) # CYGNUS LOCAL
basic_machine=hppa1.1-hp
os=-osf
hppa-next)
os=-nextstep3
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[3456]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
i[34567]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i[3456]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
i[34567]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i[3456]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
i[34567]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i[3456]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
i[34567]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach) # CYGNUS LOCAL
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta) # CYGNUS LOCAL
basic_machine=i386-unknown
os=-vsta
;;
i386-go32 | go32) # CYGNUS LOCAL
basic_machine=i386-unknown
os=-go32
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
@@ -449,28 +394,24 @@ case $basic_machine in
miniframe)
basic_machine=m68000-convergent
;;
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/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
monitor) # CYGNUS LOCAL
basic_machine=m68k-rom68k
os=-coff
;;
msdos) # CYGNUS LOCAL
basic_machine=i386-unknown
os=-msdos
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
basic_machine=i386-unknown # CYGNUS LOCAL
os=-netbsd
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
@@ -483,10 +424,6 @@ case $basic_machine in
basic_machine=mips-sony
os=-newsos
;;
necv70) # CYGNUS LOCAL
basic_machine=v70-nec
os=-sysv
;;
next | m*-next )
basic_machine=m68k-next
case $os in
@@ -515,14 +452,6 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
OSE68000 | ose68000) # CYGNUS LOCAL
basic_machine=m68000-ericsson
os=-ose
;;
os68k) # CYGNUS LOCAL
basic_machine=m68k-none
os=-os68k
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
@@ -540,25 +469,23 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5)
basic_machine=i586-intel
pentium | p5 | k5 | nexen)
basic_machine=i586-pc
;;
pentiumpro | p6)
basic_machine=i686-intel
pentiumpro | p6 | k6 | 6x86)
basic_machine=i686-pc
;;
pentium-* | p5-*)
pentiumii | pentium2)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | nexen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-*)
pentiumpro-* | p6-* | k6-* | 6x86-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
k5)
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
basic_machine=i586-amd
;;
nexgen)
# We don't have specific support for Nexgen yet, so just call it a Pentium
basic_machine=i586-nexgen
pentiumii-* | pentium2-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
@@ -578,20 +505,12 @@ case $basic_machine in
ps2)
basic_machine=i386-ibm
;;
rom68k) # CYGNUS LOCAL
basic_machine=m68k-rom68k
os=-coff
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
sa29200) # CYGNUS LOCAL
basic_machine=a29k-amd
os=-udi
;;
sequent)
basic_machine=i386-sequent
;;
@@ -599,24 +518,6 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs) # CYGNUS LOCAL
basic_machine=sparclite-wrs
os=-vxworks
;;
sparcfrw) # CYGNUS LOCAL
basic_machine=sparcfrw-sun
os=-sunos4
;;
sparcfrwcompat) # CYGNUS LOCAL
basic_machine=sparcfrwcompat-sun
os=-sunos4
;;
sparclitefrw) # CYGNUS LOCAL
basic_machine=sparclitefrw-fujitsu
;;
sparclitefrwcompat) # CYGNUS LOCAL
basic_machine=sparclitefrwcompat-fujitsu
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
@@ -624,13 +525,6 @@ case $basic_machine in
spur)
basic_machine=spur-unknown
;;
st2000) # CYGNUS LOCAL
basic_machine=m68k-tandem
;;
stratus) # CYGNUS LOCAL
basic_machine=i860-stratus
os=-sysv4
;;
sun2)
basic_machine=m68000-sun
;;
@@ -675,6 +569,12 @@ case $basic_machine in
basic_machine=i386-sequent
os=-dynix
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -686,10 +586,6 @@ case $basic_machine in
basic_machine=a29k-nyu
os=-sym1
;;
v810 | necv810) # CYGNUS LOCAL
basic_machine=v810-nec
os=-none
;;
vaxv)
basic_machine=vax-dec
os=-sysv
@@ -698,6 +594,9 @@ case $basic_machine in
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -706,13 +605,9 @@ case $basic_machine in
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k) # CYGNUS LOCAL
basic_machine=a29k-wrs
os=-vxworks
;;
w65*) # CYGNUS LOCAL
basic_machine=w65-wdc
os=-none
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
xmp)
basic_machine=xmp-cray
@@ -721,10 +616,6 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
z8k-*-coff) # CYGNUS LOCAL
basic_machine=z8k-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
@@ -732,17 +623,12 @@ case $basic_machine in
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k) # CYGNUS LOCAL
basic_machine=hppa1.1-winbond
;;
op50n) # CYGNUS LOCAL
basic_machine=hppa1.1-oki
;;
op60c) # CYGNUS LOCAL
basic_machine=hppa1.1-oki
;;
mips)
basic_machine=mips-mips
if [ x$os = x-linux-gnu ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;;
romp)
basic_machine=romp-ibm
@@ -771,12 +657,6 @@ case $basic_machine in
orion105)
basic_machine=clipper-highlevel
;;
mac | mpw | mac-mpw) # CYGNUS LOCAL
basic_machine=m68k-apple
;;
pmac | pmac-mpw) # CYGNUS LOCAL
basic_machine=powerpc-apple
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
@@ -800,6 +680,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
@@ -807,35 +689,37 @@ case $os in
-solaris)
os=-solaris2
;;
-unixware* | svr4*)
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux|'`
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative must end in a *, to match a version number.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -lites* | -minix* | -genix* | -ultrix* | -irix* \
| -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigados* | -msdos* | -moss* | -newsos* | -unicos* | -aos* \
| -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
| -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -freebsd* | -openbsd* \
| -riscix* | -lites* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi \
| -eabi* | -ieee*)
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -rhapsody* \
| -openstep*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
# CYGNUS LOCAL
-go32 | -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -proelf | -os9* \
| -macos* | -mpw* | -magic* | -pe* | -win32)
;;
-mac*) # CYGNUS LOCAL
os=`echo $os | sed -e 's|mac|macos|'`
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
@@ -858,12 +742,12 @@ case $os in
-acis*)
os=-aos
;;
-386bsd) # CYGNUS LOCAL
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-ns2 )
os=-nextstep2
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
@@ -889,12 +773,6 @@ case $os in
# This must come after -sysvr4.
-sysv*)
;;
-ose*) # CYGNUS LOCAL
os=-ose
;;
-es1800*) # CYGNUS LOCAL
os=-ose
;;
-xenix)
os=-xenix
;;
@@ -923,6 +801,9 @@ case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-semi)
os=-aout
;;
pdp11-*)
os=-none
;;
@@ -941,30 +822,18 @@ case $basic_machine in
# default.
# os=-sunos4
;;
m68*-cisco) # CYGNUS LOCAL
os=-aout
;;
mips*-cisco) # CYGNUS LOCAL
os=-elf
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-be)
os=-beos
;;
*-ibm)
os=-aix
;;
*-wec) # CYGNUS LOCAL
os=-proelf
;;
*-winbond) # CYGNUS LOCAL
os=-proelf
;;
*-oki) # CYGNUS LOCAL
os=-proelf
;;
*-hp)
os=-hpux
;;
@@ -975,7 +844,7 @@ case $basic_machine in
os=-sysv
;;
*-cbm)
os=-amigados
os=-amigaos
;;
*-dg)
os=-dgux
@@ -989,6 +858,9 @@ case $basic_machine in
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
@@ -1022,14 +894,8 @@ case $basic_machine in
*-masscomp)
os=-rtu
;;
*-rom68k) # CYGNUS LOCAL
os=-coff
;;
*-*bug) # CYGNUS LOCAL
os=-coff
;;
*-apple) # CYGNUS LOCAL
os=-macos
f301-fujitsu)
os=-uxpv
;;
*)
os=-none
@@ -1049,12 +915,6 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
-bosx*) # CYGNUS LOCAL
vendor=bull
;;
-lynxos*)
vendor=lynx
;;
-aix*)
vendor=ibm
;;
@@ -1082,13 +942,10 @@ case $basic_machine in
-ptx*)
vendor=sequent
;;
-vxworks*)
-vxsim* | -vxworks*)
vendor=wrs
;;
-hms*) # CYGNUS LOCAL
vendor=hitachi
;;
-mpw* | -macos*) # CYGNUS LOCAL
-aux*)
vendor=apple
;;
esac

View File

@@ -37,6 +37,7 @@ AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_PID_T
AC_TYPE_GETGROUPS
AC_STRUCT_ST_RDEV
AC_CHECK_TYPE(ino_t,unsigned)
@@ -47,89 +48,10 @@ if test x"$rsync_cv_errno" = x"yes"; then
AC_DEFINE(HAVE_ERRNO_DECL)
fi
AC_FUNC_MEMCMP
AC_FUNC_UTIME_NULL
AC_CHECK_FUNCS(mmap munmap waitpid getcwd strdup strerror chown chmod mknod)
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
AC_CHECK_FUNCS(memmove getopt_long lchown vsnprintf snprintf setsid glob strpbrk)
AC_CHECK_FUNCS(strlcat strlcpy)
echo $ac_n "checking for working fnmatch... $ac_c"
AC_TRY_RUN([#include <fnmatch.h>
main() { exit(fnmatch("*.o", "x.o", 0) == 0? 0: 1); }],
echo yes;AC_DEFINE(HAVE_FNMATCH),
echo no)
AC_CACHE_CHECK([for long long],rsync_cv_have_longlong,[
AC_TRY_RUN([#include <stdio.h>
main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }],
rsync_cv_have_longlong=yes,rsync_cv_have_longlong=no,rsync_cv_have_longlong=cross)])
if test x"$rsync_cv_have_longlong" = x"yes"; then
AC_DEFINE(HAVE_LONGLONG)
fi
AC_CACHE_CHECK([for off64_t],rsync_cv_HAVE_OFF64_T,[
AC_TRY_RUN([#include <stdio.h>
#include <sys/stat.h>
main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
rsync_cv_HAVE_OFF64_T=yes,rsync_cv_HAVE_OFF64_T=no,rsync_cv_HAVE_OFF64_T=cross)])
if test x"$rsync_cv_HAVE_OFF64_T" = x"yes"; then
AC_DEFINE(HAVE_OFF64_T)
fi
echo $ac_n "checking for short ino_t ... $ac_c"
AC_TRY_RUN([#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
main() { if (sizeof(ino_t) < sizeof(unsigned int)) return 0; return 1; }],
echo yes;AC_DEFINE(HAVE_SHORT_INO_T),
echo no)
AC_CACHE_CHECK([for unsigned char],rsync_cv_HAVE_UNSIGNED_CHAR,[
AC_TRY_RUN([#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }],
rsync_cv_HAVE_UNSIGNED_CHAR=yes,rsync_cv_HAVE_UNSIGNED_CHAR=no,rsync_cv_HAVE_UNSIGNED_CHAR=cross)])
if test x"$rsync_cv_HAVE_UNSIGNED_CHAR" = x"yes"; then
AC_DEFINE(HAVE_UNSIGNED_CHAR)
fi
AC_CACHE_CHECK([for broken readdir],rsync_cv_HAVE_BROKEN_READDIR,[
AC_TRY_RUN([#include <sys/types.h>
#include <dirent.h>
main() { struct dirent *di; DIR *d = opendir("."); di = readdir(d);
if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
di->d_name[0] == 0) exit(0); exit(1);} ],
rsync_cv_HAVE_BROKEN_READDIR=yes,rsync_cv_HAVE_BROKEN_READDIR=no,rsync_cv_HAVE_BROKEN_READDIR=cross)])
if test x"$rsync_cv_HAVE_BROKEN_READDIR" = x"yes"; then
AC_DEFINE(HAVE_BROKEN_READDIR)
fi
AC_CACHE_CHECK([for utimbuf],rsync_cv_HAVE_UTIMBUF,[
AC_TRY_COMPILE([#include <sys/types.h>
#include <utime.h>],
[struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));],
rsync_cv_HAVE_UTIMBUF=yes,rsync_cv_HAVE_UTIMBUF=no,rsync_cv_HAVE_UTIMBUF=cross)])
if test x"$rsync_cv_HAVE_UTIMBUF" = x"yes"; then
AC_DEFINE(HAVE_UTIMBUF)
fi
AC_CACHE_CHECK([for broken inet_ntoa],rsync_cv_REPLACE_INET_NTOA,[
AC_TRY_RUN([
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#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(0); }
exit(1);}],
rsync_cv_REPLACE_INET_NTOA=yes,rsync_cv_REPLACE_INET_NTOA=no,rsync_cv_REPLACE_INET_NTOA=cross)])
if test x"$rsync_cv_REPLACE_INET_NTOA" = x"yes"; then
AC_DEFINE(REPLACE_INET_NTOA)
fi
# The following test taken from the cvs sources
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# These need checks to be before checks for any other functions that
# might be in the same libraries.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
# libsocket.so which has a bad implementation of gethostbyname (it
# only looks in /etc/hosts), so we only look for -lsocket if we need
@@ -170,27 +92,171 @@ if test x"$ac_cv_func_strcasecmp" = x"no"; then
AC_CHECK_LIB(resolv, strcasecmp)
fi
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 setsid glob strpbrk)
AC_CHECK_FUNCS(strlcat strlcpy)
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
AC_TRY_RUN([#include <sys/types.h>
#include <sys/socket.h>
main() {
int fd[2];
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
}],
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
AC_DEFINE(HAVE_SOCKETPAIR)
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)
fi
# sometimes getopt_long cannot parse same arguments twice
# e.g. on certain versions of CygWin32
AC_CACHE_CHECK([for working getopt_long],rsync_cv_HAVE_GETOPT_LONG,[
AC_TRY_RUN([#include <getopt.h>
main() {
int i, x = 0; char *argv[] = { "x", "--xx" };
struct option o[] = {{"xx", 0, 0, 1}, {0,0,0,0}};
getopt_long(2, argv, "x", o, &i) == 1 ? x++ : 0; optind = 0;
getopt_long(2, argv, "x", o, &i) == 1 ? x++ : 0;
exit(x == 2 ? 0 : 1);
}], rsync_cv_HAVE_GETOPT_LONG=yes,rsync_cv_HAVE_GETOPT_LONG=no,
rsync_cv_HAVE_GETOPT_LONG=cross)])
if test x"$rsync_cv_HAVE_GETOPT_LONG" = x"yes"; then
AC_DEFINE(HAVE_GETOPT_LONG)
fi
AC_CACHE_CHECK([for long long],rsync_cv_HAVE_LONGLONG,[
AC_TRY_RUN([#include <stdio.h>
main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }],
rsync_cv_HAVE_LONGLONG=yes,rsync_cv_HAVE_LONGLONG=no,rsync_cv_HAVE_LONGLONG=cross)])
if test x"$rsync_cv_HAVE_LONGLONG" = x"yes"; then
AC_DEFINE(HAVE_LONGLONG)
fi
AC_CACHE_CHECK([for off64_t],rsync_cv_HAVE_OFF64_T,[
AC_TRY_RUN([#include <stdio.h>
#include <sys/stat.h>
main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
rsync_cv_HAVE_OFF64_T=yes,rsync_cv_HAVE_OFF64_T=no,rsync_cv_HAVE_OFF64_T=cross)])
if test x"$rsync_cv_HAVE_OFF64_T" = x"yes"; then
AC_DEFINE(HAVE_OFF64_T)
fi
AC_CACHE_CHECK([for short ino_t],rsync_cv_HAVE_SHORT_INO_T,[
AC_TRY_RUN([#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
main() { if (sizeof(ino_t) < sizeof(unsigned int)) return 0; return 1; }],
rsync_cv_HAVE_SHORT_INO_T=yes,rsync_cv_HAVE_SHORT_INO_T=no,rsync_cv_HAVE_SHORT_INO_T=cross)])
if test x"$rsync_cv_HAVE_SHORT_INO_T" = x"yes"; then
AC_DEFINE(HAVE_SHORT_INO_T)
fi
AC_CACHE_CHECK([for unsigned char],rsync_cv_HAVE_UNSIGNED_CHAR,[
AC_TRY_RUN([#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }],
rsync_cv_HAVE_UNSIGNED_CHAR=yes,rsync_cv_HAVE_UNSIGNED_CHAR=no,rsync_cv_HAVE_UNSIGNED_CHAR=cross)])
if test x"$rsync_cv_HAVE_UNSIGNED_CHAR" = x"yes"; then
AC_DEFINE(HAVE_UNSIGNED_CHAR)
fi
AC_CACHE_CHECK([for broken readdir],rsync_cv_HAVE_BROKEN_READDIR,[
AC_TRY_RUN([#include <sys/types.h>
#include <dirent.h>
main() { struct dirent *di; DIR *d = opendir("."); di = readdir(d);
if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
di->d_name[0] == 0) exit(0); exit(1);} ],
rsync_cv_HAVE_BROKEN_READDIR=yes,rsync_cv_HAVE_BROKEN_READDIR=no,rsync_cv_HAVE_BROKEN_READDIR=cross)])
if test x"$rsync_cv_HAVE_BROKEN_READDIR" = x"yes"; then
AC_DEFINE(HAVE_BROKEN_READDIR)
fi
AC_CACHE_CHECK([for utimbuf],rsync_cv_HAVE_UTIMBUF,[
AC_TRY_COMPILE([#include <sys/types.h>
#include <utime.h>],
[struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));],
rsync_cv_HAVE_UTIMBUF=yes,rsync_cv_HAVE_UTIMBUF=no,rsync_cv_HAVE_UTIMBUF=cross)])
if test x"$rsync_cv_HAVE_UTIMBUF" = x"yes"; then
AC_DEFINE(HAVE_UTIMBUF)
fi
AC_CACHE_CHECK([if gettimeofday takes tz argument],rsync_cv_HAVE_GETTIMEOFDAY_TZ,[
AC_TRY_RUN([
#include <sys/time.h>
#include <unistd.h>
main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}],
rsync_cv_HAVE_GETTIMEOFDAY_TZ=yes,rsync_cv_HAVE_GETTIMEOFDAY_TZ=no,rsync_cv_HAVE_GETTIMEOFDAY_TZ=cross)])
if test x"$rsync_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
AC_DEFINE(HAVE_GETTIMEOFDAY_TZ)
fi
AC_CACHE_CHECK([for broken inet_ntoa],rsync_cv_REPLACE_INET_NTOA,[
AC_TRY_RUN([
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#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); }
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
AC_DEFINE(REPLACE_INET_NTOA)
fi
AC_CACHE_CHECK([for broken inet_aton],rsync_cv_REPLACE_INET_ATON,[
AC_TRY_RUN([
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
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
AC_DEFINE(REPLACE_INET_ATON)
fi
#
# The following test was mostly taken from the tcl/tk plus patches
#
echo $ac_n "checking whether -c -o works ... $ac_c"
AC_CACHE_CHECK([whether -c -o works],rsync_cv_DASHC_WORKS_WITH_DASHO,[
rm -rf conftest*
cat > conftest.$ac_ext <<EOF
int main() { return 0; }
EOF
${CC-cc} -c -o conftest..o conftest.$ac_ext
if test -f conftest..o; then
rsync_cv_DASHC_WORKS_WITH_DASHO=yes
else
rsync_cv_DASHC_WORKS_WITH_DASHO=no
fi
rm -rf conftest*
])
if test x"$rsync_cv_DASHC_WORKS_WITH_DASHO" = x"yes"; then
OBJ_SAVE="#"
OBJ_RESTORE="#"
CC_SHOBJ_FLAG='-o $@'
echo yes
else
OBJ_SAVE=' @b=`basename $@ .o`;rm -f $$b.o.sav;if test -f $$b.o; then mv $$b.o $$b.o.sav;fi;'
OBJ_RESTORE=' @b=`basename $@ .o`;if test "$$b.o" != "$@"; then mv $$b.o $@; if test -f $$b.o.sav; then mv $$b.o.sav $$b.o; fi; fi'
CC_SHOBJ_FLAG=""
echo no
fi
rm -rf conftest*
AC_SUBST(OBJ_SAVE)
AC_SUBST(OBJ_RESTORE)
AC_SUBST(CC_SHOBJ_FLAG)

132
exclude.c
View File

@@ -23,50 +23,10 @@
#include "rsync.h"
extern int verbose;
extern int delete_mode;
static struct exclude_struct **exclude_list;
/*
* Optimization for special case when all included files are explicitly
* listed without wildcards in the "exclude" list followed by a "- *"
* to exclude the rest.
* Contributed by Dave Dykstra <dwd@bell-labs.com>
*/
static int only_included_files = 1;
static struct exclude_struct *exclude_the_rest;
int send_included_file_names(int f,struct file_list *flist)
{
struct exclude_struct *ex, **ex_list;
int n;
char *p;
if (!only_included_files || (exclude_the_rest == NULL))
return 0;
if (verbose > 1) {
rprintf(FINFO,"(using include-only optimization) ");
}
/* set exclude_list to NULL temporarily so check_exclude */
/* will always return true */
ex_list = exclude_list;
exclude_list = NULL;
for (n=0; (ex = ex_list[n]) != NULL; n++) {
if (ex == exclude_the_rest)
break;
p = ex->pattern;
while (*p == '/') {
/* skip the allowed beginning slashes */
p++;
}
send_file_name(f,flist,p,0,0);
}
exclude_list = ex_list;
return 1;
}
/* build an exclude structure given a exclude pattern */
static struct exclude_struct *make_exclude(char *pattern, int include)
{
@@ -91,14 +51,18 @@ static struct exclude_struct *make_exclude(char *pattern, int include)
if (!ret->pattern) out_of_memory("make_exclude");
if (strpbrk(pattern, "*[?")) {
if (!ret->include && (*pattern == '*') && (*(pattern+1) == '\0')) {
exclude_the_rest = ret;
} else {
only_included_files = 0;
}
ret->regular_exp = 1;
} else if (!ret->include) {
only_included_files = 0;
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 (strlen(pattern) > 1 && pattern[strlen(pattern)-1] == '/') {
@@ -140,15 +104,17 @@ static int check_one_exclude(char *name,struct exclude_struct *ex,
}
if (ex->regular_exp) {
if (fnmatch(pattern, name, 0) == 0)
if (fnmatch(pattern, name, ex->fnmatch_flags) == 0) {
return 1;
}
} else {
int l1 = strlen(name);
int l2 = strlen(pattern);
if (l2 <= l1 &&
strcmp(name+(l1-l2),pattern) == 0 &&
(l1==l2 || (!match_start && name[l1-(l2+1)] == '/')))
(l1==l2 || (!match_start && name[l1-(l2+1)] == '/'))) {
return 1;
}
}
return 0;
@@ -194,8 +160,6 @@ void add_exclude_list(char *pattern,struct exclude_struct ***list, int include)
}
free((*list));
*list = NULL;
only_included_files = 1;
exclude_the_rest = NULL;
return;
}
@@ -234,7 +198,12 @@ struct exclude_struct **make_exclude_list(char *fname,
int l = strlen(line);
if (l && line[l-1] == '\n') l--;
line[l] = 0;
if (line[0]) add_exclude_list(line,&list,include);
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);
}
}
fclose(f);
return list;
@@ -260,8 +229,11 @@ void send_exclude_list(int f)
}
for (i=0;exclude_list[i];i++) {
char *pattern = exclude_list[i]->pattern;
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;
@@ -293,14 +265,62 @@ void recv_exclude_list(int f)
}
}
/* 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=strtok(p," "); tok; tok=strtok(NULL," "))
for (tok=get_exclude_tok(p); tok; tok=get_exclude_tok(NULL))
add_exclude(tok, 0);
free(p);
}
@@ -311,7 +331,7 @@ void add_include_line(char *p)
if (!p || !*p) return;
p = strdup(p);
if (!p) out_of_memory("add_include_line");
for (tok=strtok(p," "); tok; tok=strtok(NULL," "))
for (tok=get_exclude_tok(p); tok; tok=get_exclude_tok(NULL))
add_exclude(tok, 1);
free(p);
}

171
fileio.c
View File

@@ -49,8 +49,9 @@ static int write_sparse(int f,char *buf,int len)
if (l1 == len || l2 > 0)
last_sparse=1;
if (l1 > 0)
if (l1 > 0) {
do_lseek(f,l1,SEEK_CUR);
}
if (l1 == len)
return len;
@@ -72,8 +73,9 @@ int write_file(int f,char *buf,int len)
{
int ret = 0;
if (!sparse_files)
if (!sparse_files) {
return write(f,buf,len);
}
while (len>0) {
int len1 = MIN(len, SPARSE_WRITE_SIZE);
@@ -91,123 +93,116 @@ int write_file(int f,char *buf,int 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)
{
struct map_struct *ret;
ret = (struct map_struct *)malloc(sizeof(*ret));
if (!ret) out_of_memory("map_file");
struct map_struct *map;
map = (struct map_struct *)malloc(sizeof(*map));
if (!map) out_of_memory("map_file");
ret->map = NULL;
ret->fd = fd;
ret->size = len;
ret->p = NULL;
ret->p_size = 0;
ret->p_offset = 0;
ret->p_len = 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;
#ifdef USE_MMAP
len = MIN(len, MAX_MAP_SIZE);
ret->map = (char *)do_mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
if (ret->map == (char *)-1) {
ret->map = NULL;
} else {
ret->p_len = len;
}
#endif
return ret;
return map;
}
/* slide the read window in the file */
char *map_ptr(struct map_struct *map,OFF_T offset,int len)
{
int nread;
OFF_T window_start, read_start;
int window_size, read_size, read_offset;
if (len == 0)
if (len == 0) {
return NULL;
if (len > (map->size-offset))
len = map->size-offset;
#ifdef USE_MMAP
if (map->map) {
if (offset >= map->p_offset &&
offset+len <= map->p_offset+map->p_len) {
return (map->map + (offset - map->p_offset));
}
if (munmap(map->map, map->p_len) != 0) {
rprintf(FERROR,"munmap failed : %s\n", strerror(errno));
exit_cleanup(RERR_MALLOC);
}
/* align the mmap region on a nice boundary back a bit from
where it is asked for to allow for some seeking */
if (offset > 2*CHUNK_SIZE) {
map->p_offset = offset - 2*CHUNK_SIZE;
map->p_offset &= ~((OFF_T)(CHUNK_SIZE-1));
} else {
map->p_offset = 0;
}
/* map up to MAX_MAP_SIZE */
map->p_len = MAX(len, MAX_MAP_SIZE);
map->p_len = MIN(map->p_len, map->size - map->p_offset);
map->map = (char *)do_mmap(NULL,map->p_len,PROT_READ,
MAP_SHARED,map->fd,map->p_offset);
if (map->map == (char *)-1) {
map->map = NULL;
map->p_len = 0;
map->p_offset = 0;
} else {
return (map->map + (offset - map->p_offset));
}
}
#endif
/* can't go beyond the end of file */
if (len > (map->file_size - offset)) {
len = map->file_size - offset;
}
/* in most cases the region will already be available */
if (offset >= map->p_offset &&
offset+len <= map->p_offset+map->p_len) {
return (map->p + (offset - map->p_offset));
}
len = MAX(len,CHUNK_SIZE);
if (len > (map->size-offset))
len = map->size-offset;
if (len > map->p_size) {
if (map->p) free(map->p);
map->p = (char *)malloc(len);
/* 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;
if (window_start + window_size > map->file_size) {
window_size = map->file_size - window_start;
}
if (offset + len > window_start + window_size) {
window_size = (offset+len) - window_start;
}
/* 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_size = len;
map->p_size = window_size;
}
map->p_offset = offset;
map->p_len = len;
if (do_lseek(map->fd,offset,SEEK_SET) != offset) {
rprintf(FERROR,"lseek failed in map_ptr\n");
exit_cleanup(RERR_FILEIO);
/* now try to avoid re-reading any bytes by reusing any bytes from the previous
buffer. */
if (window_start >= map->p_offset &&
window_start < map->p_offset + map->p_len &&
window_start + window_size >= map->p_offset + map->p_len) {
read_start = map->p_offset + map->p_len;
read_offset = read_start - window_start;
read_size = window_size - read_offset;
memmove(map->p, map->p + (map->p_len - read_offset), read_offset);
} else {
read_start = window_start;
read_size = window_size;
read_offset = 0;
}
if ((nread=read(map->fd,map->p,len)) != len) {
if (nread < 0) nread = 0;
/* the best we can do is zero the buffer - the file
has changed mid transfer! */
memset(map->p+nread, 0, len - nread);
if (read_size <= 0) {
rprintf(FINFO,"Warning: unexpected read size of %d in map_ptr\n", read_size);
} else {
if (map->p_fd_offset != read_start) {
if (do_lseek(map->fd,read_start,SEEK_SET) != read_start) {
rprintf(FERROR,"lseek failed in map_ptr\n");
exit_cleanup(RERR_FILEIO);
}
map->p_fd_offset = read_start;
}
if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
if (nread < 0) nread = 0;
/* the best we can do is zero the buffer - the file
has changed mid transfer! */
memset(map->p+read_offset+nread, 0, read_size - nread);
}
map->p_fd_offset += nread;
}
map->p_offset = window_start;
map->p_len = window_size;
return map->p;
return map->p + (offset - map->p_offset);
}
void unmap_file(struct map_struct *map)
{
#ifdef USE_MMAP
if (map->map) {
munmap(map->map,map->p_len);
map->map = NULL;
}
#endif
if (map->p) {
free(map->p);
map->p = NULL;

250
flist.c
View File

@@ -23,8 +23,6 @@
extern struct stats stats;
extern int csum_length;
extern int verbose;
extern int am_server;
extern int always_checksum;
@@ -44,13 +42,69 @@ extern int preserve_gid;
extern int preserve_times;
extern int relative_paths;
extern int copy_links;
extern int copy_unsafe_links;
extern int remote_version;
extern int io_error;
extern int sanitize_paths;
static char topsrcname[MAXPATHLEN];
static struct exclude_struct **local_exclude_list;
static struct file_struct null_file;
static void clean_flist(struct file_list *flist, int strip_root);
struct string_area *string_area_new(int size)
{
struct string_area *a;
if (size <= 0) size = ARENA_SIZE;
a = malloc(sizeof(*a));
if (!a) out_of_memory("string_area_new");
a->current = a->base = malloc(size);
if (!a->current) out_of_memory("string_area_new buffer");
a->end = a->base + size;
a->next = 0;
return a;
}
void string_area_free(struct string_area *a)
{
struct string_area *next;
for ( ; a ; a = next) {
next = a->next;
free(a->base);
}
}
char *string_area_malloc(struct string_area **ap, int size)
{
char *p;
struct string_area *a;
/* does the request fit into the current space? */
a = *ap;
if (a->current + size >= a->end) {
/* no; get space, move new string_area to front of the list */
a = string_area_new(size > ARENA_SIZE ? size : ARENA_SIZE);
a->next = *ap;
*ap = a;
}
/* have space; do the "allocation." */
p = a->current;
a->current += size;
return p;
}
char *string_area_strdup(struct string_area **ap, const char *src)
{
char* dest = string_area_malloc(ap, strlen(src) + 1);
return strcpy(dest, src);
}
static void list_file_entry(struct file_struct *f)
{
@@ -85,6 +139,32 @@ static void list_file_entry(struct file_struct *f)
}
int readlink_stat(const char *Path, STRUCT_STAT *Buffer, char *Linkbuf)
{
#if SUPPORT_LINKS
if (copy_links) {
return do_stat(Path, Buffer);
}
if (do_lstat(Path, Buffer) == -1) {
return -1;
}
if (S_ISLNK(Buffer->st_mode)) {
int l;
if ((l = readlink(Path,Linkbuf,MAXPATHLEN-1)) == -1) {
return -1;
}
Linkbuf[l] = 0;
if (copy_unsafe_links && (topsrcname[0] != '\0') &&
unsafe_symlink(Linkbuf, topsrcname)) {
return do_stat(Path, Buffer);
}
}
return 0;
#else
return do_stat(Path, Buffer);
#endif
}
int link_stat(const char *Path, STRUCT_STAT *Buffer)
{
#if SUPPORT_LINKS
@@ -225,7 +305,11 @@ static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
#endif
if (always_checksum) {
write_buf(f,file->sum,csum_length);
if (remote_version < 21) {
write_buf(f,file->sum,2);
} else {
write_buf(f,file->sum,MD4_SUM_LENGTH);
}
}
last_mode = file->mode;
@@ -267,7 +351,11 @@ static void receive_file_entry(struct file_struct **fptr,
memset((char *)file, 0, sizeof(*file));
(*fptr) = file;
if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
if (l2 >= MAXPATHLEN-l1) {
rprintf(FERROR,"overflow: flags=0x%x l1=%d l2=%d lastname=%s\n",
flags, l1, l2, lastname);
overflow("receive_file_entry");
}
strlcpy(thisname,lastname,l1+1);
read_sbuf(f,&thisname[l1],l2);
@@ -278,6 +366,10 @@ static void receive_file_entry(struct file_struct **fptr,
clean_fname(thisname);
if (sanitize_paths) {
sanitize_path(thisname, NULL);
}
if ((p = strrchr(thisname,'/'))) {
static char *lastdir;
*p = 0;
@@ -312,6 +404,9 @@ static void receive_file_entry(struct file_struct **fptr,
file->link = (char *)malloc(l+1);
if (!file->link) out_of_memory("receive_file_entry 2");
read_sbuf(f,file->link,l);
if (sanitize_paths) {
sanitize_path(file->link, file->dirname);
}
}
#if SUPPORT_HARD_LINKS
@@ -324,7 +419,11 @@ static void receive_file_entry(struct file_struct **fptr,
if (always_checksum) {
file->sum = (char *)malloc(MD4_SUM_LENGTH);
if (!file->sum) out_of_memory("md4 sum");
read_buf(f,file->sum,csum_length);
if (remote_version < 21) {
read_buf(f,file->sum,2);
} else {
read_buf(f,file->sum,MD4_SUM_LENGTH);
}
}
last_mode = file->mode;
@@ -366,24 +465,33 @@ static int skip_filesystem(char *fname, STRUCT_STAT *st)
return (st2.st_dev != filesystem_dev);
}
static struct file_struct *make_file(char *fname)
#define STRDUP(ap, p) (ap ? string_area_strdup(ap, p) : strdup(p))
#define MALLOC(ap, i) (ap ? string_area_malloc(ap, i) : malloc(i))
/* create a file_struct for a named file */
struct file_struct *make_file(int f, char *fname, struct string_area **ap)
{
struct file_struct *file;
STRUCT_STAT st;
char sum[SUM_LENGTH];
char *p;
char cleaned_name[MAXPATHLEN];
char linkbuf[MAXPATHLEN];
extern int delete_excluded;
strlcpy(cleaned_name, fname, MAXPATHLEN);
cleaned_name[MAXPATHLEN-1] = 0;
clean_fname(cleaned_name);
if (sanitize_paths) {
sanitize_path(cleaned_name, NULL);
}
fname = cleaned_name;
memset(sum,0,SUM_LENGTH);
if (link_stat(fname,&st) != 0) {
if (readlink_stat(fname,&st,linkbuf) != 0) {
io_error = 1;
rprintf(FERROR,"%s: %s\n",
rprintf(FERROR,"readlink %s: %s\n",
fname,strerror(errno));
return NULL;
}
@@ -398,11 +506,12 @@ static struct file_struct *make_file(char *fname)
return NULL;
}
if (!match_file_name(fname,&st))
/* f is set to -1 when calculating deletion file list */
if (((f != -1) || !delete_excluded) && !match_file_name(fname,&st))
return NULL;
if (verbose > 2)
rprintf(FINFO,"make_file(%s)\n",fname);
rprintf(FINFO,"make_file(%d,%s)\n",f,fname);
file = (struct file_struct *)malloc(sizeof(*file));
if (!file) out_of_memory("make_file");
@@ -414,14 +523,14 @@ static struct file_struct *make_file(char *fname)
if (lastdir && strcmp(fname, lastdir)==0) {
file->dirname = lastdir;
} else {
file->dirname = strdup(fname);
file->dirname = STRDUP(ap, fname);
lastdir = file->dirname;
}
file->basename = strdup(p+1);
file->basename = STRDUP(ap, p+1);
*p = '/';
} else {
file->dirname = NULL;
file->basename = strdup(fname);
file->basename = STRDUP(ap, fname);
}
file->modtime = st.st_mtime;
@@ -437,21 +546,12 @@ static struct file_struct *make_file(char *fname)
#if SUPPORT_LINKS
if (S_ISLNK(st.st_mode)) {
int l;
char lnk[MAXPATHLEN];
if ((l=readlink(fname,lnk,MAXPATHLEN-1)) == -1) {
io_error=1;
rprintf(FERROR,"readlink %s : %s\n",
fname,strerror(errno));
return NULL;
}
lnk[l] = 0;
file->link = strdup(lnk);
file->link = STRDUP(ap, linkbuf);
}
#endif
if (always_checksum) {
file->sum = (char *)malloc(MD4_SUM_LENGTH);
file->sum = (char *)MALLOC(ap, MD4_SUM_LENGTH);
if (!file->sum) out_of_memory("md4 sum");
/* drat. we have to provide a null checksum for non-regular
files in order to be compatible with earlier versions
@@ -468,7 +568,7 @@ static struct file_struct *make_file(char *fname)
if (lastdir && strcmp(lastdir, flist_dir)==0) {
file->basedir = lastdir;
} else {
file->basedir = strdup(flist_dir);
file->basedir = STRDUP(ap, flist_dir);
lastdir = file->basedir;
}
} else {
@@ -488,7 +588,7 @@ void send_file_name(int f,struct file_list *flist,char *fname,
{
struct file_struct *file;
file = make_file(fname);
file = make_file(f,fname, &flist->string_area);
if (!file) return;
@@ -578,7 +678,6 @@ static void send_directory(int f,struct file_list *flist,char *dir)
}
struct file_list *send_file_list(int f,int argc,char *argv[])
{
int i,l;
@@ -595,33 +694,36 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
start_write = stats.total_written;
flist = (struct file_list *)malloc(sizeof(flist[0]));
if (!flist) out_of_memory("send_file_list");
flist->count=0;
flist->malloced = 1000;
flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
flist->malloced);
if (!flist->files) out_of_memory("send_file_list");
flist = flist_new();
if (f != -1) {
io_start_buffering(f);
}
for (i=0;i<argc;i++) {
char fname2[MAXPATHLEN];
char *fname = fname2;
char *fname = topsrcname;
strlcpy(fname,argv[i],MAXPATHLEN);
l = strlen(fname);
if (l != 1 && fname[l-1] == '/') {
strlcat(fname,".",MAXPATHLEN);
if ((l == 2) && (fname[0] == '.')) {
/* Turn ./ into just . rather than ./.
This was put in to avoid a problem with
rsync -aR --delete from ./
The send_file_name() below of ./ was
mysteriously preventing deletes */
fname[1] = 0;
} else {
strlcat(fname,".",MAXPATHLEN);
}
}
if (link_stat(fname,&st) != 0) {
io_error=1;
rprintf(FERROR,"%s : %s\n",fname,strerror(errno));
if (f != -1) {
io_error=1;
rprintf(FERROR,"link_stat %s : %s\n",fname,strerror(errno));
}
continue;
}
@@ -652,10 +754,17 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
*p = '/';
for (p=fname+1; (p=strchr(p,'/')); p++) {
int copy_links_saved = copy_links;
int recurse_saved = recurse;
*p = 0;
copy_links = 0;
copy_links = copy_unsafe_links;
/* set recurse to 1 to prevent make_file
from ignoring directory, but still
turn off the recursive parameter to
send_file_name */
recurse = 1;
send_file_name(f, flist, fname, 0, 0);
copy_links = copy_links_saved;
recurse = recurse_saved;
*p = '/';
}
} else {
@@ -682,8 +791,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
if (one_file_system)
set_filesystem(fname);
if (!recurse || !send_included_file_names(f,flist))
send_file_name(f,flist,fname,recurse,FLAG_DELETE);
send_file_name(f,flist,fname,recurse,FLAG_DELETE);
if (olddir != NULL) {
flist_dir = NULL;
@@ -695,6 +803,8 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
}
}
topsrcname[0] = '\0';
if (f != -1) {
send_file_entry(NULL,f,0);
}
@@ -712,7 +822,8 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
/* if protocol version is >= 17 then send the io_error flag */
if (f != -1 && remote_version >= 17) {
write_int(f, io_error);
extern int module_id;
write_int(f, lp_ignore_errors(module_id)? 0 : io_error);
}
if (f != -1) {
@@ -797,7 +908,13 @@ struct file_list *recv_file_list(int f)
/* if protocol version is >= 17 then recv the io_error flag */
if (f != -1 && remote_version >= 17) {
io_error |= read_int(f);
extern int module_id;
extern int ignore_errors;
if (lp_ignore_errors(module_id) || ignore_errors) {
read_int(f);
} else {
io_error |= read_int(f);
}
}
if (list_only) {
@@ -859,16 +976,38 @@ int flist_find(struct file_list *flist,struct file_struct *f)
/*
* free up one file
*/
static void free_file(struct file_struct *file)
void free_file(struct file_struct *file)
{
if (!file) return;
if (file->basename) free(file->basename);
if (file->link) free(file->link);
if (file->sum) free(file->sum);
memset((char *)file, 0, sizeof(*file));
*file = null_file;
}
/*
* allocate a new file list
*/
struct file_list *flist_new()
{
struct file_list *flist;
flist = (struct file_list *)malloc(sizeof(flist[0]));
if (!flist) out_of_memory("send_file_list");
flist->count=0;
flist->malloced = 1000;
flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
flist->malloced);
if (!flist->files) out_of_memory("send_file_list");
#if ARENA_SIZE > 0
flist->string_area = string_area_new(0);
#else
flist->string_area = 0;
#endif
return flist;
}
/*
* free up all elements in a flist
*/
@@ -876,11 +1015,14 @@ void flist_free(struct file_list *flist)
{
int i;
for (i=1;i<flist->count;i++) {
free_file(flist->files[i]);
if (!flist->string_area)
free_file(flist->files[i]);
free(flist->files[i]);
}
memset((char *)flist->files, 0, sizeof(flist->files[0])*flist->count);
free(flist->files);
if (flist->string_area)
string_area_free(flist->string_area);
memset((char *)flist, 0, sizeof(*flist));
free(flist);
}
@@ -909,7 +1051,13 @@ static void clean_flist(struct file_list *flist, int strip_root)
if (verbose > 1 && !am_server)
rprintf(FINFO,"removing duplicate name %s from file list %d\n",
f_name(flist->files[i-1]),i-1);
free_file(flist->files[i]);
/* it's not great that the flist knows the semantics of the
* file memory usage, but i'd rather not add a flag byte
* to that struct. XXX can i use a bit in the flags field? */
if (flist->string_area)
flist->files[i][0] = null_file;
else
free_file(flist->files[i]);
}
}
@@ -936,12 +1084,12 @@ static void clean_flist(struct file_list *flist, int strip_root)
if (verbose <= 3) return;
for (i=0;i<flist->count;i++) {
rprintf(FINFO,"[%d] i=%d %s %s mode=0%o len=%d\n",
rprintf(FINFO,"[%d] i=%d %s %s mode=0%o len=%.0f\n",
getpid(), i,
NS(flist->files[i]->dirname),
NS(flist->files[i]->basename),
flist->files[i]->mode,
(int)flist->files[i]->length);
(double)flist->files[i]->length);
}
}

View File

@@ -31,6 +31,7 @@ extern int whole_file;
extern int block_size;
extern int csum_length;
extern int ignore_times;
extern int size_only;
extern int io_timeout;
extern int remote_version;
extern int always_checksum;
@@ -49,7 +50,15 @@ static int skip_file(char *fname,
if (always_checksum && S_ISREG(st->st_mode)) {
char sum[MD4_SUM_LENGTH];
file_checksum(fname,sum,st->st_size);
return (memcmp(sum,file->sum,csum_length) == 0);
if (remote_version < 21) {
return (memcmp(sum,file->sum,2) == 0);
} else {
return (memcmp(sum,file->sum,MD4_SUM_LENGTH) == 0);
}
}
if (size_only) {
return 1;
}
if (ignore_times) {
@@ -81,17 +90,19 @@ static int adapt_block_size(struct file_struct *file, int bsize)
static void send_sums(struct sum_struct *s,int f_out)
{
int i;
/* tell the other guy how many we are going to be doing and how many
bytes there are in the last chunk */
/* 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?s->count:0);
write_int(f_out,s?s->n:block_size);
write_int(f_out,s?s->remainder:0);
if (s)
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);
}
if (!s) return;
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);
}
}
@@ -125,8 +136,8 @@ static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
}
if (verbose > 3)
rprintf(FINFO,"count=%d rem=%d n=%d flength=%d\n",
s->count,s->remainder,s->n,(int)s->flength);
rprintf(FINFO,"count=%d rem=%d n=%d flength=%.0f\n",
s->count,s->remainder,s->n,(double)s->flength);
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
if (!s->sums) out_of_memory("generate_sums");
@@ -143,8 +154,8 @@ static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
s->sums[i].i = i;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] offset=%d len=%d sum1=%08x\n",
i,(int)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
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);
len -= n1;
offset += n1;
@@ -166,6 +177,8 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
char fnamecmpbuf[MAXPATHLEN];
extern char *compare_dest;
extern int list_only;
extern int preserve_perms;
extern int only_existing;
if (list_only) return;
@@ -174,10 +187,25 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
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 %s\n",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);
}
if (S_ISDIR(file->mode)) {
if (dry_run) return;
if (statret == 0 && !S_ISDIR(st.st_mode)) {
if (do_unlink(fname) != 0) {
if (robust_unlink(fname) != 0) {
rprintf(FERROR,"unlink %s : %s\n",fname,strerror(errno));
return;
}
@@ -218,10 +246,10 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
return;
}
}
delete_file(fname);
}
delete_file(fname);
if (do_symlink(file->link,fname) != 0) {
rprintf(FERROR,"link %s -> %s : %s\n",
rprintf(FERROR,"symlink %s -> %s : %s\n",
fname,file->link,strerror(errno));
} else {
set_perms(fname,file,NULL,0);
@@ -312,7 +340,8 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
}
if (skip_file(fname, file, &st)) {
set_perms(fname,file,&st,1);
if (fnamecmp == fname)
set_perms(fname,file,&st,1);
return;
}
@@ -328,11 +357,13 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
}
/* open the file */
fd = open(fnamecmp,O_RDONLY);
fd = do_open(fnamecmp, O_RDONLY, 0);
if (fd == -1) {
rprintf(FERROR,"failed to open %s : %s\n",fnamecmp,strerror(errno));
rprintf(FERROR,"skipping %s\n",fname);
rprintf(FERROR,"failed to open %s, continuing : %s\n",fnamecmp,strerror(errno));
/* pretend the file didn't exist */
write_int(f_out,i);
send_sums(NULL,f_out);
return;
}
@@ -343,7 +374,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
}
if (verbose > 3)
rprintf(FINFO,"gen mapped %s of size %d\n",fnamecmp,(int)st.st_size);
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));

View File

@@ -120,7 +120,7 @@ static void hard_link_one(int i)
} else {
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino) return;
if (do_unlink(f_name(&hlink_list[i])) != 0 ||
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",

259
io.c
View File

@@ -18,7 +18,7 @@
*/
/*
Utilities used in rsync
socket and pipe IO utilities used in rsync
tridge, June 1996
*/
@@ -27,6 +27,8 @@
/* if no timeout is specified then use a 60 second select timeout */
#define SELECT_TIMEOUT 60
extern int bwlimit;
static int io_multiplexing_out;
static int io_multiplexing_in;
static int multiplex_in_fd;
@@ -38,6 +40,9 @@ extern int io_timeout;
extern struct stats stats;
static int buffer_f_in = -1;
static int io_error_fd = -1;
static void read_loop(int fd, char *buf, int len);
void setup_readbuffer(int f_in)
{
@@ -46,6 +51,7 @@ void setup_readbuffer(int f_in)
static void check_timeout(void)
{
extern int am_server, am_daemon;
time_t t;
if (!io_timeout) return;
@@ -58,19 +64,50 @@ static void check_timeout(void)
t = time(NULL);
if (last_io && io_timeout && (t-last_io) >= io_timeout) {
rprintf(FERROR,"io timeout after %d second - exiting\n",
(int)(t-last_io));
if (!am_server && !am_daemon) {
rprintf(FERROR,"io timeout after %d second - exiting\n",
(int)(t-last_io));
}
exit_cleanup(RERR_TIMEOUT);
}
}
/* setup the fd used to propogate errors */
void io_set_error_fd(int fd)
{
io_error_fd = fd;
}
/* read some data from the error fd and write it to the write log code */
static void read_error_fd(void)
{
char buf[200];
int n;
int fd = io_error_fd;
int tag, len;
io_error_fd = -1;
read_loop(fd, buf, 4);
tag = IVAL(buf, 0);
len = tag & 0xFFFFFF;
tag = tag >> 24;
tag -= MPLEX_BASE;
while (len) {
n = len;
if (n > (sizeof(buf)-1)) n = sizeof(buf)-1;
read_loop(fd, buf, n);
rwrite((enum logcode)tag, buf, n);
len -= n;
}
io_error_fd = fd;
}
static char *read_buffer;
static char *read_buffer_p;
static int read_buffer_len;
static int read_buffer_size;
static int no_flush;
static int no_flush_read;
/* read from a socket with IO timeout. return the number of
bytes read. If no bytes can be read then exit, never return
@@ -79,24 +116,39 @@ static int read_timeout(int fd, char *buf, int len)
{
int n, ret=0;
no_flush_read++;
io_flush();
no_flush_read--;
while (ret == 0) {
fd_set fds;
struct timeval tv;
int fd_count = fd+1;
FD_ZERO(&fds);
FD_SET(fd, &fds);
if (io_error_fd != -1) {
FD_SET(io_error_fd, &fds);
if (io_error_fd > fd) fd_count = io_error_fd+1;
}
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
tv.tv_usec = 0;
if (select(fd+1, &fds, NULL, NULL, &tv) != 1) {
errno = 0;
if (select(fd_count, &fds, NULL, NULL, &tv) < 1) {
if (errno == EBADF) {
exit_cleanup(RERR_SOCKETIO);
}
check_timeout();
continue;
}
if (io_error_fd != -1 && FD_ISSET(io_error_fd, &fds)) {
read_error_fd();
}
if (!FD_ISSET(fd, &fds)) continue;
n = read(fd, buf, len);
if (n > 0) {
@@ -113,14 +165,11 @@ static int read_timeout(int fd, char *buf, int len)
}
if (n == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK)) {
/* this shouldn't happen, if it does then
sleep for a short time to prevent us
chewing too much CPU */
u_sleep(100);
(errno == EWOULDBLOCK || errno == EAGAIN)) {
continue;
}
if (n == 0) {
if (eof_error) {
rprintf(FERROR,"unexpected EOF in read_timeout\n");
@@ -128,6 +177,9 @@ static int read_timeout(int fd, char *buf, int len)
exit_cleanup(RERR_STREAMIO);
}
/* this prevents us trying to write errors on a dead socket */
io_multiplexing_close();
rprintf(FERROR,"read error: %s\n", strerror(errno));
exit_cleanup(RERR_STREAMIO);
}
@@ -153,7 +205,6 @@ static void read_loop(int fd, char *buf, int len)
static int read_unbuffered(int fd, char *buf, int len)
{
static int remaining;
char ibuf[4];
int tag, ret=0;
char line[1024];
@@ -169,8 +220,8 @@ static int read_unbuffered(int fd, char *buf, int len)
continue;
}
read_loop(fd, ibuf, 4);
tag = IVAL(ibuf, 0);
read_loop(fd, line, 4);
tag = IVAL(line, 0);
remaining = tag & 0xFFFFFF;
tag = tag >> 24;
@@ -193,7 +244,7 @@ static int read_unbuffered(int fd, char *buf, int len)
read_loop(fd, line, remaining);
line[remaining] = 0;
rprintf(tag,"%s", line);
rprintf((enum logcode)tag,"%s", line);
remaining = 0;
}
@@ -201,40 +252,6 @@ static int read_unbuffered(int fd, char *buf, int len)
}
/* This function was added to overcome a deadlock problem when using
* ssh. It looks like we can't allow our receive queue to get full or
* ssh will clag up. Uggh. */
static void read_check(int f)
{
int n = 8192;
if (f == -1) return;
if (read_buffer_len == 0) {
read_buffer_p = read_buffer;
}
if (n > MAX_READ_BUFFER/4)
n = MAX_READ_BUFFER/4;
if (read_buffer_p != read_buffer) {
memmove(read_buffer,read_buffer_p,read_buffer_len);
read_buffer_p = read_buffer;
}
if (n > (read_buffer_size - read_buffer_len)) {
read_buffer_size += n;
read_buffer = (char *)Realloc(read_buffer,read_buffer_size);
if (!read_buffer) out_of_memory("read check");
read_buffer_p = read_buffer;
}
n = read_unbuffered(f,read_buffer+read_buffer_len,n);
read_buffer_len += n;
}
/* do a buffered read from fd. don't return until all N bytes
have been read. If all N can't be read then exit with an error */
static void readfd(int fd,char *buffer,int N)
@@ -242,23 +259,8 @@ static void readfd(int fd,char *buffer,int N)
int ret;
int total=0;
if ((read_buffer_len < N) && (N < 1024)) {
read_check(buffer_f_in);
}
while (total < N) {
if (read_buffer_len > 0 && buffer_f_in == fd) {
ret = MIN(read_buffer_len,N-total);
memcpy(buffer+total,read_buffer_p,ret);
read_buffer_p += ret;
read_buffer_len -= ret;
total += ret;
continue;
}
no_flush_read++;
io_flush();
no_flush_read--;
ret = read_unbuffered(fd,buffer + total,N-total);
total += ret;
@@ -332,8 +334,6 @@ static void writefd_unbuffered(int fd,char *buf,int len)
fd_set w_fds, r_fds;
int fd_count, count;
struct timeval tv;
int reading=0;
int blocked=0;
no_flush++;
@@ -341,46 +341,47 @@ static void writefd_unbuffered(int fd,char *buf,int len)
FD_ZERO(&w_fds);
FD_ZERO(&r_fds);
FD_SET(fd,&w_fds);
fd_count = fd+1;
fd_count = fd;
if (!no_flush_read) {
reading = (buffer_f_in != -1);
}
if (reading) {
FD_SET(buffer_f_in,&r_fds);
if (buffer_f_in > fd)
fd_count = buffer_f_in+1;
if (io_error_fd != -1) {
FD_SET(io_error_fd,&r_fds);
if (io_error_fd > fd_count)
fd_count = io_error_fd;
}
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
tv.tv_usec = 0;
count = select(fd_count,
reading?&r_fds:NULL,
errno = 0;
count = select(fd_count+1,
io_error_fd != -1?&r_fds:NULL,
&w_fds,NULL,
&tv);
if (count <= 0) {
if (errno == EBADF) {
exit_cleanup(RERR_SOCKETIO);
}
check_timeout();
continue;
}
if (reading && FD_ISSET(buffer_f_in, &r_fds)) {
read_check(buffer_f_in);
if (io_error_fd != -1 && FD_ISSET(io_error_fd, &r_fds)) {
read_error_fd();
}
if (FD_ISSET(fd, &w_fds)) {
int n = (len-total)>>blocked;
int ret = write(fd,buf+total,n?n:1);
int ret, n = len-total;
ret = write(fd,buf+total,n);
if (ret == -1 && errno == EINTR) {
continue;
}
if (ret == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK)) {
blocked++;
(errno == EWOULDBLOCK || errno == EAGAIN)) {
continue;
}
@@ -389,7 +390,19 @@ static void writefd_unbuffered(int fd,char *buf,int len)
exit_cleanup(RERR_STREAMIO);
}
blocked = 0;
/* Sleep after writing to limit I/O bandwidth */
if (bwlimit)
{
tv.tv_sec = 0;
tv.tv_usec = ret * 1000 / bwlimit;
while (tv.tv_usec > 1000000)
{
tv.tv_sec++;
tv.tv_usec -= 1000000;
}
select(0, NULL, NULL, NULL, &tv);
}
total += ret;
if (io_timeout)
@@ -408,22 +421,43 @@ void io_start_buffering(int fd)
{
if (io_buffer) return;
multiplex_out_fd = fd;
io_buffer = (char *)malloc(IO_BUFFER_SIZE+4);
io_buffer = (char *)malloc(IO_BUFFER_SIZE);
if (!io_buffer) out_of_memory("writefd");
io_buffer_count = 0;
/* leave room for the multiplex header in case it's needed */
io_buffer += 4;
}
/* write an message to a multiplexed stream. If this fails then rsync
exits */
static void mplex_write(int fd, enum logcode code, char *buf, int len)
{
char buffer[4096];
int n = len;
SIVAL(buffer, 0, ((MPLEX_BASE + (int)code)<<24) + len);
if (n > (sizeof(buffer)-4)) {
n = sizeof(buffer)-4;
}
memcpy(&buffer[4], buf, n);
writefd_unbuffered(fd, buffer, n+4);
len -= n;
buf += n;
if (len) {
writefd_unbuffered(fd, buf, len);
}
}
void io_flush(void)
{
int fd = multiplex_out_fd;
if (!io_buffer_count || no_flush) return;
if (io_multiplexing_out) {
SIVAL(io_buffer-4, 0, (MPLEX_BASE<<24) + io_buffer_count);
writefd_unbuffered(fd, io_buffer-4, io_buffer_count+4);
mplex_write(fd, FNONE, io_buffer, io_buffer_count);
} else {
writefd_unbuffered(fd, io_buffer, io_buffer_count);
}
@@ -434,7 +468,7 @@ void io_end_buffering(int fd)
{
io_flush();
if (!io_multiplexing_out) {
free(io_buffer-4);
free(io_buffer);
io_buffer = NULL;
}
}
@@ -443,7 +477,7 @@ static void writefd(int fd,char *buf,int len)
{
stats.total_written += len;
if (!io_buffer) {
if (!io_buffer || fd != multiplex_out_fd) {
writefd_unbuffered(fd, buf, len);
return;
}
@@ -561,31 +595,36 @@ void io_start_multiplex_in(int fd)
{
multiplex_in_fd = fd;
io_flush();
if (read_buffer_len) {
fprintf(stderr,"ERROR: data in read buffer at mplx start\n");
exit_cleanup(RERR_STREAMIO);
}
io_multiplexing_in = 1;
}
/* write an message to the error stream */
int io_multiplex_write(int f, char *buf, int len)
/* write an message to the multiplexed error stream */
int io_multiplex_write(enum logcode code, char *buf, int len)
{
if (!io_multiplexing_out) return 0;
io_flush();
SIVAL(io_buffer-4, 0, ((MPLEX_BASE + f)<<24) + len);
memcpy(io_buffer, buf, len);
stats.total_written += (len+4);
writefd_unbuffered(multiplex_out_fd, io_buffer-4, len+4);
mplex_write(multiplex_out_fd, code, buf, len);
return 1;
}
/* write a message to the special error fd */
int io_error_write(int f, enum logcode code, char *buf, int len)
{
if (f == -1) return 0;
mplex_write(f, code, buf, len);
return 1;
}
/* stop output multiplexing */
void io_multiplexing_close(void)
{
io_multiplexing_out = 0;
}
void io_close_input(int fd)
{
buffer_f_in = -1;
}

View File

@@ -46,7 +46,25 @@
#ifndef HAVE_WAITPID
pid_t waitpid(pid_t pid, int *statptr, int options)
{
#ifdef HAVE_WAIT4
return wait4(pid, statptr, options, NULL);
#else
/* If wait4 is also not available, try wait3 for SVR3 variants */
/* Less ideal because can't actually request a specific pid */
/* At least the WNOHANG option is supported */
/* Code borrowed from apache fragment written by dwd@bell-labs.com */
int tmp_pid, dummystat;;
if (kill(pid, 0) == -1) {
errno = ECHILD;
return -1;
}
if (statptr == NULL)
statptr = &dummystat;
while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
(tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
;
return tmp_pid;
#endif
}
#endif
@@ -54,7 +72,7 @@
#ifndef HAVE_MEMMOVE
void *memmove(void *dest, const void *src, size_t n)
{
memcpy(dest, src, n);
bcopy((char *) src, (char *) dest, n);
return dest;
}
#endif
@@ -77,21 +95,6 @@
}
#endif
#ifdef REPLACE_INET_NTOA
char *rep_inet_ntoa(struct in_addr ip)
{
unsigned char *p = (unsigned char *)&ip.s_addr;
static char buf[18];
#if WORDS_BIGENDIAN
slprintf(buf, 18, "%d.%d.%d.%d",
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
#else
slprintf(buf, 18, "%d.%d.%d.%d",
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
#endif
return buf;
}
#endif
#ifndef HAVE_STRLCPY
/* like strncpy but does not 0 fill the buffer and always null
@@ -127,3 +130,56 @@
return ret;
}
#endif
#ifdef REPLACE_INET_NTOA
char *rep_inet_ntoa(struct in_addr ip)
{
unsigned char *p = (unsigned char *)&ip.s_addr;
static char buf[18];
#if WORDS_BIGENDIAN
slprintf(buf, 18, "%d.%d.%d.%d",
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
#else
slprintf(buf, 18, "%d.%d.%d.%d",
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
#endif
return buf;
}
#endif
#ifdef REPLACE_INET_ATON
int inet_aton(const char *cp, struct in_addr *inp)
{
unsigned int a1, a2, a3, a4;
unsigned long ret;
if (strcmp(cp, "255.255.255.255") == 0) {
inp->s_addr = (unsigned) -1;
return 0;
}
if (sscanf(cp, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4 ||
a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) {
return 0;
}
ret = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4;
inp->s_addr = htonl(ret);
if (inp->s_addr == (unsigned) -1) {
return 0;
}
return 1;
}
#endif
/* some systems don't take the 2nd argument */
int sys_gettimeofday(struct timeval *tv)
{
#if HAVE_GETTIMEOFDAY_TZ
return gettimeofday(tv, NULL);
#else
return gettimeofday(tv);
#endif
}

View File

@@ -1,33 +1,60 @@
#include "../rsync.h"
#ifndef HAVE_FNMATCH
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
/* ----- THE FOLLOWING UP TO 'END' is glibc-2.1.2 posix/fnmatch.c
except for the parts with '#if 0' */
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU C Library.
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, or (at your option) any
later version.
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 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.
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 General Public License
along with this program; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
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 defined (STDC_HEADERS) || !defined (isascii)
#define ISASCII(c) 1
#else
#define ISASCII(c) isascii(c)
#if 0 /* header files included better by ../rsync.h */
#if HAVE_CONFIG_H
# include <config.h>
#endif
#define ISUPPER(c) (ISASCII (c) && isupper (c))
/* 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
@@ -37,23 +64,95 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
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 !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
extern int errno;
#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. */
int
fnmatch (pattern, string, flags)
const char *pattern;
const char *string;
int flags;
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 char c;
register unsigned char c;
/* Note that this evalutes C many times. */
#define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (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')
{
@@ -64,10 +163,11 @@ fnmatch (pattern, string, flags)
case '?':
if (*n == '\0')
return FNM_NOMATCH;
else if ((flags & FNM_FILE_NAME) && *n == '/')
else if (*n == '/' && (flags & FNM_FILE_NAME))
return FNM_NOMATCH;
else if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
else if (*n == '.' && no_leading_period
&& (n == string
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
return FNM_NOMATCH;
break;
@@ -75,95 +175,245 @@ fnmatch (pattern, string, flags)
if (!(flags & FNM_NOESCAPE))
{
c = *p++;
if (c == '\0')
/* Trailing \ loses. */
return FNM_NOMATCH;
c = FOLD (c);
}
if (FOLD (*n) != c)
if (FOLD ((unsigned char) *n) != c)
return FNM_NOMATCH;
break;
case '*':
if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
if (*n == '.' && no_leading_period
&& (n == string
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
if (((flags & FNM_FILE_NAME) && *n == '/') ||
(c == '?' && *n == '\0'))
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')
return 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;
{
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
c1 = FOLD (c1);
for (--p; *n != '\0'; ++n)
if ((c == '[' || FOLD (*n) == c1) &&
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
return 0;
return FNM_NOMATCH;
}
#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 ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
if (*n == '.' && no_leading_period && (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME))))
return FNM_NOMATCH;
not = (*p == '!' || *p == '^');
if (*n == '/' && (flags & FNM_FILE_NAME))
/* `/' cannot be matched. */
return FNM_NOMATCH;
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
if (not)
++p;
c = *p++;
for (;;)
{
register char cstart = c, cend = c;
unsigned char fn = FOLD ((unsigned char) *n);
if (!(flags & FNM_NOESCAPE) && c == '\\')
cstart = cend = *p++;
{
if (*p == '\0')
return FNM_NOMATCH;
c = FOLD ((unsigned char) *p);
++p;
cstart = cend = FOLD (cstart);
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;
if (c == '\0')
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;
c = *p++;
c = FOLD (c);
if ((flags & FNM_FILE_NAME) && c == '/')
/* [/] can never match. */
return FNM_NOMATCH;
if (c == '-' && *p != ']')
else
{
cend = *p++;
if (!(flags & FNM_NOESCAPE) && cend == '\\')
cend = *p++;
if (cend == '\0')
return FNM_NOMATCH;
cend = FOLD (cend);
normal_bracket:
if (FOLD (c) == fn)
goto matched;
cold = c;
c = *p++;
}
if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
goto matched;
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:;
matched:
/* Skip the rest of the [...] that already matched. */
while (c != ']')
{
@@ -173,8 +423,21 @@ fnmatch (pattern, string, flags)
c = *p++;
if (!(flags & FNM_NOESCAPE) && c == '\\')
/* XXX 1003.2d11 is unclear if this is right. */
++p;
{
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;
@@ -182,7 +445,7 @@ fnmatch (pattern, string, flags)
break;
default:
if (c != FOLD (*n))
if (c != FOLD ((unsigned char) *n))
return FNM_NOMATCH;
}
@@ -197,8 +460,23 @@ fnmatch (pattern, string, flags)
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,41 +1,48 @@
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
NOTE: The canonical source of this file is maintained with the GNU C Library.
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
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.
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, 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.
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
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__)
#undef __P
#define __P(protos) protos
#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) ()
# 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>. */
@@ -48,18 +55,30 @@ extern "C" {
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
#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,
extern int fnmatch __P ((__const char *__pattern, __const char *__string,
int __flags));
#ifdef __cplusplus

View File

@@ -37,9 +37,9 @@ static struct mdfour *m;
#define lshift(x,s) (((x)<<(s)) | ((x)>>(32-(s))))
#endif
#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s)
#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + 0x5A827999,s)
#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + 0x6ED9EBA1,s)
#define ROUND1(a,b,c,d,k,s) a = lshift((uint32)(a + F(b,c,d) + X[k]), s)
#define ROUND2(a,b,c,d,k,s) a = lshift((uint32)(a + G(b,c,d) + X[k] + 0x5A827999),s)
#define ROUND3(a,b,c,d,k,s) a = lshift((uint32)(a + H(b,c,d) + X[k] + 0x6ED9EBA1),s)
/* this applies md4 to 64 byte chunks */
static void mdfour64(uint32 *M)

View File

@@ -44,9 +44,6 @@
*/
#include "rsync.h"
#define BOOL int
#define False 0
#define True 1
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
#define strequal(a,b) (strcasecmp(a,b)==0)
#define BOOLSTR(b) ((b) ? "Yes" : "No")
@@ -97,11 +94,9 @@ static BOOL bLoaded = False;
typedef struct
{
char *motd_file;
char *lock_file;
char *log_file;
char *pid_file;
int syslog_facility;
int max_connections;
char *socket_options;
} global;
@@ -117,16 +112,19 @@ typedef struct
char *name;
char *path;
char *comment;
char *lock_file;
BOOL read_only;
BOOL list;
BOOL use_chroot;
BOOL transfer_logging;
BOOL ignore_errors;
char *uid;
char *gid;
char *hosts_allow;
char *hosts_deny;
char *auth_users;
char *secrets_file;
BOOL strict_modes;
char *exclude;
char *exclude_from;
char *include;
@@ -135,6 +133,7 @@ typedef struct
char *refuse_options;
char *dont_compress;
int timeout;
int max_connections;
} service;
@@ -144,24 +143,28 @@ static service sDefault =
NULL, /* name */
NULL, /* path */
NULL, /* comment */
DEFAULT_LOCK_FILE, /* lock file */
True, /* read only */
True, /* list */
True, /* use chroot */
False, /* transfer logging */
False, /* ignore errors */
"nobody",/* uid */
"nobody",/* gid */
NULL, /* hosts allow */
NULL, /* hosts deny */
NULL, /* auth users */
NULL, /* secrets file */
True, /* strict modes */
NULL, /* exclude */
NULL, /* exclude from */
NULL, /* include */
NULL, /* include from */
"%o %h [%a] %m (%u) %f %l", /* log format */
NULL, /* refuse options */
"*.gz *.tgz *.zip *.z *.rpm *.deb", /* dont compress */
0 /* timeout */
"*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */
0, /* timeout */
0 /* max connections */
};
@@ -244,17 +247,17 @@ static struct enum_list enum_facilities[] = {
/* note that we do not initialise the defaults union - it is not allowed in ANSI C */
static struct parm_struct parm_table[] =
{
{"max connections", P_INTEGER, P_GLOBAL, &Globals.max_connections,NULL, 0},
{"motd file", P_STRING, P_GLOBAL, &Globals.motd_file, NULL, 0},
{"lock file", P_STRING, P_GLOBAL, &Globals.lock_file, NULL, 0},
{"syslog facility", P_ENUM, P_GLOBAL, &Globals.syslog_facility, enum_facilities,0},
{"socket options", P_STRING, P_GLOBAL, &Globals.socket_options,NULL, 0},
{"log file", P_STRING, P_GLOBAL, &Globals.log_file, NULL, 0},
{"pid file", P_STRING, P_GLOBAL, &Globals.pid_file, NULL, 0},
{"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},
{"read only", P_BOOL, P_LOCAL, &sDefault.read_only, NULL, 0},
{"list", P_BOOL, P_LOCAL, &sDefault.list, NULL, 0},
@@ -265,11 +268,13 @@ static struct parm_struct parm_table[] =
{"hosts deny", P_STRING, P_LOCAL, &sDefault.hosts_deny, NULL, 0},
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL, 0},
{"secrets file", P_STRING, P_LOCAL, &sDefault.secrets_file,NULL, 0},
{"strict modes", P_BOOL, P_LOCAL, &sDefault.strict_modes,NULL, 0},
{"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL, 0},
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from,NULL, 0},
{"include", P_STRING, P_LOCAL, &sDefault.include, NULL, 0},
{"include from", P_STRING, P_LOCAL, &sDefault.include_from,NULL, 0},
{"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging,NULL,0},
{"ignore errors", P_BOOL, P_LOCAL, &sDefault.ignore_errors,NULL,0},
{"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0},
{"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0},
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress,NULL, 0},
@@ -286,7 +291,6 @@ static void init_globals(void)
#ifdef LOG_DAEMON
Globals.syslog_facility = LOG_DAEMON;
#endif
Globals.lock_file = "/var/run/rsyncd.lock";
}
/***************************************************************************
@@ -322,26 +326,27 @@ static void init_locals(void)
FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
FN_GLOBAL_STRING(lp_lock_file, &Globals.lock_file)
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_max_connections, &Globals.max_connections)
FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility)
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_list, list)
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
FN_LOCAL_STRING(lp_uid, uid)
FN_LOCAL_STRING(lp_gid, gid)
FN_LOCAL_STRING(lp_hosts_allow, hosts_allow)
FN_LOCAL_STRING(lp_hosts_deny, hosts_deny)
FN_LOCAL_STRING(lp_auth_users, auth_users)
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
FN_LOCAL_STRING(lp_exclude, exclude)
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
FN_LOCAL_STRING(lp_include, include)
@@ -350,6 +355,7 @@ FN_LOCAL_STRING(lp_log_format, log_format)
FN_LOCAL_STRING(lp_refuse_options, refuse_options)
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
FN_LOCAL_INTEGER(lp_timeout, timeout)
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
/* local prototypes */
static int strwicmp( char *psz1, char *psz2 );

82
log.c
View File

@@ -24,7 +24,7 @@
#include "rsync.h"
static FILE *logfile;
static int log_error_fd = -1;
static void logit(int priority, char *buf)
{
@@ -77,57 +77,66 @@ void log_open(void)
logit(LOG_INFO,"rsyncd started\n");
#endif
}
/* this is the rsync debugging function. Call it with FINFO, FERROR or FLOG */
void rprintf(int fd, const char *format, ...)
/* 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;
}
/* this is the underlying (unformatted) rsync debugging function. Call
it with FINFO, FERROR or FLOG */
void rwrite(enum logcode code, char *buf, int len)
{
va_list ap;
char buf[1024];
int len;
FILE *f=NULL;
extern int am_daemon;
extern int am_server;
extern int quiet;
/* recursion can happen with certain fatal conditions */
va_start(ap, format);
len = vslprintf(buf, sizeof(buf), format, ap);
va_end(ap);
if (quiet && code == FINFO) return;
if (len < 0) exit_cleanup(RERR_MESSAGEIO);
if (len > sizeof(buf)-1) exit_cleanup(RERR_MESSAGEIO);
buf[len] = 0;
if (fd == FLOG) {
if (code == FLOG) {
if (am_daemon) logit(LOG_INFO, buf);
return;
}
/* first try to pass it off the our sibling */
if (am_server && io_error_write(log_error_fd, code, buf, len)) {
return;
}
/* then try to pass it to the other end */
if (am_server && io_multiplex_write(code, buf, len)) {
return;
}
if (am_daemon) {
static int depth;
int priority = LOG_INFO;
if (fd == FERROR) priority = LOG_WARNING;
if (code == FERROR) priority = LOG_WARNING;
if (depth) return;
depth++;
log_open();
if (!io_multiplex_write(fd, buf, strlen(buf))) {
logit(priority, buf);
}
logit(priority, buf);
depth--;
return;
}
if (fd == FERROR) {
if (code == FERROR) {
f = stderr;
}
if (fd == FINFO) {
extern int am_server;
if (code == FINFO) {
if (am_server)
f = stderr;
else
@@ -140,8 +149,25 @@ void log_open(void)
if (buf[len-1] == '\r' || buf[len-1] == '\n') fflush(f);
}
void rflush(int fd)
/* this is the rsync debugging function. Call it with FINFO, FERROR or FLOG */
void rprintf(enum logcode code, const char *format, ...)
{
va_list ap;
char buf[1024];
int len;
va_start(ap, format);
len = vslprintf(buf, sizeof(buf), format, ap);
va_end(ap);
if (len > sizeof(buf)-1) exit_cleanup(RERR_MESSAGEIO);
rwrite(code, buf, len);
}
void rflush(enum logcode code)
{
FILE *f = NULL;
extern int am_daemon;
@@ -150,15 +176,15 @@ void rflush(int fd)
return;
}
if (fd == FLOG) {
if (code == FLOG) {
return;
}
if (fd == FERROR) {
if (code == FERROR) {
f = stderr;
}
if (fd == FINFO) {
if (code == FINFO) {
extern int am_server;
if (am_server)
f = stderr;
@@ -174,7 +200,7 @@ void rflush(int fd)
/* a generic logging routine for send/recv, with parameter
substitiution */
static void log_formatted(int fd,
static void log_formatted(enum logcode code,
char *format, char *op, struct file_struct *file,
struct stats *initial_stats)
{
@@ -264,7 +290,7 @@ static void log_formatted(int fd,
s = p+l;
}
rprintf(fd,"%s\n", buf);
rprintf(code,"%s\n", buf);
}
/* log the outgoing transfer of a file */
@@ -289,9 +315,9 @@ void log_recv(struct file_struct *file, struct stats *initial_stats)
extern char *log_format;
if (lp_transfer_logging(module_id)) {
log_formatted(FLOG, lp_log_format(module_id), "send", file, initial_stats);
log_formatted(FLOG, lp_log_format(module_id), "recv", file, initial_stats);
} else if (log_format && !am_server) {
log_formatted(FINFO, log_format, "send", file, initial_stats);
log_formatted(FINFO, log_format, "recv", file, initial_stats);
}
}

191
main.c
View File

@@ -23,8 +23,6 @@ time_t starttime = 0;
struct stats stats;
extern int csum_length;
extern int verbose;
static void report(int f)
@@ -34,32 +32,46 @@ static void report(int f)
extern int am_sender;
extern int am_daemon;
extern int do_stats;
extern int remote_version;
int send_stats;
if (am_daemon) {
log_exit(0, __FILE__, __LINE__);
if (f == -1 || !am_sender) return;
}
if (!verbose) return;
if (am_server && !am_sender) return;
if (am_server && am_sender) {
write_longint(f,stats.total_read);
write_longint(f,stats.total_written);
write_longint(f,stats.total_size);
send_stats = verbose || (remote_version >= 20);
if (am_server) {
if (am_sender && send_stats) {
int64 w;
/* store total_written in a temporary
because write_longint changes it */
w = stats.total_written;
write_longint(f,stats.total_read);
write_longint(f,w);
write_longint(f,stats.total_size);
}
return;
}
if (!am_sender) {
/* this is the client */
if (!am_sender && send_stats) {
int64 r;
stats.total_written = read_longint(f);
/* store total_read in a temporary, read_longint changes it */
r = read_longint(f);
stats.total_size = read_longint(f);
stats.total_read = r;
}
if (do_stats) {
if (!am_sender && !send_stats) {
/* missing the bytes written by the generator */
rprintf(FINFO, "\nCannot show stats as receiver because remote protocol version is less than 20\n");
rprintf(FINFO, "Use --stats -v to show stats\n");
return;
}
rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
rprintf(FINFO,"Number of files transferred: %d\n",
stats.num_transferred_files);
@@ -78,13 +90,15 @@ static void report(int f)
(double)stats.total_read);
}
rprintf(FINFO,"wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
(double)stats.total_written,
(double)stats.total_read,
(stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
rprintf(FINFO,"total size is %.0f speedup is %.2f\n",
(double)stats.total_size,
(1.0*stats.total_size)/(stats.total_written+stats.total_read));
if (verbose || do_stats) {
rprintf(FINFO,"wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
(double)stats.total_written,
(double)stats.total_read,
(stats.total_written+stats.total_read)/(0.5 + (t-starttime)));
rprintf(FINFO,"total size is %.0f speedup is %.2f\n",
(double)stats.total_size,
(1.0*stats.total_size)/(stats.total_written+stats.total_read));
}
fflush(stdout);
fflush(stderr);
@@ -98,6 +112,7 @@ static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f
char *tok,*dir=NULL;
extern int local_server;
extern char *rsync_path;
extern int blocking_io;
if (!local_server) {
if (!cmd)
@@ -130,6 +145,9 @@ static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f
args[argc++] = rsync_path;
server_options(args,&argc);
if (strcmp(cmd, RSYNC_RSH) == 0) blocking_io = 1;
}
args[argc++] = ".";
@@ -171,7 +189,10 @@ static char *get_local_name(struct file_list *flist,char *name)
if (verbose > 2)
rprintf(FINFO,"get_local_name count=%d %s\n",
flist->count, name);
flist->count, NS(name));
if (!name)
return NULL;
if (do_stat(name,&st) == 0) {
if (S_ISDIR(st.st_mode)) {
@@ -189,12 +210,9 @@ static char *get_local_name(struct file_list *flist,char *name)
return name;
}
if (flist->count == 1)
if (flist->count <= 1)
return name;
if (!name)
return NULL;
if (do_mkdir(name,0777 & ~orig_umask) != 0) {
rprintf(FERROR,"mkdir %s : %s (1)\n",name,strerror(errno));
exit_cleanup(RERR_FILEIO);
@@ -222,6 +240,7 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
char *dir = argv[0];
extern int relative_paths;
extern int recurse;
extern int remote_version;
if (verbose > 2)
rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
@@ -247,17 +266,18 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
argv[0] = ".";
}
set_nonblocking(f_out);
if (f_in != f_out)
set_nonblocking(f_in);
flist = send_file_list(f_out,argc,argv);
if (!flist || flist->count == 0) {
exit_cleanup(0);
}
send_files(flist,f_out,f_in);
io_flush();
report(f_out);
if (remote_version >= 24) {
/* final goodbye message */
read_int(f_in);
}
io_flush();
exit_cleanup(0);
}
@@ -268,45 +288,80 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
int pid;
int status=0;
int recv_pipe[2];
int error_pipe[2];
extern int preserve_hard_links;
extern int delete_after;
extern int recurse;
extern int delete_mode;
extern int remote_version;
if (preserve_hard_links)
init_hard_links(flist);
if (pipe(recv_pipe) < 0) {
if (!delete_after) {
/* I moved this here from recv_files() to prevent a race condition */
if (recurse && delete_mode && !local_name && flist->count>0) {
delete_files(flist);
}
}
if (fd_pair(recv_pipe) < 0) {
rprintf(FERROR,"pipe failed in do_recv\n");
exit_cleanup(RERR_SOCKETIO);
}
if (fd_pair(error_pipe) < 0) {
rprintf(FERROR,"error pipe failed in do_recv\n");
exit_cleanup(RERR_SOCKETIO);
}
io_flush();
if ((pid=do_fork()) == 0) {
close(recv_pipe[0]);
close(error_pipe[0]);
if (f_in != f_out) close(f_out);
set_nonblocking(f_in);
set_nonblocking(recv_pipe[1]);
/* we can't let two processes write to the socket at one time */
io_multiplexing_close();
/* set place to send errors */
set_error_fd(error_pipe[1]);
recv_files(f_in,flist,local_name,recv_pipe[1]);
io_flush();
report(f_in);
write_int(recv_pipe[1],1);
close(recv_pipe[1]);
io_flush();
_exit(0);
/* finally we go to sleep until our parent kills us
with a USR2 signal. We sleepp for a short time as on
some OSes a signal won't interrupt a sleep! */
while (1) sleep(1);
}
close(recv_pipe[1]);
close(error_pipe[1]);
io_close_input(f_in);
if (f_in != f_out) close(f_in);
set_nonblocking(f_out);
set_nonblocking(recv_pipe[0]);
io_start_buffering(f_out);
io_set_error_fd(error_pipe[0]);
generate_files(f_out,flist,local_name,recv_pipe[0]);
read_int(recv_pipe[0]);
close(recv_pipe[0]);
if (remote_version >= 24) {
/* send a final goodbye message */
write_int(f_out, -1);
}
io_flush();
waitpid(pid, &status, 0);
kill(pid, SIGUSR2);
wait_process(pid, &status);
return status;
}
@@ -318,10 +373,20 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
char *local_name=NULL;
char *dir = NULL;
extern int delete_mode;
extern int delete_excluded;
extern int am_daemon;
extern int module_id;
extern int am_sender;
if (verbose > 2)
rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
if (am_daemon && lp_read_only(module_id) && !am_sender) {
rprintf(FERROR,"ERROR: module is read only\n");
exit_cleanup(RERR_SYNTAX);
return;
}
if (argc > 0) {
dir = argv[0];
@@ -334,12 +399,12 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
}
}
if (delete_mode)
if (delete_mode && !delete_excluded)
recv_exclude_list(f_in);
flist = recv_file_list(f_in);
if (!flist || flist->count == 0) {
rprintf(FERROR,"server_recv: nothing to do\n");
if (!flist) {
rprintf(FERROR,"server_recv: recv_file_list error\n");
exit_cleanup(RERR_FILESELECT);
}
@@ -360,13 +425,16 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
{
extern int cvs_exclude;
extern int am_sender;
extern int remote_version;
set_nonblocking(f_out);
if (f_in != f_out)
set_nonblocking(f_in);
setup_protocol(f_out, f_in);
set_nonblocking(f_in);
set_nonblocking(f_out);
if (remote_version >= 23)
io_start_multiplex_out(f_out);
if (am_sender) {
recv_exclude_list(f_in);
if (cvs_exclude)
@@ -385,30 +453,38 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
char *local_name = NULL;
extern int am_sender;
extern int list_only;
extern int remote_version;
set_nonblocking(f_in);
set_nonblocking(f_out);
setup_protocol(f_out,f_in);
if (remote_version >= 23)
io_start_multiplex_in(f_in);
if (am_sender) {
extern int cvs_exclude;
extern int delete_mode;
extern int delete_excluded;
if (cvs_exclude)
add_cvs_excludes();
if (delete_mode)
if (delete_mode && !delete_excluded)
send_exclude_list(f_out);
flist = send_file_list(f_out,argc,argv);
if (verbose > 3)
rprintf(FINFO,"file list sent\n");
set_nonblocking(f_out);
if (f_in != f_out)
set_nonblocking(f_in);
send_files(flist,f_out,f_in);
if (pid != -1) {
if (verbose > 3)
rprintf(FINFO,"client_run waiting on %d\n",pid);
io_flush();
waitpid(pid, &status, 0);
wait_process(pid, &status);
}
if (remote_version >= 24) {
/* final goodbye message */
read_int(f_in);
}
report(-1);
exit_cleanup(status);
@@ -432,7 +508,7 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
if (verbose > 3)
rprintf(FINFO,"client_run2 waiting on %d\n",pid);
io_flush();
waitpid(pid, &status, 0);
wait_process(pid, &status);
}
return status | status2;
@@ -568,6 +644,10 @@ static RETSIGTYPE sigusr1_handler(int val) {
exit_cleanup(RERR_SIGNAL);
}
static RETSIGTYPE sigusr2_handler(int val) {
_exit(0);
}
int main(int argc,char *argv[])
{
extern int am_root;
@@ -577,6 +657,7 @@ int main(int argc,char *argv[])
extern int am_server;
signal(SIGUSR1, sigusr1_handler);
signal(SIGUSR2, sigusr2_handler);
starttime = time(NULL);
am_root = (getuid() == 0);
@@ -592,7 +673,7 @@ int main(int argc,char *argv[])
carried across */
orig_umask = (int)umask(0);
if (!parse_arguments(argc, argv)) {
if (!parse_arguments(argc, argv, 1)) {
exit_cleanup(RERR_SYNTAX);
}
@@ -606,6 +687,12 @@ int main(int argc,char *argv[])
signal(SIGHUP,SIGNAL_CAST sig_int);
signal(SIGTERM,SIGNAL_CAST sig_int);
/* Initialize push_dir here because on some old systems getcwd
(implemented by forking "pwd" and reading its output) doesn't
work when there are other child processes. Also, on all systems
that implement getcwd that way "pwd" can't be found after chroot. */
push_dir(NULL,0);
if (am_daemon) {
return daemon_main();
}
@@ -626,6 +713,8 @@ int main(int argc,char *argv[])
#endif
if (am_server) {
set_nonblocking(STDIN_FILENO);
set_nonblocking(STDOUT_FILENO);
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
}

55
match.c
View File

@@ -97,8 +97,8 @@ 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 %d last_match=%d j=%d len=%d n=%d\n",
(int)offset,(int)last_match,i,(int)s->sums[i].len,(int)n);
rprintf(FINFO,"match at %.0f last_match=%.0f j=%d len=%d 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);
data_transfer += n;
@@ -119,25 +119,29 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
else
last_match = offset;
if (buf)
show_progress(last_match, buf->size);
if (buf) {
show_progress(last_match, buf->file_size);
if (i == -1) end_progress();
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)
{
OFF_T offset;
int j,k;
int end;
OFF_T offset, end;
int j,k, last_i;
char sum2[SUM_LENGTH];
uint32 s1, s2, sum;
schar *map;
/* last_i is used to encourage adjacent matches, allowing the RLL coding of the
output to work more efficiently */
last_i = -1;
if (verbose > 2)
rprintf(FINFO,"hash search b=%d len=%d\n",s->n,(int)len);
rprintf(FINFO,"hash search b=%d len=%.0f\n",s->n,(double)len);
k = MIN(len, s->n);
@@ -154,8 +158,8 @@ static void hash_search(int f,struct sum_struct *s,
end = len + 1 - s->sums[s->count-1].len;
if (verbose > 3)
rprintf(FINFO,"hash search s->n=%d len=%d count=%d\n",
s->n,(int)len,s->count);
rprintf(FINFO,"hash search s->n=%d len=%.0f count=%d\n",
s->n,(double)len,s->count);
do {
tag t = gettag2(s1,s2);
@@ -163,7 +167,7 @@ static void hash_search(int f,struct sum_struct *s,
j = tag_table[t];
if (verbose > 4)
rprintf(FINFO,"offset=%d sum=%08x\n",(int)offset,sum);
rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
if (j == NULL_TAG) {
goto null_tag;
@@ -172,16 +176,19 @@ static void hash_search(int f,struct sum_struct *s,
sum = (s1 & 0xffff) | (s2 << 16);
tag_hits++;
for (; j<s->count && targets[j].t == t; j++) {
int i = targets[j].i;
int l, 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;
if (verbose > 3)
rprintf(FINFO,"potential match at %d target=%d %d sum=%08x\n",
(int)offset,j,i,sum);
rprintf(FINFO,"potential match at %.0f target=%d %d sum=%08x\n",
(double)offset,j,i,sum);
if (!done_csum2) {
int l = MIN(s->n,len-offset);
map = (schar *)map_ptr(buf,offset,l);
get_checksum2((char *)map,l,sum2);
done_csum2 = 1;
@@ -191,6 +198,22 @@ static void hash_search(int f,struct sum_struct *s,
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<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;
}
}
last_i = i;
matched(f,s,buf,offset,i);
offset += s->sums[i].len - 1;

263
md4.c
View File

@@ -1,263 +0,0 @@
/*
This code is from rfc1186.
It has been modified to use the SIVAL() macro to make it
byte order and length independent, so we don't need the LOWBYTEFIRST define
*/
/*
** ********************************************************************
** md4.c -- Implementation of MD4 Message Digest Algorithm **
** Updated: 2/16/90 by Ronald L. Rivest **
** (C) 1990 RSA Data Security, Inc. **
** ********************************************************************
*/
/*
** To use MD4:
** -- Include md4.h in your program
** -- Declare an MDstruct MD to hold the state of the digest
** computation.
** -- Initialize MD using MDbegin(&MD)
** -- For each full block (64 bytes) X you wish to process, call
** MDupdate(&MD,X,512)
** (512 is the number of bits in a full block.)
** -- For the last block (less than 64 bytes) you wish to process,
** MDupdate(&MD,X,n)
** where n is the number of bits in the partial block. A partial
** block terminates the computation, so every MD computation
** should terminate by processing a partial block, even if it
** has n = 0.
** -- The message digest is available in MD.buffer[0] ...
** MD.buffer[3]. (Least-significant byte of each word
** should be output first.)
** -- You can print out the digest using MDprint(&MD)
*/
#define TRUE 1
#define FALSE 0
/* Compile-time includes
*/
#include "rsync.h"
/* Compile-time declarations of MD4 "magic constants".
*/
#define I0 0x67452301 /* Initial values for MD buffer */
#define I1 0xefcdab89
#define I2 0x98badcfe
#define I3 0x10325476
#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
** Table 2, page 660.
*/
#define fs1 3 /* round 1 shift amounts */
#define fs2 7
#define fs3 11
#define fs4 19
#define gs1 3 /* round 2 shift amounts */
#define gs2 5
#define gs3 9
#define gs4 13
#define hs1 3 /* round 3 shift amounts */
#define hs2 9
#define hs3 11
#define hs4 15
/* Compile-time macro declarations for MD4.
** Note: The "rot" operator uses the variable "tmp".
** It assumes tmp is declared as unsigned int, so that the >>
** operator will shift in zeros rather than extending the sign bit.
*/
#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
#define h(X,Y,Z) (X^Y^Z)
#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
/* MDbegin(MDp)
** Initialize message digest buffer MDp.
** This is a user-callable routine.
*/
void
MDbegin(MDp)
MDptr MDp;
{ int i;
MDp->buffer[0] = I0;
MDp->buffer[1] = I1;
MDp->buffer[2] = I2;
MDp->buffer[3] = I3;
for (i=0;i<8;i++) MDp->count[i] = 0;
MDp->done = 0;
}
/* MDreverse(X)
** Reverse the byte-ordering of every int in X.
** Assumes X is an array of 16 ints.
** The macro revx reverses the byte-ordering of the next word of X.
*/
static void MDreverse(X)
unsigned int32 *X;
{ register unsigned int32 t;
register unsigned int i;
for(i = 0; i < 16; i++) {
t = X[i];
SIVAL(X,i*4,t);
}
}
/* MDblock(MDp,X)
** Update message digest buffer MDp->buffer using 16-word data block X.
** Assumes all 16 words of X are full of data.
** Does not update MDp->count.
** This routine is not user-callable.
*/
static void
MDblock(MDp,X)
MDptr MDp;
unsigned int32 *X;
{
register unsigned int32 tmp, A, B, C, D;
MDreverse(X);
A = MDp->buffer[0];
B = MDp->buffer[1];
C = MDp->buffer[2];
D = MDp->buffer[3];
/* Update the message digest buffer */
ff(A , B , C , D , 0 , fs1); /* Round 1 */
ff(D , A , B , C , 1 , fs2);
ff(C , D , A , B , 2 , fs3);
ff(B , C , D , A , 3 , fs4);
ff(A , B , C , D , 4 , fs1);
ff(D , A , B , C , 5 , fs2);
ff(C , D , A , B , 6 , fs3);
ff(B , C , D , A , 7 , fs4);
ff(A , B , C , D , 8 , fs1);
ff(D , A , B , C , 9 , fs2);
ff(C , D , A , B , 10 , fs3);
ff(B , C , D , A , 11 , fs4);
ff(A , B , C , D , 12 , fs1);
ff(D , A , B , C , 13 , fs2);
ff(C , D , A , B , 14 , fs3);
ff(B , C , D , A , 15 , fs4);
gg(A , B , C , D , 0 , gs1); /* Round 2 */
gg(D , A , B , C , 4 , gs2);
gg(C , D , A , B , 8 , gs3);
gg(B , C , D , A , 12 , gs4);
gg(A , B , C , D , 1 , gs1);
gg(D , A , B , C , 5 , gs2);
gg(C , D , A , B , 9 , gs3);
gg(B , C , D , A , 13 , gs4);
gg(A , B , C , D , 2 , gs1);
gg(D , A , B , C , 6 , gs2);
gg(C , D , A , B , 10 , gs3);
gg(B , C , D , A , 14 , gs4);
gg(A , B , C , D , 3 , gs1);
gg(D , A , B , C , 7 , gs2);
gg(C , D , A , B , 11 , gs3);
gg(B , C , D , A , 15 , gs4);
hh(A , B , C , D , 0 , hs1); /* Round 3 */
hh(D , A , B , C , 8 , hs2);
hh(C , D , A , B , 4 , hs3);
hh(B , C , D , A , 12 , hs4);
hh(A , B , C , D , 2 , hs1);
hh(D , A , B , C , 10 , hs2);
hh(C , D , A , B , 6 , hs3);
hh(B , C , D , A , 14 , hs4);
hh(A , B , C , D , 1 , hs1);
hh(D , A , B , C , 9 , hs2);
hh(C , D , A , B , 5 , hs3);
hh(B , C , D , A , 13 , hs4);
hh(A , B , C , D , 3 , hs1);
hh(D , A , B , C , 11 , hs2);
hh(C , D , A , B , 7 , hs3);
hh(B , C , D , A , 15 , hs4);
MDp->buffer[0] += A;
MDp->buffer[1] += B;
MDp->buffer[2] += C;
MDp->buffer[3] += D;
}
/* MDupdate(MDp,X,count)
** Input: MDp -- an MDptr
** X -- a pointer to an array of unsigned characters.
** count -- the number of bits of X to use.
** (if not a multiple of 8, uses high bits of last byte.)
** Update MDp using the number of bits of X given by count.
** This is the basic input routine for an MD4 user.
** The routine completes the MD computation when count < 512, so
** every MD computation should end with one call to MDupdate with a
** count less than 512. A call with count 0 will be ignored if the
** MD has already been terminated (done != 0), so an extra call with
** count 0 can be given as a "courtesy close" to force termination
** if desired.
*/
void
MDupdate(MDp,X,count)
MDptr MDp;
unsigned char *X;
unsigned int count;
{ unsigned int32 i, tmp, bit, byte, mask;
unsigned char XX[64];
unsigned char *p;
/* return with no error if this is a courtesy close with count
** zero and MDp->done is true.
*/
if (count == 0 && MDp->done) return;
/* check to see if MD is already done and report error */
if (MDp->done)
{ rprintf(FERROR,"\nError: MDupdate MD already done."); return; }
/* Add count to MDp->count */
tmp = count;
p = MDp->count;
while (tmp)
{ tmp += *p;
*p++ = tmp;
tmp = tmp >> 8;
}
/* Process data */
if (count == 512)
{ /* Full block of data to handle */
MDblock(MDp,(unsigned int32 *)X);
}
else if (count > 512) /* Check for count too large */
{ rprintf(FERROR,"\nError: MDupdate called with illegal count value %d."
,count);
return;
}
else /* partial block -- must be last block so finish up */
{ /* Find out how many bytes and residual bits there are */
byte = count >> 3;
bit = count & 7;
/* Copy X into XX since we need to modify it */
for (i=0;i<=byte;i++) XX[i] = X[i];
for (i=byte+1;i<64;i++) XX[i] = 0;
/* Add padding '1' bit and low-order zeros in last byte */
mask = 1 << (7 - bit);
XX[byte] = (XX[byte] | mask) & ~( mask - 1);
/* If room for bit count, finish up with this block */
if (byte <= 55)
{ for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
MDblock(MDp,(unsigned int32 *)XX);
}
else /* need to do two blocks to finish up */
{ MDblock(MDp,(unsigned int32 *)XX);
for (i=0;i<56;i++) XX[i] = 0;
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
MDblock(MDp,(unsigned int32 *)XX);
}
/* Set flag saying we're done with MD computation */
MDp->done = 1;
}
}
/*
** End of md4.c
*/

49
md4.h
View File

@@ -1,49 +0,0 @@
/*
This code is from rfc1186.
*/
/*
** ********************************************************************
** md4.h -- Header file for implementation of **
** MD4 Message Digest Algorithm **
** Updated: 2/13/90 by Ronald L. Rivest **
** (C) 1990 RSA Data Security, Inc. **
** ********************************************************************
*/
/* MDstruct is the data structure for a message digest computation.
*/
typedef struct {
unsigned int32 buffer[4]; /* Holds 4-word result of MD computation */
unsigned char count[8]; /* Number of bits processed so far */
unsigned int done; /* Nonzero means MD computation finished */
} MDstruct, *MDptr;
/* MDbegin(MD)
** Input: MD -- an MDptr
** Initialize the MDstruct prepatory to doing a message digest
** computation.
*/
extern void MDbegin();
/* MDupdate(MD,X,count)
** Input: MD -- an MDptr
** X -- a pointer to an array of unsigned characters.
** count -- the number of bits of X to use (an unsigned int).
** Updates MD using the first "count" bits of X.
** The array pointed to by X is not modified.
** If count is not a multiple of 8, MDupdate uses high bits of
** last byte.
** This is the basic input routine for a user.
** The routine terminates the MD computation when count < 512, so
** every MD computation should end with one call to MDupdate with a
** count less than 512. Zero is OK for a count.
*/
extern void MDupdate();
/*
** End of md4.h
*/

197
options.c
View File

@@ -37,6 +37,7 @@ int dry_run=0;
int local_server=0;
int ignore_times=0;
int delete_mode=0;
int delete_excluded=0;
int one_file_system=0;
int remote_version=0;
int sparse_files=0;
@@ -54,13 +55,19 @@ int am_server = 0;
int am_sender=0;
int recurse = 0;
int am_daemon=0;
int am_client=0;
int do_stats=0;
int do_progress=0;
int keep_partial=0;
int safe_symlinks=0;
int copy_unsafe_links=0;
int block_size=BLOCK_SIZE;
int size_only=0;
int bwlimit=0;
int delete_after=0;
int only_existing=0;
int max_delete=0;
int ignore_errors=0;
int blocking_io=0;
char *backup_suffix = BACKUP_SUFFIX;
char *tmpdir = NULL;
@@ -68,37 +75,48 @@ char *compare_dest = NULL;
char *config_file = RSYNCD_CONF;
char *shell_cmd = NULL;
char *log_format = NULL;
char *password_file = NULL;
char *rsync_path = RSYNC_NAME;
char *backup_dir = NULL;
int rsync_port = RSYNC_PORT;
int verbose = 0;
int quiet = 0;
int always_checksum = 0;
int list_only = 0;
void usage(int F)
struct in_addr socket_address = {INADDR_ANY};
void usage(enum logcode F)
{
rprintf(F,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
VERSION);
rprintf(F,"rsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
rprintf(F,"Usage: rsync [OPTION]... SRC [USER@]HOST:DEST\n");
rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
rprintf(F," or rsync [OPTION]... SRC DEST\n");
rprintf(F," or rsync [OPTION]... SRC [SRC]... DEST\n");
rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
rprintf(F," or rsync [OPTION]... SRC [USER@]HOST::DEST\n");
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
rprintf(F," sources separated by space as long as they have same top-level\n");
rprintf(F,"\nOptions\n");
rprintf(F," -v, --verbose increase verbosity\n");
rprintf(F," -q, --quiet decrease verbosity\n");
rprintf(F," -c, --checksum always checksum\n");
rprintf(F," -a, --archive archive mode\n");
rprintf(F," -r, --recursive recurse into directories\n");
rprintf(F," -R, --relative use relative path names\n");
rprintf(F," -b, --backup make backups (default ~ extension)\n");
rprintf(F," -b, --backup make backups (default %s suffix)\n",BACKUP_SUFFIX);
rprintf(F," --backup-dir make backups into this directory\n");
rprintf(F," --suffix=SUFFIX override backup suffix\n");
rprintf(F," -u, --update update only (don't overwrite newer files)\n");
rprintf(F," -l, --links preserve soft links\n");
rprintf(F," -L, --copy-links treat soft links like regular files\n");
rprintf(F," --copy-unsafe-links copy links outside the source tree\n");
rprintf(F," --safe-links ignore links outside the destination tree\n");
rprintf(F," -H, --hard-links preserve hard links\n");
rprintf(F," -p, --perms preserve permissions\n");
@@ -110,54 +128,67 @@ void usage(int F)
rprintf(F," -n, --dry-run show what would have been transferred\n");
rprintf(F," -W, --whole-file copy whole files, no incremental checks\n");
rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
rprintf(F," -B, --block-size=SIZE checksum blocking size\n");
rprintf(F," -B, --block-size=SIZE checksum blocking size (default %d)\n",BLOCK_SIZE);
rprintf(F," -e, --rsh=COMMAND specify rsh replacement\n");
rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
rprintf(F," --existing only update files that already exist\n");
rprintf(F," --delete delete files that don't exist on the sending side\n");
rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
rprintf(F," --delete-after delete after transferring, not before\n");
rprintf(F," --ignore-errors delete even if there are IO errors\n");
rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
rprintf(F," --partial keep partially transferred files\n");
rprintf(F," --force force deletion of directories even if not empty\n");
rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
rprintf(F," --timeout=TIME set IO timeout in seconds\n");
rprintf(F," -I, --ignore-times don't exclude files that match length and time\n");
rprintf(F," --size-only only use file size when determining if a file should be transferred\n");
rprintf(F," -T --temp-dir=DIR create temporary files in directory DIR\n");
rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
rprintf(F," -P equivalent to --partial --progress\n");
rprintf(F," -z, --compress compress file data\n");
rprintf(F," --exclude=PATTERN exclude files matching PATTERN\n");
rprintf(F," --exclude-from=FILE exclude patterns listed in FILE\n");
rprintf(F," --include=PATTERN don't exclude files matching PATTERN\n");
rprintf(F," --include-from=FILE don't exclude patterns listed in FILE\n");
rprintf(F," --suffix=SUFFIX override backup suffix\n");
rprintf(F," --version print version number\n");
rprintf(F," --daemon run as a rsync daemon\n");
rprintf(F," --address bind to the specified address\n");
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
rprintf(F," --port=PORT specify alternate rsyncd port number\n");
rprintf(F," --blocking-io use blocking IO for the remote shell\n");
rprintf(F," --stats give some file transfer stats\n");
rprintf(F," --progress show progress during transfer\n");
rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
rprintf(F," --password-file=FILE get password from FILE\n");
rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
rprintf(F," -h, --help show this help screen\n");
rprintf(F,"\n");
rprintf(F,"the backup suffix defaults to %s\n",BACKUP_SUFFIX);
rprintf(F,"the block size defaults to %d\n",BLOCK_SIZE);
rprintf(F,"\nPlease see the rsync(1) and rsyncd.conf(5) man pages for full documentation\n");
rprintf(F,"See http://rsync.samba.org/ for updates and bug reports\n");
}
enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
OPT_EXCLUDE_FROM,OPT_DELETE,OPT_NUMERIC_IDS,OPT_RSYNC_PATH,
OPT_FORCE,OPT_TIMEOUT,OPT_DAEMON,OPT_CONFIG,OPT_PORT,
enum {OPT_VERSION, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
OPT_EXCLUDE_FROM, OPT_DELETE, OPT_DELETE_EXCLUDED, OPT_NUMERIC_IDS,
OPT_RSYNC_PATH, OPT_FORCE, OPT_TIMEOUT, OPT_DAEMON, OPT_CONFIG, OPT_PORT,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
OPT_SAFE_LINKS, OPT_COMPARE_DEST, OPT_LOG_FORMAT};
OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO};
static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:T:z";
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
static struct option long_options[] = {
{"version", 0, 0, OPT_VERSION},
{"server", 0, 0, OPT_SERVER},
{"sender", 0, 0, OPT_SENDER},
{"existing", 0, 0, OPT_EXISTING},
{"delete", 0, 0, OPT_DELETE},
{"delete-excluded", 0, 0, OPT_DELETE_EXCLUDED},
{"force", 0, 0, OPT_FORCE},
{"numeric-ids", 0, 0, OPT_NUMERIC_IDS},
{"exclude", 1, 0, OPT_EXCLUDE},
@@ -165,8 +196,10 @@ static struct option long_options[] = {
{"include", 1, 0, OPT_INCLUDE},
{"include-from",1, 0, OPT_INCLUDE_FROM},
{"rsync-path", 1, 0, OPT_RSYNC_PATH},
{"password-file", 1, 0, OPT_PASSWORD_FILE},
{"one-file-system",0, 0, 'x'},
{"ignore-times",0, 0, 'I'},
{"size-only", 0, 0, OPT_SIZE_ONLY},
{"help", 0, 0, 'h'},
{"dry-run", 0, 0, 'n'},
{"sparse", 0, 0, 'S'},
@@ -176,12 +209,14 @@ static struct option long_options[] = {
{"backup", 0, 0, 'b'},
{"update", 0, 0, 'u'},
{"verbose", 0, 0, 'v'},
{"quiet", 0, 0, 'q'},
{"recursive", 0, 0, 'r'},
{"relative", 0, 0, 'R'},
{"devices", 0, 0, 'D'},
{"perms", 0, 0, 'p'},
{"links", 0, 0, 'l'},
{"copy-links", 0, 0, 'L'},
{"copy-unsafe-links", 0, 0, OPT_COPY_UNSAFE_LINKS},
{"safe-links", 0, 0, OPT_SAFE_LINKS},
{"whole-file", 0, 0, 'W'},
{"hard-links", 0, 0, 'H'},
@@ -199,9 +234,16 @@ static struct option long_options[] = {
{"stats", 0, 0, OPT_STATS},
{"progress", 0, 0, OPT_PROGRESS},
{"partial", 0, 0, OPT_PARTIAL},
{"delete-after",0, 0, OPT_DELETE_AFTER},
{"ignore-errors",0, 0, OPT_IGNORE_ERRORS},
{"blocking-io" ,0, 0, OPT_BLOCKING_IO},
{"config", 1, 0, OPT_CONFIG},
{"port", 1, 0, OPT_PORT},
{"log-format", 1, 0, OPT_LOG_FORMAT},
{"bwlimit", 1, 0, OPT_BWLIMIT},
{"address", 1, 0, OPT_ADDRESS},
{"max-delete", 1, 0, OPT_MAX_DELETE},
{"backup-dir", 1, 0, OPT_BACKUP_DIR},
{0,0,0,0}};
@@ -248,7 +290,7 @@ static int check_refuse_options(char *ref, int opt)
}
int parse_arguments(int argc, char *argv[])
int parse_arguments(int argc, char *argv[], int frommain)
{
int opt;
int option_index;
@@ -276,11 +318,19 @@ int parse_arguments(int argc, char *argv[])
case OPT_RSYNC_PATH:
rsync_path = optarg;
break;
case OPT_PASSWORD_FILE:
password_file =optarg;
break;
case 'I':
ignore_times = 1;
break;
case OPT_SIZE_ONLY:
size_only = 1;
break;
case 'x':
one_file_system=1;
break;
@@ -289,6 +339,19 @@ int parse_arguments(int argc, char *argv[])
delete_mode = 1;
break;
case OPT_EXISTING:
only_existing = 1;
break;
case OPT_DELETE_AFTER:
delete_after = 1;
break;
case OPT_DELETE_EXCLUDED:
delete_excluded = 1;
delete_mode = 1;
break;
case OPT_FORCE:
force_delete = 1;
break;
@@ -313,6 +376,10 @@ int parse_arguments(int argc, char *argv[])
add_exclude_file(optarg,1, 1);
break;
case OPT_COPY_UNSAFE_LINKS:
copy_unsafe_links=1;
break;
case OPT_SAFE_LINKS:
safe_symlinks=1;
break;
@@ -391,6 +458,10 @@ int parse_arguments(int argc, char *argv[])
verbose++;
break;
case 'q':
if (frommain) quiet++;
break;
case 'a':
recurse=1;
#if SUPPORT_LINKS
@@ -399,10 +470,8 @@ int parse_arguments(int argc, char *argv[])
preserve_perms=1;
preserve_times=1;
preserve_gid=1;
if (am_root) {
preserve_devices=1;
preserve_uid=1;
}
preserve_uid=1;
preserve_devices=1;
break;
case OPT_SERVER:
@@ -433,6 +502,10 @@ int parse_arguments(int argc, char *argv[])
block_size = atoi(optarg);
break;
case OPT_MAX_DELETE:
max_delete = atoi(optarg);
break;
case OPT_TIMEOUT:
io_timeout = atoi(optarg);
break;
@@ -465,6 +538,19 @@ int parse_arguments(int argc, char *argv[])
keep_partial = 1;
break;
case OPT_IGNORE_ERRORS:
ignore_errors = 1;
break;
case OPT_BLOCKING_IO:
blocking_io = 1;
break;
case 'P':
do_progress = 1;
keep_partial = 1;
break;
case OPT_CONFIG:
config_file = optarg;
break;
@@ -476,6 +562,23 @@ int parse_arguments(int argc, char *argv[])
case OPT_LOG_FORMAT:
log_format = optarg;
break;
case OPT_BWLIMIT:
bwlimit = atoi(optarg);
break;
case OPT_ADDRESS:
{
struct in_addr *ia;
if ((ia = ip_address(optarg))) {
socket_address = *ia;
}
}
break;
case OPT_BACKUP_DIR:
backup_dir = optarg;
break;
default:
slprintf(err_buf,sizeof(err_buf),"unrecognised option\n");
@@ -486,12 +589,17 @@ int parse_arguments(int argc, char *argv[])
}
/* need to pass all the valid options from the client to the server */
void server_options(char **args,int *argc)
{
int ac = *argc;
static char argstr[50];
static char bsize[30];
static char iotime[30];
static char mdelete[30];
static char bw[50];
int i, x;
args[ac++] = "--server";
@@ -503,6 +611,7 @@ void server_options(char **args,int *argc)
argstr[0] = '-';
for (i=0;i<verbose;i++)
argstr[x++] = 'v';
/* the -q option is intentionally left out */
if (make_backups)
argstr[x++] = 'b';
if (update_only)
@@ -548,40 +657,76 @@ void server_options(char **args,int *argc)
if (x != 1) args[ac++] = argstr;
if (block_size != BLOCK_SIZE) {
sprintf(bsize,"-B%d",block_size);
slprintf(bsize,sizeof(bsize),"-B%d",block_size);
args[ac++] = bsize;
}
if (max_delete && am_sender) {
slprintf(mdelete,sizeof(mdelete),"--max-delete=%d",max_delete);
args[ac++] = mdelete;
}
if (io_timeout) {
sprintf(iotime,"--timeout=%d",io_timeout);
slprintf(iotime,sizeof(iotime),"--timeout=%d",io_timeout);
args[ac++] = iotime;
}
if (bwlimit) {
slprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
args[ac++] = bw;
}
if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
args[ac++] = "--suffix";
args[ac++] = backup_suffix;
}
if (delete_mode)
if (delete_mode && !delete_excluded)
args[ac++] = "--delete";
if (delete_excluded)
args[ac++] = "--delete-excluded";
if (size_only)
args[ac++] = "--size-only";
if (keep_partial)
args[ac++] = "--partial";
if (force_delete)
args[ac++] = "--force";
if (delete_after)
args[ac++] = "--delete-after";
if (ignore_errors)
args[ac++] = "--ignore-errors";
if (copy_unsafe_links)
args[ac++] = "--copy-unsafe-links";
if (safe_symlinks)
args[ac++] = "--safe-links";
if (numeric_ids)
args[ac++] = "--numeric-ids";
if (only_existing && am_sender)
args[ac++] = "--existing";
if (tmpdir) {
args[ac++] = "--temp-dir";
args[ac++] = tmpdir;
}
if (backup_dir && am_sender) {
/* only the receiver needs this option, if we are the sender
* then we need to send it to the receiver.
*/
args[ac++] = "--backup-dir";
args[ac++] = backup_dir;
}
if (compare_dest && am_sender) {
/* the server only needs this option if it is not the sender,
* and it may be an older version that doesn't know this

View File

@@ -1,10 +1,10 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.2.1
Version: 2.4.4
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.2.1.tar.gz
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.4.4.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
@@ -21,6 +21,8 @@ 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)
@@ -58,7 +60,7 @@ previous package(s).)
%build
./configure --prefix=/usr
make CFLAGS=$RPM_OPT_FLAGS
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install

View File

@@ -21,6 +21,8 @@ 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)
@@ -58,7 +60,7 @@ previous package(s).)
%build
./configure --prefix=/usr
make CFLAGS=$RPM_OPT_FLAGS
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install

View File

@@ -74,9 +74,6 @@
*/
#include "rsync.h"
#define BOOL int
#define False 0
#define True 1
/* -------------------------------------------------------------------------- **
* Constants...

View File

@@ -36,14 +36,12 @@ extern char *compare_dest;
extern int make_backups;
extern char *backup_suffix;
static struct delete_list {
dev_t dev;
INO_T inode;
} *delete_list;
static int dlist_len, dlist_alloc_len;
/* 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.
@@ -83,7 +81,7 @@ static void add_delete_entry(struct file_struct *file)
static void delete_one(struct file_struct *f)
{
if (!S_ISDIR(f->mode)) {
if (do_unlink(f_name(f)) != 0) {
if (robust_unlink(f_name(f)) != 0) {
rprintf(FERROR,"unlink %s : %s\n",f_name(f),strerror(errno));
} else if (verbose) {
rprintf(FINFO,"deleting %s\n",f_name(f));
@@ -104,16 +102,20 @@ static void delete_one(struct file_struct *f)
/* 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 */
static void delete_files(struct file_list *flist)
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;
static int deletion_count;
if (cvs_exclude)
add_cvs_excludes();
if (io_error) {
if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
rprintf(FINFO,"IO error encountered - skipping file deletion\n");
return;
}
@@ -136,6 +138,7 @@ static void delete_files(struct file_list *flist)
rprintf(FINFO,"deleting in %s\n", name);
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))
@@ -143,10 +146,12 @@ static void delete_files(struct file_list *flist)
if (-1 == flist_find(flist,local_file_list->files[i])) {
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);
} else {
deletion_count++;
delete_one(local_file_list->files[i]);
}
}
@@ -221,8 +226,8 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
extern int cleanup_got_literal;
if (verbose > 3) {
rprintf(FINFO,"data recv %d at %d\n",
i,(int)offset);
rprintf(FINFO,"data recv %d at %.0f\n",
i,(double)offset);
}
stats.literal_data += i;
@@ -239,7 +244,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
}
i = -(i+1);
offset2 = i*n;
offset2 = i*(OFF_T)n;
len = n;
if (i == count-1 && remainder != 0)
len = remainder;
@@ -247,13 +252,15 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
stats.matched_data += len;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] of size %d at %d offset=%d\n",
i,len,(int)offset2,(int)offset);
rprintf(FINFO,"chunk[%d] of size %d at %.0f offset=%.0f\n",
i,len,(double)offset2,(double)offset);
map = map_ptr(buf,offset2,len);
if (buf) {
map = map_ptr(buf,offset2,len);
see_token(map, len);
sum_update(map,len);
see_token(map, len);
sum_update(map,len);
}
if (fd != -1 && write_file(fd,map,len) != len) {
rprintf(FERROR,"write failed on %s : %s\n",
@@ -263,7 +270,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
offset += len;
}
end_progress();
end_progress(total_size);
if (fd != -1 && offset > 0 && sparse_end(fd) != 0) {
rprintf(FERROR,"write failed on %s : %s\n",
@@ -287,6 +294,8 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
}
/* 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 f_gen)
{
@@ -302,16 +311,14 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
int phase=0;
int recv_ok;
extern struct stats stats;
extern int preserve_perms;
extern int delete_after;
struct stats initial_stats;
if (verbose > 2) {
rprintf(FINFO,"recv_files(%d) starting\n",flist->count);
}
if (recurse && delete_mode && !local_name && flist->count>0) {
delete_files(flist);
}
while (1) {
cleanup_disable();
@@ -358,14 +365,14 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
fnamecmp = fname;
/* open the file */
fd1 = open(fnamecmp,O_RDONLY);
fd1 = do_open(fnamecmp, O_RDONLY, 0);
if ((fd1 == -1) && (compare_dest != NULL)) {
/* try the file at compare_dest instead */
slprintf(fnamecmpbuf,MAXPATHLEN,"%s/%s",
compare_dest,fname);
fnamecmp = fnamecmpbuf;
fd1 = open(fnamecmp,O_RDONLY);
fd1 = do_open(fnamecmp, O_RDONLY, 0);
}
if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
@@ -382,10 +389,17 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
continue;
}
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 */
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 %d\n",fnamecmp,(int)st.st_size);
rprintf(FINFO,"recv mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
} else {
buf = NULL;
}
@@ -412,17 +426,21 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
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 */
this out. We also set it initially without group
access because of a similar race condition. */
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
file->mode & ACCESSPERMS);
file->mode & INITACCESSPERMS);
/* 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) {
fd2 = do_open(fnametmp,O_WRONLY|O_CREAT|O_EXCL,
file->mode & ACCESSPERMS);
file->mode & INITACCESSPERMS);
}
if (fd2 == -1) {
rprintf(FERROR,"open %s : %s\n",fnametmp,strerror(errno));
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);
@@ -452,7 +470,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
finish_transfer(fname, fnametmp, file);
cleanup_disable();
if (!recv_ok) {
if (csum_length == SUM_LENGTH) {
rprintf(FERROR,"ERROR: file corruption in %s. File changed during transfer?\n",
@@ -465,6 +483,12 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
}
}
if (delete_after) {
if (recurse && delete_mode && !local_name && flist->count>0) {
delete_files(flist);
}
}
if (preserve_hard_links)
do_hard_links(flist);
@@ -473,7 +497,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
for (i = 0; i < flist->count; i++) {
file = flist->files[i];
if (!file->basename || !S_ISDIR(file->mode)) continue;
recv_generator(f_name(file),flist,i,-1);
recv_generator(local_name?local_name:f_name(file),flist,i,-1);
}
if (verbose > 2)

121
rsync.c
View File

@@ -30,7 +30,6 @@ extern int preserve_uid;
extern int preserve_gid;
extern int preserve_perms;
extern int make_backups;
extern char *backup_suffix;
/*
@@ -57,8 +56,6 @@ int delete_file(char *fname)
int ret;
extern int recurse;
if (do_unlink(fname) == 0 || errno == ENOENT) return 0;
#if SUPPORT_LINKS
ret = do_lstat(fname, &st);
#else
@@ -70,6 +67,7 @@ int delete_file(char *fname)
}
if (!S_ISDIR(st.st_mode)) {
if (robust_unlink(fname) == 0 || errno == ENOENT) return 0;
rprintf(FERROR,"unlink(%s) : %s\n", fname, strerror(errno));
return -1;
}
@@ -113,13 +111,46 @@ int delete_file(char *fname)
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 updated = 0;
STRUCT_STAT st2;
extern int am_daemon;
int change_uid, change_gid;
if (dry_run) return 0;
@@ -145,33 +176,41 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st,
}
}
if ((am_root || !am_daemon) &&
((am_root && preserve_uid && st->st_uid != file->uid) ||
(preserve_gid && st->st_gid != file->gid))) {
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);
}
if (change_uid || change_gid) {
if (do_lchown(fname,
(am_root&&preserve_uid)?file->uid:-1,
preserve_gid?file->gid:-1) != 0) {
if (preserve_uid && st->st_uid != file->uid)
updated = 1;
if (verbose>1 || preserve_uid) {
rprintf(FERROR,"chown %s : %s\n",
fname,strerror(errno));
return 0;
}
} else {
updated = 1;
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));
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 */
if (st->st_mode & (S_ISUID | S_ISGID)) {
link_stat(fname, st);
}
updated = 1;
}
#ifdef HAVE_CHMOD
if (preserve_perms && !S_ISLNK(st->st_mode) &&
(st->st_mode != file->mode ||
(updated && (file->mode & ~ACCESSPERMS)))) {
updated = 1;
if (do_chmod(fname,file->mode) != 0) {
rprintf(FERROR,"failed to set permissions on %s : %s\n",
fname,strerror(errno));
return 0;
if (!S_ISLNK(st->st_mode)) {
if (st->st_mode != file->mode) {
updated = 1;
if (do_chmod(fname,file->mode) != 0) {
rprintf(FERROR,"failed to set permissions on %s : %s\n",
fname,strerror(errno));
return 0;
}
}
}
#endif
@@ -191,26 +230,6 @@ void sig_int(void)
exit_cleanup(RERR_SIGNAL);
}
int make_backup(char *fname)
{
char fnamebak[MAXPATHLEN];
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
rprintf(FERROR,"backup filename too long\n");
return 0;
}
slprintf(fnamebak,sizeof(fnamebak)-1,"%s%s",fname,backup_suffix);
if (do_rename(fname,fnamebak) != 0) {
if (errno != ENOENT) {
rprintf(FERROR,"rename %s %s : s\n",fname,fnamebak,strerror(errno));
return 0;
}
} else if (verbose > 1) {
rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
}
return 1;
}
/* finish off a file transfer, renaming the file and setting the permissions
and ownership */
@@ -220,26 +239,22 @@ void finish_transfer(char *fname, char *fnametmp, struct file_struct *file)
return;
/* move tmp file over real file */
if (do_rename(fnametmp,fname) != 0) {
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 & ACCESSPERMS)) {
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);
}
do_unlink(fnametmp);
} else {
rprintf(FERROR,"rename %s -> %s : %s\n",
fnametmp,fname,strerror(errno));
do_unlink(fnametmp);
}
do_unlink(fnametmp);
} else {
set_perms(fname,file,NULL,0);
}
}

58
rsync.h
View File

@@ -17,18 +17,22 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define False 0
#define True 1
#define BLOCK_SIZE 700
#define RSYNC_RSH_ENV "RSYNC_RSH"
#define RSYNC_NAME "rsync"
#define RSYNCD_CONF "/etc/rsyncd.conf"
#define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock"
#define URL_PREFIX "rsync://"
#define BACKUP_SUFFIX "~"
/* a non-zero CHAR_OFFSET makes the rolling sum stronger, but is
imcompatible with older versions :-( */
incompatible with older versions :-( */
#define CHAR_OFFSET 0
@@ -43,8 +47,8 @@
#define SAME_TIME (1<<7)
/* update this if you make incompatible changes */
#define PROTOCOL_VERSION 19
#define MIN_PROTOCOL_VERSION 11
#define PROTOCOL_VERSION 24
#define MIN_PROTOCOL_VERSION 15
#define MAX_PROTOCOL_VERSION 30
#define RSYNC_PORT 873
@@ -52,16 +56,14 @@
#define SPARSE_WRITE_SIZE (1024)
#define WRITE_SIZE (32*1024)
#define CHUNK_SIZE (32*1024)
#define MAX_MAP_SIZE (1*1024*1024)
#define MAX_MAP_SIZE (256*1024)
#define IO_BUFFER_SIZE (4092)
#define MAX_READ_BUFFER (1024*1024)
#define MAX_ARGS 1000
#define MPLEX_BASE 7
#define FERROR 1
#define FINFO 2
#define FLOG 3
enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3};
#include "errcode.h"
@@ -148,11 +150,6 @@
#endif
#include <errno.h>
#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP)
#include <sys/mman.h>
#define USE_MMAP 1
#endif
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
@@ -274,6 +271,10 @@
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 256
#endif
/* the length of the md4 checksum */
#define MD4_SUM_LENGTH 16
#define SUM_LENGTH 16
@@ -303,10 +304,21 @@ struct file_struct {
char *sum;
};
#define ARENA_SIZE (32 * 1024)
struct string_area {
char *base;
char *end;
char *current;
struct string_area *next;
};
struct file_list {
int count;
int malloced;
struct file_struct **files;
struct string_area *string_area;
};
struct sum_buf {
@@ -326,15 +338,16 @@ struct sum_struct {
};
struct map_struct {
char *map,*p;
char *p;
int fd,p_size,p_len;
OFF_T size, p_offset;
OFF_T file_size, p_offset, p_fd_offset;
};
struct exclude_struct {
char *orig;
char *pattern;
int regular_exp;
int fnmatch_flags;
int include;
int directory;
int local;
@@ -454,18 +467,31 @@ extern int errno;
#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
#endif
/* work out what fcntl flag to use for non-blocking */
#ifdef O_NONBLOCK
# define NONBLOCK_FLAG O_NONBLOCK
#elif defined(SYSV)
# define NONBLOCK_FLAG O_NDELAY
#else
# define NONBLOCK_FLAG FNDELAY
#endif
#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 */
#define INITACCESSPERMS 0700
/* handler for null strings in printf format */
#define NS(s) ((s)?(s):"<NULL>")
/* use magic gcc attributes to catch format errors */
void rprintf(int , const char *, ...)
void rprintf(enum logcode , const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif

277
rsync.yo
View File

@@ -1,19 +1,19 @@
mailto(rsync-bugs@samba.org)
manpage(rsync)(1)(24 Nov 1998)()()
manpage(rsync)(1)(1 Mar 1999)()()
manpagename(rsync)(faster, flexible replacement for rcp)
manpagesynopsis()
rsync [options] [user@]host:path path
rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
rsync [options] path [user@]host:path
rsync [OPTION]... [USER@]HOST:SRC DEST
rsync [options] path path
rsync [OPTION]... SRC [SRC]... DEST
rsync [options] [user@]host::module[/path] path
rsync [OPTION]... [USER@]HOST::SRC [DEST]
rsync [options] path [user@]host::module[/path]
rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
rsync [options] rsync://[user@]host[:port]/module/path path
rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
manpagedescription()
@@ -54,7 +54,7 @@ itemize(
single : separator.
it() for copying from a remote machine to the local machine
using a remote shell program. This is invoked when the local path
using a remote shell program. This is invoked when the source
contains a : separator.
it() for copying from a remote rsync server to the local
@@ -139,6 +139,11 @@ It is also possible to use rsync without using rsh or ssh as the
transport. In this case you will connect to a remote rsync server
running on TCP port 873.
You may establish the connetcion via a web proxy by setting the
environment variable RSYNC_PROXY to a hostname:port pair pointing to
your web proxy. Note that your web proxy must allow proxying to port
873, this must be configured in your proxy servers ruleset.
Using rsync in this way is the same as using it with rsh or ssh except
that:
@@ -159,7 +164,11 @@ itemize(
Some paths on the remote server may require authentication. If so then
you will receive a password prompt when you connect. You can avoid the
password prompt by setting the environment variable RSYNC_PASSWORD to
the password you want to use. This may be useful when scripting rsync.
the password you want to use or using the --password-file option. This
may be useful when scripting rsync.
WARNING: On some systems environment variables are visible to all
users. On those systems using --password-file is recommended.
manpagesection(RUNNING AN RSYNC SERVER)
@@ -207,23 +216,19 @@ Here is a short summary of the options available in rsync. Please refer
to the detailed description below for a complete description.
verb(
Usage: rsync [OPTION]... SRC [USER@]HOST:DEST
or rsync [OPTION]... [USER@]HOST:SRC DEST
or rsync [OPTION]... SRC DEST
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
or rsync [OPTION]... SRC [USER@]HOST::DEST
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
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 ~ extension)
-b, --backup make backups (default ~ suffix)
--backup-dir=DIR put backups in the specified directory
--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
@@ -235,31 +240,41 @@ Options
-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
-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
--existing only update files that already exist
--delete delete files that don't exist on the sending side
--delete-excluded also delete excluded files on the receiving side
--delete-after delete after transferring, not before
--ignore-errors delete even if there are IO errors
--max-delete=NUM don't delete more than NUM files
--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
-P equivalent to --partial --progress
-z, --compress compress file data
--exclude=PATTERN exclude files matching PATTERN
--exclude-from=FILE exclude files listed in FILE
--exclude-from=FILE exclude patterns listed in FILE
--include=PATTERN don't exclude files matching PATTERN
--include-from=FILE don't exclude files listed in FILE
--suffix=SUFFIX override backup suffix
--include-from=FILE don't exclude patterns listed in FILE
--version print version number
--daemon run as a rsync daemon
--address bind to the specified address
--config=FILE specify alternate rsyncd.conf file
--port=PORT specify alternate rsyncd port number
--blocking-io use blocking IO for the remote shell
--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
--bwlimit=KBPS limit I/O bandwidth, KBytes per second
-h, --help show this help screen
)
@@ -268,6 +283,8 @@ manpageoptions()
rsync uses the GNU long options package. Many of the command line
options have two variants, one short and one long. These are shown
below, separated by commas. Some options only have a long variant.
The '=' for options that take a parameter is optional; whitespace
can be used instead.
startdit()
dit(bf(-h, --help)) Print a short help page describing the options
@@ -283,23 +300,34 @@ information on what files are being skipped and slightly more
information at the end. More than two -v flags should only be used if
you are debugging rsync.
dit(bf(-q, --quiet)) This option decreases the amount of information you
are given during the transfer, notably suppressing information messages
from the remote server. This flag is useful when invoking rsync from
cron.
dit(bf(-I, --ignore-times)) Normally rsync will skip any files that are
already the same length and have the same time-stamp. This option turns
off this behavior.
dit(bf(--size-only)) Normally rsync will skip any files that are
already the same length and have the same time-stamp. With the
--size-only option files will be skipped if they have the same size,
regardless of timestamp. This is useful when starting to use rsync
after using another mirroring system which may not preserve timestamps
exactly.
dit(bf(-c, --checksum)) This forces the sender to checksum all files using
a 128-bit MD4 checksum before transfer. The checksum is then
explicitly checked on the receiver and any files of the same name
which already exist and have the same checksum and size on the
receiver are skipped. This option can be quite slow.
dit(bf(-a, --archive)) This is equivalent to -rlptDg. It is a quick way
dit(bf(-a, --archive)) This is equivalent to -rlptgoD. It is a quick way
of saying you want recursion and want to preserve everything.
Note: if the user launching rsync is root then the -o option (preserve
uid) is also implied.
dit(bf(-r, --recursive)) This tells rsync to copy directories recursively.
dit(bf(-r, --recursive)) This tells rsync to copy directories
recursively. If you don't specify this then rsync won't copy
directories at all.
dit(bf(-R, --relative)) Use relative paths. This means that the full path
names specified on the command line are sent to the server rather than
@@ -321,6 +349,13 @@ dit(bf(-b, --backup)) With this option preexisting destination files are
renamed with a ~ extension as each file is transferred. You can
control the backup suffix using the --suffix option.
dit(bf(--backup-dir=DIR)) In combination with the --backup option, this
tells rsync to store all backups in the specified directory. This is
very useful for incremental backups.
dit(bf(--suffix=SUFFIX)) This option allows you to override the default
backup suffix used with the -b option. The default is a ~.
dit(bf(-u, --update)) This forces rsync to skip any files for which the
destination file already exists and has a date later than the source
file.
@@ -330,7 +365,12 @@ remote system to be the same as the local system. Without this
option, all symbolic links are skipped.
dit(bf(-L, --copy-links)) This tells rsync to treat symbolic links just
like ordinary files.
like ordinary files.
dit(bf(--copy-unsafe-links)) This tells rsync to treat symbolic links that
point outside the source tree like ordinary files. Absolute symlinks are
also treated like ordinary files, and so are any symlinks in the source
path itself when --relative is used.
dit(bf(--safe-links)) This tells rsync to ignore any symbolic links
which point outside the destination tree. All absolute symlinks are
@@ -350,12 +390,6 @@ dit(bf(-W, --whole-file)) With this option the incremental rsync algorithm
is not used and the whole file is sent as-is instead. This may be
useful when using rsync with a local machine.
dit(bf(--partial)) By default, rsync will delete any partially
transferred file if the transfer is interrupted. In some circumstances
it is more desirable to keep partially transferred files. Using the
--partial option tells rsync to keep the partial file which should
make a subsequent transfer of the rest of the file much faster.
dit(bf(-p, --perms)) This option causes rsync to update the remote
permissions to be the same as the local permissions.
@@ -366,9 +400,9 @@ the --numeric-ids option is implied because the source system cannot get
access to the usernames.
dit(bf(-g, --group)) This option causes rsync to update the remote group
of the file to be the same as the local group. Note that if the source
system is a daemon using chroot, the --numeric-ids option is implied because
the source system cannot get access to the group names.
of the file to be the same as the local group. If the receving system is
not running as the super-user, only groups that the receiver is a member of
will be preserved (by group name, not group id number).
dit(bf(-D, --devices)) This option causes rsync to transfer character and
block device information to the remote system to recreate these
@@ -396,22 +430,22 @@ dit(bf(-x, --one-file-system)) This tells rsync not to cross filesystem
boundaries when recursing. This is useful for transferring the
contents of only one filesystem.
dit(bf(--existing)) This tells rsync not to create any new files -
only update files that already exist on the destination.
dit(bf(--max-delete=NUM)) This tells rsync not to delete more than NUM
files or directories. This is useful when mirroring very large trees
to prevent disasters.
dit(bf(--delete)) This tells rsync to delete any files on the receiving
side that aren't on the sending side. This option can be dangerous if
used incorrectly!
side that aren't on the sending side. Files that are excluded from
transfer are excluded from being deleted unless you use --delete-excluded.
It is a very good idea to run first using the dry run option (-n) to
see what files would be deleted to make sure important files aren't
listed.
This option has no effect if directory recursion is not selected.
rsync 1.6.4 changed the behavior of --delete to make it less
dangerous. rsync now only scans directories on the receiving side
that are explicitly transferred from the sending side. Only files in
these directories are deleted.
Still, it is probably easy to get burnt with this option. The moral
of the story is to use the -n option until you get used to the
behavior of --delete.
This option can be dangerous if used incorrectly! It is a very good idea
to run first using the dry run option (-n) to see what files would be
deleted to make sure important files aren't listed.
If the sending side detects any IO errors then the deletion of any
files at the destination will be automatically disabled. This is to
@@ -419,19 +453,27 @@ prevent temporary filesystem failures (such as NFS errors) on the
sending side causing a massive deletion of files on the
destination.
dit(bf(--delete-excluded)) In addition to deleting the files on the
receiving side that are not on the sending side, this tells rsync to also
delete any files on the receiving side that are excluded (see --exclude).
dit(bf(--delete-after)) By default rsync does file deletions before
transferring files to try to ensure that there is sufficient space on
the receiving filesystem. If you want to delete after transferring
then use the --delete-after switch.
dit(bf(--force)) This options tells rsync to delete directories even if
they are not empty. This applies to both the --delete option and to
cases where rsync tries to copy a normal file but the destination
contains a directory of the same name. Normally rsync will refuse to
do a recursive directory deletion in such cases, by using --force
the recursive deletion will be done.
contains a directory of the same name.
Use this option with caution!
Since this option was added, deletions were reordered to be done depth-first
so it is hardly ever needed anymore except in very obscure cases.
dit(bf(-B , --block_size BLOCKSIZE)) This controls the block size used in
dit(bf(-B , --block_size=BLOCKSIZE)) This controls the block size used in
the rsync algorithm. See the technical report for details.
dit(bf(-e, --rsh COMMAND)) This option allows you to choose an alternative
dit(bf(-e, --rsh=COMMAND)) This option allows you to choose an alternative
remote shell program to use for communication between the local and
remote copies of rsync. By default, rsync will use rsh, but you may
like to instead use ssh because of its high security.
@@ -439,10 +481,12 @@ like to instead use ssh because of its high security.
You can also choose the remote shell program using the RSYNC_RSH
environment variable.
dit(bf(--rsync-path PATH)) Use this to specify the path to the copy of
rsync on the remote machine. Useful when it's not in your path.
dit(bf(--rsync-path=PATH)) Use this to specify the path to the copy of
rsync on the remote machine. Useful when it's not in your path. Note
that this is the full path to the binary, not just the directory that
the binary is in.
dit(bf(--exclude pattern)) This option allows you to selectively exclude
dit(bf(--exclude=PATTERN)) This option allows you to selectively exclude
certain files from the list of files to be transferred. This is most
useful in combination with a recursive transfer.
@@ -452,18 +496,19 @@ to build up the list of files to exclude.
See the section on exclude patterns for information on the syntax of
this option.
dit(bf(--exclude-from FILE)) This option is similar to the --exclude
dit(bf(--exclude-from=FILE)) This option is similar to the --exclude
option, but instead it adds all filenames listed in the file FILE to
the exclude list.
the exclude list. Blank lines in FILE and lines starting with ';' or '#'
are ignored.
dit(bf(--include pattern)) This option tells rsync to not exclude the
dit(bf(--include=PATTERN)) This option tells rsync to not exclude the
specified pattern of filenames. This is useful as it allows you to
build up quite complex exclude/include rules.
See the section of exclude patterns for information on the syntax of
this option.
dit(bf(--include-from FILE)) This specifies a list of include patterns
dit(bf(--include-from=FILE)) This specifies a list of include patterns
from a file.
dit(bf(-C, --cvs-exclude)) This is a useful shorthand for excluding a
@@ -483,10 +528,7 @@ files listed in the CVSIGNORE environment variable (space delimited).
Finally in each directory any files listed in the .cvsignore file in
that directory are added to the list.
dit(bf(--suffix SUFFIX)) This option allows you to override the default
backup suffix used with the -b option. The default is a ~.
dit(bf(--csum-length LENGTH)) By default the primary checksum used in
dit(bf(--csum-length=LENGTH)) By default the primary checksum used in
rsync is a very strong 16 byte MD4 checksum. In most cases you will
find that a truncated version of this checksum is quite efficient, and
this will decrease the size of the checksum data sent over the link,
@@ -505,12 +547,12 @@ checksum length by default, using a 16 byte file checksum to determine
if a 2nd pass is required with a longer block checksum. Only use this
option if you have read the source code and know what you are doing.
dit(bf(-T, --temp-dir DIR)) This option instructs rsync to use DIR as a
dit(bf(-T, --temp-dir=DIR)) This option instructs rsync to use DIR as a
scratch directory when creating temporary copies of the files
transferred on the receiving side. The default behavior is to create
the temporary files in the receiving directory.
dit(bf(--compare-dest DIR)) This option instructs rsync to use DIR as an
dit(bf(--compare-dest=DIR)) This option instructs rsync to use DIR as an
additional directory to compare destination files against when doing
transfers. This is useful for doing transfers to a new destination while
leaving existing files intact, and then doing a flash-cutover when all
@@ -557,13 +599,24 @@ config file (/etc/rsyncd.conf) on each connect made by a client and
respond to requests accordingly. See the rsyncd.conf(5) man page for more
details.
dit(bf(--config FILE)) This specifies an alternate config file than
dit(bf(--address)) By default rsync will bind to the wildcard address
when run as a daemon with the --daemon option or when connecting to a
rsync server. The --address option allows you to specify a specific IP
address (or hostname) to bind to. This makes virtual hosting possible
in conjunction with the --config option.
dit(bf(--config=FILE)) This specifies an alternate config file than
the default /etc/rsyncd.conf. This is only relevant when --daemon is
specified.
dit(bf(--port PORT)) This specifies an alternate TCP port number to use
dit(bf(--port=PORT)) This specifies an alternate TCP port number to use
rather than the default port 873.
dit(bf(--blocking-io)) This specifies whether rsync will use blocking
IO when launching a remote shell transport. You may find this is
needed for some remote shells that can't handle the default
non-blocking IO.
dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
rsync client logs to stdout on a per-file basis. The log format is
specified using the same format conventions as the log format option in
@@ -571,13 +624,40 @@ rsyncd.conf.
dit(bf(--stats)) This tells rsync to print a verbose set of statistics
on the file transfer, allowing you to tell how effective the rsync
algorithm is for your data. This option only works in conjunction with
the -v (verbose) option.
algorithm is for your data.
dit(bf(--partial)) By default, rsync will delete any partially
transferred file if the transfer is interrupted. In some circumstances
it is more desirable to keep partially transferred files. Using the
--partial option tells rsync to keep the partial file which should
make a subsequent transfer of the rest of the file much faster.
dit(bf(--progress)) This option tells rsync to print information
showing the progress of the transfer. This gives a bored user
something to watch.
This option is normally combined with -v. Using this option without
the -v option will produce weird results on your display.
dit(bf(-P)) The -P option is equivalent to --partial --progress. I
found myself typing that combination quite often so I created an
option to make it easier.
dit(bf(--password-file)) This option allows you to provide a password
in a file for accessing a remote rsync server. Note that this option
is only useful when accessing a rsync server using the built in
transport, not when using a remote shell as the transport. The file
must not be world readable. It should contain just the password as a
single line.
dit(bf(--bwlimit=KBPS)) This option allows you to specify a maximum
transfer rate in kilobytes per second. This option is most effective when
using rsync with large files (several megabytes and up). Due to the nature
of rsync transfers, blocks of data are sent, then if rsync determines the
transfer was too fast, it will wait before sending the next data block. The
result is an average transfer rate equalling the specified limit. A value
of zero specifies no limit.
enddit()
manpagesection(EXCLUDE PATTERNS)
@@ -593,34 +673,48 @@ skipped. If it is an include pattern then that filename is not
skipped. If no matching include/exclude pattern is found then the
filename is not skipped.
Note that when used with -r (which is implied by -a), every subcomponent of
every path is visited from top down, so include/exclude patterns get
applied recursively to each subcomponent.
Note also that the --include and --exclude options take one pattern
each. To add multiple patterns use the --include-from and
--exclude-from options or multiple --include and --exclude options.
The patterns can take several forms. The rules are:
itemize(
it() if the pattern starts with a / then it is matched against the
start of the filename, otherwise it is matched against the end of
the filename. Thus /foo would match a file called foo
at the base of the tree whereas foo would match any file
called foo anywhere in the tree.
the filename. Thus "/foo" would match a file called "foo" at the base of
the tree. On the other hand, "foo" would match any file called "foo"
anywhere in the tree because the algorithm is applied recursively from
top down; it behaves as if each path component gets a turn at being the
end of the file name.
it() if the pattern ends with a / then it will only match a
directory, not a file, link or device.
it() if the pattern contains a wildcard character from the set
*?[ then regular expression matching is applied using the
normal shell filename matching rules. Otherwise a simple string
match is used.
*?[ then expression matching is applied using the shell filename
matching rules. Otherwise a simple string match is used.
it() if the pattern includes a double asterisk "**" then all wildcards in
the pattern will match slashes, otherwise they will stop at slashes.
it() if the pattern contains a / (not counting a trailing /) then it
is matched against the full filename, including any leading
directory. If the pattern doesn't contain a / then it is matched
only against the final component of the filename.
only against the final component of the filename. Again, remember
that the algorithm is applied recursively so "full filename" can
actually be any portion of a path.
it() if the pattern starts with "+ " (a plus followed by a space)
then it is always considered a include pattern, even if specified as
then it is always considered an include pattern, even if specified as
part of an exclude option. The "+ " part is discarded before matching.
it() if the pattern starts with "- " (a minus followed by a space)
then it is always considered a exclude pattern, even if specified as
then it is always considered an exclude pattern, even if specified as
part of an include option. The "- " part is discarded before matching.
it() if the pattern is a single exclamation mark ! then the current
@@ -630,12 +724,23 @@ itemize(
The +/- rules are most useful in exclude lists, allowing you to have a
single exclude list that contains both include and exclude options.
Here are some examples:
If you end an exclude list with --exclude '*', note that since the
algorithm is applied recursively that unless you explicitly include
parent directories of files you want to include then the algorithm
will stop at the parent directories and never see the files below
them. To include all directories, use --include '*/' before the
--exclude '*'.
Here are some exclude/include examples:
itemize(
it() --exclude "*.o" would exclude all filenames matching *.o
it() --exclude "/foo" would exclude a file in the base directory called foo
it() --exclude "foo/" would exclude any directory called foo
it() --exclude "/foo/*/bar" would exclude any file called bar two
levels below a base directory called foo
it() --exclude "/foo/**/bar" would exclude any file called bar two
or more levels below a base directory called foo
it() --include "*/" --include "*.c" --exclude "*" would include all
directories and C source files
it() --include "foo/" --include "foo/bar.c" --exclude "*" would include
@@ -659,7 +764,7 @@ verb(
)
then look at out.dat. If everything is working correctly then out.dat
should be a zero length file. You you are getting the above error from
should be a zero length file. If you are getting the above error from
rsync then you will probably find that out.dat contains some text or
data. Look at the contents and try to work out what is producing
it. The most common cause is incorrectly configured shell startup
@@ -678,6 +783,10 @@ dit(bf(RSYNC_RSH)) The RSYNC_RSH environment variable allows you to
override the default shell used as the transport for rsync. This can
be used instead of the -e option.
dit(bf(RSYNC_PROXY)) The RSYNC_PROXY environment variable allows you to
redirect your rsync client to use a web proxy when connecting to a
rsync daemon. You should set RSYNC_PROXY to a hostname:port pair.
dit(bf(RSYNC_PASSWORD)) Setting RSYNC_PASSWORD to the required
password allows you to run authenticated rsync connections to a rsync
daemon without user intervention. Note that this does not supply a

View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsyncd.conf)(5)(25 Nov 1998)()()
manpage(rsyncd.conf)(5)(12 Feb 1999)()()
manpagename(rsyncd.conf)(configuration file for rsync server)
manpagesynopsis()
@@ -58,8 +58,9 @@ and a single line something like this to /etc/inetd.conf:
quote(rsync stream tcp nowait root /usr/bin/rsync rsyncd --daemon)
You will then need to send inetd a HUP signal to tell it to reread its
config file.
Replace "/usr/bin/rsync" with the path to where you have rsync installed on
your system. You will then need to send inetd a HUP signal to tell it to
reread its config file.
Note that you should not send the rsync server a HUP signal to force
it to reread the tt(/etc/rsyncd.conf). The file is re-read on each client
@@ -80,17 +81,6 @@ dit(bf(motd file)) The "motd file" option allows you to specify a
usually contains site information and any legal notices. The default
is no motd file.
dit(bf(max connections)) The "max connections" option allows you to
specify the maximum number of simultaneous connections you will allow
to 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.
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).
dit(bf(log file)) The "log file" option tells the rsync daemon to log
messages to that file rather than using syslog. This is particularly
useful on systems (such as AIX) where syslog() doesn't work for
@@ -138,8 +128,22 @@ 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.
The default is to use chroot.
of not being able to follow symbolic links outside of the new root path
when reading. For writing 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.
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.
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).
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
@@ -153,18 +157,24 @@ 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
file transfers to and from that module should take place as. In
combination with the "gid" option this determines what file
permissions are available. The default is the user "nobody".
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 the user "nobody".
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. This
complements the "uid" option. The default is the group "nobody".
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 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. Note that this option is not designed with strong security in
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.
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
@@ -173,17 +183,19 @@ file permissions.
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. See also the note about security for the exclude
option above.
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.
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.
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 for information on the syntax of
this option.
See the section of exclude patterns in the rsync man page for information
on the syntax of this option.
dit(bf(include from)) The "include from" option specifies a filename
on the server that contains include patterns, one per line. This is
@@ -210,10 +222,15 @@ can contain any characters but be warned that many operating systems
limit the length of passwords that can be typed at the client end, so
you may find that passwords longer than 8 characters don't work.
bf(You should make sure that the secrets file is not readable by anyone
other than the system administrator.) There is no default for the
"secrets file" option, you must choose a name (such as
tt(/etc/rsyncd.secrets)).
There is no default for the "secrets file" option, you must choose a name
(such as tt(/etc/rsyncd.secrets)).
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
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.
dit(bf(hosts allow)) The "hosts allow" option allows you to specify a
list of patterns that are matched against a connecting clients
@@ -260,6 +277,14 @@ 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
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
test is counter productive so you can use this option to turn off this
behaviour.
dit(bf(transfer logging)) The "transfer logging" option enables per-file
logging of downloads and uploads in a format somewhat similar to that
used by ftp daemons. If you want to customize the log formats look at
@@ -281,14 +306,15 @@ itemize(
it() %f for the filename
it() %P for the module path
it() %m for the module name
it() %t for the current time
it() %t for the current date time
it() %u for the authenticated username (or the null string)
it() %b for the number of bytes actually transferred
it() %c when sending files this gives the number of checksum bytes
received for this file
)
The default log format is "%o %h [%a] %m (%u) %f %l"
The default log format is "%o %h [%a] %m (%u) %f %l", and a "%t [%p] "
is always added to the beginning when using the "log file" option.
A perl script called rsyncstats to summarize this format is included
in the rsync source code distribution.
@@ -319,7 +345,7 @@ 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.
The default setting is verb(*.gz *.tgz *.zip *.z *.rpm *.deb)
The default setting is verb(*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz)
enddit()

View File

@@ -70,8 +70,8 @@ static struct sum_struct *receive_sums(int f)
offset += s->sums[i].len;
if (verbose > 3)
rprintf(FINFO,"chunk[%d] len=%d offset=%d sum1=%08x\n",
i,s->sums[i].len,(int)s->sums[i].offset,s->sums[i].sum1);
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;
@@ -160,7 +160,7 @@ void send_files(struct file_list *flist,int f_out,int f_in)
return;
}
fd = open(fname,O_RDONLY);
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) {
io_error = 1;
rprintf(FERROR,"send_files failed to open %s: %s\n",
@@ -185,8 +185,8 @@ void send_files(struct file_list *flist,int f_out,int f_in)
}
if (verbose > 2)
rprintf(FINFO,"send_files mapped %s of size %d\n",
fname,(int)st.st_size);
rprintf(FINFO,"send_files mapped %s of size %.0f\n",
fname,(double)st.st_size);
write_int(f_out,i);

169
socket.c
View File

@@ -23,38 +23,138 @@
#include "rsync.h"
/* 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)
{
char buffer[1024];
char *cp;
slprintf(buffer, sizeof(buffer), "CONNECT %s:%d HTTP/1.0\r\n\r\n", host, port);
if (write(fd, buffer, strlen(buffer)) != strlen(buffer)) {
rprintf(FERROR, "failed to write to proxy - %s\n",
strerror(errno));
return -1;
}
for (cp = buffer; cp < &buffer[sizeof(buffer) - 1]; cp++) {
if (read(fd, cp, 1) != 1) {
rprintf(FERROR, "failed to read from proxy\n");
return -1;
}
if (*cp == '\n')
break;
}
if (*cp != '\n')
cp++;
*cp-- = '\0';
if (*cp == '\r')
*cp = '\0';
if (strncmp(buffer, "HTTP/", 5) != 0) {
rprintf(FERROR, "bad response from proxy - %s\n",
buffer);
return -1;
}
for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
;
while (*cp == ' ')
cp++;
if (*cp != '2') {
rprintf(FERROR, "bad response from proxy - %s\n",
buffer);
return -1;
}
/* throw away the rest of the HTTP header */
while (1) {
for (cp = buffer; cp < &buffer[sizeof(buffer) - 1];
cp++) {
if (read(fd, cp, 1) != 1) {
rprintf(FERROR, "failed to read from proxy\n");
return -1;
}
if (*cp == '\n')
break;
}
if ((cp > buffer) && (*cp == '\n'))
cp--;
if ((cp == buffer) && ((*cp == '\n') || (*cp == '\r')))
break;
}
return 0;
}
/* open a socket to a tcp remote host with the specified port
based on code from Warren */
int open_socket_out(char *host, int port)
based on code from Warren
proxy support by Stephen Rothwell */
int open_socket_out(char *host, int port, struct in_addr *address)
{
int type = SOCK_STREAM;
struct sockaddr_in sock_out;
struct sockaddr_in sock;
int res;
struct hostent *hp;
char *h;
unsigned p;
int proxied = 0;
char buffer[1024];
char *cp;
/* 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 */
h = getenv("RSYNC_PROXY");
proxied = (h != NULL) && (*h != '\0');
if (proxied) {
strlcpy(buffer, h, sizeof(buffer));
cp = strchr(buffer, ':');
if (cp == NULL) {
rprintf(FERROR, "invalid proxy specification\n");
return -1;
}
*cp++ = '\0';
p = atoi(cp);
h = buffer;
} else {
h = host;
p = port;
}
res = socket(PF_INET, type, 0);
if (res == -1) {
return -1;
}
hp = gethostbyname(host);
hp = gethostbyname(h);
if (!hp) {
rprintf(FERROR,"unknown host: %s\n", host);
rprintf(FERROR,"unknown host: %s\n", h);
close(res);
return -1;
}
memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
sock_out.sin_port = htons(port);
sock_out.sin_port = htons(p);
sock_out.sin_family = PF_INET;
if (address) {
sock.sin_addr = *address;
sock.sin_port = 0;
sock.sin_family = hp->h_addrtype;
bind(res, (struct sockaddr * ) &sock,sizeof(sock));
}
if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
rprintf(FERROR,"failed to connect to %s - %s\n", h, strerror(errno));
close(res);
rprintf(FERROR,"failed to connect to %s - %s\n", host, strerror(errno));
return -1;
}
set_nonblocking(res);
if (proxied && establish_proxy_connection(res, host, port) != 0) {
close(res);
return -1;
}
return res;
}
@@ -63,11 +163,11 @@ int open_socket_out(char *host, int port)
/****************************************************************************
open a socket of the specified type, port and address for incoming data
****************************************************************************/
static int open_socket_in(int type, int port)
static int open_socket_in(int type, int port, struct in_addr *address)
{
struct hostent *hp;
struct sockaddr_in sock;
char host_name[200];
char host_name[MAXHOSTNAMELEN];
int res;
int one=1;
@@ -87,7 +187,11 @@ static int open_socket_in(int type, int port)
memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
sock.sin_port = htons(port);
sock.sin_family = hp->h_addrtype;
sock.sin_addr.s_addr = INADDR_ANY;
if (address) {
sock.sin_addr = *address;
} else {
sock.sin_addr.s_addr = INADDR_ANY;
}
res = socket(hp->h_addrtype, type, 0);
if (res == -1) {
rprintf(FERROR,"socket failed\n");
@@ -121,9 +225,10 @@ int is_a_socket(int fd)
void start_accept_loop(int port, int (*fn)(int ))
{
int s;
extern struct in_addr socket_address;
/* open an incoming socket */
s = open_socket_in(SOCK_STREAM, port);
s = open_socket_in(SOCK_STREAM, port, &socket_address);
if (s == -1)
exit_cleanup(RERR_SOCKETIO);
@@ -161,14 +266,12 @@ void start_accept_loop(int port, int (*fn)(int ))
but I have had reports that on Digital Unix zombies
are produced, so this ensures that they are reaped */
#ifdef WNOHANG
waitpid(-1, NULL, WNOHANG);
while (waitpid(-1, NULL, WNOHANG) > 0);
#endif
if (fork()==0) {
close(s);
set_nonblocking(fd);
_exit(fn(fd));
}
@@ -386,3 +489,39 @@ char *client_name(int fd)
return name_buf;
}
/*******************************************************************
convert a string to an IP address. The string can be a name or
dotted decimal number
******************************************************************/
struct in_addr *ip_address(const char *str)
{
static struct in_addr ret;
struct hostent *hp;
/* try as an IP address */
if (inet_aton(str, &ret) != 0) {
return &ret;
}
/* otherwise assume it's a network name of some sort and use
gethostbyname */
if ((hp = gethostbyname(str)) == 0) {
rprintf(FERROR, "gethostbyname: Unknown host. %s\n",str);
return NULL;
}
if (hp->h_addr == NULL) {
rprintf(FERROR, "gethostbyname: host address is invalid for host %s\n",str);
return NULL;
}
if (hp->h_length > sizeof(ret)) {
rprintf(FERROR, "gethostbyname: host address is too large\n");
return NULL;
}
memcpy(&ret.s_addr, hp->h_addr, hp->h_length);
return(&ret);
}

View File

@@ -24,8 +24,9 @@
extern int dry_run;
extern int read_only;
extern int list_only;
#define CHECK_RO if (read_only) {errno = EROFS; return -1;}
#define CHECK_RO if (read_only || list_only) {errno = EROFS; return -1;}
int do_unlink(char *fname)
{
@@ -75,12 +76,17 @@ int do_rmdir(char *pathname)
int do_open(char *pathname, int flags, mode_t mode)
{
if (dry_run) return -1;
if (flags != O_RDONLY) {
if (dry_run) return -1;
CHECK_RO
}
#ifdef O_BINARY
/* for Windows */
flags |= O_BINARY;
#endif
CHECK_RO
/* some systems can't handle a double / */
if (pathname[0] == '/' && pathname[1] == '/') pathname++;
return open(pathname, flags, mode);
}

111
test.sh
View File

@@ -1,7 +1,6 @@
#!/bin/sh
#
# Copyright (C) 1998 Philip Hands <http://www.hands.com/~phil/>
# Copyright (C) 1998,1999 Philip Hands <phil@hands.com>
#
# This program is distributable under the terms of the GNU GPL (see COPYING)
#
@@ -10,7 +9,15 @@
#
#
cat <<EOF
# 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
@@ -18,7 +25,19 @@ do not indicate a problem with rsync.
EOF
export PATH=.:$PATH
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
@@ -38,34 +57,53 @@ ln -s nolf ${FROM}/nolf-symlink
cat /etc/inittab /etc/services /etc/resolv.conf > ${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() {
echo -n "Test $4: $5:"
log=${LOG}.$4
testnum=`expr 0${testnum} + 1`
log=${LOG}.${testnum}
failed=
echo "Running: \"$1\"" >${log}
echo "">>${log}
eval "$1 || failed=YES" >>${log} 2>&1
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} || failed=YES
diff -ur $2 $3 >>${log} 2>&1 || failed=YES
echo "-------------">>${log}
echo "check how the directory listings compare with diff:">>${log}
echo "">>${log}
ls -la $2 > ${TMP}/ls-from
ls -la $3 > ${TMP}/ls-to
diff -u ${TMP}/ls-from ${TMP}/ls-to >>${log} || failed=YES
( 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
echo " done."
test -z "${Debian}" && echo " done."
rm $log
return 0
else
echo " FAILED."
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
@@ -87,44 +125,45 @@ EOF
# Main script starts here
checkit "rsync -av ${FROM}/ ${TO}" ${FROM}/ ${TO} \
1 "basic operation"
runtest "basic operation" 'checkit "$RSYNC -av ${FROM}/ ${TO}" ${FROM}/ ${TO}'
ln ${FROM}/pslist ${FROM}/dir
checkit "rsync -avH ${FROM}/ ${TO}" ${FROM}/ ${TO} \
2 "hard links"
runtest "hard links" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
rm ${TO}/${F1}
checkit "rsync -avH ${FROM}/ ${TO}" ${FROM}/ ${TO} \
3 "one file"
runtest "one file" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
echo "extra line" >> ${TO}/${F1}
checkit "rsync -avH ${FROM}/ ${TO}" ${FROM}/ ${TO} \
4 "extra data"
runtest "extra data" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
cp ${FROM}/${F1} ${TO}/ThisShouldGo
checkit "rsync --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO} \
5 " --delete"
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
checkit "rsync --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO} \
6 "long paths"
runtest "long paths" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
if type ssh >/dev/null ; then
rm -rf ${TO}
checkit "rsync -avH -e ssh ${FROM}/ localhost:${TO}" ${FROM}/ ${TO} \
7 "ssh: basic test"
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
checkit "rsync --delete -avH -e ssh ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}\
8 "ssh: renamed file"
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
echo ""
echo "**** Skipping SSH tests because ssh is not in the path ****"
echo ""
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

@@ -28,6 +28,7 @@
extern int preserve_uid;
extern int preserve_gid;
extern int numeric_ids;
extern int am_root;
struct idlist {
struct idlist *next;
@@ -122,7 +123,10 @@ static gid_t match_gid(gid_t gid)
list = list->next;
}
last_out = gid;
if (am_root)
last_out = gid;
else
last_out = (gid_t) -1;
return last_out;
}
@@ -276,12 +280,12 @@ void recv_uid_list(int f, struct file_list *flist)
}
}
if (!uidlist && !gidlist) return;
if (!(am_root && preserve_uid) && !preserve_gid) return;
/* now convert the uid/gid of all files in the list to the mapped
uid/gid */
for (i=0;i<flist->count;i++) {
if (preserve_uid && flist->files[i]->uid != 0) {
if (am_root && preserve_uid && flist->files[i]->uid != 0) {
flist->files[i]->uid = match_uid(flist->files[i]->uid);
}
if (preserve_gid && flist->files[i]->gid != 0) {

333
util.c
View File

@@ -24,42 +24,83 @@
*/
#include "rsync.h"
extern int verbose;
/****************************************************************************
Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
else
if SYSV use O_NDELAY
if BSD use FNDELAY
Set a fd into nonblocking mode
****************************************************************************/
int set_nonblocking(int fd)
void set_nonblocking(int fd)
{
int val;
#ifdef O_NONBLOCK
#define FLAG_TO_SET O_NONBLOCK
#else
#ifdef SYSV
#define FLAG_TO_SET O_NDELAY
#else /* BSD */
#define FLAG_TO_SET FNDELAY
#endif
#endif
if((val = fcntl(fd, F_GETFL, 0)) == -1)
return -1;
val |= FLAG_TO_SET;
return fcntl( fd, F_SETFL, val);
#undef FLAG_TO_SET
return;
if (!(val & NONBLOCK_FLAG)) {
val |= NONBLOCK_FLAG;
fcntl(fd, F_SETFL, val);
}
}
/****************************************************************************
Set a fd into blocking mode
****************************************************************************/
void set_blocking(int fd)
{
int val;
if((val = fcntl(fd, F_GETFL, 0)) == -1)
return;
if (val & NONBLOCK_FLAG) {
val &= ~NONBLOCK_FLAG;
fcntl(fd, F_SETFL, val);
}
}
/* this is taken from CVS */
/* create a file descriptor pair - like pipe() but use socketpair if
possible (because of blocking issues on pipes)
always set non-blocking
*/
int fd_pair(int fd[2])
{
int ret;
#if HAVE_SOCKETPAIR
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
#else
ret = pipe(fd);
#endif
if (ret == 0) {
set_nonblocking(fd[0]);
set_nonblocking(fd[1]);
}
return ret;
}
/* 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.
*/
int piped_child(char **command,int *f_in,int *f_out)
{
int pid;
int to_child_pipe[2];
int from_child_pipe[2];
extern int blocking_io;
if (pipe(to_child_pipe) < 0 ||
pipe(from_child_pipe) < 0) {
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rprintf(FERROR,"pipe: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
@@ -84,6 +125,10 @@ int piped_child(char **command,int *f_in,int *f_out)
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) {
set_blocking(STDOUT_FILENO);
}
execvp(command[0], command);
rprintf(FERROR,"Failed to exec %s : %s\n",
command[0],strerror(errno));
@@ -99,9 +144,6 @@ int piped_child(char **command,int *f_in,int *f_out)
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
set_nonblocking(*f_in);
set_nonblocking(*f_out);
return pid;
}
@@ -111,8 +153,8 @@ int local_child(int argc, char **argv,int *f_in,int *f_out)
int to_child_pipe[2];
int from_child_pipe[2];
if (pipe(to_child_pipe) < 0 ||
pipe(from_child_pipe) < 0) {
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rprintf(FERROR,"pipe: %s\n",strerror(errno));
exit_cleanup(RERR_IPC);
}
@@ -280,14 +322,14 @@ int copy_file(char *source, char *dest, mode_t mode)
char buf[1024 * 8];
int len; /* Number of bytes read into `buf'. */
ifd = open(source, O_RDONLY);
ifd = do_open(source, O_RDONLY, 0);
if (ifd == -1) {
rprintf(FERROR,"open %s: %s\n",
source,strerror(errno));
return -1;
}
if (do_unlink(dest) && errno != ENOENT) {
if (robust_unlink(dest) && errno != ENOENT) {
rprintf(FERROR,"unlink %s: %s\n",
dest,strerror(errno));
return -1;
@@ -323,14 +365,78 @@ int copy_file(char *source, char *dest, mode_t mode)
return 0;
}
/* sleep for a while via select */
void u_sleep(int usec)
{
struct timeval tv;
/*
Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
rename to <path>/.rsyncNNN instead. Note that successive rsync runs
will shuffle the filenames around a bit as long as the file is still
busy; this is because this function does not know if the unlink call
is due to a new file coming in, or --delete trying to remove old
.rsyncNNN files, hence it renames it each time.
*/
/* MAX_RENAMES should be 10**MAX_RENAMES_DIGITS */
#define MAX_RENAMES_DIGITS 3
#define MAX_RENAMES 1000
tv.tv_sec = 0;
tv.tv_usec = usec;
select(0, NULL, NULL, NULL, &tv);
int robust_unlink(char *fname)
{
#ifndef ETXTBSY
return do_unlink(fname);
#else
static int counter = 1;
int rc, pos, start;
char path[MAXPATHLEN];
rc = do_unlink(fname);
if ((rc == 0) || (errno != ETXTBSY))
return rc;
strlcpy(path, fname, MAXPATHLEN);
pos = strlen(path);
while((path[--pos] != '/') && (pos >= 0))
;
++pos;
strlcpy(&path[pos], ".rsync", MAXPATHLEN-pos);
pos += sizeof(".rsync")-1;
if (pos > (MAXPATHLEN-MAX_RENAMES_DIGITS-1)) {
errno = ETXTBSY;
return -1;
}
/* start where the last one left off to reduce chance of clashes */
start = counter;
do {
sprintf(&path[pos], "%03d", counter);
if (++counter >= MAX_RENAMES)
counter = 1;
} while (((rc = access(path, 0)) == 0) && (counter != start));
if (verbose > 0)
rprintf(FINFO,"renaming %s to %s because of text busy\n",
fname, path);
/* maybe we should return rename()'s exit status? Nah. */
if (do_rename(fname, path) != 0) {
errno = ETXTBSY;
return -1;
}
return 0;
#endif
}
int robust_rename(char *from, char *to)
{
#ifndef ETXTBSY
return do_rename(from, to);
#else
int rc = do_rename(from, to);
if ((rc == 0) || (errno != ETXTBSY))
return rc;
if (robust_unlink(to) != 0)
return -1;
return do_rename(from, to);
#endif
}
@@ -400,7 +506,7 @@ int lock_range(int fd, int offset, int len)
}
static void glob_expand_one(char *s, char **argv, int *argc, int maxargs, int sanitize_paths)
static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
{
#if !(defined(HAVE_GLOB) && defined(HAVE_GLOB_H))
if (!*s) s = ".";
@@ -408,14 +514,16 @@ static void glob_expand_one(char *s, char **argv, int *argc, int maxargs, int sa
(*argc)++;
return;
#else
extern int sanitize_paths;
glob_t globbuf;
int i;
if (!*s) s = ".";
s = strdup(s);
sanitize_path(s);
argv[*argc] = s;
argv[*argc] = strdup(s);
if (sanitize_paths) {
sanitize_path(argv[*argc], NULL);
}
memset(&globbuf, 0, sizeof(globbuf));
glob(argv[*argc], 0, NULL, &globbuf);
@@ -434,7 +542,7 @@ static void glob_expand_one(char *s, char **argv, int *argc, int maxargs, int sa
#endif
}
void glob_expand(char *base1, char **argv, int *argc, int maxargs, int sanitize_paths)
void glob_expand(char *base1, char **argv, int *argc, int maxargs)
{
char *s = argv[*argc];
char *p, *q;
@@ -458,11 +566,11 @@ void glob_expand(char *base1, char **argv, int *argc, int maxargs, int sanitize_
while ((p = strstr(q,base)) && ((*argc) < maxargs)) {
/* split it at this point */
*p = 0;
glob_expand_one(q, argv, argc, maxargs, sanitize_paths);
glob_expand_one(q, argv, argc, maxargs);
q = p+strlen(base);
}
if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs, sanitize_paths);
if (*q && (*argc < maxargs)) glob_expand_one(q, argv, argc, maxargs);
free(s);
free(base);
@@ -558,19 +666,37 @@ void clean_fname(char *name)
/*
* Make path appear as if a chroot had occurred:
* 1. remove leading "/" (or replace with "." if at end)
* 2. remove leading ".." components
* 2. remove leading ".." components (except those allowed by "reldir")
* 3. delete any other "<dir>/.." (recursively)
* Can only shrink paths, so sanitizes in place.
* While we're at it, remove double slashes and "." components like
* clean_fname does(), but DON'T remove a trailing slash because that
* is sometimes significant on command line arguments.
* Can only shrink paths, so sanitizes in place.
* If "reldir" is non-null, it is a sanitized directory that the path will be
* relative to, so allow as many ".." at the beginning of the path as
* there are components in reldir. This is used for symbolic link targets.
* If reldir is non-null and the path began with "/", to be completely like
* a chroot we should add in depth levels of ".." at the beginning of the
* path, but that would blow the assumption that the path doesn't grow and
* it is not likely to end up being a valid symlink anyway, so just do
* the normal removal of the leading "/" instead.
* Contributed by Dave Dykstra <dwd@bell-labs.com>
*/
void sanitize_path(char *p)
void sanitize_path(char *p, char *reldir)
{
char *start, *sanp;
int depth = 0;
int allowdotdot = 0;
if (reldir) {
depth++;
while (*reldir) {
if (*reldir++ == '/') {
depth++;
}
}
}
start = p;
sanp = p;
while (*p == '/') {
@@ -588,36 +714,55 @@ void sanitize_path(char *p)
/* skip following slashes */
;
}
} else if ((*p == '.') && (*(p+1) == '.') &&
continue;
}
allowdotdot = 0;
if ((*p == '.') && (*(p+1) == '.') &&
((*(p+2) == '/') || (*(p+2) == '\0'))) {
/* skip ".." component followed by slash or end */
p += 2;
if (*p == '/')
p++;
if (sanp != start) {
/* back up sanp one level */
--sanp; /* now pointing at slash */
while ((sanp > start) && (*(sanp - 1) != '/')) {
/* skip back up to slash */
sanp--;
}
}
} else {
while (1) {
/* copy one component through next slash */
*sanp++ = *p++;
if ((*p == '\0') || (*(p-1) == '/')) {
while (*p == '/') {
/* skip multiple slashes */
p++;
/* ".." component followed by slash or end */
if ((depth > 0) && (sanp == start)) {
/* allow depth levels of .. at the beginning */
--depth;
allowdotdot = 1;
} else {
p += 2;
if (*p == '/')
p++;
if (sanp != start) {
/* back up sanp one level */
--sanp; /* now pointing at slash */
while ((sanp > start) && (*(sanp - 1) != '/')) {
/* skip back up to slash */
sanp--;
}
break;
}
continue;
}
}
while (1) {
/* copy one component through next slash */
*sanp++ = *p++;
if ((*p == '\0') || (*(p-1) == '/')) {
while (*p == '/') {
/* skip multiple slashes */
p++;
}
break;
}
}
if (allowdotdot) {
/* move the virtual beginning to leave the .. alone */
start = sanp;
}
}
if (sanp == start) {
if ((sanp == start) && !allowdotdot) {
/* ended up with nothing, so put in "." component */
/*
* note that the !allowdotdot doesn't prevent this from
* happening in all allowed ".." situations, but I didn't
* think it was worth putting in an extra variable to ensure
* it since an extra "." won't hurt in those situations.
*/
*sanp++ = '.';
}
*sanp = '\0';
@@ -638,6 +783,8 @@ char *push_dir(char *dir, int save)
getcwd(curr_dir, sizeof(curr_dir)-1);
}
if (!dir) return NULL; /* this call was probably just to initialize */
if (chdir(dir)) return NULL;
if (save) {
@@ -690,12 +837,12 @@ int u_strcmp(const char *cs1, const char *cs2)
static OFF_T last_ofs;
void end_progress(void)
void end_progress(OFF_T size)
{
extern int do_progress, am_server;
if (do_progress && !am_server) {
rprintf(FINFO,"\n");
rprintf(FINFO,"%.0f (100%%)\n", (double)size);
}
last_ofs = 0;
}
@@ -782,3 +929,47 @@ char *timestring(time_t t)
return(TimeBuf);
}
/****************************************************************************
like waitpid but does the WEXITSTATUS
****************************************************************************/
#ifndef WEXITSTATUS
#define WEXITSTATUS(stat) ((int)(((stat)>>8)&0xFF))
#endif
void wait_process(pid_t pid, int *status)
{
waitpid(pid, status, 0);
*status = WEXITSTATUS(*status);
}
#ifdef __INSURE__
#include <dlfcn.h>
/*******************************************************************
This routine is a trick to immediately catch errors when debugging
with insure. A xterm with a gdb is popped up when insure catches
a error. It is Linux specific.
********************************************************************/
int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
{
static int (*fn)();
int ret;
char cmd[1024];
sprintf(cmd, "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'",
getpid(), getpid(), getpid());
if (!fn) {
static void *h;
h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
fn = dlsym(h, "_Insure_trap_error");
}
ret = fn(a1, a2, a3, a4, a5, a6);
system(cmd);
return ret;
}
#endif

View File

@@ -1 +1 @@
#define VERSION "2.2.1"
#define VERSION "2.4.4"