Compare commits

...

27 Commits

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

what we've done before is to set both stdin and stdout to either
blocking or non-blocking. Now I set stdin to blocking and stdout to
non-blocking. This seems to fix all cases I've tested.
2000-04-09 02:16:42 +00:00
rsync-bugs
ec3f7d1b61 preparing for release of 2.4.2 2000-03-30 14:24:37 +00:00
Andrew Tridgell
f0359dd00d went back to non-blokcing IO
it looks like ssh is willing to accept a non-blocking fd when used as
a transport, this seems to avoid the Solaris socketpair bug
2000-03-30 14:15:00 +00:00
Andrew Tridgell
ef55c686bc add a --ignore-errors option 2000-03-21 04:06:04 +00:00
David Dykstra
5f7ce2041c Describe symbolic link handling when writing to a "use chroot = no" module. 2000-02-25 17:02:45 +00:00
David Dykstra
328fcf113a Somebody was confused into thinking that "Here are some examples" in the
section on exclude/include was supposed to be about "+/-" so I changed
the statement to "Here are some exclude/include examples".
2000-02-22 19:47:44 +00:00
David Dykstra
24c857f1de Change socketpair test to verify that it works rather than just exists,
because I have an obscure system (Amdahl's UTS 2.1.2) in which socketpair()
exists but is broken.
2000-02-22 15:55:40 +00:00
David Dykstra
a784e10d00 Move the checking for -lsocket -lnsl ahead of the checking for most of
the functions, especially "socketpair" so that socket-related functions will
be properly discovered on SVR4-based systems such as Solaris.  Problem
discovered by Kenji Miyake <kenji@miyake.org>
2000-02-15 22:44:18 +00:00
18 changed files with 453 additions and 118 deletions

View File

@@ -10,4 +10,6 @@
#undef HAVE_SHORT_INO_T
#undef HAVE_GETOPT_LONG
#undef REPLACE_INET_NTOA
#undef REPLACE_INET_ATON
#undef HAVE_GETTIMEOFDAY_TZ
#undef HAVE_SOCKETPAIR

View File

@@ -197,7 +197,7 @@ static int keep_backup(char *fname)
if (do_stat (fname, &st)) return 1;
#endif
file = make_file (0, fname);
file = make_file (0, fname, 0);
/* make a complete pathname for backup file */
if (strlen(backup_dir) + strlen(fname) > (MAXPATHLEN - 1)) {

View File

@@ -363,7 +363,7 @@ static int start_daemon(int fd)
set_socket_options(fd,"SO_KEEPALIVE");
set_socket_options(fd,lp_socket_options());
set_nonblocking(fd);
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);

View File

@@ -48,12 +48,68 @@ if test x"$rsync_cv_errno" = x"yes"; then
AC_DEFINE(HAVE_ERRNO_DECL)
fi
# The following test taken from the cvs sources
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# These need checks to be before checks for any other functions that
# might be in the same libraries.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
# libsocket.so which has a bad implementation of gethostbyname (it
# only looks in /etc/hosts), so we only look for -lsocket if we need
# it.
AC_CHECK_FUNCS(connect)
if test x"$ac_cv_func_connect" = x"no"; then
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl_s, printf) ;;
esac
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl, printf) ;;
esac
case "$LIBS" in
*-lsocket*) ;;
*) AC_CHECK_LIB(socket, connect) ;;
esac
case "$LIBS" in
*-linet*) ;;
*) AC_CHECK_LIB(inet, connect) ;;
esac
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
dnl has been cached.
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
# ac_cv_func_connect=yes
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
AC_DEFINE(HAVE_CONNECT)
fi
fi
#
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
#
AC_CHECK_FUNCS(strcasecmp)
if test x"$ac_cv_func_strcasecmp" = x"no"; then
AC_CHECK_LIB(resolv, strcasecmp)
fi
AC_FUNC_MEMCMP
AC_FUNC_UTIME_NULL
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf setsid glob strpbrk)
AC_CHECK_FUNCS(strlcat strlcpy inet_aton socketpair)
AC_CHECK_FUNCS(strlcat strlcpy)
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
AC_TRY_RUN([#include <sys/types.h>
#include <sys/socket.h>
main() {
int fd[2];
exit((socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != -1) ? 0 : 1);
}],
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
AC_DEFINE(HAVE_SOCKETPAIR)
fi
AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[
AC_TRY_RUN([#include <fnmatch.h>
@@ -154,53 +210,25 @@ AC_TRY_RUN([
#include <arpa/inet.h>
main() { struct in_addr ip; ip.s_addr = 0x12345678;
if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); }
exit(1);}],
rsync_cv_REPLACE_INET_NTOA=yes,rsync_cv_REPLACE_INET_NTOA=no,rsync_cv_REPLACE_INET_NTOA=cross)])
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(1); }
exit(0);}],
rsync_cv_REPLACE_INET_NTOA=no,rsync_cv_REPLACE_INET_NTOA=yes,rsync_cv_REPLACE_INET_NTOA=cross)])
if test x"$rsync_cv_REPLACE_INET_NTOA" = x"yes"; then
AC_DEFINE(REPLACE_INET_NTOA)
fi
# The following test taken from the cvs sources
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
# libsocket.so which has a bad implementation of gethostbyname (it
# only looks in /etc/hosts), so we only look for -lsocket if we need
# it.
AC_CHECK_FUNCS(connect)
if test x"$ac_cv_func_connect" = x"no"; then
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl_s, printf) ;;
esac
case "$LIBS" in
*-lnsl*) ;;
*) AC_CHECK_LIB(nsl, printf) ;;
esac
case "$LIBS" in
*-lsocket*) ;;
*) AC_CHECK_LIB(socket, connect) ;;
esac
case "$LIBS" in
*-linet*) ;;
*) AC_CHECK_LIB(inet, connect) ;;
esac
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
dnl has been cached.
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
# ac_cv_func_connect=yes
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
AC_DEFINE(HAVE_CONNECT)
fi
fi
#
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
#
AC_CHECK_FUNCS(strcasecmp)
if test x"$ac_cv_func_strcasecmp" = x"no"; then
AC_CHECK_LIB(resolv, strcasecmp)
AC_CACHE_CHECK([for broken inet_aton],rsync_cv_REPLACE_INET_ATON,[
AC_TRY_RUN([
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
main() { struct in_addr ip;
if (inet_aton("example", &ip) == 0) exit(0); exit(1);}],
rsync_cv_REPLACE_INET_ATON=no,rsync_cv_REPLACE_INET_ATON=yes,rsync_cv_REPLACE_INET_ATON=cross)])
if test x"$rsync_cv_REPLACE_INET_ATON" = x"yes"; then
AC_DEFINE(REPLACE_INET_ATON)
fi
#

