Compare commits

...

69 Commits

Author SHA1 Message Date
Martin Pool
23212669ac Bump version to 2.5.3pre1 2002-02-19 02:16:37 +00:00
Martin Pool
3ce0f9a653 Clean up error message 2002-02-19 01:41:20 +00:00
Martin Pool
d834adc14f Doc 2002-02-19 01:39:11 +00:00
Martin Pool
b84ba8967a rsync prefix on mkdir and pushdir error messages. 2002-02-19 01:07:24 +00:00
Martin Pool
79845f2834 Doc. 2002-02-18 23:36:10 +00:00
Martin Pool
78ece130a4 Change shell syntax to try to please Solaris 2002-02-18 23:09:50 +00:00
Martin Pool
bd37c66630 Fix error handling for failing to fork after accepting a connection --
close fd, sleep, then try again.
2002-02-18 22:58:49 +00:00
Martin Pool
371d1c36b3 Solaris does not have diff -u. 2002-02-18 22:55:21 +00:00
Martin Pool
d0f821ad3d Must use STRUCT_STAT not "struct stat" to be compatible with other
rsync functions.
2002-02-18 22:49:00 +00:00
Martin Pool
ded8347d6b Cope with BSD systems on which mkdir() will not accept a trailing
slash.

<http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html>
2002-02-18 22:44:23 +00:00
Martin Pool
c4a5c57dc3 If the daemon is unable to fork a child to accept a connection, print
an error message.  (Colin Walters)
2002-02-18 22:38:03 +00:00
Martin Pool
404e813c52 Add -vvv trace statement to set_modtime to help with Debian bug
#100295.
2002-02-18 22:25:55 +00:00
Martin Pool
90d0a8db38 This test must specify --times because it compares listings that
include mtimes.
2002-02-18 22:14:46 +00:00
Martin Pool
956ff9ff72 Fix bug that made tls.o not be removed by 'make clean'. 2002-02-18 22:07:44 +00:00
Martin Pool
1eca49c6ed Doc:
#defiine lchown chown

could be bad on systems which have no lchown and where chown
follows symbollic links.  On such systems it might be better not to
try to chown symlinks at all.
2002-02-18 21:46:49 +00:00
Martin Pool
34758d5c15 Ignore SIGPIPE and allow EPIPE to get through to the program so that
we don't get stuck in a recursive loop trying to report a broken pipe
across that same broken pipe.  Debian bug #128632 (Colin Walters)
2002-02-18 20:06:57 +00:00
Martin Pool
befbfe6115 Fix for rsync server processes hanging around after the client
unexpectedly disconnects.  (Colin Walters) (Debian bug #128632)
2002-02-18 19:54:00 +00:00
Martin Pool
900748fca1 rwrite: Doc. 2002-02-18 19:51:12 +00:00
Martin Pool
87ee248169 Document multiplex stuff. 2002-02-18 19:44:04 +00:00
Martin Pool
bb7c4fa361 Doc. 2002-02-18 19:10:28 +00:00
David Dykstra
c613d37048 If a daemon prints an error message of @ERROR, have the client treat the
message as an FERROR rather than an FINFO.
2002-02-18 18:29:48 +00:00
David Dykstra
d52a22e4db Add item about fixing "out of memory in flist_expand" on Sunos4. 2002-02-14 15:27:55 +00:00
David Dykstra
6dfb45bcdf Added the two most important bug fixes to NEWS to make sure they're not
forgotten for the next release.
2002-02-13 18:57:06 +00:00
David Dykstra
145794936f Patch from Jos Backus <josb@cncdsl.com> to use HAVE_SOCKADDR_LEN rather
than HAVE_SOCK_SIN_LEN around use of sin_len.  Correct usage was already
in place in clientname.c.
2002-02-13 18:45:17 +00:00
David Dykstra
301c680fd7 Suggested patch from Jim Ogilvie <jogilvie@us.ibm.com> to print out the
system error message when mkstemp fails.
2002-02-13 18:42:20 +00:00
David Dykstra
d27cbec598 Reversing the order of maybe_emit_filelist_progress() and
emit_filelist_progress() makes the native compilers on systems
including Solaris and Irix happier.
2002-02-13 18:30:27 +00:00
David Dykstra
f5be54d6ab Some systems, notably Sunos4, do not support realloc(NULL, n), so if
nothing has yet been malloced in flist_expand(), call malloc instead of
realloc.  Problem introduced in revision 1.106 of flist.c on January 25.
2002-02-13 18:06:36 +00:00
Martin Pool
1e19f7ba5f At least change INO64_T and DEV64_T back to just 'int64', not
'unsigned int64'.  This should fix some compile problems on machines
where int64 is not a simple integer type, but I'm not convinced it is
the ideal fix.
2002-02-13 02:57:55 +00:00
Martin Pool
db719fb0d7 Factor out code for filelist progress. Copy&paste considered harmful.
Add a little doc about potential optimization of stat() calls.
2002-02-13 02:44:31 +00:00
Martin Pool
b0d4f4c10e Add a test that --owner correctly propagates ownership of files for a
local transfer as root.
2002-02-09 07:43:13 +00:00
Martin Pool
238d23d775 Add a test that --group correctly propagates groups of which the local
user is a member.
2002-02-09 07:42:37 +00:00
Martin Pool
c019068f06 Add $preserve_scratch and $always_log so if you want to see details
about successful tests, you can.
2002-02-09 03:36:33 +00:00
Martin Pool
715d1f4504 Oops -- have to call setgroups() before giving up root.
Doc some of the peculiarities about starting rsyncd as root vs
non-root.
2002-02-09 03:30:22 +00:00
Martin Pool
4f092bee9f Make sure we call setgroups() after setuid(). (Ethan Benson) 2002-02-09 02:18:42 +00:00
David Dykstra
1bbd10fe07 Remove the "rsync:" prefixes on FINFO messages. Return the "building file
list ... done" to the way it was in 2.5.1 and before when not using -P.
Apply the file list progress messages when receiving files in addition to
sending files.
2002-02-07 16:36:12 +00:00
David Dykstra
088aac8597 Make batch mode actually work and add man page documentation. From Jos Backus. 2002-02-06 21:20:48 +00:00
Martin Pool
81c652d5d2 Merge modified --with-rsh patch: we now determine the default
remote-execution command as follows:

 1) if --with-rsh is specified, use that.

 2) otherwise if remsh is in the path, use that.

 3) otherwise use rsh

If remsh is present, we always modify the order of parameters to suit
it.  This is a bit strange.
2002-02-06 04:37:09 +00:00
Martin Pool
d7761c1480 Doc: Rusty's /*/* exclude hack produces spurious output with -vv. 2002-02-06 04:34:40 +00:00
David Dykstra
93689aa51a Add --no-whole-file and --no-blocking-io options 2002-02-05 23:05:31 +00:00
Martin Pool
46e6ad492a Only print the command used to open connections with -vv, not just -v. 2002-02-05 00:37:53 +00:00
Martin Pool
97efa5c36c Roll over NEWS 2002-02-05 00:35:31 +00:00
Martin Pool
0b1ffe2755 Only print the command used to open connections with -vv, not just -v.
<Pine.LNX.4.33L2.0201301015260.11155-100000@phong.blorf.net>
2002-02-05 00:34:03 +00:00
Martin Pool
8c35542d1f Patch from wayned so that add_exclude_list produces clearer debugging
output with -vvv.
2002-02-05 00:25:52 +00:00
Andrew Tridgell
0e9480317d the signed/unsigned change seems to have caused a logic bug on some
systems (only those without large file support perhaps?)

