Compare commits

..

63 Commits

Author SHA1 Message Date
rsync-bugs
e2d1033d5d preparing for release of 2.1.0 1998-07-20 05:43:51 +00:00
Andrew Tridgell
c46ded4621 I think I might havefinally fixed the rsync hanging bug. It was caused
by a read during an io_flush() triggered during a readfd(). A simple
logic bug in the io code :(
1998-07-20 05:36:25 +00:00
Andrew Tridgell
8cd9fd4e8c always use a timeout to select, even if --timeout is not
specified. This makes things easier to debug.
1998-07-19 10:51:26 +00:00
Andrew Tridgell
41979ff87c - defer the error message from the options parsing until after the
socket is multiplexed. This allows clients sending new options which
the remote server doesn't understand to get a sensible error message.
1998-07-19 05:22:05 +00:00
Andrew Tridgell
b11ed3b150 - close stdout and stderr and reopen then as /dev/null when running as
a daemon. This prevents library functions (such as getopt) stuffing up
our protocol stream when errors are detected.

- defer the error message from the options parsing until after the
socket is multiplexed. This allows clients sending new options which
the remote server doesn't understand to get a sensible error message.
1998-07-19 04:50:48 +00:00
rsync-bugs
42245f1b56 preparing for release of 2.0.19 1998-07-17 14:53:00 +00:00
Andrew Tridgell
c29ee43dbd handle hard links on systems with 16 bit ino_t 1998-07-17 14:42:59 +00:00
Andrew Tridgell
d310a212f7 added a bit in the man page about the clean shell error 1998-07-17 14:25:14 +00:00
Andrew Tridgell
ca6c93f817 check whether there is a / before a : in the rsync command line. If
there is then assume that the : is from a filename, not a host:dir
separator. This allows you to copy files with a : in them. (suggestion
from pfeifer@wait.de)
1998-07-17 14:05:57 +00:00
Andrew Tridgell
72914a606e make rsync behave more like GNU cp with regard to file permissions
when -p (preserve permissions) isn't set.

It works by taking the sending file permissions and masking them with
the umask to create the destination file permissions. (There is really
no "correct" way of doing this but at least we now behave like GNU cp
which fits the principle of least surprise.)

also fixed a race condition in copy_file()
1998-07-17 13:18:32 +00:00
Andrew Tridgell
4b957c2238 added the --safe-links option to disallow symlinks outside the
destination tree
1998-07-17 10:00:48 +00:00
Andrew Tridgell
d853783f21 added the --safe-links option to disallow symlinks outside the
destination tree
1998-07-17 10:00:43 +00:00
Andrew Tridgell
298c10d5bb some code reformatting 1998-07-17 07:42:04 +00:00
Andrew Tridgell
6608462cac removed old "make dist" target 1998-07-17 07:26:08 +00:00
Andrew Tridgell
ca8e96946e changed wording of an error message 1998-07-17 07:25:42 +00:00
Andrew Tridgell
6ed67e6dd5 moved getopt.h above unistd.h to prevent problems with uwin on NT 1998-07-17 07:17:11 +00:00
Andrew Tridgell
1f658d4207 fixed a problem with rsync buffering the debug output when redirected
to a file.
1998-07-17 07:07:23 +00:00
Andrew Tridgell
d3bc0b68ab make a function static 1998-07-17 05:38:51 +00:00
Andrew Tridgell
1a0de6c68b remove a useless debug message 1998-07-17 05:38:21 +00:00
Andrew Tridgell
eb601ffeb8 code style change 1998-07-17 05:37:56 +00:00
Andrew Tridgell
8d72ef6e52 use error to detect lockfile open failures vs. max connections reached
and report an appropriate error message
1998-07-17 05:37:18 +00:00
Andrew Tridgell
bcf5b1335d - use explicit flushes instead of setlinebuf. I've had reports of
verbose info not being line buffered to files.

- add a call to localtime() in open_log() in order to prime the C
  libraries timezone cache before the chroot(). This should fix the
  problem of rsyncd log entries being in GMT time.
1998-07-02 10:57:20 +00:00
Andrew Tridgell
bd7e05d799 remove a redundent continue statement 1998-07-02 03:02:14 +00:00
Andrew Tridgell
c95f1aa9d3 prioritise reading over writing in the select loop. (this is another
ssh-friendly attempt)
1998-07-02 02:59:04 +00:00
Andrew Tridgell
86ffe37f11 fix the problem of --timeout waiting for twice the specified time. 1998-07-02 02:48:09 +00:00
Andrew Tridgell
b536f47e3c - don't show "created directory" message unless verbose is selected
- check for null buf in show_progress
1998-07-02 02:08:55 +00:00
Andrew Tridgell
43b06eeae9 output progress % every 1k instead of every 1%, this is better for
large files.
1998-07-02 01:28:39 +00:00
Andrew Tridgell
067857e0ac the recv_generator can be static 1998-07-02 01:27:51 +00:00
Andrew Tridgell
b3e10ed75b enable output buffering in the recv generator. This makes a
significant difference when the transport is ssh as ssh will otherwise
output a complete frame for each checksum record, which increases the
checksum data in size by a factor of around 4.
1998-07-02 01:27:14 +00:00
Andrew Tridgell
a353d56337 don't need to send --progress option to server as the server never
prints progress info.
1998-07-02 00:48:20 +00:00
Andrew Tridgell
eb86d661d7 added --progress option which shows the progress of transfers. This
gives bored users something to watch.
1998-07-02 00:47:13 +00:00
Andrew Tridgell
fe055c718a - only keep a partial file if some literal data has been transferred,
this prevents a second interrupted transfer from reducing the size of
the transferred file.

- set SIGUSR1 to SIG_IGN early to prevent a race condition that
prevents the --partial code from working properly
1998-07-01 11:03:50 +00:00
Andrew Tridgell
31f440e68b I've had reports of rsyncd leaving zombies under digital unix. This
patch tries to address the problem in two ways:

1) reinstall the SIGCHLD handler before each fork
2) reap any children not caught by the handler using waitpid with
WNOHANG.

I expect this will fix the problem.
1998-07-01 05:10:42 +00:00
Andrew Tridgell
c95da96a0c added a --partial option which tells rsync to keep partially
transferred files if the transfer is interrupted.

added a "options summary" section to the man page
1998-07-01 03:36:03 +00:00
Andrew Tridgell
bf9f01689f if we get EWOULDBLOCK on a write then reduce the amount of data we are
trying to write. This guarantees that the maximum amount of data that
can be written at any one time is written.
1998-06-19 00:55:19 +00:00
Andrew Tridgell
da81e21536 use LDFLAGS in Makefile.in (fix from arndt@schoenewald.de) 1998-06-18 14:15:16 +00:00
Andrew Tridgell
46831d6fcf fixed chmod bug pointed out by Han Holl <jeholl@euronet.nl> 1998-06-18 13:26:10 +00:00
rsync-bugs
b58ad6c569 preparing for release of 2.0.18 1998-06-18 13:06:00 +00:00
Andrew Tridgell
22b1933287 fixed a race condition in rsync that opened a security hole. The
temporary files were being created with the same permissions as the
original file. So if the file was setuid but not owned by the user
doing the transfer then there was a window of opportunity for a
malicious user to execute it with the wrong permissions while it was
being transferred.

Thanks to snabb@epipe.fi for pointing this out.
1998-06-18 12:17:23 +00:00
rsync-bugs
5a03f68a5a preparing for release of 2.0.17 1998-06-18 10:30:48 +00:00
Andrew Tridgell
e81da93e86 if as non-root we failed to update the group of a file then don't
print the file name.
1998-06-18 10:03:44 +00:00
Andrew Tridgell
f578043391 for consistency use memcpy/memset everywhere instead of bcopy/bzero 1998-06-18 09:51:44 +00:00
Andrew Tridgell
e8f5b936ad move include of compat.h after other includes. 1998-06-18 09:37:21 +00:00
Andrew Tridgell
667e72a195 change the order of chmod and chown calls so that setuid bits don't
get removed by chown calls.
1998-06-18 09:36:24 +00:00
Andrew Tridgell
e1b3d5c4be set network file descriptors non-blocking before starting main rsync
algorithm.
1998-06-18 09:34:56 +00:00
Andrew Tridgell
f7b9377863 handle non-blocking file descriptors for both read and write. Add a
workaround for buggy systems that say there is space to write when
there isn't.
1998-06-18 09:33:46 +00:00
Andrew Tridgell
a5343e765b put set_nonblocking() code back in. 1998-06-18 09:32:45 +00:00
Andrew Tridgell
704f908eae --help changes suggested by Francois 1998-06-18 09:31:42 +00:00
Andrew Tridgell
de2fd20eb7 manpage updates, mostly suggested by Francois 1998-06-18 09:30:51 +00:00
Andrew Tridgell
100e5241b0 the tag table should be of type int* not tag*.
This bug resulted in rsync being much less efficient that it could be
for files with more than 64k blocks. With the adaptive block size code
giving a maximum block size of 16k this means that files larger than
1GB were handled very inefficiently. The transfer was still accurate,
just slow.
1998-06-03 02:47:52 +00:00
Andrew Tridgell
ddecf7060b if the user passes a block size on the command line then don't adapt
the block size.
1998-06-03 02:35:51 +00:00
Andrew Tridgell
56cdbccb92 added note to docs saying that --stats doesn't work unless -v is used 1998-06-02 12:50:23 +00:00
Andrew Tridgell
fc8a6b9705 added some fflush() calls to make sure the statistics lines are
printed when redirecting output to a file.
1998-06-02 12:46:46 +00:00
rsync-bugs
143384f367 preparing for release of 2.0.16 1998-06-01 13:49:12 +00:00
Andrew Tridgell
8c3b04730b added some notes to test.sh 1998-06-01 13:44:06 +00:00
Andrew Tridgell
aa9b77a56c replace calls to strcmp() with a u_strcmp() function that uses only
unsigned comparisons. Transferring files between two machines that
treated strcmp() differently led to the files being given the wrong
name at the destination if the filenames had characters > 128 (such as
Kanji characters) and the source and destination machines treated
strcmp() differently (ie. one treated strings as signed and the other
as unsigned).

We now treat all string comparisons for file list sorting as unsigned.
1998-06-01 13:39:54 +00:00
Andrew Tridgell
b72f24c719 updated the usage info 1998-06-01 10:38:24 +00:00
Andrew Tridgell
a800434a82 added --stats option for verbose stats on the file transfer 1998-06-01 03:42:14 +00:00
rsync-bugs
3b3c3d4390 preparing for release of 2.0.15 1998-05-30 02:10:18 +00:00
Andrew Tridgell
d846b09874 replace BAD with zBAD so it compiles on AIX 1998-05-30 02:07:36 +00:00
Andrew Tridgell
1d3754aede cosmetic fix.
reset offset to 0 at the start of each loop so the filenames get
printed correctly when sending directories followed by local names.
1998-05-30 02:03:29 +00:00
Andrew Tridgell
e44f9a12c4 make sure that io_flush() doesn't call writefd_unbuffered from within
a writefd_unbuffered call!