121
flist.c
View File

@@ -51,8 +51,60 @@ static char topsrcname[MAXPATHLEN];
static struct exclude_struct **local_exclude_list;
static struct file_struct null_file;
static void clean_flist(struct file_list *flist, int strip_root);
struct string_area *string_area_new(int size)
{
struct string_area *a;
if (size <= 0) size = ARENA_SIZE;
a = malloc(sizeof(*a));
if (!a) out_of_memory("string_area_new");
a->current = a->base = malloc(size);
if (!a->current) out_of_memory("string_area_new buffer");
a->end = a->base + size;
a->next = 0;
return a;
}
void string_area_free(struct string_area *a)
{
struct string_area *next;
for ( ; a ; a = next) {
next = a->next;
free(a->base);
}
}
char *string_area_malloc(struct string_area **ap, int size)
{
char *p;
struct string_area *a;
/* does the request fit into the current space? */
a = *ap;
if (a->current + size >= a->end) {
/* no; get space, move new string_area to front of the list */
a = string_area_new(size > ARENA_SIZE ? size : ARENA_SIZE);
a->next = *ap;
*ap = a;
}
/* have space; do the "allocation." */
p = a->current;
a->current += size;
return p;
}
char *string_area_strdup(struct string_area **ap, const char *src)
{
char* dest = string_area_malloc(ap, strlen(src) + 1);
return strcpy(dest, src);
}
static void list_file_entry(struct file_struct *f)
{
@@ -413,8 +465,11 @@ static int skip_filesystem(char *fname, STRUCT_STAT *st)
return (st2.st_dev != filesystem_dev);
}
#define STRDUP(ap, p) (ap ? string_area_strdup(ap, p) : strdup(p))
#define MALLOC(ap, i) (ap ? string_area_malloc(ap, i) : malloc(i))
/* create a file_struct for a named file */
struct file_struct *make_file(int f, char *fname)
struct file_struct *make_file(int f, char *fname, struct string_area **ap)
{
struct file_struct *file;
STRUCT_STAT st;
@@ -468,14 +523,14 @@ struct file_struct *make_file(int f, char *fname)
if (lastdir && strcmp(fname, lastdir)==0) {
file->dirname = lastdir;
} else {
file->dirname = strdup(fname);
file->dirname = STRDUP(ap, fname);
lastdir = file->dirname;
}
file->basename = strdup(p+1);
file->basename = STRDUP(ap, p+1);
*p = '/';
} else {
file->dirname = NULL;
file->basename = strdup(fname);
file->basename = STRDUP(ap, fname);
}
file->modtime = st.st_mtime;
@@ -491,12 +546,12 @@ struct file_struct *make_file(int f, char *fname)
#if SUPPORT_LINKS
if (S_ISLNK(st.st_mode)) {
file->link = strdup(linkbuf);
file->link = STRDUP(ap, linkbuf);
}
#endif
if (always_checksum) {
file->sum = (char *)malloc(MD4_SUM_LENGTH);
file->sum = (char *)MALLOC(ap, MD4_SUM_LENGTH);
if (!file->sum) out_of_memory("md4 sum");
/* drat. we have to provide a null checksum for non-regular
files in order to be compatible with earlier versions
@@ -513,7 +568,7 @@ struct file_struct *make_file(int f, char *fname)
if (lastdir && strcmp(lastdir, flist_dir)==0) {
file->basedir = lastdir;
} else {
file->basedir = strdup(flist_dir);
file->basedir = STRDUP(ap, flist_dir);
lastdir = file->basedir;
}
} else {
@@ -533,7 +588,7 @@ void send_file_name(int f,struct file_list *flist,char *fname,
{
struct file_struct *file;
file = make_file(f,fname);
file = make_file(f,fname, &flist->string_area);
if (!file) return;
@@ -623,7 +678,6 @@ static void send_directory(int f,struct file_list *flist,char *dir)
}
struct file_list *send_file_list(int f,int argc,char *argv[])
{
int i,l;
@@ -640,14 +694,7 @@ struct file_list *send_file_list(int f,int argc,char *argv[])
start_write = stats.total_written;
flist = (struct file_list *)malloc(sizeof(flist[0]));
if (!flist) out_of_memory("send_file_list");
flist->count=0;
flist->malloced = 1000;
flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
flist->malloced);
if (!flist->files) out_of_memory("send_file_list");
flist = flist_new();
if (f != -1) {
io_start_buffering(f);
@@ -862,7 +909,8 @@ struct file_list *recv_file_list(int f)
/* if protocol version is >= 17 then recv the io_error flag */
if (f != -1 && remote_version >= 17) {
extern int module_id;
if (lp_ignore_errors(module_id)) {
extern int ignore_errors;
if (lp_ignore_errors(module_id) || ignore_errors) {
read_int(f);
} else {
io_error |= read_int(f);
@@ -934,10 +982,32 @@ 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);
memset((char *)file, 0, sizeof(*file));
*file = null_file;
}
/*
* allocate a new file list
*/
struct file_list *flist_new()
{
struct file_list *flist;
flist = (struct file_list *)malloc(sizeof(flist[0]));
if (!flist) out_of_memory("send_file_list");
flist->count=0;
flist->malloced = 1000;
flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
flist->malloced);
if (!flist->files) out_of_memory("send_file_list");
#if ARENA_SIZE > 0
flist->string_area = string_area_new(0);
#else
flist->string_area = 0;
#endif
return flist;
}
/*
* free up all elements in a flist
*/
@@ -945,11 +1015,14 @@ void flist_free(struct file_list *flist)
{
int i;
for (i=1;i<flist->count;i++) {
free_file(flist->files[i]);
if (!flist->string_area)
free_file(flist->files[i]);
free(flist->files[i]);
}
memset((char *)flist->files, 0, sizeof(flist->files[0])*flist->count);
free(flist->files);
if (flist->string_area)
string_area_free(flist->string_area);
memset((char *)flist, 0, sizeof(*flist));
free(flist);
}
@@ -978,7 +1051,13 @@ static void clean_flist(struct file_list *flist, int strip_root)
if (verbose > 1 && !am_server)
rprintf(FINFO,"removing duplicate name %s from file list %d\n",
f_name(flist->files[i-1]),i-1);
free_file(flist->files[i]);
/* it's not great that the flist knows the semantics of the
* file memory usage, but i'd rather not add a flag byte
* to that struct. XXX can i use a bit in the flags field? */
if (flist->string_area)
flist->files[i][0] = null_file;
else
free_file(flist->files[i]);
}
}