this fixes it
2002-02-03 01:38:39 +00:00
David Dykstra
b695d088cf Better explanation of --force. It is applicable whenever --delete is
not in effect.
2002-01-29 21:52:57 +00:00
David Dykstra
81dc5750ca A more accurate description of --force as I know it. 2002-01-28 21:09:03 +00:00
David Dykstra
d82434cf27 Clarify the --force entry in the rsync man page. 2002-01-28 17:06:04 +00:00
Martin Pool
cd6058f3d4 Oops, version should be just 2.5.2. 2002-01-25 23:19:21 +00:00
Martin Pool
9be3ba223c Bump version to 2.5.3. 2002-01-25 23:16:18 +00:00
Martin Pool
a261989cda More signedness fixes; should be harmless. 2002-01-25 23:07:33 +00:00
Martin Pool
7b5c3eb05e io_end_buffering doesn't need (or use) it's fd parameter: there's only
one multiplexed stream.
2002-01-25 23:01:50 +00:00
Martin Pool
0feec72eee DEV64_t and INO64_T should probably be unsigned 2002-01-25 23:00:21 +00:00
Martin Pool
be8bd99aa4 check_name doesn't need a socklen_t, because it knows what is inside
each sockaddr type.
2002-01-25 22:59:37 +00:00
Martin Pool
355b8bcd73 Add test case for device nodes. This test will be skipped unless you
run "make check" as root.
2002-01-25 10:56:43 +00:00
Martin Pool
d58e4c273c When comparing directories, use find . to call diff, rather than
diff -r.  Two reasons: diff -r might not work everywhere, and it also
might complain about nonregular files.
2002-01-25 10:55:59 +00:00
Martin Pool
a217ad3095 Add test_skipped function. 2002-01-25 10:47:47 +00:00
Martin Pool
3d6feada8a New --ignore-existing option, patch previously distributed with
Vipul's Razor.  (Debian #124286)
2002-01-25 10:42:23 +00:00
Martin Pool
5f78da2025 Fix for device nodes. (dann frazier) (Debian #129135) 2002-01-25 10:39:08 +00:00
Martin Pool
a05e4fa512 Fix for device nodes. (dann frazier) (Debian #129135) 2002-01-25 10:28:13 +00:00
Martin Pool
2119a4c462 Another DEV64_T change. 2002-01-25 10:16:11 +00:00
Martin Pool
1d5a1da9f8 With -vv, when the file list grows, show a message. 2002-01-25 10:12:36 +00:00
Martin Pool
2e7d19945c With -vv, when the file list grows, show a message. 2002-01-25 10:12:02 +00:00
Martin Pool
5d2c5c4c73 Undo overzealous deletion. 2002-01-25 10:09:00 +00:00
Martin Pool
8694312695 Add dummy show_flist_stats(). 2002-01-25 10:06:36 +00:00
Martin Pool
d9d6bc5278 Factor out code to grow the file list into a common location. 2002-01-25 10:05:49 +00:00
Martin Pool
ebed4c3af0 indent -kr -i8 2002-01-25 09:59:00 +00:00
Martin Pool
172875cf15 Add link to the message that introduced string_area. 2002-01-25 09:54:21 +00:00
Martin Pool
4d26e9e4f4 mallinfo is implemented. 2002-01-25 09:45:45 +00:00
Martin Pool
8f4455f296 Notes about flist. 2002-01-25 09:44:17 +00:00
32 changed files with 1194 additions and 686 deletions

View File

@@ -36,7 +36,7 @@ popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
tls_OBJ = tls.o syscall.o lib/permstring.o
TLS_OBJ = tls.o syscall.o lib/permstring.o
# Programs we must have to run the test cases
CHECK_PROGS = rsync tls
@@ -68,8 +68,8 @@ rsync: $(OBJS)
$(OBJS): config.h
tls: $(tls_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(tls_OBJ) $(LIBS)
tls: $(TLS_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
Makefile: Makefile.in configure config.status
echo "WARNING: You need to run ./config.status --recheck"

43
NEWS
View File

@@ -1,34 +1,39 @@
rsync 2.5.2 (???)
rsync 2.5.3 (not released yet)
SECURITY FIXES:
* Signedness security patch from Sebastian Krahmer
<krahmer@suse.de> -- in some cases we were not sufficiently
careful about reading integers from the network.
* Make sure that supplementary groups are removed from a server
process after changing uid and gid. (Ethan Benson)
BUG FIXES:
* Fix possible string mangling in log files.
* Fixed problem that in many cases caused the error message
unexpected read size of 0 in map_ptr
and resulted in the wrong data being copied.
* Fix for setting local address of outgoing sockets.
* Fixed compilation errors on some systems caused by the use of
"unsigned int64" in rsync.h.
* Better handling of hardlinks and devices on platforms with
64-bit dev_t or ino_t.
* Fixed problem on systems such as Sunos4 that do not support realloc
on a NULL pointer; error was "out of memory in flist_expand".
* Name resolution on machines supporting IPv6 is improved.
* Fix for rsync server processes hanging around after the client
unexpectedly disconnects. (Colin Walters) (Debian bug #128632)
* Cope with BSD systems on which mkdir() will not accept a trailing
slash.
ENHANCEMENTS:
* With -v, rsync now shows the command used to initiate an ssh/rsh
connection.
* Command to initiate connections is only shown with -vv, rather
than -v as in 2.5.2. Output from plain -v is more similar to
what was historically used so as not to break scripts that try
to parse the output.
* --statistics now shows memory heap usage on platforms that
support mallinfo().
* Added --no-whole-file and --no-blocking-io options (Dave Dykstra)
* "The Ted T'so school of program optimization": make progress
visible and people will think it's faster. (With --progress,
rsync will show you how many files it has seen as it builds the
file_list, giving some indication that it has not hung.)
* Made the --write-batch and --read-batch options actually work
and added documentation in the man page (Jos Backus)
* Improvements to batch mode support. This is still experimental
but testing would be welcome. (Jos Backus)
* If the daemon is unable to fork a child to accept a connection,
print an error message. (Colin Walters)

40
OLDNEWS
View File

@@ -1,3 +1,43 @@
rsync 2.5.2 (26 Jan 2002)
SECURITY FIXES:
* Signedness security patch from Sebastian Krahmer
<krahmer@suse.de> -- in some cases we were not sufficiently
careful about reading integers from the network.
BUG FIXES:
* Fix possible string mangling in log files.
* Fix for setting local address of outgoing sockets.
* Better handling of hardlinks and devices on platforms with
64-bit dev_t or ino_t.
* Name resolution on machines supporting IPv6 is improved.
* Fix for device nodes. (dann frazier) (Debian #129135)
ENHANCEMENTS:
* With -v, rsync now shows the command used to initiate an ssh/rsh
connection.
* --statistics now shows memory heap usage on platforms that
support mallinfo().
* "The Ted T'so school of program optimization": make progress
visible and people will think it's faster. (With --progress,
rsync will show you how many files it has seen as it builds the
file_list, giving some indication that it has not hung.)
* Improvements to batch mode support. This is still experimental
but testing would be welcome. (Jos Backus)
* New --ignore-existing option, patch previously distributed with
Vipul's Razor. (Debian #124286)
rsync 2.5.1 (2002-01-03)
BUG FIXES:

16
TODO
View File

@@ -32,6 +32,16 @@ use chroot
for people who want to generate the file list using a find(1)
command or a script.
File list structure in memory
Rather than one big array, perhaps have a tree in memory mirroring
the directory tree.
This might make sorting much faster! (I'm not sure it's a big CPU
problem, mind you.)
It might also reduce memory use in storing repeated directory names
-- again I'm not sure this is a problem.
Performance
@@ -94,9 +104,6 @@ Memory accounting
not sure this makes sense with modern mallocs. At any rate it will
make us allocate a huge amount of memory for large file lists.
We can try using the GNU/SVID/XPG mallinfo() function to get some
heap statistics.
Hard-link handling
@@ -289,6 +296,9 @@ verbose output
Indicate whether files are new, updated, or deleted
At end of transfer, show how many files were or were not transferred
correctly.
internationalization
Change to using gettext(). Probably need to ship this for platforms

228
batch.c
View File

@@ -8,55 +8,38 @@
#include "rsync.h"
#include <time.h>
char rsync_flist_file[27] = "rsync_flist.";
char rsync_csums_file[27] = "rsync_csums.";
char rsync_delta_file[27] = "rsync_delta.";
char rsync_argvs_file[27] = "rsync_argvs.";
char batch_file_ext[15];
int fdb;
int fdb_delta;
int fdb_open;
int fdb_close;
extern char *batch_prefix;
struct file_list *batch_flist;
void create_batch_file_ext()
{
struct tm *timeptr;
time_t elapsed_seconds;
static char rsync_flist_file[] = ".rsync_flist";
static char rsync_csums_file[] = ".rsync_csums";
static char rsync_delta_file[] = ".rsync_delta";
static char rsync_argvs_file[] = ".rsync_argvs";
/* Save run date and time to use for batch file extensions */
time(&elapsed_seconds);
timeptr = localtime(&elapsed_seconds);
sprintf(batch_file_ext, "%4d%02d%02d%02d%02d%02d",
timeptr->tm_year + 1900, timeptr->tm_mon + 1,
timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min,
timeptr->tm_sec);
rprintf(FINFO,"batch file extension: %s\n", batch_file_ext);
}
void set_batch_file_ext(char *ext)
{
strcpy(batch_file_ext, ext);
}
static int fdb;
static int fdb_delta;
static int fdb_open;
static int fdb_close;
void write_batch_flist_file(char *buff, int bytes_to_write)
{
char filename[MAXPATHLEN];
if (fdb_open) {
/* Set up file extension */
strcat(rsync_flist_file, batch_file_ext);
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_flist_file, sizeof(filename));
/* Open batch flist file for writing; create it if it doesn't exist */
fdb =
do_open(rsync_flist_file, O_WRONLY | O_CREAT | O_TRUNC,
/*
* Open batch flist file for writing;
* create it if it doesn't exist
*/
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_flist_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
@@ -67,12 +50,11 @@ void write_batch_flist_file(char *buff, int bytes_to_write)
if (write(fdb, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
rsync_flist_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
if (fdb_close) {
close(fdb);
}
@@ -110,7 +92,6 @@ void write_batch_flist_info(int flist_count, struct file_struct **fptr)
}
write_char_bufs(fptr[i]->sum);
}
}
void write_char_bufs(char *buf)
@@ -118,11 +99,8 @@ void write_char_bufs(char *buf)
/* Write the size of the string which will follow */
char b[4];
if (buf != NULL)
SIVAL(b, 0, strlen(buf));
else {
SIVAL(b, 0, 0);
}
SIVAL(b, 0, buf != NULL ? strlen(buf) : 0);
write_batch_flist_file(b, sizeof(int));
@@ -137,36 +115,52 @@ void write_batch_argvs_file(int argc, char *argv[])
{
int fdb;
int i;
char buff[256];
char buff[256]; /* XXX */
char buff2[MAXPATHLEN + 6];
char filename[MAXPATHLEN];
strcat(rsync_argvs_file, batch_file_ext);
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_argvs_file, sizeof(filename));
/* Open batch argvs file for writing; create it if it doesn't exist */
fdb = do_open(rsync_argvs_file, O_WRONLY | O_CREAT | O_TRUNC,
/*
* Open batch argvs file for writing;
* create it if it doesn't exist
*/
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE | S_IEXEC);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_argvs_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
buff[0] = '\0';
/* Write argvs info to batch file */
for (i = 0; i < argc; ++i) {
if (i == argc - 2)
if (i == argc - 2) /* Skip source directory on cmdline */
continue;
/*
* FIXME:
* I think directly manipulating argv[] is probably bogus
*/
if (!strcmp(argv[i], "--write-batch")) {
if (!strncmp(argv[i], "--write-batch",
strlen("--write-batch"))) {
/* Safer to change it here than script */
/* Change to --read-batch + ext * to get ready for remote */
strlcat(buff, "--read-batch ", sizeof(buff));
strlcat(buff, batch_file_ext, sizeof(buff));
} else {
/*
* Change to --read-batch=prefix
* to get ready for remote
*/
strlcat(buff, "--read-batch=", sizeof(buff));
strlcat(buff, batch_prefix, sizeof(buff));
} else
if (i == argc - 1) {
snprintf(buff2, sizeof(buff2), "${1:-%s}", argv[i]);
strlcat(buff, buff2, sizeof(buff));
}
else {
strlcat(buff, argv[i], sizeof(buff));
}
@@ -177,14 +171,14 @@ void write_batch_argvs_file(int argc, char *argv[])
strlcat(buff, "\n", sizeof(buff));
if (!write(fdb, buff, strlen(buff))) {
rprintf(FERROR, "Batch file %s write error: %s\n",
rsync_argvs_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
close(fdb);
}
struct file_list *create_flist_from_batch()
struct file_list *create_flist_from_batch(void)
{
unsigned char flags;
@@ -201,7 +195,7 @@ struct file_list *create_flist_from_batch()
(struct file_struct **) malloc(sizeof(batch_flist->files[0]) *
batch_flist->malloced);
if (!batch_flist->files) {
out_of_memory("create_flist_from_batch"); /* dw -- will exit */
out_of_memory("create_flist_from_batch");
}
for (flags = read_batch_flags(); flags; flags = read_batch_flags()) {
@@ -231,23 +225,23 @@ struct file_list *create_flist_from_batch()
}
return batch_flist;
}
int read_batch_flist_file(char *buff, int len)
{
int bytes_read;
char filename[MAXPATHLEN];
if (fdb_open) {
/* Set up file extension */
strcat(rsync_flist_file, batch_file_ext);
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_flist_file, sizeof(filename));
/* Open batch flist file for reading */
fdb = do_open(rsync_flist_file, O_RDONLY, 0);
fdb = do_open(filename, O_RDONLY, 0);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_flist_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
@@ -256,17 +250,17 @@ int read_batch_flist_file(char *buff, int len)
/* Read flist batch file */
bytes_read = read(fdb, buff, len);
if (bytes_read == -1) {
switch (bytes_read = read(fdb, buff, len)) {
case -1:
rprintf(FERROR, "Batch file %s read error: %s\n",
rsync_flist_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
if (bytes_read == 0) { /* EOF */
break;
case 0: /* EOF */
close(fdb);
}
return bytes_read;
}
@@ -293,8 +287,12 @@ void read_batch_flist_info(struct file_struct **fptr)
out_of_memory("read_batch_flist_info");
memset((char *) file, 0, sizeof(*file));
(*fptr) = file;
*fptr = file;
/*
* Keep these in sync with bytes_to_write assignment
* in write_batch_flist_info()
*/
read_batch_flist_file((char *) &file->modtime, sizeof(time_t));
read_batch_flist_file((char *) &file->length, sizeof(OFF_T));
read_batch_flist_file((char *) &file->mode, sizeof(mode_t));
@@ -356,20 +354,23 @@ void read_batch_flist_info(struct file_struct **fptr)
void write_batch_csums_file(void *buff, int bytes_to_write)
{
static int fdb_open = 1;
char filename[MAXPATHLEN];
if (fdb_open) {
/* Set up file extension */
strcat(rsync_csums_file, batch_file_ext);
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_csums_file, sizeof(filename));
/* Open batch csums file for writing; create it if it doesn't exist */
fdb =
do_open(rsync_csums_file, O_WRONLY | O_CREAT | O_TRUNC,
/*
* Open batch csums file for writing;
* create it if it doesn't exist
*/
fdb = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_csums_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
@@ -380,16 +381,15 @@ void write_batch_csums_file(void *buff, int bytes_to_write)
if (write(fdb, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
rsync_csums_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
}
void close_batch_csums_file()
void close_batch_csums_file(void)
{
close(fdb);
}
void write_batch_csum_info(int *flist_entry, int flist_count,
@@ -405,10 +405,7 @@ void write_batch_csum_info(int *flist_entry, int flist_count,
/* FIXME: This will break if s->count is ever not exactly an int. */
write_batch_csums_file(flist_entry, sizeof(int));
if (s)
write_batch_csums_file(&s->count, sizeof(int));
else
write_batch_csums_file(&int_zero, sizeof (int));
write_batch_csums_file(s ? &s->count : &int_zero, sizeof(int));
if (s) {
for (i = 0; i < s->count; i++) {
@@ -417,8 +414,7 @@ void write_batch_csum_info(int *flist_entry, int flist_count,
&& (i == s->count - 1)) {
fdb_close = 1;
}
write_batch_csums_file(s->sums[i].sum2,
csum_length);
write_batch_csums_file(s->sums[i].sum2, csum_length);
}
}
}
@@ -427,17 +423,18 @@ int read_batch_csums_file(char *buff, int len)
{
static int fdb_open = 1;
int bytes_read;
char filename[MAXPATHLEN];
if (fdb_open) {
/* Set up file extension */
strcat(rsync_csums_file, batch_file_ext);
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_csums_file, sizeof(filename));
/* Open batch flist file for reading */
fdb = do_open(rsync_csums_file, O_RDONLY, 0);
fdb = do_open(filename, O_RDONLY, 0);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_csums_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
@@ -450,14 +447,14 @@ int read_batch_csums_file(char *buff, int len)
if (bytes_read == -1) {
rprintf(FERROR, "Batch file %s read error: %s\n",
rsync_csums_file, strerror(errno));
filename, strerror(errno));
close(fdb);
exit_cleanup(1);
}
return bytes_read;
}
void read_batch_csum_info(int flist_entry, struct sum_struct *s,
int *checksums_match)
{
@@ -468,11 +465,9 @@ void read_batch_csum_info(int flist_entry, struct sum_struct *s,
char file_sum2[SUM_LENGTH];
extern int csum_length;
read_batch_csums_file((char *) &file_flist_entry, sizeof(int));
if (file_flist_entry != flist_entry) {
rprintf(FINFO, "file_list_entry NE flist_entry\n");
rprintf(FINFO, "file_flist_entry = %d flist_entry = %d\n",
rprintf(FINFO, "file_flist_entry (%d) != flist_entry (%d)\n",
file_flist_entry, flist_entry);
close(fdb);
exit_cleanup(1);
@@ -488,31 +483,33 @@ void read_batch_csum_info(int flist_entry, struct sum_struct *s,
read_batch_csums_file(file_sum2, csum_length);
if ((s->sums[i].sum1 != file_sum1) ||
(memcmp
(s->sums[i].sum2, file_sum2,
csum_length) != 0)) {
(memcmp(s->sums[i].sum2, file_sum2, csum_length)
!= 0)) {
*checksums_match = 0;
}
} /* end for */
}
}
void write_batch_delta_file(char *buff, int bytes_to_write)
{
static int fdb_delta_open = 1;
char filename[MAXPATHLEN];
if (fdb_delta_open) {
/* Set up file extension */
strcat(rsync_delta_file, batch_file_ext);
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_delta_file, sizeof(filename));
/* Open batch delta file for writing; create it if it doesn't exist */
fdb_delta =
do_open(rsync_delta_file, O_WRONLY | O_CREAT | O_TRUNC,
/*
* Open batch delta file for writing;
* create it if it doesn't exist
*/
fdb_delta = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb_delta == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_delta_file, strerror(errno));
filename, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
@@ -523,32 +520,33 @@ void write_batch_delta_file(char *buff, int bytes_to_write)
if (write(fdb_delta, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
rsync_delta_file, strerror(errno));
filename, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
}
void close_batch_delta_file()
void close_batch_delta_file(void)
{
close(fdb_delta);
}
int read_batch_delta_file(char *buff, int len)
{
static int fdb_delta_open = 1;
int bytes_read;
char filename[MAXPATHLEN];
if (fdb_delta_open) {
/* Set up file extension */
strcat(rsync_delta_file, batch_file_ext);
/* Set up file extension */
strlcpy(filename, batch_prefix, sizeof(filename));
strlcat(filename, rsync_delta_file, sizeof(filename));
/* Open batch flist file for reading */
fdb_delta = do_open(rsync_delta_file, O_RDONLY, 0);
fdb_delta = do_open(filename, O_RDONLY, 0);
if (fdb_delta == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_delta_file, strerror(errno));
filename, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
@@ -561,14 +559,14 @@ int read_batch_delta_file(char *buff, int len)
if (bytes_read == -1) {
rprintf(FERROR, "Batch file %s read error: %s\n",
rsync_delta_file, strerror(errno));
filename, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
return bytes_read;
}
void show_flist(int index, struct file_struct **fptr)
{
/* for debugging show_flist(flist->count, flist->files * */

View File

@@ -91,7 +91,7 @@ char *client_name(int fd)
client_sockaddr(fd, &ss, &ss_len);
if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf))
check_name(fd, &ss, ss_len, name_buf, port_buf);
check_name(fd, &ss, name_buf, port_buf);
return name_buf;
}
@@ -229,7 +229,6 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
**/
int check_name(int fd,
const struct sockaddr_storage *ss,
socklen_t ss_len,
char *name_buf,
const char *port_buf)
{

View File

@@ -79,6 +79,8 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
if (!user) user = getenv("USER");
if (!user) user = getenv("LOGNAME");
if (verbose >= 2) {
}
fd = open_socket_out_wrapped (host, rsync_port, bind_address,
default_af_hint);
if (fd == -1) {
@@ -127,7 +129,10 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
if (strcmp(line,"@RSYNCD: EXIT") == 0) exit(0);
rprintf(FINFO,"%s\n", line);
if (strncmp(line, "@ERROR", 6) == 0)
rprintf(FERROR,"%s\n", line);
else
rprintf(FINFO,"%s\n", line);
}
kludge_around_eof = False;
@@ -280,6 +285,26 @@ static int rsync_module(int fd, int i)
}
if (am_root) {
#ifdef HAVE_SETGROUPS
/* Get rid of any supplementary groups this process
* might have inheristed. */
if (setgroups(0, NULL)) {
rsyserr(FERROR, errno, "setgroups failed");
io_printf(fd, "@ERROR: setgroups failed\n");
return -1;
}
#endif
/* XXXX: You could argue that if the daemon is started
* by a non-root user and they explicitly specify a
* gid, then we should try to change to that gid --
* this could be possible if it's already in their
* supplementary groups. */
/* TODO: Perhaps we need to document that if rsyncd is
* started by somebody other than root it will inherit
* all their supplementary groups. */
if (setgid(gid)) {
rsyserr(FERROR, errno, "setgid %d failed", (int) gid);
io_printf(fd,"@ERROR: setgid failed\n");

View File

@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.52)
RSYNC_VERSION=2.5.2pre3
RSYNC_VERSION=2.5.3pre1
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -82,11 +82,26 @@ AC_ARG_WITH(rsync-path,
[ --with-rsync-path=PATH set default --rsync-path to PATH (default: \"rsync\")],
[ RSYNC_PATH="$with_rsync_path" ],
[ RSYNC_PATH="rsync" ])
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [ ])
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
AC_ARG_WITH(rsh,
AC_HELP_STRING([--with-rsh=CMD], [set rsh command to CMD (default: \"remsh\" or \"rsh\")]))
AC_CHECK_PROG(HAVE_REMSH, remsh, 1, 0)
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [ ])
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [remote shell is remsh not rsh])
if test x"$with_rsh" != x
then
RSYNC_RSH="$with_rsh"
elif test x"$HAVE_REMSH" = x1
then
RSYNC_RSH="remsh"
else
RSYNC_RSH="rsh"
fi
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
# arrgh. libc in the current debian stable screws up the largefile
# stuff, getting byte range locking wrong
@@ -336,7 +351,7 @@ AC_FUNC_UTIME_NULL
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
AC_CHECK_FUNCS(strlcat strlcpy mtrace mallinfo)
AC_CHECK_FUNCS(strlcat strlcpy mtrace mallinfo setgroups)
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
AC_TRY_RUN([

View File

@@ -26,6 +26,7 @@
#define RERR_PROTOCOL 2 /* protocol incompatibility */
#define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */
#define RERR_UNSUPPORTED 4 /* requested action not supported */
#define RERR_STARTCLIENT 5 /* error starting client-server protocol */
#define RERR_SOCKETIO 10 /* error in socket IO */
#define RERR_FILEIO 11 /* error in file IO */

View File

@@ -201,9 +201,11 @@ void add_exclude_list(const char *pattern, struct exclude_struct ***list, int in
if (!*list || !((*list)[len] = make_exclude(pattern, include)))
out_of_memory("add_exclude");
if (verbose > 2)
rprintf(FINFO,"add_exclude(%s)\n",pattern);
if (verbose > 2) {
rprintf(FINFO,"add_exclude(%s,%s)\n",pattern,
include ? "include" : "exclude");
}
(*list)[len+1] = NULL;
}
@@ -260,7 +262,10 @@ void send_exclude_list(int f)
extern int remote_version;
extern int list_only, recurse;
/* this is a complete hack - blame Rusty */
/* This is a complete hack - blame Rusty.
*
* FIXME: This pattern shows up in the output of
* report_exclude_result(), which is not ideal. */
if (list_only && !recurse) {
add_exclude("/*/*", 0);
}

View File

@@ -1,5 +1,6 @@
/*
Copyright (C) Andrew Tridgell 1998
Copyright (C) 2002 by Martin Pool
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -38,7 +39,7 @@ int sparse_end(int f)
static int write_sparse(int f,char *buf,size_t len)
{
int l1=0,l2=0;
size_t l1=0, l2=0;
int ret;
for (l1=0;l1<len && buf[l1]==0;l1++) ;
@@ -56,10 +57,11 @@ static int write_sparse(int f,char *buf,size_t len)
if (l1 == len)
return len;
if ((ret=write(f,buf+l1,len-(l1+l2))) != len-(l1+l2)) {
if (ret == -1 || ret == 0) return ret;
ret = write(f, buf + l1, len - (l1+l2));
if (ret == -1 || ret == 0)
return ret;
else if (ret != (int) (len - (l1+l2)))
return (l1+ret);
}
if (l2 > 0)
do_lseek(f,l2,SEEK_CUR);

855
flist.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -31,6 +31,7 @@ extern int am_root;
extern int preserve_devices;
extern int preserve_hard_links;
extern int update_only;
extern int opt_ignore_existing;
extern int whole_file;
extern int block_size;
extern int csum_length;
@@ -218,8 +219,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
if (only_existing && statret == -1 && errno == ENOENT) {
/* we only want to update existing files */
if (verbose > 1) rprintf(FINFO, RSYNC_NAME
": not creating new file \"%s\"\n",fname);
if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
return;
}
@@ -272,7 +272,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
if (safe_symlinks && unsafe_symlink(file->link, fname)) {
if (verbose) {
rprintf(FINFO,RSYNC_NAME ": ignoring unsafe symlink \"%s\" -> \"%s\"\n",
rprintf(FINFO,"ignoring unsafe symlink \"%s\" -> \"%s\"\n",
fname,file->link);
}
return;
@@ -300,8 +300,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
} else {
set_perms(fname,file,NULL,0);
if (verbose) {
rprintf(FINFO,RSYNC_NAME": %s -> %s\n",
fname,file->link);
rprintf(FINFO,"%s -> %s\n", fname,file->link);
}
}
#endif
@@ -333,14 +332,12 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
if (preserve_hard_links && check_hard_link(file)) {
if (verbose > 1)
rprintf(FINFO, RSYNC_NAME
": \"%s\" is a hard link\n",f_name(file));
rprintf(FINFO, "\"%s\" is a hard link\n",f_name(file));
return;
}
if (!S_ISREG(file->mode)) {
rprintf(FINFO, RSYNC_NAME
": skipping non-regular file \"%s\"\n",fname);
rprintf(FINFO, "skipping non-regular file \"%s\"\n",fname);
return;
}
@@ -383,6 +380,12 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
return;
}
if (opt_ignore_existing && fnamecmp == fname) {
if (verbose > 1)
rprintf(FINFO,"%s exists\n",fname);
return;
}
if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
if (verbose > 1)
rprintf(FINFO,"%s is newer\n",fname);

34
io.c
View File

@@ -19,11 +19,22 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
socket and pipe IO utilities used in rsync
/**
*
* @file io.c
*
* Socket and pipe IO utilities used in rsync.
*
* rsync provides its own multiplexing system, which is used to send
* stderr and stdout over a single socket. We need this because
* stdout normally carries the binary data stream, and stderr all our
* error messages.
*
* For historical reasons this is off during the start of the
* connection, but it's switched on quite early using
* io_start_multiplex_out() and io_start_multiplex_in().
**/
tridge, June 1996
*/
#include "rsync.h"
/* if no timeout is specified then use a 60 second select timeout */
@@ -377,7 +388,8 @@ unsigned char read_byte(int f)
return c;
}
/* write len bytes to fd */
/* Write len bytes to fd. This underlies the multiplexing system,
* which is always called by application code. */
static void writefd_unbuffered(int fd,char *buf,size_t len)
{
size_t total = 0;
@@ -442,8 +454,11 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
}
if (ret <= 0) {
rprintf(FERROR,
"error writing %d unbuffered bytes"
/* Don't try to write errors back
* across the stream */
io_multiplexing_close();
rprintf(FERROR, RSYNC_NAME
": error writing %d unbuffered bytes"
" - exiting: %s\n", len,
strerror(errno));
exit_cleanup(RERR_STREAMIO);
@@ -527,8 +542,7 @@ void io_flush(void)
}
/* XXX: fd is ignored, which seems a little strange. */
void io_end_buffering(int fd)
void io_end_buffering(void)
{
io_flush();
if (!io_multiplexing_out) {
@@ -549,7 +563,7 @@ static void writefd(int fd,char *buf,size_t len)
}
while (len) {
int n = MIN(len, IO_BUFFER_SIZE-io_buffer_count);
int n = MIN((int) len, IO_BUFFER_SIZE-io_buffer_count);
if (n > 0) {
memcpy(io_buffer+io_buffer_count, buf, n);
buf += n;

25
log.c
View File

@@ -41,6 +41,7 @@ struct {
{ RERR_PROTOCOL , "protocol incompatibility" },
{ RERR_FILESELECT , "errors selecting input/output files, dirs" },
{ RERR_UNSUPPORTED, "requested action not supported" },
{ RERR_STARTCLIENT, "error starting client-server protocol" },
{ RERR_SOCKETIO , "error in socket IO" },
{ RERR_FILEIO , "error in file IO" },
{ RERR_STREAMIO , "error in rsync protocol data stream" },
@@ -236,7 +237,11 @@ void rwrite(enum logcode code, char *buf, int len)
return;
}
/* if that fails, try to pass it to the other end */
/* If that fails, try to pass it to the other end.
*
* io_multiplex_write can fail if we do not have a multiplexed
* connection at the moment, in which case we fall through and
* log locally instead. */
if (am_server && io_multiplex_write(code, buf, len)) {
return;
}
@@ -341,6 +346,8 @@ void rsyserr(enum logcode code, int errcode, const char *format, ...)
len = vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
/* TODO: Put in RSYNC_NAME at the start. */
if ((size_t) len > sizeof(buf)-1)
exit_cleanup(RERR_MESSAGEIO);
@@ -559,20 +566,16 @@ void log_exit(int code, const char *file, int line)
}
}
/* log the incoming transfer of a file for interactive use, this
will be called at the end where the client was run
it i called when a file starts to be transferred
*/
/*
* Log the incoming transfer of a file for interactive use,
* this will be called at the end where the client was run.
* Called when a file starts to be transferred.
*/
void log_transfer(struct file_struct *file, const char *fname)
{
extern int verbose;
if (!verbose) return;
rprintf(FINFO,"%s\n", fname);
rprintf(FINFO, "%s\n", fname);
}

82
main.c
View File

@@ -60,6 +60,7 @@ static void report(int f)
if (do_stats) {
/* These come out from every process */
show_malloc_stats();
show_flist_stats();
}
if (am_daemon) {
@@ -176,7 +177,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
extern int blocking_io;
extern int read_batch;
if (!read_batch && !local_server) { /* dw -- added read_batch */
if (!read_batch && !local_server) {
if (!cmd)
cmd = getenv(RSYNC_RSH_ENV);
if (!cmd)
@@ -206,10 +207,11 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
args[argc++] = rsync_path;
if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0))
blocking_io = 1;
server_options(args,&argc);
if (strcmp(cmd, RSYNC_RSH) == 0) blocking_io = 1;
}
args[argc++] = ".";
@@ -228,7 +230,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
if (local_server) {
if (read_batch)
create_flist_from_batch();
create_flist_from_batch(); /* sets batch_flist */
ret = local_child(argc, args, f_in, f_out);
} else {
ret = piped_child(args,f_in,f_out);
@@ -278,7 +280,8 @@ static char *get_local_name(struct file_list *flist,char *name)
return name;
if (do_mkdir(name,0777 & ~orig_umask) != 0) {
rprintf(FERROR,"mkdir %s : %s (1)\n",name,strerror(errno));
rprintf(FERROR, RSYNC_NAME ": mkdir %s: %s\n",
name, strerror(errno));
exit_cleanup(RERR_FILEIO);
} else {
if (verbose > 0)
@@ -286,8 +289,8 @@ static char *get_local_name(struct file_list *flist,char *name)
}
if (!push_dir(name, 0)) {
rprintf(FERROR,"push_dir %s : %s (2)\n",
name,strerror(errno));
rprintf(FERROR, RSYNC_NAME ": push_dir %s: %s\n",
name, strerror(errno));
exit_cleanup(RERR_FILESELECT);
}
@@ -441,8 +444,8 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
extern int am_daemon;
extern int module_id;
extern int am_sender;
extern int read_batch; /* dw */
extern struct file_list *batch_flist; /* dw */
extern int read_batch;
extern struct file_list *batch_flist;
if (verbose > 2)
rprintf(FINFO,"server_recv(%d) starting pid=%d\n",argc,(int)getpid());
@@ -468,7 +471,7 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
if (delete_mode && !delete_excluded)
recv_exclude_list(f_in);
if (read_batch) /* dw */
if (read_batch)
flist = batch_flist;
else
flist = recv_file_list(f_in);
@@ -495,7 +498,7 @@ 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;
extern int read_batch; /* dw */
extern int read_batch;
setup_protocol(f_out, f_in);
@@ -506,7 +509,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
io_start_multiplex_out(f_out);
if (am_sender) {
if (!read_batch) { /* dw */
if (!read_batch) {
recv_exclude_list(f_in);
if (cvs_exclude)
add_cvs_excludes();
@@ -525,19 +528,19 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
*/
int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
{
struct file_list *flist;
struct file_list *flist = NULL;
int status = 0, status2 = 0;
char *local_name = NULL;
extern int am_sender;
extern int remote_version;
extern pid_t cleanup_child_pid;
extern int write_batch; /* dw */
extern int read_batch; /* dw */
extern struct file_list *batch_flist; /* dw */
extern int write_batch;
extern int read_batch;
extern struct file_list *batch_flist;
cleanup_child_pid = pid;
if (read_batch)
flist = batch_flist; /* dw */
flist = batch_flist;
set_nonblocking(f_in);
set_nonblocking(f_out);
@@ -580,7 +583,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
list_only = 1;
}
if (!write_batch) /* dw */
if (!write_batch)
send_exclude_list(f_out);
flist = recv_file_list(f_in);
@@ -656,6 +659,7 @@ static int start_client(int argc, char *argv[])
extern char *shell_cmd;
extern int rsync_port;
extern int whole_file;
extern int write_batch;
extern int read_batch;
int rc;
@@ -683,7 +687,7 @@ static int start_client(int argc, char *argv[])
return start_socket_client(host, path, argc-1, argv+1);
}
if (!read_batch) { /* dw */
if (!read_batch) {
p = find_colon(argv[0]);
if (p) {
@@ -709,8 +713,12 @@ static int start_client(int argc, char *argv[])
p = find_colon(argv[argc-1]);
if (!p) {
local_server = 1;
/* disable "rsync algorithm" when both sides local */
whole_file = 1;
/*
* disable "rsync algorithm" when both sides local,
* except when creating a batch update
*/
if (!write_batch && whole_file == -1)
whole_file = 1;
} else if (p[1] == ':') {
*p = 0;
return start_socket_client(argv[argc-1], p+2, argc-1, argv);
@@ -732,9 +740,9 @@ static int start_client(int argc, char *argv[])
argc--;
}
} else {
am_sender = 1; /* dw */
local_server = 1; /* dw */
shell_path = argv[argc-1]; /* dw */
am_sender = 1;
local_server = 1;
shell_path = argv[argc-1];
}
if (shell_machine) {
@@ -799,13 +807,11 @@ int main(int argc,char *argv[])
extern int am_daemon;
extern int am_server;
int ret;
extern int read_batch; /* dw */
extern int write_batch; /* dw */
extern char *batch_ext; /* dw */
int orig_argc; /* dw */
extern int write_batch;
int orig_argc;
char **orig_argv;
orig_argc = argc; /* dw */
orig_argc = argc;
orig_argv = argv;
signal(SIGUSR1, sigusr1_handler);
@@ -834,25 +840,23 @@ int main(int argc,char *argv[])
}
signal(SIGINT,SIGNAL_CAST sig_int);
signal(SIGPIPE,SIGNAL_CAST sig_int);
signal(SIGHUP,SIGNAL_CAST sig_int);
signal(SIGTERM,SIGNAL_CAST sig_int);
/* Ignore SIGPIPE; we consistently check error codes and will
* see the EPIPE. */
signal(SIGPIPE, SIG_IGN);
/* 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 (write_batch) { /* dw */
create_batch_file_ext();
if (write_batch && !am_server) {
write_batch_argvs_file(orig_argc, orig_argv);
}
if (read_batch) { /* dw */
set_batch_file_ext(batch_ext);
}
if (am_daemon) {
return daemon_main();
}
@@ -879,7 +883,9 @@ int main(int argc,char *argv[])
}
ret = start_client(argc, argv);
exit_cleanup(ret);
if (ret == -1)
exit_cleanup(RERR_STARTCLIENT);
else
exit_cleanup(ret);
return ret;
}

View File

@@ -71,7 +71,7 @@ static void build_hash_table(struct sum_struct *s)
if (!tag_table || !targets)
out_of_memory("build_hash_table");
for (i=0;i<s->count;i++) {
for (i=0;i<(int) s->count;i++) {
targets[i].i = i;
targets[i].t = gettag(s->sums[i].sum1);
}
@@ -175,7 +175,7 @@ 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++) {
for (; j < (int) s->count && targets[j].t == t; j++) {
int l, i = targets[j].i;
if (sum != s->sums[i].sum1) continue;
@@ -201,7 +201,7 @@ static void hash_search(int f,struct sum_struct *s,
/* 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++) {
for (j++; j < (int) s->count && targets[j].t == t; j++) {
int i2 = targets[j].i;
if (i2 == last_i + 1) {
if (sum != s->sums[i2].sum1) break;
@@ -246,7 +246,8 @@ static void hash_search(int f,struct sum_struct *s,
match. The 3 reads are caused by the
running match, the checksum update and the
literal send. */
if (offset-last_match >= CHUNK_SIZE+s->n &&
if (offset > last_match &&
offset-last_match >= CHUNK_SIZE+s->n &&
(end-offset > CHUNK_SIZE)) {
matched(f,s,buf,offset - s->n, -2);
}

View File

@@ -22,7 +22,7 @@
#include "popt.h"
int make_backups = 0;
int whole_file = 0;
int whole_file = -1;
int copy_links = 0;
int preserve_links = 0;
int preserve_hard_links = 0;
@@ -65,6 +65,7 @@ int size_only=0;
int bwlimit=0;
int delete_after=0;
int only_existing=0;
int opt_ignore_existing=0;
int max_delete=0;
int ignore_errors=0;
#ifdef _WIN32
@@ -72,7 +73,7 @@ int modify_window=2;
#else
int modify_window=0;
#endif
int blocking_io=0;
int blocking_io=-1;
/** Network address family. **/
#ifdef INET6
@@ -86,9 +87,8 @@ int default_af_hint = AF_INET; /* Must use IPv4 */
* or under Unix process-monitors. **/
int no_detach = 0;
int read_batch=0;
int write_batch=0;
int write_batch = 0;
int read_batch = 0;
char *backup_suffix = BACKUP_SUFFIX;
char *tmpdir = NULL;
@@ -106,7 +106,7 @@ int quiet = 0;
int always_checksum = 0;
int list_only = 0;
char *batch_ext = NULL;
char *batch_prefix = NULL;
static int modify_window_set;
@@ -202,12 +202,14 @@ void usage(enum logcode F)
rprintf(F," -S, --sparse handle sparse files efficiently\n");
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," --no-whole-file turn off --whole-file\n");
rprintf(F," -x, --one-file-system don't cross filesystem boundaries\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," --ignore-existing ignore files that already exist on the receiving side\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");
@@ -235,13 +237,14 @@ void usage(enum logcode F)
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," --no-blocking-io turn off --blocking-io\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," --read-batch=EXT read batch file\n");
rprintf(F," --write-batch write batch file\n");
rprintf(F," --write-batch=PREFIX write batch fileset starting with PREFIX\n");
rprintf(F," --read-batch=PREFIX read batch fileset starting with PREFIX\n");
rprintf(F," -h, --help show this help screen\n");
#ifdef INET6
rprintf(F," -4 prefer IPv4\n");
@@ -262,7 +265,8 @@ enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
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,
OPT_MODIFY_WINDOW, OPT_READ_BATCH, OPT_WRITE_BATCH};
OPT_NO_BLOCKING_IO, OPT_NO_WHOLE_FILE,
OPT_MODIFY_WINDOW, OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_IGNORE_EXISTING};
static struct poptOption long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
@@ -276,6 +280,7 @@ static struct poptOption long_options[] = {
{"one-file-system", 'x', POPT_ARG_NONE, &one_file_system},
{"delete", 0, POPT_ARG_NONE, &delete_mode},
{"existing", 0, POPT_ARG_NONE, &only_existing},
{"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing},
{"delete-after", 0, POPT_ARG_NONE, &delete_after},
{"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED},
{"force", 0, POPT_ARG_NONE, &force_delete},
@@ -294,6 +299,7 @@ static struct poptOption long_options[] = {
{"links", 'l', POPT_ARG_NONE, &preserve_links},
{"copy-links", 'L', POPT_ARG_NONE, &copy_links},
{"whole-file", 'W', POPT_ARG_NONE, &whole_file},
{"no-whole-file", 0, POPT_ARG_NONE, 0, OPT_NO_WHOLE_FILE},
{"copy-unsafe-links", 0, POPT_ARG_NONE, &copy_unsafe_links},
{"perms", 'p', POPT_ARG_NONE, &preserve_perms},
{"owner", 'o', POPT_ARG_NONE, &preserve_uid},
@@ -323,6 +329,7 @@ static struct poptOption long_options[] = {
{"partial", 0, POPT_ARG_NONE, &keep_partial},
{"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors},
{"blocking-io", 0, POPT_ARG_NONE, &blocking_io},
{"no-blocking-io", 0, POPT_ARG_NONE, 0, OPT_NO_BLOCKING_IO},
{0, 'P', POPT_ARG_NONE, 0, 'P'},
{"config", 0, POPT_ARG_STRING, &config_file},
{"port", 0, POPT_ARG_INT, &rsync_port},
@@ -331,8 +338,8 @@ static struct poptOption long_options[] = {
{"address", 0, POPT_ARG_STRING, &bind_address, 0},
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir},
{"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links},
{"read-batch", 0, POPT_ARG_STRING, &batch_ext, OPT_READ_BATCH},
{"write-batch", 0, POPT_ARG_NONE, &write_batch},
{"read-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH},
{"write-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH},
#ifdef INET6
{0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET },
{0, '6', POPT_ARG_VAL, &default_af_hint, AF_INET6 },
@@ -452,8 +459,12 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
add_exclude_file(poptGetOptArg(pc), 1, 0);
break;
case OPT_INCLUDE_FROM:
add_exclude_file(poptGetOptArg(pc), 1, 1);
case OPT_NO_WHOLE_FILE:
whole_file = 0;
break;
case OPT_NO_BLOCKING_IO:
blocking_io = 0;
break;
case 'h':
@@ -511,8 +522,13 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
keep_partial = 1;
break;
case OPT_WRITE_BATCH:
/* popt stores the filename in batch_prefix for us */
write_batch = 1;
break;
case OPT_READ_BATCH:
/* The filename is stored in batch_ext for us by popt */
/* popt stores the filename in batch_prefix for us */
read_batch = 1;
break;
@@ -528,6 +544,22 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
}
}
if (write_batch && read_batch) {
snprintf(err_buf,sizeof(err_buf),
"write-batch and read-batch can not be used together\n");
rprintf(FERROR,"ERROR: write-batch and read-batch"
" can not be used together\n");
return 0;
}
if (do_compression && (write_batch || read_batch)) {
snprintf(err_buf,sizeof(err_buf),
"compress can not be used with write-batch or read-batch\n");
rprintf(FERROR,"ERROR: compress can not be used with"
" write-batch or read-batch\n");
return 0;
}
*argv = poptGetArgs(pc);
if (*argv)
*argc = count_args(*argv);
@@ -549,11 +581,16 @@ void server_options(char **args,int *argc)
static char mdelete[30];
static char mwindow[30];
static char bw[50];
static char fext[20];
static char wbatch[14];
/* Leave room for ``--(write|read)-batch='' */
static char fext[MAXPATHLEN + 15];
int i, x;
if (whole_file == -1)
whole_file = 0;
if (blocking_io == -1)
blocking_io = 0;
args[ac++] = "--server";
if (!am_sender)
@@ -627,13 +664,14 @@ void server_options(char **args,int *argc)
args[ac++] = mdelete;
}
if (write_batch) {
snprintf(wbatch,sizeof(wbatch),"--write-batch");
args[ac++] = wbatch;
}
if (batch_ext != NULL) {
snprintf(fext,sizeof(fext),"--read-batch=%s",batch_ext);
if (batch_prefix != NULL) {
char *fmt = "";
if (write_batch)
fmt = "--write-batch=%s";
else
if (read_batch)
fmt = "--read-batch=%s";
snprintf(fext,sizeof(fext),fmt,batch_prefix);
args[ac++] = fext;
}
@@ -691,6 +729,9 @@ void server_options(char **args,int *argc)
if (only_existing && am_sender)
args[ac++] = "--existing";
if (opt_ignore_existing && am_sender)
args[ac++] = "--ignore-existing";
if (tmpdir) {
args[ac++] = "--temp-dir";
args[ac++] = tmpdir;

View File

@@ -249,7 +249,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
i = -(i+1);
offset2 = i*(OFF_T)n;
len = n;
if (i == count-1 && remainder != 0)
if (i == (int) count-1 && remainder != 0)
len = remainder;
stats.matched_data += len;
@@ -265,7 +265,7 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
sum_update(map,len);
}
if (fd != -1 && write_file(fd,map,len) != len) {
if (fd != -1 && write_file(fd,map,len) != (int) len) {
rprintf(FERROR,"write failed on %s : %s\n",
fname,strerror(errno));
exit_cleanup(RERR_FILEIO);
@@ -424,7 +424,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
access because of a similar race condition. */
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
if (fd2 == -1) {
rprintf(FERROR,"mkstemp %s failed\n",fnametmp);
rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno));
receive_data(f_in,buf,-1,NULL,file->length);
if (buf) unmap_file(buf);
continue;

11
rsync.h
View File

@@ -85,11 +85,9 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
#include "config.h"
#if HAVE_REMSH
#define RSYNC_RSH "remsh"
#else
#define RSYNC_RSH "rsh"
#endif
/* The default RSYNC_RSH is always set in config.h, either to "remsh",
* "rsh", or otherwise something specified by the user. HAVE_REMSH
* controls parameter munging for HP/UX, etc. */
#include <sys/types.h>
@@ -463,6 +461,9 @@ extern int errno;
#define SUPPORT_LINKS HAVE_READLINK
#define SUPPORT_HARD_LINKS HAVE_LINK
/* This could be bad on systems which have no lchown and where chown
* follows symbollic links. On such systems it might be better not to
* try to chown symlinks at all. */
#ifndef HAVE_LCHOWN
#define lchown chown
#endif

122
rsync.yo
View File

@@ -1,5 +1,5 @@
mailto(rsync-bugs@samba.org)
manpage(rsync)(1)(14 Dec 2001)()()
manpage(rsync)(1)(25 Jan 2002)()()
manpagename(rsync)(faster, flexible replacement for rcp)
manpagesynopsis()
@@ -239,12 +239,14 @@ verb(
-S, --sparse handle sparse files efficiently
-n, --dry-run show what would have been transferred
-W, --whole-file copy whole files, no incremental checks
--no-whole-file turn off --whole-file
-x, --one-file-system don't cross filesystem boundaries
-B, --block-size=SIZE checksum blocking size (default 700)
-e, --rsh=COMMAND specify rsh replacement
--rsync-path=PATH specify path to rsync on the remote machine
-C, --cvs-exclude auto ignore files in the same way CVS does
--existing only update files that already exist
--ignore-existing ignore files that already exist on the receiving side
--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
@@ -272,13 +274,14 @@ verb(
--config=FILE specify alternate rsyncd.conf file
--port=PORT specify alternate rsyncd port number
--blocking-io use blocking IO for the remote shell
--no-blocking-io turn off --blocking-io
--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
--read-batch=FILE read batch file
--write-batch write batch file
--read-batch=PREFIX read batch fileset starting with PREFIX
--write-batch=PREFIX write batch fileset starting with PREFIX
-h, --help show this help screen
@@ -410,6 +413,9 @@ target machines is higher than the bandwidth to disk (especially when the
"disk" is actually a networked file system). This is the default when both
the source and target are on the local machine.
dit(bf(--no-whole-file)) Turn off --whole-file, for use when it is the
default.
dit(bf(-p, --perms)) This option causes rsync to update the remote
permissions to be the same as the local permissions.
@@ -452,6 +458,10 @@ 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(--ignore-existing))
This tells rsync not to 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.
@@ -485,12 +495,9 @@ dit(bf(--ignore-errors)) Tells --delete to go ahead and delete files
even when there are IO errors.
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.
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.
they are not empty when they are to be replaced by non-directories. This
is only relevant without --delete because deletions are now done depth-first.
Requires the --recursive option (which is implied by -a) to have any effect.
dit(bf(-B , --block-size=BLOCKSIZE)) This controls the block size used in
the rsync algorithm. See the technical report for details.
@@ -655,6 +662,9 @@ the default "rsh", this defaults to blocking IO, otherwise it defaults to
non-blocking IO. You may find the --blocking-io option is needed for some
remote shells that can't handle non-blocking IO. Ssh prefers blocking IO.
dit(bf(--no-blocking-io)) Turn off --blocking-io, for use when it is the
default.
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
@@ -696,10 +706,13 @@ 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.
dit(bf(--read-batch)) Apply a previously generated change batch.
dit(bf(--write-batch=PREFIX)) Generate a set of files that can be
transferred as a batch update. Each filename in the set starts with
PREFIX. See the "BATCH MODE" section for details.
dit(bf(--write-batch)) Generate a set of files that can be transferred
as a batch update.
dit(bf(--read-batch=PREFIX)) Apply a previously generated change batch,
using the fileset whose filenames start with PREFIX. See the "BATCH
MODE" section for details.
enddit()
@@ -794,26 +807,83 @@ itemize(
manpagesection(BATCH MODE)
bf(Note:) Batch mode should be considered experimental in this version
of rsync. The interface or behaviour may change before it stabilizes.
of rsync. The interface or behaviour may change before it stabilizes.
The following call generates 4 files that encapsulate the information
for synchronizing the contents of bf(target_dir) with the updates found in
bf(src_dir)
Batch mode can be used to apply the same set of updates to many
identical systems. Suppose one has a tree which is replicated on a
number of hosts. Now suppose some changes have been made to this
source tree and those changes need to be propagated to the other
hosts. In order to do this using batch mode, rsync is run with the
write-batch option to apply the changes made to the source tree to one
of the destination trees. The write-batch option causes the rsync
client to store the information needed to repeat this operation against
other destination trees in a batch update fileset (see below). The
filename of each file in the fileset starts with a prefix specified by
the user as an argument to the write-batch option. This fileset is
then copied to each remote host, where rsync is run with the read-batch
option, again specifying the same prefix, and the destination tree.
Rsync updates the destination tree using the information stored in the
batch update fileset.
quote(
$ rsync --write-batch [other rsync options here] \nl()
/somewhere/src_dir /somewhere/target_dir
)
The generated files are labeled with a common timestamp:
The fileset consists of 4 files:
itemize(
it() bf(rsync_argvs.<timestamp>) command-line arguments
it() bf(rsync_flist.<timestamp>) rsync internal file metadata
it() bf(rsync_csums.<timestamp>) rsync checksums
it() bf(rsync_delta.<timestamp>) data blocks for file update & change
it() bf(<prefix>.rsync_argvs) command-line arguments
it() bf(<prefix>.rsync_flist) rsync internal file metadata
it() bf(<prefix>.rsync_csums) rsync checksums
it() bf(<prefix>.rsync_delta) data blocks for file update & change
)
The .rsync_argvs file contains a command-line suitable for updating a
destination tree using that batch update fileset. It can be executed
using a Bourne(-like) shell, optionally passing in an alternate
destination tree pathname which is then used instead of the original
path. This is useful when the destination tree path differs from the
original destination tree path.
Generating the batch update fileset once saves having to perform the
file status, checksum and data block generation more than once when
updating multiple destination trees. Multicast transport protocols can
be used to transfer the batch update files in parallel to many hosts at
once, instead of sending the same data to every host individually.
Example:
verb(
$ rsync --write_batch=pfx -a /source/dir/ /adest/dir/
$ rcp pfx.rsync_* remote:
$ rsh remote rsync --read_batch=pfx -a /bdest/dir/
# or alternatively
$ rsh remote ./pfx.rsync_argvs /bdest/dir/
)
In this example, rsync is used to update /adest/dir/ with /source/dir/
and the information to repeat this operation is stored in the files
pfx.rsync_*. These files are then copied to the machine named "remote".
Rsync is then invoked on "remote" to update /bdest/dir/ the same way as
/adest/dir/. The last line shows the rsync_argvs file being used to
invoke rsync.
Caveats:
The read-batch option expects the destination tree it is meant to update
to be identical to the destination tree that was used to create the
batch update fileset. When a difference between the destination trees
is encountered the update will fail at that point, leaving the
destination tree in a partially updated state. In that case, rsync can
be used in its regular (non-batch) mode of operation to fix up the
destination tree.
The rsync version used on all destinations should be identical to the
one used on the original destination.
The -z/--compress option does not work in batch mode and yields a usage
error. A separate compression tool can be used instead to reduce the
size of the batch update files for transport to the destination.
The -n/--dryrun option does not work in batch mode and yields a runtime
error.
See bf(http://www.ils.unc.edu/i2dsi/unc_rsync+.html) for papers and technical
reports.

View File

@@ -176,8 +176,8 @@ prep_scratch() {
return 0
}
discard_scratch() {
[ -d "$scratchdir" ] && rm -rf "$scratchdir"
maybe_discard_scratch() {
[ x"$preserve_scratch" != xyes ] && [ -d "$scratchdir" ] && rm -rf "$scratchdir"
return 0
}
@@ -198,16 +198,23 @@ do
result=$?
set -e
if [ "x$always_log" = xyes -o \( $result != 0 -a $result != 77 -a $result != 78 \) ]
then
echo "----- $testbase log follows"
cat "$scratchdir/test.log"
echo "----- $testbase log ends"
fi
case $result in
0)
echo "PASS $testbase"
passed=`expr $passed + 1`
discard_scratch
maybe_discard_scratch
;;
77)
echo "SKIP $testbase"
skipped=`expr $skipped + 1`
discard_scratch
maybe_discard_scratch
;;
78)
# It failed, but we expected that. don't dump out error logs,
@@ -218,9 +225,6 @@ do
;;
*)
echo "FAIL $testbase"
echo "----- $testbase failed: log follows"
cat "$scratchdir/test.log"
echo "----- $testbase log ends"
failed=`expr $failed + 1`
if [ "x$nopersist" = "xyes" ]
then

View File

@@ -55,14 +55,14 @@ static struct sum_struct *receive_sums(int f)
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
if (!s->sums) out_of_memory("receive_sums");
for (i=0;i<s->count;i++) {
for (i=0; i < (int) s->count;i++) {
s->sums[i].sum1 = read_int(f);
read_buf(f,s->sums[i].sum2,csum_length);
s->sums[i].offset = offset;
s->sums[i].i = i;
if (i == s->count-1 && s->remainder != 0) {
if (i == (int) s->count-1 && s->remainder != 0) {
s->sums[i].len = s->remainder;
} else {
s->sums[i].len = s->n;

View File

@@ -387,6 +387,7 @@ void start_accept_loop(int port, int (*fn)(int ))
for each incoming connection */
while (1) {
fd_set fds;
pid_t pid;
int fd;
struct sockaddr_storage addr;
socklen_t addrlen = sizeof addr;
@@ -418,15 +419,26 @@ void start_accept_loop(int port, int (*fn)(int ))
while (waitpid(-1, NULL, WNOHANG) > 0);
#endif
if (fork()==0) {
if ((pid = fork()) == 0) {
close(s);
/* open log file in child before possibly giving
up privileges */
log_open();
_exit(fn(fd));
} else if (pid < 0) {
rprintf(FERROR,
RSYNC_NAME
": could not create child server process: %s\n",
strerror(errno));
close(fd);
/* This might have happened because we're
* overloaded. Sleep briefly before trying to
* accept again. */
sleep(2);
} else {
/* Parent doesn't need this fd anymore. */
close(fd);
}
close(fd);
}
}
@@ -590,7 +602,7 @@ static int socketpair_tcp(int fd[2])
if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) goto failed;
memset(&sock2, 0, sizeof(sock2));
#ifdef HAVE_SOCK_SIN_LEN
#ifdef HAVE_SOCKADDR_LEN
sock2.sin_len = sizeof(sock2);
#endif
sock2.sin_family = PF_INET;

View File

@@ -1,5 +1,6 @@
/*
Copyright (C) Andrew Tridgell 1998
Copyright (C) 2002 by Martin Pool
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -16,9 +17,12 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
syscall wrappers to ensure that nothing gets done in dry_run mode
*/
/**
* @file syscall.c
*
* Syscall wrappers to ensure that nothing gets done in dry_run mode
* and to handle system peculiarities.
**/
#include "rsync.h"
@@ -106,13 +110,24 @@ int do_rename(char *fname1, char *fname2)
return rename(fname1, fname2);
}
int do_mkdir(char *fname, mode_t mode)
{
if (dry_run) return 0;
CHECK_RO
int l;
if (dry_run)
return 0;
CHECK_RO;
/* Some BSD systems cannot make a directory if the name
* contains a trailing slash.
* <http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html> */
if ((l = strlen(fname)) && (fname[l-1] == '/'))
fname[l-1] = '/';
return mkdir(fname, mode);
}
/* like mkstemp but forces permissions */
int do_mkstemp(char *template, mode_t perms)
{

36
testsuite/chgrp.test Normal file
View File

@@ -0,0 +1,36 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that rsync with -gr will preserve groups when the user running
# the test is a member of them. Hopefully they're in at least one
# test.
. $srcdir/testsuite/rsync.fns
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
mygrps="`groups`" || fail "Can't get groups"
mkdir "$fromdir"
for g in $mygrps
do
name="$fromdir/foo-$g"
date > "$name"
chgrp "$g" "$name" || fail "Can't chgrp"
done
sleep 2
checkit "rsync -rtgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
exit 0
# last [] may have failed but if we get here then we've won

38
testsuite/chown.test Normal file
View File

@@ -0,0 +1,38 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test that when rsync is running as root and has -a it correctly sets
# the ownership of the destination.
# We don't know what users will be present on this system, so we just
# use random numeric uids and gids.
. $srcdir/testsuite/rsync.fns
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
mkdir "$fromdir"
name1="$fromdir/name1"
name2="$fromdir/name2"
echo "This is the file" > "$name1"
echo "This is the other file" > "$name2"
chown 5000 "$name1" || test_skipped "Can't chown"
chown 5001 "$name2" || test_skipped "Can't chown"
chgrp 5002 "$name1" || test_skipped "Can't chgrp"
chgrp 5003 "$name2" || test_skipped "Can't chgrp"
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
exit 0
# last [] may have failed but if we get here then we've won

29
testsuite/devices.test Normal file
View File

@@ -0,0 +1,29 @@
#! /bin/sh
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
# This program is distributable under the terms of the GNU GPL (see
# COPYING).
# Test rsync handling of devices. This can only run if you're root.
. $srcdir/testsuite/rsync.fns
set -x
# Build some hardlinks
fromdir="$scratchdir/from"
todir="$scratchdir/to"
# TODO: Need to test whether hardlinks are possible on this OS/filesystem
mkdir "$fromdir"
mknod "$fromdir/char" c 42 69 || test_skipped "Can't create char device node?"
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node?"
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
exit 0
# last [] may have failed but if we get here then we've won

View File

@@ -150,7 +150,11 @@ checkit() {
echo "-------------"
echo "check how the files compare with diff:"
echo ""
diff -cr $2 $3 || failed=YES
for f in `cd "$2"; find . -type f -print `
do
diff -c "$2"/"$f" "$3"/"$f" || failed=YES
done
echo "-------------"
echo "check how the directory listings compare with diff:"
echo ""
@@ -222,6 +226,11 @@ test_fail() {
exit 1
}
test_skipped() {
echo "$@" >&2
exit 77
}
# It failed, but we expected that. don't dump out error logs,
# because most users won't want to see them. But do leave
# the working directory around.

View File

@@ -20,9 +20,20 @@ build_symlinks || test_fail "failed to build symlinks"
[ -f "${todir}/referent" ] || test_fail "referent was not copied"
[ -d "${todir}/from" ] && test_fail "extra level of directories"
[ -L "${todir}/dangling" ] && test_fail "dangling symlink was copied"
[ -L "${todir}/relative" ] && test_fail "relative symlink was copied"
[ -L "${todir}/absolute" ] && test_fail "absolute symlink was copied"
if [ -L "${todir}/dangling" ]
then
test_fail "dangling symlink was copied"
fi
if [ -L "${todir}/relative" ]
then
test_fail "relative symlink was copied"
fi
if [ -L "${todir}/absolute" ]
then
test_fail "absolute symlink was copied"
fi
exit 0
# last [] may have failed but if we get here then we've one

2
tls.c
View File

@@ -62,7 +62,7 @@ static void failed (char const *what,
static void list_file (const char *fname)
{
struct stat buf;
STRUCT_STAT buf;
char permbuf[PERMSTRING_SIZE];
struct tm *mt;
char datebuf[50];

18
util.c
View File

@@ -86,7 +86,7 @@ int fd_pair(int fd[2])
void print_child_argv(char **cmd)
{
rprintf(FINFO, RSYNC_NAME ": open connection using ");
rprintf(FINFO, "opening connection using ");
for (; *cmd; cmd++) {
/* Look for characters that ought to be quoted. This
* is not a great quoting algorithm, but it's
@@ -121,7 +121,7 @@ pid_t piped_child(char **command, int *f_in, int *f_out)
int from_child_pipe[2];
extern int blocking_io;
if (verbose > 0) {
if (verbose >= 2) {
print_child_argv(command);
}
@@ -240,10 +240,18 @@ void overflow(char *str)
int set_modtime(char *fname,time_t modtime)
int set_modtime(char *fname, time_t modtime)
{
extern int dry_run;
if (dry_run) return 0;
if (dry_run)
return 0;
if (verbose > 2) {
rprintf(FINFO, "set modtime of %s to (%ld) %s",
fname, (long) modtime,
asctime(localtime(&modtime)));
}
{
#ifdef HAVE_UTIMBUF
struct utimbuf tbuf;
@@ -559,7 +567,7 @@ static void glob_expand_one(char *s, char **argv, int *argc, int maxargs)
globfree(&globbuf);
return;
}
for (i=0; i<(maxargs - (*argc)) && i<globbuf.gl_pathc;i++) {
for (i=0; i<(maxargs - (*argc)) && i < (int) globbuf.gl_pathc;i++) {
if (i == 0) free(argv[*argc]);
argv[(*argc) + i] = strdup(globbuf.gl_pathv[i]);
if (!argv[(*argc) + i]) out_of_memory("glob_expand");