this should fix the "decompressor lost sync" bug
1998-05-30 02:02:23 +00:00
Andrew Tridgell
5243c216d6 replaced chdir and getcwd calls with push_dir/pop_dir functions. These
are faster and don't cause problems in a chrooted environment on any
systems.
1998-05-29 14:36:39 +00:00
28 changed files with 2030 additions and 1401 deletions

View File

@@ -46,7 +46,7 @@ install: all
${INSTALLCMD} -m 644 $(srcdir)/rsyncd.conf.5 ${INSTALL_MAN}/man5
rsync: $(OBJS)
$(CC) $(CFLAGS) -o rsync $(OBJS) $(LIBS)
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
rsync.1: rsync.yo
yodl2man -o rsync.1 rsync.yo
@@ -60,10 +60,3 @@ proto:
clean:
rm -f *~ $(OBJS) rsync config.cache config.log config.status
dist:
tar --exclude-from .ignore -czf dist.tar.gz .
-mkdir rsync-$(VERSION)
(cd rsync-$(VERSION) ; tar xzf ../dist.tar.gz)
tar -czf rsync-$(VERSION).tar.gz rsync-$(VERSION)
rm -f dist.tar.gz
echo rsync-$(VERSION) >> .cvsignore

View File

@@ -7,3 +7,4 @@
#undef HAVE_UTIMBUF
#undef ino_t
#undef HAVE_CONNECT
#undef HAVE_SHORT_INO_T

View File

@@ -77,7 +77,7 @@ void get_checksum2(char *buf,int len,char *sum)
MDbegin(&MD);
bcopy(buf,buf1,len);
memcpy(buf1,buf,len);
if (checksum_seed) {
SIVAL(buf1,len,checksum_seed);
len += 4;
@@ -102,7 +102,7 @@ void file_checksum(char *fname,char *sum,OFF_T size)
OFF_T len = size;
char tmpchunk[CSUM_CHUNK];
bzero(sum,csum_length);
memset(sum,0,csum_length);
fd = open(fname,O_RDONLY);
if (fd == -1) return;
@@ -112,12 +112,12 @@ void file_checksum(char *fname,char *sum,OFF_T size)
MDbegin(&MD);
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
bcopy(map_ptr(buf,i,CSUM_CHUNK),tmpchunk,CSUM_CHUNK);
memcpy(tmpchunk, map_ptr(buf,i,CSUM_CHUNK), CSUM_CHUNK);
MDupdate(&MD, tmpchunk, CSUM_CHUNK*8);
}
if (len - i > 0) {
bcopy(map_ptr(buf,i,len-i),tmpchunk,len-i);
memcpy(tmpchunk, map_ptr(buf,i,len-i), len-i);
MDupdate(&MD, tmpchunk, (len-i)*8);
}
@@ -155,27 +155,27 @@ void sum_update(char *p,int len)
{
int i;
if (len + sumresidue < CSUM_CHUNK) {
bcopy(p,sumrbuf+sumresidue,len);
memcpy(sumrbuf+sumresidue, p, len);
sumresidue += len;
return;
}
if (sumresidue) {
i = MIN(CSUM_CHUNK-sumresidue,len);
bcopy(p,sumrbuf+sumresidue,i);
memcpy(sumrbuf+sumresidue,p,i);
MDupdate(&sumMD, sumrbuf, (i+sumresidue)*8);
len -= i;
p += i;
}
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
bcopy(p+i,sumrbuf,CSUM_CHUNK);
memcpy(sumrbuf,p+i,CSUM_CHUNK);
MDupdate(&sumMD, sumrbuf, CSUM_CHUNK*8);
}
if (len - i > 0) {
sumresidue = len-i;
bcopy(p+i,sumrbuf,sumresidue);
memcpy(sumrbuf,p+i,sumresidue);
} else {
sumresidue = 0;
}

View File