View File

@@ -246,8 +246,8 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
return;
}
}
delete_file(fname);
}
delete_file(fname);
if (do_symlink(file->link,fname) != 0) {
rprintf(FERROR,"symlink %s -> %s : %s\n",
fname,file->link,strerror(errno));

34
io.c
View File

@@ -27,6 +27,8 @@
/* if no timeout is specified then use a 60 second select timeout */
#define SELECT_TIMEOUT 60
extern int bwlimit;
static int io_multiplexing_out;
static int io_multiplexing_in;
static int multiplex_in_fd;
@@ -49,6 +51,7 @@ void setup_readbuffer(int f_in)
static void check_timeout(void)
{
extern int am_server, am_daemon;
time_t t;
if (!io_timeout) return;
@@ -61,8 +64,10 @@ static void check_timeout(void)
t = time(NULL);
if (last_io && io_timeout && (t-last_io) >= io_timeout) {
rprintf(FERROR,"io timeout after %d second - exiting\n",
(int)(t-last_io));
if (!am_server && !am_daemon) {
rprintf(FERROR,"io timeout after %d second - exiting\n",
(int)(t-last_io));
}
exit_cleanup(RERR_TIMEOUT);
}
}
@@ -159,6 +164,11 @@ static int read_timeout(int fd, char *buf, int len)
continue;
}
if (n == -1 &&
(errno == EWOULDBLOCK || errno == EAGAIN)) {
continue;
}
if (n == 0) {
if (eof_error) {
@@ -364,17 +374,35 @@ static void writefd_unbuffered(int fd,char *buf,int len)
if (FD_ISSET(fd, &w_fds)) {
int ret, n = len-total;
ret = write(fd,buf+total,n?n:1);
ret = write(fd,buf+total,n);
if (ret == -1 && errno == EINTR) {
continue;
}
if (ret == -1 &&
(errno == EWOULDBLOCK || errno == EAGAIN)) {
continue;
}
if (ret <= 0) {
rprintf(FERROR,"erroring writing %d bytes - exiting\n", len);
exit_cleanup(RERR_STREAMIO);
}
/* Sleep after writing to limit I/O bandwidth */
if (bwlimit)
{
tv.tv_sec = 0;
tv.tv_usec = ret * 1000 / bwlimit;
while (tv.tv_usec > 1000000)
{
tv.tv_sec++;
tv.tv_usec -= 1000000;
}
select(0, NULL, NULL, NULL, &tv);
}
total += ret;
if (io_timeout)

View File

@@ -95,21 +95,6 @@
}
#endif
#ifdef REPLACE_INET_NTOA
char *rep_inet_ntoa(struct in_addr ip)
{
unsigned char *p = (unsigned char *)&ip.s_addr;
static char buf[18];
#if WORDS_BIGENDIAN
slprintf(buf, 18, "%d.%d.%d.%d",
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
#else
slprintf(buf, 18, "%d.%d.%d.%d",
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
#endif
return buf;
}
#endif
#ifndef HAVE_STRLCPY
/* like strncpy but does not 0 fill the buffer and always null
@@ -146,7 +131,23 @@
}
#endif
#ifndef HAVE_INET_ATON
#ifdef REPLACE_INET_NTOA
char *rep_inet_ntoa(struct in_addr ip)
{
unsigned char *p = (unsigned char *)&ip.s_addr;
static char buf[18];
#if WORDS_BIGENDIAN
slprintf(buf, 18, "%d.%d.%d.%d",
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
#else
slprintf(buf, 18, "%d.%d.%d.%d",
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
#endif
return buf;
}
#endif
#ifdef REPLACE_INET_ATON
int inet_aton(const char *cp, struct in_addr *inp)
{
unsigned int a1, a2, a3, a4;
@@ -154,12 +155,12 @@
if (strcmp(cp, "255.255.255.255") == 0) {
inp->s_addr = (unsigned) -1;
return 1;
return 0;
}
if (sscanf(cp, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4 ||
a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) {
return 1;
return 0;
}
ret = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4;

View File

@@ -162,7 +162,7 @@ static service sDefault =
NULL, /* include from */
"%o %h [%a] %m (%u) %f %l", /* log format */
NULL, /* refuse options */
"*.gz *.tgz *.zip *.z *.rpm *.deb", /* dont compress */
"*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */
0, /* timeout */
0 /* max connections */
};

28
main.c
View File

@@ -112,6 +112,7 @@ static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f
char *tok,*dir=NULL;
extern int local_server;
extern char *rsync_path;
extern int blocking_io;
if (!local_server) {
if (!cmd)
@@ -144,6 +145,9 @@ static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f
args[argc++] = rsync_path;
server_options(args,&argc);
if (strcmp(cmd, RSYNC_RSH) == 0) blocking_io = 1;
}
args[argc++] = ".";
@@ -236,6 +240,7 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
char *dir = argv[0];
extern int relative_paths;
extern int recurse;
extern int remote_version;
if (verbose > 2)
rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
@@ -267,7 +272,12 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
}
send_files(flist,f_out,f_in);
io_flush();
report(f_out);
if (remote_version >= 24) {
/* final goodbye message */
read_int(f_in);
}
io_flush();
exit_cleanup(0);
}
@@ -319,14 +329,16 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
set_error_fd(error_pipe[1]);
recv_files(f_in,flist,local_name,recv_pipe[1]);
io_flush();
report(f_in);
write_int(recv_pipe[1],1);
close(recv_pipe[1]);
io_flush();
/* finally we go to sleep until our parent kills us with
a USR2 signal */
while (1) sleep(60);
/* finally we go to sleep until our parent kills us
with a USR2 signal. We sleepp for a short time as on
some OSes a signal won't interrupt a sleep! */
while (1) sleep(1);
}
close(recv_pipe[1]);
@@ -417,6 +429,9 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
setup_protocol(f_out, f_in);
set_nonblocking(f_in);
set_nonblocking(f_out);
if (remote_version >= 23)
io_start_multiplex_out(f_out);
@@ -440,6 +455,9 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
extern int list_only;
extern int remote_version;
set_nonblocking(f_in);
set_nonblocking(f_out);
setup_protocol(f_out,f_in);
if (remote_version >= 23)
@@ -464,11 +482,11 @@ int client_run(int f_in, int f_out, int pid, int argc, char *argv[])
io_flush();
wait_process(pid, &status);
}
report(-1);
if (remote_version >= 24) {
/* final goodbye message */
read_int(f_in);
}
report(-1);
exit_cleanup(status);
}
@@ -695,6 +713,8 @@ int main(int argc,char *argv[])
#endif
if (am_server) {
set_nonblocking(STDIN_FILENO);
set_nonblocking(STDOUT_FILENO);
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
}