@@ -118,6 +118,7 @@ static int rsync_module(int fd, int i)
char *name = lp_name(i);
char *user;
int start_glob=0;
int ret;
char *request=NULL;
extern int am_sender;
extern int remote_version;
@@ -132,9 +133,16 @@ static int rsync_module(int fd, int i)
}
if (!claim_connection(lp_lock_file(), lp_max_connections())) {
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());
if (errno) {
rprintf(FERROR,"failed to open lock file %s : %s\n",
lp_lock_file(), strerror(errno));
io_printf(fd,"@ERROR: failed to open lock file %s : %s\n",
lp_lock_file(), 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());
}
return -1;
}
@@ -244,7 +252,7 @@ static int rsync_module(int fd, int i)
}
}
parse_arguments(argc, argv);
ret = parse_arguments(argc, argv);
if (request) {
if (*user) {
@@ -269,6 +277,11 @@ static int rsync_module(int fd, int i)
if (remote_version > 17 && am_sender)
io_start_multiplex_out(fd);
if (!ret) {
rprintf(FERROR,"Error parsing options (unsupported option?) - aborting\n");
exit_cleanup(1);
}
start_server(fd, fd, argc, argp);
return 0;
@@ -362,8 +375,21 @@ int daemon_main(void)
{
extern char *config_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)) {
/* we are running via inetd */
int i;
/* we are running via inetd - close off stdout and
stderr so that library functions (and getopt) don't
try to use them. Redirect them to /dev/null */
for (i=1;i<3;i++) {
close(i);
open("/dev/null", O_RDWR);
}
return start_daemon(STDIN_FILENO);
}

View File

@@ -53,6 +53,7 @@ void setup_protocol(int f_out,int f_in)
if (remote_version < MIN_PROTOCOL_VERSION ||
remote_version > MAX_PROTOCOL_VERSION) {
rprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
rprintf(FERROR,"(see the rsync man page for an explanation)\n");
exit_cleanup(1);
}

View File

@@ -40,8 +40,8 @@ echo no)
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 bcopy bzero readlink link utime utimes)
AC_CHECK_FUNCS(memmove getopt_long lchown setlinebuf vsnprintf setsid glob strpbrk)
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes)
AC_CHECK_FUNCS(memmove getopt_long lchown vsnprintf setsid glob strpbrk)
echo $ac_n "checking for working fnmatch... $ac_c"
AC_TRY_RUN([#include <fnmatch.h>
@@ -62,6 +62,14 @@ main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) retu
echo yes;AC_DEFINE(HAVE_OFF64_T),
echo no)
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)
echo $ac_n "checking for unsigned char ... $ac_c"
AC_TRY_RUN([#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }],

View File

@@ -29,7 +29,7 @@ int claim_connection(char *fname,int max_connections)
if (max_connections <= 0)
return 1;
fd = open(fname,O_RDWR|O_CREAT, 0600);
if (fd == -1) {
@@ -41,6 +41,9 @@ int claim_connection(char *fname,int max_connections)
if (lock_range(fd, i*4, 4)) return 1;
}
/* only interested in open failures */
errno = 0;
close(fd);
return 0;
}

394
flist.c
View File

@@ -21,12 +21,13 @@
#include "rsync.h"
extern struct stats stats;
extern int csum_length;
extern int verbose;
extern int am_server;
extern int always_checksum;
extern int64 total_size;
extern int cvs_exclude;
@@ -90,141 +91,98 @@ static void send_directory(int f,struct file_list *flist,char *dir);
static char *flist_dir;
static void clean_fname(char *name)
{
char *p;
int l;
int modified = 1;
if (!name) return;
while (modified) {
modified = 0;
if ((p=strstr(name,"/./"))) {
modified = 1;
while (*p) {
p[0] = p[2];
p++;
}
}
if ((p=strstr(name,"//"))) {
modified = 1;
while (*p) {
p[0] = p[1];
p++;
}
}
if (strncmp(p=name,"./",2) == 0) {
modified = 1;
do {
p[0] = p[2];
} while (*p++);
}
l = strlen(p=name);
if (l > 1 && p[l-1] == '/') {
modified = 1;
p[l-1] = 0;
}
}
}
void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
{
unsigned char flags;
static time_t last_time;
static mode_t last_mode;
static dev_t last_rdev;
static uid_t last_uid;
static gid_t last_gid;
static char lastname[MAXPATHLEN];
char *fname;
int l1,l2;
unsigned char flags;
static time_t last_time;
static mode_t last_mode;
static dev_t last_rdev;
static uid_t last_uid;
static gid_t last_gid;
static char lastname[MAXPATHLEN];
char *fname;
int l1,l2;
if (f == -1) return;
if (f == -1) return;
if (!file) {
write_byte(f,0);
return;
}
if (!file) {
write_byte(f,0);
return;
}
fname = f_name(file);
fname = f_name(file);
flags = base_flags;
flags = base_flags;
if (file->mode == last_mode) flags |= SAME_MODE;
if (file->rdev == last_rdev) flags |= SAME_RDEV;
if (file->uid == last_uid) flags |= SAME_UID;
if (file->gid == last_gid) flags |= SAME_GID;
if (file->modtime == last_time) flags |= SAME_TIME;
if (file->mode == last_mode) flags |= SAME_MODE;
if (file->rdev == last_rdev) flags |= SAME_RDEV;
if (file->uid == last_uid) flags |= SAME_UID;
if (file->gid == last_gid) flags |= SAME_GID;
if (file->modtime == last_time) flags |= SAME_TIME;
for (l1=0;lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);l1++) ;
l2 = strlen(fname) - l1;
for (l1=0;lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);l1++) ;
l2 = strlen(fname) - l1;
if (l1 > 0) flags |= SAME_NAME;
if (l2 > 255) flags |= LONG_NAME;
if (l1 > 0) flags |= SAME_NAME;
if (l2 > 255) flags |= LONG_NAME;
/* we must make sure we don't send a zero flags byte or the other
end will terminate the flist transfer */
if (flags == 0 && !S_ISDIR(file->mode)) flags |= FLAG_DELETE;
if (flags == 0) flags |= LONG_NAME;
/* we must make sure we don't send a zero flags byte or the other
end will terminate the flist transfer */
if (flags == 0 && !S_ISDIR(file->mode)) flags |= FLAG_DELETE;
if (flags == 0) flags |= LONG_NAME;
write_byte(f,flags);
if (flags & SAME_NAME)
write_byte(f,l1);
if (flags & LONG_NAME)
write_int(f,l2);
else
write_byte(f,l2);
write_buf(f,fname+l1,l2);
write_byte(f,flags);
if (flags & SAME_NAME)
write_byte(f,l1);
if (flags & LONG_NAME)
write_int(f,l2);
else
write_byte(f,l2);
write_buf(f,fname+l1,l2);
write_longint(f,file->length);
if (!(flags & SAME_TIME))
write_int(f,(int)file->modtime);
if (!(flags & SAME_MODE))
write_int(f,(int)file->mode);
if (preserve_uid && !(flags & SAME_UID)) {
add_uid(file->uid);
write_int(f,(int)file->uid);
}
if (preserve_gid && !(flags & SAME_GID)) {
add_gid(file->gid);
write_int(f,(int)file->gid);
}
if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
write_int(f,(int)file->rdev);
write_longint(f,file->length);
if (!(flags & SAME_TIME))
write_int(f,(int)file->modtime);
if (!(flags & SAME_MODE))
write_int(f,(int)file->mode);
if (preserve_uid && !(flags & SAME_UID)) {
add_uid(file->uid);
write_int(f,(int)file->uid);
}
if (preserve_gid && !(flags & SAME_GID)) {
add_gid(file->gid);
write_int(f,(int)file->gid);
}
if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
write_int(f,(int)file->rdev);
#if SUPPORT_LINKS
if (preserve_links && S_ISLNK(file->mode)) {
write_int(f,strlen(file->link));
write_buf(f,file->link,strlen(file->link));
}
if (preserve_links && S_ISLNK(file->mode)) {
write_int(f,strlen(file->link));
write_buf(f,file->link,strlen(file->link));
}
#endif
#if SUPPORT_HARD_LINKS
if (preserve_hard_links && S_ISREG(file->mode)) {
write_int(f,(int)file->dev);
write_int(f,(int)file->inode);
}
if (preserve_hard_links && S_ISREG(file->mode)) {
write_int(f,(int)file->dev);
write_int(f,(int)file->inode);
}
#endif
if (always_checksum) {
write_buf(f,file->sum,csum_length);
}
if (always_checksum) {
write_buf(f,file->sum,csum_length);
}
last_mode = file->mode;
last_rdev = file->rdev;
last_uid = file->uid;
last_gid = file->gid;
last_time = file->modtime;
last_mode = file->mode;
last_rdev = file->rdev;
last_uid = file->uid;
last_gid = file->gid;
last_time = file->modtime;
strlcpy(lastname,fname,MAXPATHLEN-1);
lastname[MAXPATHLEN-1] = 0;
strlcpy(lastname,fname,MAXPATHLEN-1);
lastname[MAXPATHLEN-1] = 0;
}
@@ -232,101 +190,108 @@ void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
static void receive_file_entry(struct file_struct **fptr,
unsigned flags,int f)
{
static time_t last_time;
static mode_t last_mode;
static dev_t last_rdev;
static uid_t last_uid;
static gid_t last_gid;
static char lastname[MAXPATHLEN];
char thisname[MAXPATHLEN];
int l1=0,l2=0;
char *p;
struct file_struct *file;
static time_t last_time;
static mode_t last_mode;
static dev_t last_rdev;
static uid_t last_uid;
static gid_t last_gid;
static char lastname[MAXPATHLEN];
char thisname[MAXPATHLEN];
int l1=0,l2=0;
char *p;
struct file_struct *file;
if (flags & SAME_NAME)
l1 = read_byte(f);
if (flags & SAME_NAME)
l1 = read_byte(f);
if (flags & LONG_NAME)
l2 = read_int(f);
else
l2 = read_byte(f);
if (flags & LONG_NAME)
l2 = read_int(f);
else
l2 = read_byte(f);
file = (struct file_struct *)malloc(sizeof(*file));
if (!file) out_of_memory("receive_file_entry");
bzero((char *)file,sizeof(*file));
(*fptr) = file;
file = (struct file_struct *)malloc(sizeof(*file));
if (!file) out_of_memory("receive_file_entry");
memset((char *)file, 0, sizeof(*file));
(*fptr) = file;
if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
strlcpy(thisname,lastname,l1);
read_sbuf(f,&thisname[l1],l2);
thisname[l1+l2] = 0;
strlcpy(thisname,lastname,l1);
read_sbuf(f,&thisname[l1],l2);
thisname[l1+l2] = 0;
strlcpy(lastname,thisname,MAXPATHLEN-1);
lastname[MAXPATHLEN-1] = 0;
strlcpy(lastname,thisname,MAXPATHLEN-1);
lastname[MAXPATHLEN-1] = 0;
clean_fname(thisname);
clean_fname(thisname);
if (relative_paths && thisname[0] == '/') {
/* strip / off absolute paths in destination */
memmove(thisname, thisname+1, strlen(thisname));
if (!thisname[0]) strcpy(thisname,".");
}
if (relative_paths && thisname[0] == '/') {
/* strip / off absolute paths in destination */
memmove(thisname, thisname+1, strlen(thisname));
if (!thisname[0]) strcpy(thisname,".");
}
if ((p = strrchr(thisname,'/'))) {
static char *lastdir;
*p = 0;
if (lastdir && strcmp(thisname, lastdir)==0) {
file->dirname = lastdir;
} else {
file->dirname = strdup(thisname);
lastdir = file->dirname;
}
file->basename = strdup(p+1);
} else {
file->dirname = NULL;
file->basename = strdup(thisname);
}
if ((p = strrchr(thisname,'/'))) {
static char *lastdir;
*p = 0;
if (lastdir && strcmp(thisname, lastdir)==0) {
file->dirname = lastdir;
} else {
file->dirname = strdup(thisname);
lastdir = file->dirname;
}
file->basename = strdup(p+1);
} else {
file->dirname = NULL;
file->basename = strdup(thisname);
}
if (!file->basename) out_of_memory("receive_file_entry 1");
if (!file->basename) out_of_memory("receive_file_entry 1");
file->flags = flags;
file->length = read_longint(f);
file->modtime = (flags & SAME_TIME) ? last_time : (time_t)read_int(f);
file->mode = (flags & SAME_MODE) ? last_mode : (mode_t)read_int(f);
if (preserve_uid)
file->uid = (flags & SAME_UID) ? last_uid : (uid_t)read_int(f);
if (preserve_gid)
file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
if (preserve_devices && IS_DEVICE(file->mode))
file->rdev = (flags & SAME_RDEV) ? last_rdev : (dev_t)read_int(f);
file->flags = flags;
file->length = read_longint(f);
file->modtime = (flags & SAME_TIME) ? last_time : (time_t)read_int(f);
file->mode = (flags & SAME_MODE) ? last_mode : (mode_t)read_int(f);
if (preserve_uid)
file->uid = (flags & SAME_UID) ? last_uid : (uid_t)read_int(f);
if (preserve_gid)
file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
if (preserve_devices && IS_DEVICE(file->mode))
file->rdev = (flags & SAME_RDEV) ? last_rdev : (dev_t)read_int(f);
if (preserve_links && S_ISLNK(file->mode)) {
int l = read_int(f);
file->link = (char *)malloc(l+1);
if (!file->link) out_of_memory("receive_file_entry 2");
read_sbuf(f,file->link,l);
}
if (preserve_links && S_ISLNK(file->mode)) {
int l = read_int(f);
file->link = (char *)malloc(l+1);
if (!file->link) out_of_memory("receive_file_entry 2");
read_sbuf(f,file->link,l);
}
#if SUPPORT_HARD_LINKS
if (preserve_hard_links && S_ISREG(file->mode)) {
file->dev = read_int(f);
file->inode = read_int(f);
}
if (preserve_hard_links && S_ISREG(file->mode)) {
file->dev = read_int(f);
file->inode = read_int(f);
}
#endif
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 (always_checksum) {
file->sum = (char *)malloc(MD4_SUM_LENGTH);
if (!file->sum) out_of_memory("md4 sum");
read_buf(f,file->sum,csum_length);
}
last_mode = file->mode;
last_rdev = file->rdev;
last_uid = file->uid;
last_gid = file->gid;
last_time = file->modtime;
last_mode = file->mode;
last_rdev = file->rdev;
last_uid = file->uid;
last_gid = file->gid;
last_time = file->modtime;
if (!preserve_perms) {
extern int orig_umask;
/* set an appropriate set of permissions based on original
permissions and umask. This emulates what GNU cp does */
file->mode &= ~orig_umask;
}
}
@@ -367,7 +332,7 @@ static struct file_struct *make_file(char *fname)
clean_fname(cleaned_name);
fname = cleaned_name;
bzero(sum,SUM_LENGTH);
memset(sum,0,SUM_LENGTH);
if (link_stat(fname,&st) != 0) {
io_error = 1;
@@ -394,7 +359,7 @@ static struct file_struct *make_file(char *fname)
file = (struct file_struct *)malloc(sizeof(*file));
if (!file) out_of_memory("make_file");
bzero((char *)file,sizeof(*file));
memset((char *)file,0,sizeof(*file));
if ((p = strrchr(fname,'/'))) {
static char *lastdir;
@@ -464,7 +429,7 @@ static struct file_struct *make_file(char *fname)
}
if (!S_ISDIR(st.st_mode))
total_size += st.st_size;
stats.total_size += st.st_size;
return file;
}
@@ -566,15 +531,17 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
int i,l;
STRUCT_STAT st;
char *p,*dir;
char dbuf[MAXPATHLEN];
char lastpath[MAXPATHLEN]="";
struct file_list *flist;
int64 start_write;
if (verbose && recurse && !am_server && f != -1) {
rprintf(FINFO,"building file list ... ");
rflush(FINFO);
}
start_write = stats.total_written;
flist = (struct file_list *)malloc(sizeof(flist[0]));
if (!flist) out_of_memory("send_file_list");
@@ -646,24 +613,23 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
fname = ".";
if (dir && *dir) {
if (getcwd(dbuf,MAXPATHLEN-1) == NULL) {
rprintf(FERROR,"getwd : %s\n",strerror(errno));
exit_cleanup(1);
}
if (chdir(dir) != 0) {
char *olddir = push_dir(dir, 1);
if (!olddir) {
io_error=1;
rprintf(FERROR,"chdir %s : %s\n",
rprintf(FERROR,"push_dir %s : %s\n",
dir,strerror(errno));
continue;
}
flist_dir = dir;
if (one_file_system)
set_filesystem(fname);
send_file_name(f,flist,fname,recurse,FLAG_DELETE);
flist_dir = NULL;
if (chdir(dbuf) != 0) {
rprintf(FERROR,"chdir %s : %s\n",
dbuf,strerror(errno));
if (pop_dir(olddir) != 0) {
rprintf(FERROR,"pop_dir %s : %s\n",
dir,strerror(errno));
exit_cleanup(1);
}
continue;
@@ -696,6 +662,8 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
if (f != -1) {
io_end_buffering(f);
stats.flist_size = stats.total_written - start_write;
stats.num_files = flist->count;
}
if (verbose > 2)
@@ -709,12 +677,15 @@ struct file_list *recv_file_list(int f)
{
struct file_list *flist;
unsigned char flags;
int64 start_read;
if (verbose && recurse && !am_server) {
rprintf(FINFO,"receiving file list ... ");
rflush(FINFO);
}
start_read = stats.total_read;
flist = (struct file_list *)malloc(sizeof(flist[0]));
if (!flist)
goto oom;
@@ -745,7 +716,7 @@ struct file_list *recv_file_list(int f)
receive_file_entry(&flist->files[i],flags,f);
if (S_ISREG(flist->files[i]->mode))
total_size += flist->files[i]->length;
stats.total_size += flist->files[i]->length;
flist->count++;
@@ -776,6 +747,9 @@ struct file_list *recv_file_list(int f)
if (verbose > 2)
rprintf(FINFO,"recv_file_list done\n");
stats.flist_size = stats.total_read - start_read;
stats.num_files = flist->count;
return flist;
oom:
@@ -790,8 +764,8 @@ int file_compare(struct file_struct **f1,struct file_struct **f2)
if (!(*f1)->basename) return -1;
if (!(*f2)->basename) return 1;
if ((*f1)->dirname == (*f2)->dirname)
return strcmp((*f1)->basename, (*f2)->basename);
return strcmp(f_name(*f1),f_name(*f2));
return u_strcmp((*f1)->basename, (*f2)->basename);
return u_strcmp(f_name(*f1),f_name(*f2));
}
@@ -827,7 +801,7 @@ static void free_file(struct file_struct *file)
if (file->basename) free(file->basename);
if (file->link) free(file->link);
if (file->sum) free(file->sum);
bzero((char *)file, sizeof(*file));
memset((char *)file, 0, sizeof(*file));
}
@@ -841,9 +815,9 @@ void flist_free(struct file_list *flist)
free_file(flist->files[i]);
free(flist->files[i]);
}
bzero((char *)flist->files, sizeof(flist->files[0])*flist->count);
memset((char *)flist->files, 0, sizeof(flist->files[0])*flist->count);
free(flist->files);
bzero((char *)flist, sizeof(*flist));
memset((char *)flist, 0, sizeof(*flist));
free(flist);
}

View File

@@ -56,7 +56,7 @@ void init_hard_links(struct file_list *flist)
out_of_memory("init_hard_links");
for (i = 0; i < flist->count; i++)
bcopy(flist->files[i], &hlink_list[i], sizeof(hlink_list[0]));
memcpy(&hlink_list[i], flist->files[i], sizeof(hlink_list[0]));
qsort(hlink_list,flist->count,
sizeof(hlink_list[0]),

90
io.c
View File

@@ -24,8 +24,8 @@
*/
#include "rsync.h"
static int64 total_written;
static int64 total_read;
/* if no timeout is specified then use a 60 second select timeout */
#define SELECT_TIMEOUT 60
static int io_multiplexing_out;
static int io_multiplexing_in;
@@ -35,17 +35,7 @@ static time_t last_io;
static int eof_error=1;
extern int verbose;
extern int io_timeout;
int64 write_total(void)
{
return total_written;
}
int64 read_total(void)
{
return total_read;
}
extern struct stats stats;
static int buffer_f_in = -1;
@@ -67,8 +57,8 @@ static void check_timeout(void)
t = time(NULL);
if (last_io && io_timeout && (t-last_io)>io_timeout) {
rprintf(FERROR,"read timeout after %d second - exiting\n",
if (last_io && io_timeout && (t-last_io) >= io_timeout) {
rprintf(FERROR,"io timeout after %d second - exiting\n",
(int)(t-last_io));
exit_cleanup(1);
}
@@ -79,6 +69,8 @@ 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
@@ -87,7 +79,9 @@ 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;
@@ -95,11 +89,10 @@ static int read_timeout(int fd, char *buf, int len)
FD_ZERO(&fds);
FD_SET(fd, &fds);
tv.tv_sec = io_timeout;
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
tv.tv_usec = 0;
if (select(fd+1, &fds, NULL, NULL,
io_timeout?&tv:NULL) != 1) {
if (select(fd+1, &fds, NULL, NULL, &tv) != 1) {
check_timeout();
continue;
}
@@ -107,6 +100,7 @@ static int read_timeout(int fd, char *buf, int len)
n = read(fd, buf, len);
if (n > 0) {
stats.total_read += n;
buf += n;
len -= n;
ret += n;
@@ -119,9 +113,18 @@ static int read_timeout(int fd, char *buf, int len)
continue;
}
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);
continue;
}
if (n == 0) {
if (eof_error) {
rprintf(FERROR,"EOF in read_timeout\n");
rprintf(FERROR,"unexpected EOF in read_timeout\n");
}
exit_cleanup(1);
}
@@ -240,7 +243,7 @@ static void readfd(int fd,char *buffer,int N)
int ret;
int total=0;
if (read_buffer_len < N && N < 1024) {
if ((read_buffer_len < N) && (N < 1024)) {
read_check(buffer_f_in);
}
@@ -254,7 +257,9 @@ static void readfd(int fd,char *buffer,int N)
continue;
}
no_flush_read++;
io_flush();
no_flush_read--;
ret = read_unbuffered(fd,buffer + total,N-total);
total += ret;
@@ -266,7 +271,6 @@ int32 read_int(int f)
{
char b[4];
readfd(f,b,4);
total_read += 4;
return IVAL(b,0);
}
@@ -285,7 +289,6 @@ int64 read_longint(int f)
#else
if (remote_version >= 16) {
readfd(f,b,8);
total_read += 8;
ret = IVAL(b,0) | (((int64)IVAL(b,4))<<32);
}
#endif
@@ -296,7 +299,6 @@ int64 read_longint(int f)
void read_buf(int f,char *buf,int len)
{
readfd(f,buf,len);
total_read += len;
}
void read_sbuf(int f,char *buf,int len)
@@ -323,9 +325,10 @@ 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;
int reading=0;
int blocked=0;
reading = (buffer_f_in != -1 && read_buffer_len < MAX_READ_BUFFER);
no_flush++;
while (total < len) {
FD_ZERO(&w_fds);
@@ -333,47 +336,63 @@ static void writefd_unbuffered(int fd,char *buf,int len)
FD_SET(fd,&w_fds);
fd_count = fd+1;
if (!no_flush_read) {
reading = (buffer_f_in != -1 &&
read_buffer_len < MAX_READ_BUFFER);
}
if (reading) {
FD_SET(buffer_f_in,&r_fds);
if (buffer_f_in > fd)
fd_count = buffer_f_in+1;
}
tv.tv_sec = io_timeout;
tv.tv_sec = io_timeout?io_timeout:SELECT_TIMEOUT;
tv.tv_usec = 0;
count = select(fd_count,
reading?&r_fds:NULL,
&w_fds,NULL,
io_timeout?&tv:NULL);
&tv);
if (count <= 0) {
check_timeout();
continue;
}
if (reading && FD_ISSET(buffer_f_in, &r_fds)) {
read_check(buffer_f_in);
}
if (FD_ISSET(fd, &w_fds)) {
int ret = write(fd,buf+total,len-total);
int n = (len-total)>>blocked;
int ret = write(fd,buf+total,n?n:1);
if (ret == -1 && errno == EINTR) {
continue;
}
if (ret == -1 &&
(errno == EAGAIN || errno == EWOULDBLOCK)) {
blocked++;
continue;
}
if (ret <= 0) {
rprintf(FERROR,"erroring writing %d bytes - exiting\n", len);
exit_cleanup(1);
}
blocked = 0;
total += ret;
stats.total_written += ret;
if (io_timeout)
last_io = time(NULL);
continue;
}
if (reading && FD_ISSET(buffer_f_in, &r_fds)) {
read_check(buffer_f_in);
}
}
no_flush--;
}
@@ -395,7 +414,7 @@ void io_start_buffering(int fd)
void io_flush(void)
{
int fd = multiplex_out_fd;
if (!io_buffer_count) return;
if (!io_buffer_count || no_flush) return;
if (io_multiplexing_out) {
SIVAL(io_buffer-4, 0, (MPLEX_BASE<<24) + io_buffer_count);
@@ -441,7 +460,6 @@ void write_int(int f,int32 x)
char b[4];
SIVAL(b,0,x);
writefd(f,b,4);
total_written += 4;
}
void write_longint(int f, int64 x)
@@ -459,13 +477,11 @@ void write_longint(int f, int64 x)
SIVAL(b,4,((x>>32)&0xFFFFFFFF));
writefd(f,b,8);
total_written += 8;
}
void write_buf(int f,char *buf,int len)
{
writefd(f,buf,len);
total_written += len;
}
/* write a string to the connection */

View File

@@ -54,7 +54,7 @@ pid_t waitpid(pid_t pid, int *statptr, int options)
#ifndef HAVE_MEMMOVE
void *memmove(void *dest, const void *src, size_t n)
{
bcopy(src, dest, n);
memcpy(dest, src, n);
return dest;
}
#endif

View File

@@ -329,7 +329,7 @@ initialise a service to the defaults
***************************************************************************/
static void init_service(service *pservice)
{
bzero((char *)pservice,sizeof(service));
memset((char *)pservice,0,sizeof(service));
copy_service(pservice,&sDefault);
}

9
log.c
View File

@@ -28,6 +28,7 @@ void log_open(void)
{
static int initialised;
int options = LOG_PID;
time_t t;
if (initialised) return;
initialised = 1;
@@ -45,6 +46,12 @@ void log_open(void)
#ifndef LOG_NDELAY
syslog(LOG_INFO,"rsyncd started\n");
#endif
/* this looks pointless, but it is needed in order for the
C library on some systems to fetch the timezone info
before the chroot */
t = time(NULL);
localtime(&t);
}
@@ -102,6 +109,8 @@ void rprintf(int fd, const char *format, ...)
if (fwrite(buf, len, 1, f) != 1) exit_cleanup(1);
if (buf[len-1] == '\r' || buf[len-1] == '\n') fflush(f);
depth--;
}

144
main.c
View File

@@ -20,7 +20,8 @@
#include "rsync.h"
time_t starttime = 0;
int64 total_size = 0;
struct stats stats;
extern int csum_length;
@@ -28,16 +29,17 @@ extern int verbose;
static void report(int f)
{
int64 in,out,tsize;
time_t t = time(NULL);
extern int am_server;
extern int am_sender;
extern int am_daemon;
extern int do_stats;
if (am_daemon) {
syslog(LOG_INFO,"wrote %.0f bytes read %.0f bytes total size %.0f\n",
(double)write_total(),(double)read_total(),
(double)total_size);
(double)stats.total_written,
(double)stats.total_read,
(double)stats.total_size);
if (f == -1 || !am_sender) return;
}
@@ -46,26 +48,49 @@ static void report(int f)
if (am_server && !am_sender) return;
if (am_server && am_sender) {
write_longint(f,read_total());
write_longint(f,write_total());
write_longint(f,total_size);
write_longint(f,stats.total_read);
write_longint(f,stats.total_written);
write_longint(f,stats.total_size);
return;
}
if (am_sender) {
in = read_total();
out = write_total();
tsize = total_size;
} else {
out = read_longint(f);
in = read_longint(f);
tsize = read_longint(f);
if (!am_sender) {
int64 r;
stats.total_written = read_longint(f);
r = read_longint(f);
stats.total_size = read_longint(f);
stats.total_read = r;
}
if (do_stats) {
rprintf(FINFO,"\nNumber of files: %d\n", stats.num_files);
rprintf(FINFO,"Number of files transferred: %d\n",
stats.num_transferred_files);
rprintf(FINFO,"Total file size: %.0f bytes\n",
(double)stats.total_size);
rprintf(FINFO,"Total transferred file size: %.0f bytes\n",
(double)stats.total_transferred_size);
rprintf(FINFO,"Literal data: %.0f bytes\n",
(double)stats.literal_data);
rprintf(FINFO,"Matched data: %.0f bytes\n",
(double)stats.matched_data);
rprintf(FINFO,"File list size: %d\n", stats.flist_size);
rprintf(FINFO,"Total bytes written: %.0f\n",
(double)stats.total_written);
rprintf(FINFO,"Total bytes read: %.0f\n\n",
(double)stats.total_read);
}
printf("wrote %.0f bytes read %.0f bytes %.2f bytes/sec\n",
(double)out,(double)in,(in+out)/(0.5 + (t-starttime)));
printf("total size is %.0f speedup is %.2f\n",
(double)tsize,(1.0*tsize)/(in+out));
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);
}
@@ -147,10 +172,14 @@ static char *get_local_name(struct file_list *flist,char *name)
STRUCT_STAT st;
extern int orig_umask;
if (verbose > 2)
rprintf(FINFO,"get_local_name count=%d %s\n",
flist->count, name);
if (do_stat(name,&st) == 0) {
if (S_ISDIR(st.st_mode)) {
if (chdir(name) != 0) {
rprintf(FERROR,"chdir %s : %s (1)\n",
if (!push_dir(name, 0)) {
rprintf(FERROR,"push_dir %s : %s (1)\n",
name,strerror(errno));
exit_cleanup(1);
}
@@ -173,11 +202,13 @@ static char *get_local_name(struct file_list *flist,char *name)
rprintf(FERROR,"mkdir %s : %s (1)\n",name,strerror(errno));
exit_cleanup(1);
} else {
rprintf(FINFO,"created directory %s\n",name);
if (verbose > 0)
rprintf(FINFO,"created directory %s\n",name);
}
if (chdir(name) != 0) {
rprintf(FERROR,"chdir %s : %s (2)\n",name,strerror(errno));
if (!push_dir(name, 0)) {
rprintf(FERROR,"push_dir %s : %s (2)\n",
name,strerror(errno));
exit_cleanup(1);
}
@@ -198,8 +229,8 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
if (verbose > 2)
rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
if (!relative_paths && chdir(dir) != 0) {
rprintf(FERROR,"chdir %s: %s (3)\n",dir,strerror(errno));
if (!relative_paths && !push_dir(dir, 0)) {
rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno));
exit_cleanup(1);
}
argc--;
@@ -224,6 +255,10 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
exit_cleanup(0);
}
set_nonblocking(f_out);
if (f_in != f_out)
set_nonblocking(f_in);
send_files(flist,f_out,f_in);
report(f_out);
io_flush();
@@ -252,12 +287,11 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
close(recv_pipe[0]);
if (f_in != f_out) close(f_out);
set_nonblocking(f_in);
recv_files(f_in,flist,local_name,recv_pipe[1]);
report(f_in);
if (verbose > 3)
rprintf(FINFO,"do_recv waiting on %d\n",pid);
io_flush();
_exit(0);
}
@@ -265,6 +299,11 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
close(recv_pipe[1]);
io_close_input(f_in);
if (f_in != f_out) close(f_in);
set_nonblocking(f_out);
io_start_buffering(f_out);
generate_files(f_out,flist,local_name,recv_pipe[0]);
io_flush();
@@ -289,8 +328,8 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
dir = argv[0];
argc--;
argv++;
if (!am_daemon && chdir(dir) != 0) {
rprintf(FERROR,"chdir %s : %s (4)\n",
if (!am_daemon && !push_dir(dir, 0)) {
rprintf(FERROR,"push_dir %s : %s (4)\n",
dir,strerror(errno));
exit_cleanup(1);
}
@@ -355,6 +394,11 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
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)
@@ -388,20 +432,34 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
return status | status2;
}
static char *find_colon(char *s)
{
char *p, *p2;
int start_client(int argc, char *argv[])
p = strchr(s,':');
if (!p) return NULL;
/* now check to see if there is a / in the string before the : - if there is then
discard the colon on the assumption that the : is part of a filename */
p2 = strchr(s,'/');
if (p2 && p2 < p) return NULL;
return p;
}
static int start_client(int argc, char *argv[])
{
char *p;
char *shell_machine = NULL;
char *shell_path = NULL;
char *shell_user = NULL;
int pid;
int pid, ret;
int f_in,f_out;
extern int local_server;
extern int am_sender;
extern char *shell_cmd;
p = strchr(argv[0],':');
p = find_colon(argv[0]);
if (p) {
if (p[1] == ':') {
@@ -423,7 +481,7 @@ int start_client(int argc, char *argv[])
} else {
am_sender = 1;
p = strchr(argv[argc-1],':');
p = find_colon(argv[argc-1]);
if (!p) {
local_server = 1;
} else if (p[1] == ':') {
@@ -471,12 +529,12 @@ int start_client(int argc, char *argv[])
pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out);
#if HAVE_SETLINEBUF
setlinebuf(stdout);
setlinebuf(stderr);
#endif
ret = client_run(f_in, f_out, pid, argc, argv);
return client_run(f_in, f_out, pid, argc, argv);
fflush(stdout);
fflush(stderr);
return ret;
}
@@ -497,6 +555,8 @@ int main(int argc,char *argv[])
starttime = time(NULL);
am_root = (getuid() == 0);
memset(&stats, 0, sizeof(stats));
if (argc < 2) {
usage(FERROR);
exit_cleanup(1);
@@ -506,7 +566,9 @@ int main(int argc,char *argv[])
carried across */
orig_umask = (int)umask(0);
parse_arguments(argc, argv);
if (!parse_arguments(argc, argv)) {
exit_cleanup(1);
}
argc -= optind;
argv += optind;

32
match.c
View File

@@ -29,18 +29,18 @@ extern int remote_version;
typedef unsigned short tag;
#define TABLESIZE (1<<16)
#define NULL_TAG ((tag)-1)
#define NULL_TAG (-1)
static int false_alarms;
static int tag_hits;
static int matches;
static int data_transfer;
static int64 data_transfer;
static int total_false_alarms;
static int total_tag_hits;
static int total_matches;
static int64 total_data_transfer;
extern struct stats stats;
struct target {
tag t;
@@ -49,7 +49,7 @@ struct target {
static struct target *targets;
static tag *tag_table;
static int *tag_table;
#define gettag2(s1,s2) (((s1) + (s2)) & 0xFFFF)
#define gettag(sum) gettag2((sum)&0xFFFF,(sum)>>16)
@@ -65,7 +65,7 @@ static void build_hash_table(struct sum_struct *s)
int i;
if (!tag_table)
tag_table = (tag *)malloc(sizeof(tag)*TABLESIZE);
tag_table = (int *)malloc(sizeof(tag_table[0])*TABLESIZE);
targets = (struct target *)malloc(sizeof(targets[0])*s->count);
if (!tag_table || !targets)
@@ -103,8 +103,10 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
send_token(f,i,buf,last_match,n,i<0?0:s->sums[i].len);
data_transfer += n;
if (i >= 0)
if (i >= 0) {
stats.matched_data += s->sums[i].len;
n += s->sums[i].len;
}
for (j=0;j<n;j+=CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,n-j);
@@ -116,6 +118,11 @@ static void matched(int f,struct sum_struct *s,struct map_struct *buf,
last_match = offset + s->sums[i].len;
else
last_match = offset;
if (buf)
show_progress(last_match, buf->size);
if (i == -1) end_progress();
}
@@ -250,6 +257,12 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
if (verbose > 2)
rprintf(FINFO,"done hash search\n");
} else {
OFF_T j;
/* by doing this in pieces we avoid too many seeks */
for (j=0;j<(len-CHUNK_SIZE);j+=CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,(len-CHUNK_SIZE)-j);
matched(f,s,buf,j+n1,-2);
}
matched(f,s,buf,len,-1);
}
@@ -273,7 +286,7 @@ void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
total_tag_hits += tag_hits;
total_false_alarms += false_alarms;
total_matches += matches;
total_data_transfer += data_transfer;
stats.literal_data += data_transfer;
}
void match_report(void)
@@ -282,7 +295,8 @@ void match_report(void)
return;
rprintf(FINFO,
"total: matches=%d tag_hits=%d false_alarms=%d data=%ld\n",
"total: matches=%d tag_hits=%d false_alarms=%d data=%.0f\n",
total_matches,total_tag_hits,
total_false_alarms,(long)total_data_transfer);
total_false_alarms,
(double)stats.literal_data);
}

596
options.c
View File

@@ -55,6 +55,10 @@ 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 block_size=BLOCK_SIZE;
@@ -74,58 +78,73 @@ void usage(int F)
{
rprintf(F,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
VERSION);
rprintf(F,"Usage:\t%s [options] src user@host:dest\nOR",RSYNC_NAME);
rprintf(F,"\t%s [options] user@host:src dest\n\n",RSYNC_NAME);
rprintf(F,"Options:\n");
rprintf(F,"-v, --verbose increase verbosity\n");
rprintf(F,"-c, --checksum always checksum\n");
rprintf(F,"-a, --archive archive mode (same as -rlptDog)\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,"-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,"-H, --hard-links preserve hard links\n");
rprintf(F,"-p, --perms preserve permissions\n");
rprintf(F,"-o, --owner preserve owner (root only)\n");
rprintf(F,"-g, --group preserve group\n");
rprintf(F,"-D, --devices preserve devices (root only)\n");
rprintf(F,"-t, --times preserve times\n");
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,"-x, --one-file-system don't cross filesystem boundaries\n");
rprintf(F,"-B, --block-size SIZE checksum blocking size\n");
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," --delete delete files that don't exist on the sending side\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,"-T --temp-dir DIR create temporary files in directory DIR\n");
rprintf(F,"-z, --compress compress file data\n");
rprintf(F," --exclude FILE exclude file FILE\n");
rprintf(F," --exclude-from FILE exclude files listed in FILE\n");
rprintf(F," --include FILE don't exclude file FILE\n");
rprintf(F," --include-from FILE don't exclude files 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," --config FILE specify alternate rsyncd.conf file\n");
rprintf(F," --port PORT specify alternate rsyncd port number\n");
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," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
rprintf(F," or rsync [OPTION]... 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,"\nOptions\n");
rprintf(F," -v, --verbose increase 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," -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," --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");
rprintf(F," -o, --owner preserve owner (root only)\n");
rprintf(F," -g, --group preserve group\n");
rprintf(F," -D, --devices preserve devices (root only)\n");
rprintf(F," -t, --times preserve times\n");
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," -x, --one-file-system don't cross filesystem boundaries\n");
rprintf(F," -B, --block-size=SIZE checksum blocking size\n");
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," --delete delete files that don't exist on the sending side\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," -T --temp-dir=DIR create temporary files in directory DIR\n");
rprintf(F," -z, --compress compress file data\n");
rprintf(F," --exclude=PATTERN exclude file FILE\n");
rprintf(F," --exclude-from=PATTERN exclude files listed in FILE\n");
rprintf(F," --include=PATTERN don't exclude file FILE\n");
rprintf(F," --include-from=PATTERN don't exclude files 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," --config=FILE specify alternate rsyncd.conf file\n");
rprintf(F," --port=PORT specify alternate rsyncd port number\n");
rprintf(F," --stats give some file transfer stats\n");
rprintf(F," --progress show progress during transfer\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://samba.anu.edu.au/rsync/ 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,
OPT_INCLUDE, OPT_INCLUDE_FROM};
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
OPT_SAFE_LINKS};
static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:T:z";
@@ -158,6 +177,7 @@ static struct option long_options[] = {
{"perms", 0, 0, 'p'},
{"links", 0, 0, 'l'},
{"copy-links", 0, 0, 'L'},
{"safe-links", 0, 0, OPT_SAFE_LINKS},
{"whole-file", 0, 0, 'W'},
{"hard-links", 0, 0, 'H'},
{"owner", 0, 0, 'o'},
@@ -170,306 +190,332 @@ static struct option long_options[] = {
{"temp-dir", 1, 0, 'T'},
{"compress", 0, 0, 'z'},
{"daemon", 0, 0, OPT_DAEMON},
{"stats", 0, 0, OPT_STATS},
{"progress", 0, 0, OPT_PROGRESS},
{"partial", 0, 0, OPT_PARTIAL},
{"config", 1, 0, OPT_CONFIG},
{"port", 1, 0, OPT_PORT},
{0,0,0,0}};
void parse_arguments(int argc, char *argv[])
int parse_arguments(int argc, char *argv[])
{
int opt;
int option_index;
int opt;
int option_index;
while ((opt = getopt_long(argc, argv,
short_options, long_options, &option_index))
!= -1) {
switch (opt)
{
case OPT_VERSION:
printf("rsync version %s protocol version %d\n",
VERSION,PROTOCOL_VERSION);
exit_cleanup(0);
while ((opt = getopt_long(argc, argv,
short_options, long_options, &option_index))
!= -1) {
switch (opt) {
case OPT_VERSION:
rprintf(FINFO,"rsync version %s protocol version %d\n\n",
VERSION,PROTOCOL_VERSION);
rprintf(FINFO,"Written by Andrew Tridgell and Paul Mackerras\n");
exit_cleanup(0);
case OPT_SUFFIX:
backup_suffix = optarg;
break;
case OPT_RSYNC_PATH:
rsync_path = optarg;
break;
case 'I':
ignore_times = 1;
break;
case OPT_SUFFIX:
backup_suffix = optarg;
break;
case 'x':
one_file_system=1;
break;
case OPT_RSYNC_PATH:
rsync_path = optarg;
break;
case OPT_DELETE:
delete_mode = 1;
break;
case 'I':
ignore_times = 1;
break;
case OPT_FORCE:
force_delete = 1;
break;
case 'x':
one_file_system=1;
break;
case OPT_NUMERIC_IDS:
numeric_ids = 1;
break;
case OPT_DELETE:
delete_mode = 1;
break;
case OPT_EXCLUDE:
add_exclude(optarg, 0);
break;
case OPT_FORCE:
force_delete = 1;
break;
case OPT_INCLUDE:
add_exclude(optarg, 1);
break;
case OPT_NUMERIC_IDS:
numeric_ids = 1;
break;
case OPT_EXCLUDE_FROM:
add_exclude_file(optarg,1, 0);
break;
case OPT_EXCLUDE:
add_exclude(optarg, 0);
break;
case OPT_INCLUDE_FROM:
add_exclude_file(optarg,1, 1);
break;
case OPT_INCLUDE:
add_exclude(optarg, 1);
break;
case OPT_SAFE_LINKS:
safe_symlinks=1;
break;
case OPT_EXCLUDE_FROM:
add_exclude_file(optarg,1, 0);
break;
case 'h':
usage(FINFO);
exit_cleanup(0);
case OPT_INCLUDE_FROM:
add_exclude_file(optarg,1, 1);
break;
case 'b':
make_backups=1;
break;
case 'h':
usage(FINFO);
exit_cleanup(0);
case 'n':
dry_run=1;
break;
case 'b':
make_backups=1;
break;
case 'S':
sparse_files=1;
break;
case 'n':
dry_run=1;
break;
case 'C':
cvs_exclude=1;
break;
case 'S':
sparse_files=1;
break;
case 'u':
update_only=1;
break;
case 'C':
cvs_exclude=1;
break;
case 'l':
preserve_links=1;
break;
case 'u':
update_only=1;
break;
case 'L':
copy_links=1;
break;
case 'l':
preserve_links=1;
break;
case 'W':
whole_file=1;
break;
case 'L':
copy_links=1;
break;
case 'W':
whole_file=1;
break;
case 'H':
case 'H':
#if SUPPORT_HARD_LINKS
preserve_hard_links=1;
preserve_hard_links=1;
#else
rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
exit_cleanup(1);
rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
return 0;
#endif
break;
break;
case 'p':
preserve_perms=1;
break;
case 'p':
preserve_perms=1;
break;
case 'o':
preserve_uid=1;
break;
case 'o':
preserve_uid=1;
break;
case 'g':
preserve_gid=1;
break;
case 'g':
preserve_gid=1;
break;
case 'D':
preserve_devices=1;
break;
case 'D':
preserve_devices=1;
break;
case 't':
preserve_times=1;
break;
case 't':
preserve_times=1;
break;
case 'c':
always_checksum=1;
break;
case 'c':
always_checksum=1;
break;
case 'v':
verbose++;
break;
case 'v':
verbose++;
break;
case 'a':
recurse=1;
case 'a':
recurse=1;
#if SUPPORT_LINKS
preserve_links=1;
preserve_links=1;
#endif
preserve_perms=1;
preserve_times=1;
preserve_gid=1;
if (am_root) {
preserve_devices=1;
preserve_uid=1;
}
break;
preserve_perms=1;
preserve_times=1;
preserve_gid=1;
if (am_root) {
preserve_devices=1;
preserve_uid=1;
}
break;
case OPT_SERVER:
am_server = 1;
break;
case OPT_SERVER:
am_server = 1;
break;
case OPT_SENDER:
if (!am_server) {
usage(FERROR);
exit_cleanup(1);
}
am_sender = 1;
break;
case OPT_SENDER:
if (!am_server) {
usage(FERROR);
exit_cleanup(1);
}
am_sender = 1;
break;
case 'r':
recurse = 1;
break;
case 'r':
recurse = 1;
break;
case 'R':
relative_paths = 1;
break;
case 'R':
relative_paths = 1;
break;
case 'e':
shell_cmd = optarg;
break;
case 'e':
shell_cmd = optarg;
break;
case 'B':
block_size = atoi(optarg);
break;
case 'B':
block_size = atoi(optarg);
break;
case OPT_TIMEOUT:
io_timeout = atoi(optarg);
break;
case OPT_TIMEOUT:
io_timeout = atoi(optarg);
break;
case 'T':
tmpdir = optarg;
break;
case 'T':
tmpdir = optarg;
break;
case 'z':
do_compression = 1;
break;
case 'z':
do_compression = 1;
break;
case OPT_DAEMON:
am_daemon = 1;
break;
case OPT_DAEMON:
am_daemon = 1;
break;
case OPT_CONFIG:
config_file = optarg;
break;
case OPT_STATS:
do_stats = 1;
break;
case OPT_PORT:
rsync_port = atoi(optarg);
break;
case OPT_PROGRESS:
do_progress = 1;
break;
default:
/* rprintf(FERROR,"bad option -%c\n",opt); */
exit_cleanup(1);
case OPT_PARTIAL:
keep_partial = 1;
break;
case OPT_CONFIG:
config_file = optarg;
break;
case OPT_PORT:
rsync_port = atoi(optarg);
break;
default:
return 0;
}
}
}
return 1;
}
void server_options(char **args,int *argc)
{
int ac = *argc;
static char argstr[50];
static char bsize[30];
static char iotime[30];
int i, x;
int ac = *argc;
static char argstr[50];
static char bsize[30];
static char iotime[30];
int i, x;
args[ac++] = "--server";
args[ac++] = "--server";
if (!am_sender)
args[ac++] = "--sender";
if (!am_sender)
args[ac++] = "--sender";
x = 1;
argstr[0] = '-';
for (i=0;i<verbose;i++)
argstr[x++] = 'v';
if (make_backups)
argstr[x++] = 'b';
if (update_only)
argstr[x++] = 'u';
if (dry_run)
argstr[x++] = 'n';
if (preserve_links)
argstr[x++] = 'l';
if (copy_links)
argstr[x++] = 'L';
if (whole_file)
argstr[x++] = 'W';
if (preserve_hard_links)
argstr[x++] = 'H';
if (preserve_uid)
argstr[x++] = 'o';
if (preserve_gid)
argstr[x++] = 'g';
if (preserve_devices)
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
if (preserve_perms)
argstr[x++] = 'p';
if (recurse)
argstr[x++] = 'r';
if (always_checksum)
argstr[x++] = 'c';
if (cvs_exclude)
argstr[x++] = 'C';
if (ignore_times)
argstr[x++] = 'I';
if (relative_paths)
argstr[x++] = 'R';
if (one_file_system)
argstr[x++] = 'x';
if (sparse_files)
argstr[x++] = 'S';
if (do_compression)
argstr[x++] = 'z';
argstr[x] = 0;
x = 1;
argstr[0] = '-';
for (i=0;i<verbose;i++)
argstr[x++] = 'v';
if (make_backups)
argstr[x++] = 'b';
if (update_only)
argstr[x++] = 'u';
if (dry_run)
argstr[x++] = 'n';
if (preserve_links)
argstr[x++] = 'l';
if (copy_links)
argstr[x++] = 'L';
if (whole_file)
argstr[x++] = 'W';
if (preserve_hard_links)
argstr[x++] = 'H';
if (preserve_uid)
argstr[x++] = 'o';
if (preserve_gid)
argstr[x++] = 'g';
if (preserve_devices)
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
if (preserve_perms)
argstr[x++] = 'p';
if (recurse)
argstr[x++] = 'r';
if (always_checksum)
argstr[x++] = 'c';
if (cvs_exclude)
argstr[x++] = 'C';
if (ignore_times)
argstr[x++] = 'I';
if (relative_paths)
argstr[x++] = 'R';
if (one_file_system)
argstr[x++] = 'x';
if (sparse_files)
argstr[x++] = 'S';
if (do_compression)
argstr[x++] = 'z';
argstr[x] = 0;
if (x != 1) args[ac++] = argstr;
if (x != 1) args[ac++] = argstr;
if (block_size != BLOCK_SIZE) {
sprintf(bsize,"-B%d",block_size);
args[ac++] = bsize;
}
if (block_size != BLOCK_SIZE) {
sprintf(bsize,"-B%d",block_size);
args[ac++] = bsize;
}
if (io_timeout) {
sprintf(iotime,"--timeout=%d",io_timeout);
args[ac++] = iotime;
}
if (io_timeout) {
sprintf(iotime,"--timeout=%d",io_timeout);
args[ac++] = iotime;
}
if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
args[ac++] = "--suffix";
args[ac++] = backup_suffix;
}
if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
args[ac++] = "--suffix";
args[ac++] = backup_suffix;
}
if (delete_mode)
args[ac++] = "--delete";
if (delete_mode)
args[ac++] = "--delete";
if (force_delete)
args[ac++] = "--force";
if (keep_partial)
args[ac++] = "--partial";
if (numeric_ids)
args[ac++] = "--numeric-ids";
if (force_delete)
args[ac++] = "--force";
if (tmpdir) {
args[ac++] = "--temp-dir";
args[ac++] = tmpdir;
}
if (safe_symlinks)
args[ac++] = "--safe-links";
*argc = ac;
if (numeric_ids)
args[ac++] = "--numeric-ids";
if (tmpdir) {
args[ac++] = "--temp-dir";
args[ac++] = tmpdir;
}
*argc = ac;
}

View File

@@ -1,10 +1,10 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.0.14
Version: 2.1.0
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.0.14.tar.gz
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.1.0.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync

1525
rsync.c
View File

File diff suppressed because it is too large Load Diff

99
rsync.h
View File

@@ -69,6 +69,13 @@
#endif
#include <sys/types.h>
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
#else
#include "lib/getopt.h"
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -91,10 +98,6 @@
#include <string.h>
#endif
#ifdef HAVE_COMPAT_H
#include <compat.h>
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
@@ -166,12 +169,6 @@
#include "lib/fnmatch.h"
#endif
#ifdef HAVE_GETOPT_LONG
#include <getopt.h>
#else
#include "lib/getopt.h"
#endif
#ifdef HAVE_GLOB
#include <glob.h>
#endif
@@ -187,6 +184,26 @@
#include <syslog.h>
#include <sys/file.h>
#if HAVE_DIRENT_H
# include <dirent.h>
#else
# define dirent direct
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# if HAVE_NDIR_H
# include <ndir.h>
# endif
#endif
#ifdef HAVE_COMPAT_H
#include <compat.h>
#endif
#ifndef S_IFLNK
#define S_IFLNK 0120000
#endif
@@ -242,6 +259,12 @@
#define NO_INT64
#endif
#if HAVE_SHORT_INO_T
#define INO_T uint32
#else
#define INO_T ino_t
#endif
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
@@ -267,7 +290,7 @@ struct file_struct {
time_t modtime;
OFF_T length;
mode_t mode;
ino_t inode;
INO_T inode;
dev_t dev;
dev_t rdev;
uid_t uid;
@@ -280,17 +303,17 @@ struct file_struct {
};
struct file_list {
int count;
int malloced;
struct file_struct **files;
int count;
int malloced;
struct file_struct **files;
};
struct sum_buf {
OFF_T offset; /* offset in file of this chunk */
int len; /* length of chunk of file */
int i; /* index of this chunk */
uint32 sum1; /* simple checksum */
char sum2[SUM_LENGTH]; /* checksum */
OFF_T offset; /* offset in file of this chunk */
int len; /* length of chunk of file */
int i; /* index of this chunk */
uint32 sum1; /* simple checksum */
char sum2[SUM_LENGTH]; /* checksum */
};
struct sum_struct {
@@ -316,6 +339,18 @@ struct exclude_struct {
int local;
};
struct stats {
int64 total_size;
int64 total_transferred_size;
int64 total_written;
int64 total_read;
int64 literal_data;
int64 matched_data;
int flist_size;
int num_files;
int num_transferred_files;
};
/* we need this function because of the silly way in which duplicate
entries are handled in the file lists - we can't change this
@@ -326,21 +361,6 @@ static inline int flist_up(struct file_list *flist, int i)
return i;
}
#if HAVE_DIRENT_H
# include <dirent.h>
#else
# define dirent direct
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# if HAVE_NDIR_H
# include <ndir.h>
# endif
#endif
#include "byteorder.h"
#include "version.h"
#include "proto.h"
@@ -360,14 +380,6 @@ extern char *sys_errlist[];
extern int errno;
#endif
#ifndef HAVE_BCOPY
#define bcopy(src,dest,n) memcpy(dest,src,n)
#endif
#ifndef HAVE_BZERO
#define bzero(buf,n) memset(buf,0,n)
#endif
#define SUPPORT_LINKS HAVE_READLINK
#define SUPPORT_HARD_LINKS HAVE_LINK
@@ -432,3 +444,6 @@ extern int errno;
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))
#ifndef ACCESSPERMS
#define ACCESSPERMS 0777
#endif

152
rsync.yo
View File

@@ -187,6 +187,65 @@ quote(rsync -az -e ssh --delete ~ftp/pub/samba/ nimbus:"~ftp/pub/tridge/samba")
this is launched from cron every few hours.
manpagesection(OPTIONS SUMMARY)
Here is a short summary of the options avalable 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
Options
-v, --verbose increase 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)
-u, --update update only (don't overwrite newer files)
-l, --links preserve soft links
-L, --copy-links treat soft links like regular files
--safe-links ignore links outside the destination tree
-H, --hard-links preserve hard links
-p, --perms preserve permissions
-o, --owner preserve owner (root only)
-g, --group preserve group
-D, --devices preserve devices (root only)
-t, --times preserve times
-S, --sparse handle sparse files efficiently
-n, --dry-run show what would have been transferred
-W, --whole-file copy whole files, no incremental checks
-x, --one-file-system don't cross filesystem boundaries
-B, --block-size=SIZE checksum blocking size
-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
--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
-T --temp-dir=DIR create temporary files in directory DIR
-z, --compress compress file data
--exclude=PATTERN exclude file FILE
--exclude-from=PATTERN exclude files listed in FILE
--include=PATTERN don't exclude file FILE
--include-from=PATTERN don't exclude files 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
--port=PORT specify alternate rsyncd port number
--stats give some file transfer stats
--progress show progress during transfer
-h, --help show this help screen
)
manpageoptions()
rsync uses the GNU long options package. Many of the command line
@@ -217,9 +276,12 @@ 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 -rlptDog. It is a quick way
dit(bf(-a, --archive)) This is equivalent to -rlptDg. It is a quick way
of saying I 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, --relative)) Use relative paths. This means that the full path
@@ -253,6 +315,11 @@ option all symbolic links are skipped.
dit(bf(-L, --copy-links)) This tells rsync to treat symbolic links just
like ordinary files.
dit(bf(--safe-links)) This tells rsync to ignore any symbolic links
which point outside the destination tree. All absolute symlinks are
also ignored. Using this option in conjunction with --relative may
give unexpecetd results.
dit(bf(-H, --hard-links)) This tells rsync to recreate hard links on
the remote system to be the same as the local system. Without this
option hard links are treated like regular files.
@@ -266,6 +333,12 @@ 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.
@@ -289,6 +362,10 @@ instead it will just report the actions it would have taken.
dit(bf(-S, --sparse)) Try to handle sparse files efficiently so they take
up less space on the destination.
NOTE: Don't use this option when the destination is a Solaris "tmpfs"
filesystem. It doesn't seem to handle seeks over null regions
correctly and ends up corrupting the files.
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.
@@ -385,7 +462,7 @@ 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,
making things faster.
making things faster.
You can choose the number of bytes in the truncated checksum using the
--csum-length option. Any value less than or equal to 16 is valid.
@@ -395,6 +472,11 @@ with an incorrect target file. The risk with a value of 16 is
microscopic and can be safely ignored (the universe will probably end
before it fails) but with smaller values the risk is higher.
Current versions of rsync actually use an adaptive algorithm for the
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 options instructs rsync to use DIR as a
scratch directory when creating a temporary copies of the files
transferred on the receiving side. The default behavior is to create
@@ -422,9 +504,9 @@ option is not specified.
If a user or group name does not exist on the destination system then
the numeric id from the source system is used instead.
dit(bf(--timeout)) This option allows you to set a maximum IO timeout in
seconds. If no data is transferred for the specified time then rsync
will exit. The default is 0, which means no timeout.
dit(bf(--timeout=TIMEOUT)) This option allows you to set a maximum IO
timeout in seconds. If no data is transferred for the specified time
then rsync will exit. The default is 0, which means no timeout.
dit(bf(--daemon)) This tells rsync that it is to run as a rsync
daemon. If standard input is a socket then rsync will assume that it
@@ -441,6 +523,15 @@ specified.
dit(bf(--port PORT)) This specifies an alternate TCP port number to use
rather than the default port 873.
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.
dit(bf(--progress)) This option tells rsync to print information
showing the progress of the transfer. This gives a bored user
something to watch.
enddit()
manpagesection(EXCLUDE PATTERNS)
@@ -485,6 +576,9 @@ itemize(
it() if the pattern starts with "- " (a minus followed by a space)
then it is always considered a 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
exclude list is reset, removing all previous exclude patterns.
)
The +/- rules are most useful in exclude lists, allowing you to have a
@@ -500,6 +594,54 @@ itemize(
directories and C source files.
)
manpagesection(DIAGNOSTICS)
rsync occasinally produces error messages that may seem a little
cryptic. The one that seems to cause the most confusion is "protocol
version mismatch - is your shell clean?".
This message is usually caused by your startup scripts or remote shell
facility producing unwanted garbage on the stream that rsync is using
for its transport. The way ot diagnose this problem is to run your
remote shell like this:
verb(
rsh remotehost /bin/true > out.dat
)
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
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 configued shell startup
scripts (such as .cshrc or .profile) that contain output statements
for non-interactive logins.
manpagesection(ENVIRONMENT VARIABLES)
startdit()
dit(bf(CVSIGNORE)) The CVSIGNORE environment variable supplements any
ignore patterns in .cvsignore files. See the --cvs-exclude option for
more details.
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_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
password to a shell transport such as ssh.
dit(bf(USER) or bf(LOGNAME)) The USER or LOGNAME environment variables
are used to determine the default username sent to a rsync server.
dit(bf(HOME)) The HOME environment variable is used to find the users
default .cvsignore file.
enddit()
manpagefiles()
/etc/rsyncd.conf

View File

@@ -225,7 +225,7 @@ connect.
The default is no "hosts allow" option, which means all hosts can connect.
dit(bf(hosts allow)) The "hosts deny" option allows you to specify a
dit(bf(hosts deny)) The "hosts deny" option allows you to specify a
list of patterns that are matched against a connecting clients
hostname and IP address. If the pattern matches then the connection is
rejected. See the "hosts allow" option for more information.

View File

@@ -81,7 +81,7 @@ static int open_socket_in(int type, int port)
return -1;
}
bzero((char *)&sock,sizeof(sock));
memset((char *)&sock,0,sizeof(sock));
memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
sock.sin_port = htons(port);
sock.sin_family = hp->h_addrtype;
@@ -120,8 +120,6 @@ void start_accept_loop(int port, int (*fn)(int ))
{
int s;
signal(SIGCHLD, SIG_IGN);
/* open an incoming socket */
s = open_socket_in(SOCK_STREAM, port);
if (s == -1)
@@ -155,6 +153,15 @@ void start_accept_loop(int port, int (*fn)(int ))
if (fd == -1) continue;
signal(SIGCHLD, SIG_IGN);
/* we shouldn't have any children left hanging around
but I have had reports that on Digital Unix zombies
are produced, so this ensures that they are reaped */
#ifdef WNOHANG
waitpid(-1, NULL, WNOHANG);
#endif
if (fork()==0) {
close(s);
@@ -274,27 +281,30 @@ become a daemon, discarding the controlling terminal
****************************************************************************/
void become_daemon(void)
{
if (fork())
int i;
if (fork()) {
_exit(0);
}
/* detach from the terminal */
#ifdef HAVE_SETSID
setsid();
#else
#ifdef TIOCNOTTY
{
int i = open("/dev/tty", O_RDWR);
if (i >= 0)
{
ioctl(i, (int) TIOCNOTTY, (char *)0);
close(i);
}
i = open("/dev/tty", O_RDWR);
if (i >= 0) {
ioctl(i, (int) TIOCNOTTY, (char *)0);
close(i);
}
#endif /* TIOCNOTTY */
#endif
close(0);
close(1);
close(2);
/* make sure that stdin, stdout an stderr don't stuff things
up (library functions, for example) */
for (i=0;i<3;i++) {
close(i);
open("/dev/null", O_RDWR);
}
}
/*******************************************************************

View File

@@ -10,6 +10,14 @@
#
#
cat <<EOF
This set of tests is not completely portable. It is intended for developers
not for end users. You may experience failures on some platforms that
do not indicate a problem with rsync.
EOF
export PATH=.:$PATH
TMP=/tmp/rsync-test.$$
FROM=${TMP}/from

212
util.c
View File

@@ -24,15 +24,33 @@
*/
#include "rsync.h"
int num_waiting(int fd)
/****************************************************************************
Set a fd into nonblocking mode. Uses POSIX O_NONBLOCK if available,
else
if SYSV use O_NDELAY
if BSD use FNDELAY
****************************************************************************/
int set_nonblocking(int fd)
{
int len=0;
ioctl(fd,FIONREAD,&len);
return(len);
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
}
/* this is taken from CVS */
int piped_child(char **command,int *f_in,int *f_out)
{
@@ -206,7 +224,7 @@ int create_directory_path(char *fname)
derived from GNU C's cccp.c.
*/
int full_write(int desc, char *ptr, int len)
static int full_write(int desc, char *ptr, int len)
{
int total_written;
@@ -273,7 +291,7 @@ int copy_file(char *source, char *dest, mode_t mode)
}
ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode);
if (ofd < 0) {
if (ofd == -1) {
rprintf(FERROR,"open %s: %s\n",
dest,strerror(errno));
close(ifd);
@@ -559,3 +577,183 @@ void *Realloc(void *p, int size)
if (!p) return (void *)malloc(size);
return (void *)realloc(p, size);
}
void clean_fname(char *name)
{
char *p;
int l;
int modified = 1;
if (!name) return;
while (modified) {
modified = 0;
if ((p=strstr(name,"/./"))) {
modified = 1;
while (*p) {
p[0] = p[2];
p++;
}
}
if ((p=strstr(name,"//"))) {
modified = 1;
while (*p) {
p[0] = p[1];
p++;
}
}
if (strncmp(p=name,"./",2) == 0) {
modified = 1;
do {
p[0] = p[2];
} while (*p++);
}
l = strlen(p=name);
if (l > 1 && p[l-1] == '/') {
modified = 1;
p[l-1] = 0;
}
}
}
static char curr_dir[MAXPATHLEN];
/* like chdir() but can be reversed with pop_dir() if save is set. It
is also much faster as it remembers where we have been */
char *push_dir(char *dir, int save)
{
char *ret = curr_dir;
static int initialised;
if (!initialised) {
initialised = 1;
getcwd(curr_dir, sizeof(curr_dir)-1);
}
if (chdir(dir)) return NULL;
if (save) {
ret = strdup(curr_dir);
}
if (*dir == '/') {
strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
} else {
strlcat(curr_dir,"/", sizeof(curr_dir)-1);
strlcat(curr_dir,dir, sizeof(curr_dir)-1);
}
clean_fname(curr_dir);
return ret;
}
/* reverse a push_dir call */
int pop_dir(char *dir)
{
int ret;
ret = chdir(dir);
if (ret) {
free(dir);
return ret;
}
strlcpy(curr_dir, dir, sizeof(curr_dir)-1);
free(dir);
return 0;
}
/* we need to supply our own strcmp function for file list comparisons
to ensure that signed/unsigned usage is consistent between machines. */
int u_strcmp(const char *cs1, const char *cs2)
{
const uchar *s1 = (uchar *)cs1;
const uchar *s2 = (uchar *)cs2;
while (*s1 && *s2 && (*s1 == *s2)) {
s1++; s2++;
}
return (int)*s1 - (int)*s2;
}
static OFF_T last_ofs;
void end_progress(void)
{
extern int do_progress, am_server;
if (do_progress && !am_server) {
rprintf(FINFO,"\n");
}
last_ofs = 0;
}
void show_progress(OFF_T ofs, OFF_T size)
{
extern int do_progress, am_server;
if (do_progress && !am_server) {
if (ofs > last_ofs + 1000) {
int pct = (int)((100.0*ofs)/size);
rprintf(FINFO,"%.0f (%d%%)\r", (double)ofs, pct);
last_ofs = ofs;
}
}
}
/* determine if a symlink points outside the current directory tree */
int unsafe_symlink(char *dest, char *src)
{
char *tok;
int depth = 0;
/* all absolute and null symlinks are unsafe */
if (!dest || !(*dest) || (*dest == '/')) return 1;
src = strdup(src);
if (!src) out_of_memory("unsafe_symlink");
/* find out what our safety margin is */
for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) {
if (strcmp(tok,"..") == 0) {
depth=0;
} else if (strcmp(tok,".") == 0) {
/* nothing */
} else {
depth++;
}
}
free(src);
/* drop by one to account for the filename portion */
depth--;
dest = strdup(dest);
if (!dest) out_of_memory("unsafe_symlink");
for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) {
if (strcmp(tok,"..") == 0) {
depth--;
} else if (strcmp(tok,".") == 0) {
/* nothing */
} else {
depth++;
}
/* if at any point we go outside the current directory then
stop - it is unsafe */
if (depth < 0) break;
}
free(dest);
return (depth < 0);
}

View File

@@ -1 +1 @@
#define VERSION "2.0.14"
#define VERSION "2.1.0"

View File

@@ -176,7 +176,7 @@ int r;
break;
case 3: /* illegal */
DUMPBITS(3)
s->mode = BAD;
s->mode = zBAD;
z->msg = (char*)"invalid block type";
r = Z_DATA_ERROR;
LEAVE
@@ -186,7 +186,7 @@ int r;
NEEDBITS(32)
if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
{
s->mode = BAD;
s->mode = zBAD;
z->msg = (char*)"invalid stored block lengths";
r = Z_DATA_ERROR;
LEAVE
@@ -219,7 +219,7 @@ int r;
#ifndef PKZIP_BUG_WORKAROUND
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
{
s->mode = BAD;
s->mode = zBAD;
z->msg = (char*)"too many length or distance symbols";
r = Z_DATA_ERROR;
LEAVE
@@ -252,7 +252,7 @@ int r;
ZFREE(z, s->sub.trees.blens);
r = t;
if (r == Z_DATA_ERROR)
s->mode = BAD;
s->mode = zBAD;
LEAVE
}
s->sub.trees.index = 0;
@@ -289,7 +289,7 @@ int r;
(c == 16 && i < 1))
{
ZFREE(z, s->sub.trees.blens);
s->mode = BAD;
s->mode = zBAD;
z->msg = (char*)"invalid bit length repeat";
r = Z_DATA_ERROR;
LEAVE
@@ -317,7 +317,7 @@ int r;
if (t != Z_OK)
{
if (t == (uInt)Z_DATA_ERROR)
s->mode = BAD;
s->mode = zBAD;
r = t;
LEAVE
}
@@ -361,7 +361,7 @@ int r;
case DONE:
r = Z_STREAM_END;
LEAVE
case BAD:
case zBAD:
r = Z_DATA_ERROR;
LEAVE
default:

View File

@@ -22,7 +22,7 @@ typedef enum {
CHECK2, /* two check bytes to go */
CHECK1, /* one check byte to go */
DONE, /* finished check, done */
BAD} /* got an error--stay here */
zBAD} /* got an error--stay here */
inflate_mode;
/* inflate private state */
@@ -38,7 +38,7 @@ struct internal_state {
uLong was; /* computed check value */
uLong need; /* stream check value */
} check; /* if CHECK, check values to compare */
uInt marker; /* if BAD, inflateSync's marker bytes count */
uInt marker; /* if zBAD, inflateSync's marker bytes count */
} sub; /* submode */
/* mode independent information */
@@ -164,14 +164,14 @@ int f;
NEEDBYTE
if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
{
z->state->mode = BAD;
z->state->mode = zBAD;
z->msg = (char*)"unknown compression method";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
}
if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
{
z->state->mode = BAD;
z->state->mode = zBAD;
z->msg = (char*)"invalid window size";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
@@ -182,7 +182,7 @@ int f;
b = NEXTBYTE;
if (((z->state->sub.method << 8) + b) % 31)
{
z->state->mode = BAD;
z->state->mode = zBAD;
z->msg = (char*)"incorrect header check";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
@@ -213,7 +213,7 @@ int f;
z->state->mode = DICT0;
return Z_NEED_DICT;
case DICT0:
z->state->mode = BAD;
z->state->mode = zBAD;
z->msg = (char*)"need dictionary";
z->state->sub.marker = 0; /* can try inflateSync */
return Z_STREAM_ERROR;
@@ -221,7 +221,7 @@ int f;
r = inflate_blocks(z->state->blocks, z, r);
if (r == Z_DATA_ERROR)
{
z->state->mode = BAD;
z->state->mode = zBAD;
z->state->sub.marker = 0; /* can try inflateSync */
break;
}
@@ -255,7 +255,7 @@ int f;
if (z->state->sub.check.was != z->state->sub.check.need)
{
z->state->mode = BAD;
z->state->mode = zBAD;
z->msg = (char*)"incorrect data check";
z->state->sub.marker = 5; /* can't try inflateSync */
break;
@@ -264,7 +264,7 @@ int f;
z->state->mode = DONE;
case DONE:
return Z_STREAM_END;
case BAD:
case zBAD:
return Z_DATA_ERROR;
default:
return Z_STREAM_ERROR;
@@ -310,9 +310,9 @@ z_streamp z;
/* set up */
if (z == Z_NULL || z->state == Z_NULL)
return Z_STREAM_ERROR;
if (z->state->mode != BAD)
if (z->state->mode != zBAD)
{
z->state->mode = BAD;
z->state->mode = zBAD;
z->state->sub.marker = 0;
}
if ((n = z->avail_in) == 0)

View File

@@ -21,7 +21,7 @@ typedef enum {
CODES, /* processing fixed or dynamic block */
DRY, /* output remaining window bytes */
DONE, /* finished last block, done */
BAD} /* got a data error--stuck here */
zBAD} /* got a data error--stuck here */
inflate_block_mode;
/* inflate blocks semi-private state */