View File

@@ -62,9 +62,12 @@ int safe_symlinks=0;
int copy_unsafe_links=0;
int block_size=BLOCK_SIZE;
int size_only=0;
int bwlimit=0;
int delete_after=0;
int only_existing=0;
int max_delete=0;
int ignore_errors=0;
int blocking_io=0;
char *backup_suffix = BACKUP_SUFFIX;
char *tmpdir = NULL;
@@ -133,6 +136,7 @@ void usage(enum logcode F)
rprintf(F," --delete delete files that don't exist on the sending side\n");
rprintf(F," --delete-excluded also delete excluded files on the receiving side\n");
rprintf(F," --delete-after delete after transferring, not before\n");
rprintf(F," --ignore-errors delete even if there are IO errors\n");
rprintf(F," --max-delete=NUM don't delete more than NUM files\n");
rprintf(F," --partial keep partially transferred files\n");
rprintf(F," --force force deletion of directories even if not empty\n");
@@ -153,10 +157,12 @@ void usage(enum logcode F)
rprintf(F," --address bind to the specified address\n");
rprintf(F," --config=FILE specify alternate rsyncd.conf file\n");
rprintf(F," --port=PORT specify alternate rsyncd port number\n");
rprintf(F," --blocking-io use blocking IO for the remote shell\n");
rprintf(F," --stats give some file transfer stats\n");
rprintf(F," --progress show progress during transfer\n");
rprintf(F," --log-format=FORMAT log file transfers using specified format\n");
rprintf(F," --password-file=FILE get password from FILE\n");
rprintf(F," --bwlimit=KBPS limit I/O bandwidth, KBytes per second\n");
rprintf(F," -h, --help show this help screen\n");
rprintf(F,"\n");
@@ -171,7 +177,8 @@ enum {OPT_VERSION, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR};
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO};
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
@@ -228,9 +235,12 @@ static struct option long_options[] = {
{"progress", 0, 0, OPT_PROGRESS},
{"partial", 0, 0, OPT_PARTIAL},
{"delete-after",0, 0, OPT_DELETE_AFTER},
{"ignore-errors",0, 0, OPT_IGNORE_ERRORS},
{"blocking-io" ,0, 0, OPT_BLOCKING_IO},
{"config", 1, 0, OPT_CONFIG},
{"port", 1, 0, OPT_PORT},
{"log-format", 1, 0, OPT_LOG_FORMAT},
{"bwlimit", 1, 0, OPT_BWLIMIT},
{"address", 1, 0, OPT_ADDRESS},
{"max-delete", 1, 0, OPT_MAX_DELETE},
{"backup-dir", 1, 0, OPT_BACKUP_DIR},
@@ -528,6 +538,14 @@ int parse_arguments(int argc, char *argv[], int frommain)
keep_partial = 1;
break;
case OPT_IGNORE_ERRORS:
ignore_errors = 1;
break;
case OPT_BLOCKING_IO:
blocking_io = 1;
break;
case 'P':
do_progress = 1;
keep_partial = 1;
@@ -544,6 +562,10 @@ int parse_arguments(int argc, char *argv[], int frommain)
case OPT_LOG_FORMAT:
log_format = optarg;
break;
case OPT_BWLIMIT:
bwlimit = atoi(optarg);
break;
case OPT_ADDRESS:
{
@@ -576,6 +598,8 @@ void server_options(char **args,int *argc)
static char bsize[30];
static char iotime[30];
static char mdelete[30];
static char bw[50];
int i, x;
args[ac++] = "--server";
@@ -647,6 +671,11 @@ void server_options(char **args,int *argc)
args[ac++] = iotime;
}
if (bwlimit) {
slprintf(bw,sizeof(bw),"--bwlimit=%d",bwlimit);
args[ac++] = bw;
}
if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
args[ac++] = "--suffix";
args[ac++] = backup_suffix;
@@ -670,6 +699,9 @@ void server_options(char **args,int *argc)
if (delete_after)
args[ac++] = "--delete-after";
if (ignore_errors)
args[ac++] = "--ignore-errors";
if (copy_unsafe_links)
args[ac++] = "--copy-unsafe-links";

View File

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

View File

@@ -108,13 +108,14 @@ void delete_files(struct file_list *flist)
int i, j;
char *name;
extern int module_id;
extern int ignore_errors;
extern int max_delete;
static int deletion_count;
if (cvs_exclude)
add_cvs_excludes();
if (io_error && !lp_ignore_errors(module_id)) {
if (io_error && !(lp_ignore_errors(module_id) || ignore_errors)) {
rprintf(FINFO,"IO error encountered - skipping file deletion\n");
return;
}

19
rsync.h
View File

@@ -305,10 +305,20 @@ struct file_struct {
};
#define ARENA_SIZE (32 * 1024)
struct string_area {
char *base;
char *end;
char *current;
struct string_area *next;
};
struct file_list {
int count;
int malloced;
struct file_struct **files;
struct string_area *string_area;
};
struct sum_buf {
@@ -457,6 +467,15 @@ extern int errno;
#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
#endif
/* work out what fcntl flag to use for non-blocking */
#ifdef O_NONBLOCK
# define NONBLOCK_FLAG O_NONBLOCK
#elif defined(SYSV)
# define NONBLOCK_FLAG O_NDELAY
#else
# define NONBLOCK_FLAG FNDELAY
#endif
#define IS_DEVICE(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISSOCK(mode) || S_ISFIFO(mode))

View File

@@ -248,6 +248,7 @@ verb(
--delete delete files that don't exist on the sending side
--delete-excluded also delete excluded files on the receiving side
--delete-after delete after transferring, not before
--ignore-errors delete even if there are IO errors
--max-delete=NUM don't delete more than NUM files
--partial keep partially transferred files
--force force deletion of directories even if not empty
@@ -268,10 +269,12 @@ verb(
--address bind to the specified address
--config=FILE specify alternate rsyncd.conf file
--port=PORT specify alternate rsyncd port number
--blocking-io use blocking IO for the remote shell
--stats give some file transfer stats
--progress show progress during transfer
--log-format=FORMAT log file transfers using specified format
--password-file=FILE get password from FILE
--bwlimit=KBPS limit I/O bandwidth, KBytes per second
-h, --help show this help screen
)
@@ -609,6 +612,11 @@ specified.
dit(bf(--port=PORT)) This specifies an alternate TCP port number to use
rather than the default port 873.
dit(bf(--blocking-io)) This specifies whether rsync will use blocking
IO when launching a remote shell transport. You may find this is
needed for some remote shells that can't handle the default
non-blocking IO.
dit(bf(--log-format=FORMAT)) This allows you to specify exactly what the
rsync client logs to stdout on a per-file basis. The log format is
specified using the same format conventions as the log format option in
@@ -642,6 +650,14 @@ transport, not when using a remote shell as the transport. The file
must not be world readable. It should contain just the password as a
single line.
dit(bf(--bwlimit=KBPS)) This option allows you to specify a maximum
transfer rate in kilobytes per second. This option is most effective when
using rsync with large files (several megabytes and up). Due to the nature
of rsync transfers, blocks of data are sent, then if rsync determines the
transfer was too fast, it will wait before sending the next data block. The
result is an average transfer rate equalling the specified limit. A value
of zero specifies no limit.
enddit()
manpagesection(EXCLUDE PATTERNS)
@@ -657,7 +673,11 @@ skipped. If it is an include pattern then that filename is not
skipped. If no matching include/exclude pattern is found then the
filename is not skipped.
Note that the --include and --exclude options take one pattern
Note that when used with -r (which is implied by -a), every subcomponent of
every path is visited from top down, so include/exclude patterns get
applied recursively to each subcomponent.
Note also that the --include and --exclude options take one pattern
each. To add multiple patterns use the --include-from and
--exclude-from options or multiple --include and --exclude options.
@@ -666,9 +686,11 @@ The patterns can take several forms. The rules are:
itemize(
it() if the pattern starts with a / then it is matched against the
start of the filename, otherwise it is matched against the end of
the filename. Thus /foo would match a file called foo
at the base of the tree whereas foo would match any file
called foo anywhere in the tree.
the filename. Thus "/foo" would match a file called "foo" at the base of
the tree. On the other hand, "foo" would match any file called "foo"
anywhere in the tree because the algorithm is applied recursively from
top down; it behaves as if each path component gets a turn at being the
end of the file name.
it() if the pattern ends with a / then it will only match a
directory, not a file, link or device.
@@ -677,12 +699,15 @@ itemize(
*?[ then expression matching is applied using the shell filename
matching rules. Otherwise a simple string match is used.
it() if the pattern includes a double asterisk "**" then all wildcards in
the pattern will match slashes, otherwise they will stop at slashes.
it() if the pattern contains a / (not counting a trailing /) then it
is matched against the full filename, including any leading
directory. If the pattern doesn't contain a / then it is matched
only against the final component of the filename. Furthermore, if
the pattern includes a double asterisk "**" then all wildcards in
the pattern will match slashes, otherwise they will stop at slashes.
only against the final component of the filename. Again, remember
that the algorithm is applied recursively so "full filename" can
actually be any portion of a path.
it() if the pattern starts with "+ " (a plus followed by a space)
then it is always considered an include pattern, even if specified as
@@ -699,7 +724,14 @@ itemize(
The +/- rules are most useful in exclude lists, allowing you to have a
single exclude list that contains both include and exclude options.
Here are some examples:
If you end an exclude list with --exclude '*', note that since the
algorithm is applied recursively that unless you explicitly include
parent directories of files you want to include then the algorithm
will stop at the parent directories and never see the files below
them. To include all directories, use --include '*/' before the
--exclude '*'.
Here are some exclude/include examples:
itemize(
it() --exclude "*.o" would exclude all filenames matching *.o

View File

@@ -128,8 +128,11 @@ dit(bf(use chroot)) If "use chroot" is true, the rsync server will chroot
to the "path" before starting the file transfer with the client. This has
the advantage of extra protection against possible implementation security
holes, but it has the disadvantages of requiring super-user privileges and
of not being able to follow symbolic links outside of the new root path.
The default is to use chroot.
of not being able to follow symbolic links outside of the new root path
when reading. For writing when "use chroot" is false, for security reasons
symlinks may only be relative paths pointing to other files within the
root path, and leading slashes are removed from absolute paths. The
default for "use chroot" is true.
dit(bf(max connections)) The "max connections" option allows you to
specify the maximum number of simultaneous connections you will allow
@@ -342,7 +345,7 @@ The "dont compress" option takes a space separated list of
case-insensitive wildcard patterns. Any source filename matching one
of the patterns will not be compressed during transfer.
The default setting is verb(*.gz *.tgz *.zip *.z *.rpm *.deb)
The default setting is verb(*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz)
enddit()

108
util.c
View File

@@ -26,24 +26,78 @@
extern int verbose;
/* create a file descriptor - like pipe() but use socketpair if
possible (because of blocking issues on pipes */
int fd_pair(int fd[2])
/****************************************************************************
Set a fd into nonblocking mode
****************************************************************************/
void set_nonblocking(int fd)
{
#if HAVE_SOCKETPAIR
return socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
#else
return pipe(fd);
#endif
int val;
if((val = fcntl(fd, F_GETFL, 0)) == -1)
return;
if (!(val & NONBLOCK_FLAG)) {
val |= NONBLOCK_FLAG;
fcntl(fd, F_SETFL, val);
}
}
/****************************************************************************
Set a fd into blocking mode
****************************************************************************/
void set_blocking(int fd)
{
int val;
if((val = fcntl(fd, F_GETFL, 0)) == -1)
return;
if (val & NONBLOCK_FLAG) {
val &= ~NONBLOCK_FLAG;
fcntl(fd, F_SETFL, val);
}
}
/* this is taken from CVS */
/* create a file descriptor pair - like pipe() but use socketpair if
possible (because of blocking issues on pipes)
always set non-blocking
*/
int fd_pair(int fd[2])
{
int ret;
#if HAVE_SOCKETPAIR
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
#else
ret = pipe(fd);
#endif
if (ret == 0) {
set_nonblocking(fd[0]);
set_nonblocking(fd[1]);
}
return ret;
}
/* this is derived from CVS code
note that in the child STDIN is set to blocking and STDOUT
is set to non-blocking. This is necessary as rsh relies on stdin being blocking
and ssh relies on stdout being non-blocking
if blocking_io is set then use blocking io on both fds. That can be
used to cope with badly broken rsh implementations like the one on
solaris.
*/
int piped_child(char **command,int *f_in,int *f_out)
{
int pid;
int to_child_pipe[2];
int from_child_pipe[2];
extern int blocking_io;
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
@@ -71,6 +125,10 @@ int piped_child(char **command,int *f_in,int *f_out)
if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
umask(orig_umask);
set_blocking(STDIN_FILENO);
if (blocking_io) {
set_blocking(STDOUT_FILENO);
}
execvp(command[0], command);
rprintf(FERROR,"Failed to exec %s : %s\n",
command[0],strerror(errno));
@@ -883,3 +941,35 @@ void wait_process(pid_t pid, int *status)
waitpid(pid, status, 0);
*status = WEXITSTATUS(*status);
}
#ifdef __INSURE__
#include <dlfcn.h>
/*******************************************************************
This routine is a trick to immediately catch errors when debugging
with insure. A xterm with a gdb is popped up when insure catches
a error. It is Linux specific.
********************************************************************/
int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
{
static int (*fn)();
int ret;
char cmd[1024];
sprintf(cmd, "/usr/X11R6/bin/xterm -display :0 -T Panic -n Panic -e /bin/sh -c 'cat /tmp/ierrs.*.%d ; gdb /proc/%d/exe %d'",
getpid(), getpid(), getpid());
if (!fn) {
static void *h;
h = dlopen("/usr/local/parasoft/insure++lite/lib.linux2/libinsure.so", RTLD_LAZY);
fn = dlsym(h, "_Insure_trap_error");
}
ret = fn(a1, a2, a3, a4, a5, a6);
system(cmd);
return ret;
}
#endif

View File

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