mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-25 07:15:35 -04:00
Compare commits
46 Commits
v2.4.7pre2
...
v2.4.7pre4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3966b9c609 | ||
|
|
1c47fbd96b | ||
|
|
1691bdcafc | ||
|
|
6a5ef41fb3 | ||
|
|
09b6f4b00d | ||
|
|
7067b0aa28 | ||
|
|
112e731150 | ||
|
|
1336e41460 | ||
|
|
7c1b7890d3 | ||
|
|
dd0700b025 | ||
|
|
04d8e8b25f | ||
|
|
3723efcb1d | ||
|
|
054b40b6fa | ||
|
|
6773a7798f | ||
|
|
2d4c8e5945 | ||
|
|
087173c887 | ||
|
|
57835c00ad | ||
|
|
4ed886ae6e | ||
|
|
740819ef7b | ||
|
|
829230689e | ||
|
|
77ba4cc2f9 | ||
|
|
e94989fe4d | ||
|
|
c11b88061f | ||
|
|
647c5433f8 | ||
|
|
8f694072a5 | ||
|
|
9a689986c6 | ||
|
|
3174b31d96 | ||
|
|
4eb61975b7 | ||
|
|
76e26e1042 | ||
|
|
9069dfd005 | ||
|
|
2be5d2daad | ||
|
|
22cd0063e5 | ||
|
|
3d2e458a4d | ||
|
|
a57568d716 | ||
|
|
61f543cade | ||
|
|
b8771f9615 | ||
|
|
d5d4b28220 | ||
|
|
a037edaccd | ||
|
|
356bbb8351 | ||
|
|
1f0fa9318a | ||
|
|
15c1707887 | ||
|
|
9dec7aa9c1 | ||
|
|
bc3d7454e0 | ||
|
|
56901bc7c3 | ||
|
|
5c7f570b16 | ||
|
|
4f6e5fe323 |
15
INSTALL
15
INSTALL
@@ -13,3 +13,18 @@ As of 2.4.7, rsync uses Eric Troan's popt option-parsing library. A
|
||||
cut-down copy of release 1.5 is included in the rsync distribution,
|
||||
and will be used it there is no popt library on your build host, or if
|
||||
the --with-included-popt option is passed to ./configure.
|
||||
|
||||
|
||||
|
||||
HP-UX NOTES
|
||||
-----------
|
||||
|
||||
The HP-UX 10.10 "bundled" C compiler seems not to be able to cope with
|
||||
ANSI C. You may see this error message in config.log if ./configure
|
||||
fails:
|
||||
|
||||
(Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature.
|
||||
|
||||
Install gcc or HP's "ANSI/C Compiler".
|
||||
|
||||
|
||||
|
||||
18
Makefile.in
18
Makefile.in
@@ -23,6 +23,7 @@ VERSION=@VERSION@
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
|
||||
lib/permstring.o \
|
||||
@LIBOBJS@
|
||||
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
|
||||
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
|
||||
@@ -34,7 +35,7 @@ popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
|
||||
popt/popthelp.o popt/poptparse.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
|
||||
|
||||
tls_OBJ = tls.o syscall.o
|
||||
tls_OBJ = tls.o syscall.o lib/permstring.o
|
||||
|
||||
# Programs we must have to run the test cases
|
||||
CHECK_PROGS = rsync tls
|
||||
@@ -83,17 +84,12 @@ proto:
|
||||
cat *.c lib/compat.c | awk -f mkproto.awk > proto.h
|
||||
|
||||
clean:
|
||||
rm -f *~ $(OBJS) rsync
|
||||
rm -f *~ $(OBJS) rsync $(TLS_OBJ) tls
|
||||
rm -rf ./testtmp
|
||||
rm -f config.cache
|
||||
|
||||
distclean: clean
|
||||
rm -f config.h config.cache config.status Makefile
|
||||
|
||||
# missing functions
|
||||
getaddrinfo.o: lib/getaddrinfo.c
|
||||
$(CC) -I. -I$(srcdir) -I$(srcdir)/lib $(CFLAGS) -c lib/getaddrinfo.c
|
||||
getnameinfo.o: lib/getnameinfo.c
|
||||
$(CC) -I. -I$(srcdir) -I$(srcdir)/lib $(CFLAGS) -c lib/getnameinfo.c
|
||||
rm -f Makefile config.h config.status
|
||||
|
||||
# this target is really just for my use. It only works on a limited
|
||||
# range of machines and is used to produce a list of potentially
|
||||
@@ -123,13 +119,13 @@ test: check
|
||||
# might lose in the future where POSIX diverges from old sh.
|
||||
|
||||
check: all $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 rsync_bin=`pwd`/rsync srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin=`pwd`/rsync srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
# This does *not* depend on building or installing: you can use it to
|
||||
# check a version installed from a binary or some other source tree,
|
||||
# if you want.
|
||||
|
||||
installcheck: $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 rsync_bin="$(bindir)/rsync" srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin="$(bindir)/rsync" srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
# TODO: Add 'dist' target; need to know which files will be included
|
||||
|
||||
8
NEWS
8
NEWS
@@ -1,4 +1,4 @@
|
||||
rsync 2.4.7 (sometime in 2001, maybe :)
|
||||
rsync 2.4.7 (sometime in 2001, maybe :) -*- indented-text -*-
|
||||
|
||||
ANNOUNCEMENTS
|
||||
|
||||
@@ -14,7 +14,11 @@ rsync 2.4.7 (sometime in 2001, maybe :)
|
||||
sets. By Bert J. Dempsey and Debra Weiss, updated by Jos
|
||||
Backus. <http://www.ils.unc.edu/i2dsi/unc_rsync+.html>
|
||||
|
||||
* Merged IPv6 patch from KAME.net.
|
||||
* IPv6 support based on a patch from KAME.net, on systems
|
||||
including modern versions of Linux, Solaris, and HP-UX. Also
|
||||
includes IPv6 compatibility functions for old OSs by the
|
||||
Internet Software Consortium, Paul Vixie, the OpenSSH
|
||||
portability project, and OpenBSD.
|
||||
|
||||
ENHANCEMENTS
|
||||
|
||||
|
||||
4
aclocal.m4
vendored
4
aclocal.m4
vendored
@@ -43,8 +43,8 @@ AC_DEFUN([TYPE_SOCKLEN_T],
|
||||
for arg2 in "struct sockaddr" void; do
|
||||
for t in int size_t unsigned long "unsigned long"; do
|
||||
AC_TRY_COMPILE([
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
int getpeername (int, $arg2 *, $t *);
|
||||
],[
|
||||
|
||||
@@ -78,7 +78,8 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
if (!user) user = getenv("USER");
|
||||
if (!user) user = getenv("LOGNAME");
|
||||
|
||||
fd = open_socket_out_wrapped (host, rsync_port, bind_address);
|
||||
fd = open_socket_out_wrapped (host, rsync_port, bind_address,
|
||||
global_opts.af_hint);
|
||||
if (fd == -1) {
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
204
configure.in
204
configure.in
@@ -15,7 +15,7 @@ AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_SUBST(SHELL)
|
||||
|
||||
RSYNC_VERSION=2.4.7pre2
|
||||
RSYNC_VERSION=2.4.7pre4
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$RSYNC_VERSION"], [rsync release version])
|
||||
|
||||
@@ -90,29 +90,10 @@ if test x"$rsync_cv_HAVE_BROKEN_LARGEFILE" != x"yes"; then
|
||||
AC_SYS_LARGEFILE
|
||||
fi
|
||||
|
||||
|
||||
|
||||
AC_DEFINE(ss_family, __ss_family, [KAME hack])
|
||||
AC_DEFINE(ss_len, __ss_len, [KAME hack])
|
||||
|
||||
CFLAGS="$CFLAGS"
|
||||
AC_ARG_ENABLE(ipv6,
|
||||
AC_HELP_STRING([--disable-ipv6], [do not try to support IPv6]))
|
||||
AC_MSG_CHECKING([whether IPv6 is explicitly disabled])
|
||||
if test "$xenable_ipv6" = xyes
|
||||
then
|
||||
AC_MSG_RESULT(yes)
|
||||
ipv6=no
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
ipv6=yes
|
||||
fi
|
||||
|
||||
ipv6type=unknown
|
||||
ipv6lib=none
|
||||
ipv6trylibc=no
|
||||
ipv6trylibc=yes
|
||||
|
||||
if test "$ipv6" = "yes"; then
|
||||
AC_MSG_CHECKING([ipv6 stack type])
|
||||
for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
|
||||
case $i in
|
||||
@@ -197,151 +178,8 @@ yes
|
||||
fi
|
||||
done
|
||||
AC_MSG_RESULT($ipv6type)
|
||||
fi
|
||||
|
||||
if test "$ipv6" = "yes" -a -f /usr/local/v6/lib/libinet6.a; then
|
||||
ac_inet6_LDFLAGS="inet6"
|
||||
ipv6libdir=/usr/local/v6/lib
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/v6/lib"
|
||||
AC_CHECK_LIB(inet6, getaddrinfo, , ipv6lib="$ac_inet6_LDFLAGS")
|
||||
fi
|
||||
|
||||
if test "$ipv6" = "yes" -a -f /usr/lib/libinet6.a; then
|
||||
ac_inet6_LDFLAGS="inet6"
|
||||
AC_CHECK_LIB(inet6, getaddrinfo, , ipv6lib="$ac_inet6_LDFLAGS")
|
||||
fi
|
||||
|
||||
if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then
|
||||
if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then
|
||||
LIBS="-L$ipv6libdir -l$ipv6lib $LIBS"
|
||||
echo "You have $ipv6lib library, using it"
|
||||
else
|
||||
if test "$ipv6trylibc" = "yes"; then
|
||||
echo "You do not have $ipv6lib library, using libc"
|
||||
else
|
||||
echo 'Fatal: no $ipv6lib library found. cannot continue.'
|
||||
echo "You need to fetch lib$ipv6lib.a from appropriate"
|
||||
echo 'ipv6 kit and compile beforehand.'
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
AC_MSG_CHECKING(getaddrinfo bug)
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
main()
|
||||
{
|
||||
int passive, gaierr, inet4 = 0, inet6 = 0;
|
||||
struct addrinfo hints, *ai, *aitop;
|
||||
char straddr[INET6_ADDRSTRLEN], strport[16];
|
||||
|
||||
for (passive = 0; passive <= 1; passive++) {
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = passive ? AI_PASSIVE : 0;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
|
||||
(void)gai_strerror(gaierr);
|
||||
goto bad;
|
||||
}
|
||||
for (ai = aitop; ai; ai = ai->ai_next) {
|
||||
if (ai->ai_addr == NULL ||
|
||||
ai->ai_addrlen == 0 ||
|
||||
getnameinfo(ai->ai_addr, ai->ai_addrlen,
|
||||
straddr, sizeof(straddr), strport, sizeof(strport),
|
||||
NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
|
||||
goto bad;
|
||||
}
|
||||
switch (ai->ai_family) {
|
||||
case AF_INET:
|
||||
if (strcmp(strport, "54321") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
if (passive) {
|
||||
if (strcmp(straddr, "0.0.0.0") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(straddr, "127.0.0.1") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
inet4++;
|
||||
break;
|
||||
case AF_INET6:
|
||||
if (strcmp(strport, "54321") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
if (passive) {
|
||||
if (strcmp(straddr, "::") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
} else {
|
||||
if (strcmp(straddr, "::1") != 0) {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
inet6++;
|
||||
break;
|
||||
case AF_UNSPEC:
|
||||
goto bad;
|
||||
break;
|
||||
default:
|
||||
/* another family support? */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(inet4 == 0 || inet4 == 2))
|
||||
goto bad;
|
||||
if (!(inet6 == 0 || inet6 == 2))
|
||||
goto bad;
|
||||
|
||||
if (aitop)
|
||||
freeaddrinfo(aitop);
|
||||
exit(0);
|
||||
|
||||
bad:
|
||||
if (aitop)
|
||||
freeaddrinfo(aitop);
|
||||
exit(1);
|
||||
}
|
||||
],
|
||||
AC_MSG_RESULT(good)
|
||||
buggygetaddrinfo=no,
|
||||
AC_MSG_RESULT(buggy)
|
||||
buggygetaddrinfo=yes,
|
||||
AC_MSG_RESULT(buggy)
|
||||
buggygetaddrinfo=yes)
|
||||
|
||||
if test "$buggygetaddrinfo" = "yes"; then
|
||||
if test "$ipv6" = "yes" -a "$ipv6type" != "linux"; then
|
||||
echo 'Fatal: You must get working getaddrinfo() function.'
|
||||
echo ' or you can specify "--disable-ipv6"'.
|
||||
exit 1
|
||||
elif test "$ipv6type" = "linux"; then
|
||||
echo 'Warning: getaddrinfo() implementation on your system seems be buggy.'
|
||||
echo ' Better upgreade your system library to newest version'
|
||||
echo ' of GNU C library (aka glibc).'
|
||||
fi
|
||||
fi
|
||||
AC_REPLACE_FUNCS(getaddrinfo getnameinfo)
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr.sa_len],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
AC_SEARCH_LIBS(getaddrinfo, inet6)
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
AC_HEADER_DIRENT
|
||||
@@ -350,7 +188,8 @@ AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h unistd.h utime.h grp.h)
|
||||
AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h)
|
||||
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h)
|
||||
AC_CHECK_HEADERS(glob.h alloca.h mcheck.h)
|
||||
AC_CHECK_HEADERS(glob.h alloca.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
|
||||
AC_CHECK_HEADERS(netdb.h)
|
||||
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
@@ -413,7 +252,24 @@ if test x"$ac_cv_func_connect" = x"no"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
AC_CHECK_LIB(resolv, inet_ntop)
|
||||
|
||||
AC_MSG_NOTICE([Looking in libraries: $LIBS])
|
||||
|
||||
AC_CHECK_FUNC(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
|
||||
AC_CHECK_FUNC(inet_pton, , AC_LIBOBJ(lib/inet_pton))
|
||||
|
||||
AC_CHECK_FUNC(getaddrinfo, , AC_LIBOBJ(lib/getaddrinfo))
|
||||
AC_CHECK_FUNC(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr.sa_len],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
])
|
||||
|
||||
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
|
||||
#
|
||||
AC_CHECK_FUNCS(strcasecmp)
|
||||
@@ -429,12 +285,14 @@ AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy mtrace)
|
||||
|
||||
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);
|
||||
}],
|
||||
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, 1, [ ])
|
||||
|
||||
53
flist.c
53
flist.c
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -111,24 +112,14 @@ static char *string_area_strdup(struct string_area **ap, const char *src)
|
||||
|
||||
static void list_file_entry(struct file_struct *f)
|
||||
{
|
||||
char perms[11] = "----------";
|
||||
char *perm_map = "rwxrwxrwx";
|
||||
int i;
|
||||
char perms[11];
|
||||
|
||||
if (!f->basename)
|
||||
/* this can happen if duplicate names were removed */
|
||||
return;
|
||||
|
||||
for (i=0;i<9;i++) {
|
||||
if (f->mode & (1<<i)) perms[9-i] = perm_map[8-i];
|
||||
}
|
||||
if (S_ISLNK(f->mode)) perms[0] = 'l';
|
||||
if (S_ISDIR(f->mode)) perms[0] = 'd';
|
||||
if (S_ISBLK(f->mode)) perms[0] = 'b';
|
||||
if (S_ISCHR(f->mode)) perms[0] = 'c';
|
||||
if (S_ISSOCK(f->mode)) perms[0] = 's';
|
||||
if (S_ISFIFO(f->mode)) perms[0] = 'p';
|
||||
|
||||
permstring(perms, f->mode);
|
||||
|
||||
if (preserve_links && S_ISLNK(f->mode)) {
|
||||
rprintf(FINFO,"%s %11.0f %s %s -> %s\n",
|
||||
perms,
|
||||
@@ -185,12 +176,18 @@ int link_stat(const char *Path, STRUCT_STAT *Buffer)
|
||||
This function is used to check if a file should be included/excluded
|
||||
from the list of files based on its name and type etc
|
||||
*/
|
||||
static int match_file_name(char *fname,STRUCT_STAT *st)
|
||||
static int check_exclude_file(int f,char *fname,STRUCT_STAT *st)
|
||||
{
|
||||
if (check_exclude(fname,local_exclude_list,st)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
extern int delete_excluded;
|
||||
|
||||
/* f is set to -1 when calculating deletion file list */
|
||||
if ((f == -1) && delete_excluded) {
|
||||
return 0;
|
||||
}
|
||||
if (check_exclude(fname,local_exclude_list,st)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* used by the one_file_system code */
|
||||
@@ -479,7 +476,6 @@ struct file_struct *make_file(int f, char *fname, struct string_area **ap,
|
||||
char *p;
|
||||
char cleaned_name[MAXPATHLEN];
|
||||
char linkbuf[MAXPATHLEN];
|
||||
extern int delete_excluded;
|
||||
extern int module_id;
|
||||
|
||||
strlcpy(cleaned_name, fname, MAXPATHLEN);
|
||||
@@ -490,17 +486,21 @@ struct file_struct *make_file(int f, char *fname, struct string_area **ap,
|
||||
}
|
||||
fname = cleaned_name;
|
||||
|
||||
/* f is set to -1 when calculating deletion file list */
|
||||
if (((f != -1) || !delete_excluded) && !noexcludes && !match_file_name(fname,&st))
|
||||
return NULL;
|
||||
|
||||
|
||||
memset(sum,0,SUM_LENGTH);
|
||||
|
||||
if (readlink_stat(fname,&st,linkbuf) != 0) {
|
||||
int save_errno = errno;
|
||||
if ((errno == ENOENT) && copy_links && !noexcludes) {
|
||||
/* symlink pointing nowhere, see if excluded */
|
||||
memset((char *)&st, 0, sizeof(st));
|
||||
if (check_exclude_file(f,fname,&st)) {
|
||||
/* file is excluded anyway, ignore silently */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
io_error = 1;
|
||||
rprintf(FERROR,"readlink %s: %s\n",
|
||||
fname,strerror(errno));
|
||||
fname,strerror(save_errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -517,6 +517,9 @@ struct file_struct *make_file(int f, char *fname, struct string_area **ap,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (check_exclude_file(f,fname,&st))
|
||||
return NULL;
|
||||
|
||||
|
||||
if (lp_ignore_nonreadable(module_id) && access(fname, R_OK) != 0)
|
||||
return NULL;
|
||||
|
||||
184
lib/inet_ntop.c
Normal file
184
lib/inet_ntop.c
Normal file
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2001 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define NS_INT16SZ 2
|
||||
#define NS_IN6ADDRSZ 16
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4(const unsigned char *src, char *dst,
|
||||
size_t size);
|
||||
|
||||
#ifdef AF_INET6
|
||||
static const char *inet_ntop6(const unsigned char *src, char *dst,
|
||||
size_t size);
|
||||
#endif
|
||||
|
||||
/* char *
|
||||
* isc_net_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
#ifdef AF_INET6
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a unsigned char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
static const char *fmt = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
|
||||
if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
|
||||
{
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* isc_inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
#ifdef AF_INET6
|
||||
static const char *
|
||||
inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp,
|
||||
sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += sprintf(tp, "%x", words[i]);
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
#endif /* AF_INET6 */
|
||||
210
lib/inet_pton.c
Normal file
210
lib/inet_pton.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 1996-2001 Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
|
||||
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define NS_INT16SZ 2
|
||||
#define NS_INADDRSZ 4
|
||||
#define NS_IN6ADDRSZ 16
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
|
||||
/* int
|
||||
* isc_net_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton(int af,
|
||||
const char *src,
|
||||
void *dst)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(src, dst)
|
||||
const char *src;
|
||||
unsigned char *dst;
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
unsigned char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
unsigned int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (! saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
#ifdef INET6
|
||||
static int
|
||||
inet_pton6(src, dst)
|
||||
const char *src;
|
||||
unsigned char *dst;
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
unsigned int val;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (unsigned char) (val >> 8) & 0xff;
|
||||
*tp++ = (unsigned char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
61
lib/permstring.c
Normal file
61
lib/permstring.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1996
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
/**
|
||||
* Produce a string representation of Unix mode bits like that used by
|
||||
* ls(1).
|
||||
*
|
||||
* @param buf buffer of at least 11 characters
|
||||
**/
|
||||
void permstring(char *perms,
|
||||
int mode)
|
||||
{
|
||||
static const char *perm_map = "rwxrwxrwx";
|
||||
int i;
|
||||
|
||||
strcpy(perms, "----------");
|
||||
|
||||
for (i=0;i<9;i++) {
|
||||
if (mode & (1<<i)) perms[9-i] = perm_map[8-i];
|
||||
}
|
||||
|
||||
/* Handle setuid/sticky bits. You might think the indices are
|
||||
* off by one, but remember there's a type char at the
|
||||
* start. */
|
||||
if (mode & S_ISUID)
|
||||
perms[3] = (mode & S_IXUSR) ? 's' : 'S';
|
||||
|
||||
if (mode & S_ISGID)
|
||||
perms[6] = (mode & S_IXGRP) ? 's' : 'S';
|
||||
|
||||
if (mode & S_ISVTX)
|
||||
perms[9] = (mode & S_IXOTH) ? 't' : 'T';
|
||||
|
||||
if (S_ISLNK(mode)) perms[0] = 'l';
|
||||
if (S_ISDIR(mode)) perms[0] = 'd';
|
||||
if (S_ISBLK(mode)) perms[0] = 'b';
|
||||
if (S_ISCHR(mode)) perms[0] = 'c';
|
||||
if (S_ISSOCK(mode)) perms[0] = 's';
|
||||
if (S_ISFIFO(mode)) perms[0] = 'p';
|
||||
}
|
||||
|
||||
|
||||
3
lib/permstring.h
Normal file
3
lib/permstring.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#define PERMSTRING_SIZE 11
|
||||
|
||||
void permstring(char *perms, int mode);
|
||||
18
loadparm.c
18
loadparm.c
@@ -1,6 +1,11 @@
|
||||
/* This is based on loadparm.c from Samba, written by Andrew Tridgell
|
||||
and Karl Auer */
|
||||
|
||||
/* some fixes
|
||||
*
|
||||
* Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -379,14 +384,23 @@ static void init_service(service *pservice)
|
||||
copy_service(pservice,&sDefault);
|
||||
}
|
||||
|
||||
static void string_set(char **s, char *v)
|
||||
|
||||
/**
|
||||
* Assign a copy of @p v to @p *s, freeing any existing values and
|
||||
* handling NULL strings. @p *v must be initialized when this is
|
||||
* called, either to NULL or a malloc'd string.
|
||||
**/
|
||||
static void string_set(char **s, const char *v)
|
||||
{
|
||||
if (!v) {
|
||||
*s = NULL;
|
||||
return;
|
||||
}
|
||||
if (*s)
|
||||
free(*s);
|
||||
*s = strdup(v);
|
||||
if (!*s) exit_cleanup(RERR_MALLOC);
|
||||
if (!*s)
|
||||
exit_cleanup(RERR_MALLOC);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -74,8 +74,8 @@ int modify_window=0;
|
||||
#endif
|
||||
int blocking_io=0;
|
||||
|
||||
/** Network address family. **/
|
||||
int af = AF_INET;
|
||||
/** Global options set from command line. **/
|
||||
struct global_opts global_opts;
|
||||
|
||||
int read_batch=0; /* dw */
|
||||
int write_batch=0; /* dw */
|
||||
@@ -314,8 +314,8 @@ static struct poptOption long_options[] = {
|
||||
{"read-batch", 'f', POPT_ARG_STRING, &batch_ext, 'f'},
|
||||
{"write-batch", 'F', POPT_ARG_NONE, &write_batch, 0},
|
||||
#ifdef INET6
|
||||
{0, '4', POPT_ARG_VAL, &af, AF_INET },
|
||||
{0, '6', POPT_ARG_VAL, &af, AF_INET6 },
|
||||
{0, '4', POPT_ARG_VAL, &global_opts.af_hint, AF_INET },
|
||||
{0, '6', POPT_ARG_VAL, &global_opts.af_hint, AF_INET6 },
|
||||
#endif
|
||||
{0,0,0,0}
|
||||
};
|
||||
|
||||
17
rsync.h
17
rsync.h
@@ -389,7 +389,7 @@ static inline int flist_up(struct file_list *flist, int i)
|
||||
#include "byteorder.h"
|
||||
#include "proto.h"
|
||||
#include "lib/mdfour.h"
|
||||
|
||||
#include "lib/permstring.h"
|
||||
|
||||
/* We have replacement versions of these if they're missing. */
|
||||
#ifndef HAVE_ASPRINTF
|
||||
@@ -562,3 +562,18 @@ size_t strlcat(char *d, const char *s, size_t bufsize);
|
||||
|
||||
|
||||
extern int verbose;
|
||||
|
||||
extern struct global_opts {
|
||||
/** Network address family. **/
|
||||
int af_hint;
|
||||
} global_opts;
|
||||
|
||||
|
||||
#ifndef HAVE_INET_NTOP
|
||||
const char *
|
||||
inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif /* !HAVE_INET_NTOP */
|
||||
|
||||
#ifndef HAVE_INET_PTON
|
||||
int isc_net_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
||||
212
socket.c
212
socket.c
@@ -18,10 +18,11 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
socket functions used in rsync
|
||||
|
||||
*/
|
||||
/**
|
||||
* @file socket.c
|
||||
*
|
||||
* Socket functions used in rsync.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -29,8 +30,6 @@
|
||||
#include "lib/addrinfo.h"
|
||||
#endif
|
||||
|
||||
extern int af;
|
||||
|
||||
/* Establish a proxy connection on an open socket to a web roxy by
|
||||
* using the CONNECT method. */
|
||||
static int establish_proxy_connection(int fd, char *host, int port)
|
||||
@@ -96,14 +95,28 @@ static int establish_proxy_connection(int fd, char *host, int port)
|
||||
|
||||
|
||||
|
||||
/** Open a socket to a tcp remote host with the specified port .
|
||||
/**
|
||||
* Open a socket to a tcp remote host with the specified port .
|
||||
*
|
||||
* Based on code from Warren. Proxy support by Stephen Rothwell
|
||||
* Based on code from Warren. Proxy support by Stephen Rothwell.
|
||||
* getaddrinfo() rewrite contributed by KAME.net.
|
||||
*
|
||||
* Now that we support IPv6 we need to look up the remote machine's
|
||||
* address first, using @p af_hint to set a preference for the type
|
||||
* of address. Then depending on whether it has v4 or v6 addresses we
|
||||
* try to open a connection.
|
||||
*
|
||||
* @param bind_address Local address to use. Normally NULL to get the stack default.
|
||||
* The loop allows for machines with some addresses which may not be
|
||||
* reachable, perhaps because we can't e.g. route ipv6 to that network
|
||||
* but we can get ip4 packets through.
|
||||
*
|
||||
* @param bind_address Local address to use. Normally NULL to bind
|
||||
* the wildcard address.
|
||||
*
|
||||
* @param af_hint Address family, e.g. AF_INET or AF_INET6.
|
||||
**/
|
||||
int open_socket_out(char *host, int port, const char *bind_address)
|
||||
int open_socket_out(char *host, int port, const char *bind_address,
|
||||
int af_hint)
|
||||
{
|
||||
int type = SOCK_STREAM;
|
||||
int error;
|
||||
@@ -139,11 +152,12 @@ int open_socket_out(char *host, int port, const char *bind_address)
|
||||
}
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = af;
|
||||
hints.ai_family = af_hint;
|
||||
hints.ai_socktype = type;
|
||||
error = getaddrinfo(h, portbuf, &hints, &res0);
|
||||
if (error) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s: %s\n", portbuf, gai_strerror(error));
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: %s %s: %s\n",
|
||||
h, portbuf, gai_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -162,7 +176,7 @@ int open_socket_out(char *host, int port, const char *bind_address)
|
||||
bhints.ai_flags = AI_PASSIVE;
|
||||
error = getaddrinfo(bind_address, NULL, &bhints, &bres);
|
||||
if (error) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: %s\n",
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s <noport>: %s\n",
|
||||
bind_address, gai_strerror(error));
|
||||
continue;
|
||||
}
|
||||
@@ -212,14 +226,16 @@ int open_socket_out(char *host, int port, const char *bind_address)
|
||||
**/
|
||||
int open_socket_out_wrapped (char *host,
|
||||
int port,
|
||||
const char *bind_address)
|
||||
const char *bind_address,
|
||||
int af_hint)
|
||||
{
|
||||
char *prog;
|
||||
|
||||
if ((prog = getenv ("RSYNC_CONNECT_PROG")) != NULL)
|
||||
return sock_exec (prog);
|
||||
else
|
||||
return open_socket_out (host, port, bind_address);
|
||||
return open_socket_out (host, port, bind_address,
|
||||
af_hint);
|
||||
}
|
||||
|
||||
|
||||
@@ -227,19 +243,32 @@ int open_socket_out_wrapped (char *host,
|
||||
/**
|
||||
* Open a socket of the specified type, port and address for incoming data
|
||||
*
|
||||
* Try to be better about handling the results of getaddrinfo(): when
|
||||
* opening an inbound socket, we might get several address results,
|
||||
* e.g. for the machine's ipv4 and ipv6 name.
|
||||
*
|
||||
* If binding a wildcard, then any one of them should do. If an address
|
||||
* was specified but it's insufficiently specific then that's not our
|
||||
* fault.
|
||||
*
|
||||
* However, some of the advertized addresses may not work because e.g. we
|
||||
* don't have IPv6 support in the kernel. In that case go on and try all
|
||||
* addresses until one succeeds.
|
||||
*
|
||||
* @param bind_address Local address to bind, or NULL to allow it to
|
||||
* default.
|
||||
**/
|
||||
static int open_socket_in(int type, int port, const char *bind_address)
|
||||
static int open_socket_in(int type, int port, const char *bind_address,
|
||||
int af_hint)
|
||||
{
|
||||
int one=1;
|
||||
int s;
|
||||
struct addrinfo hints, *res;
|
||||
struct addrinfo hints, *res, *resp;
|
||||
char portbuf[10];
|
||||
int error;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = af;
|
||||
hints.ai_family = af_hint;
|
||||
hints.ai_socktype = type;
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
snprintf(portbuf, sizeof(portbuf), "%d", port);
|
||||
@@ -249,20 +278,32 @@ static int open_socket_in(int type, int port, const char *bind_address)
|
||||
bind_address, gai_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
if (res->ai_next) {
|
||||
rprintf(FERROR, RSYNC_NAME ": getaddrinfo: bind address %s: "
|
||||
"resolved to multiple hosts\n",
|
||||
bind_address);
|
||||
freeaddrinfo(res);
|
||||
return -1;
|
||||
}
|
||||
/* XXX: Do we need to care about getting multiple results
|
||||
* back? I think probably not; if the user passed
|
||||
* bind_address == NULL and we set AI_PASSIVE then we ought to
|
||||
* get a wildcard result. */
|
||||
|
||||
s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
if (s < 0) {
|
||||
rprintf(FERROR, RSYNC_NAME ": open socket in failed: %s\n",
|
||||
strerror(errno));
|
||||
freeaddrinfo(res);
|
||||
return -1;
|
||||
resp = res;
|
||||
while (1) {
|
||||
s = socket(resp->ai_family, resp->ai_socktype, resp->ai_protocol);
|
||||
|
||||
if (s >= 0) {
|
||||
break; /* got a socket */
|
||||
} else if ((resp = resp->ai_next)) {
|
||||
switch (errno) {
|
||||
case EPROTONOSUPPORT:
|
||||
case EAFNOSUPPORT:
|
||||
case EPFNOSUPPORT:
|
||||
/* See if there's another address that will work... */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
rprintf(FERROR, RSYNC_NAME ": open inbound socket"
|
||||
"(dom=%d, type=%d, proto=%d) failed: %s\n",
|
||||
resp->ai_family, resp->ai_socktype, resp->ai_protocol,
|
||||
strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
|
||||
@@ -270,12 +311,15 @@ static int open_socket_in(int type, int port, const char *bind_address)
|
||||
/* now we've got a socket - we need to bind it */
|
||||
if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
|
||||
rprintf(FERROR, RSYNC_NAME ": bind failed on port %d\n", port);
|
||||
freeaddrinfo(res);
|
||||
close(s);
|
||||
return -1;
|
||||
close(s);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
fail:
|
||||
freeaddrinfo(res);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -311,7 +355,8 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
extern char *bind_address;
|
||||
|
||||
/* open an incoming socket */
|
||||
s = open_socket_in(SOCK_STREAM, port, bind_address);
|
||||
s = open_socket_in(SOCK_STREAM, port, bind_address,
|
||||
global_opts.af_hint);
|
||||
if (s == -1)
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
|
||||
@@ -327,7 +372,7 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
while (1) {
|
||||
fd_set fds;
|
||||
int fd;
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr addr;
|
||||
int in_addrlen = sizeof(addr);
|
||||
|
||||
/* close log file before the potentially very long select so
|
||||
@@ -505,12 +550,12 @@ void become_daemon(void)
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
return the IP addr of the client as a string
|
||||
******************************************************************/
|
||||
/**
|
||||
* Return the IP addr of the client as a string
|
||||
**/
|
||||
char *client_addr(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr ss;
|
||||
int length = sizeof(ss);
|
||||
static char addr_buf[100];
|
||||
static int initialised;
|
||||
@@ -519,22 +564,22 @@ char *client_addr(int fd)
|
||||
|
||||
initialised = 1;
|
||||
|
||||
if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
|
||||
if (getpeername(fd, &ss, &length)) {
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
getnameinfo((struct sockaddr *)&ss, length,
|
||||
getnameinfo(&ss, length,
|
||||
addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
|
||||
return addr_buf;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
return the DNS name of the client
|
||||
******************************************************************/
|
||||
/**
|
||||
* Return the DNS name of the client
|
||||
**/
|
||||
char *client_name(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr ss;
|
||||
int length = sizeof(ss);
|
||||
static char name_buf[100];
|
||||
static char port_buf[100];
|
||||
@@ -550,11 +595,14 @@ char *client_name(int fd)
|
||||
strcpy(name_buf,def);
|
||||
|
||||
if (getpeername(fd, (struct sockaddr *)&ss, &length)) {
|
||||
/* FIXME: Can we really not continue? */
|
||||
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
|
||||
fd, strerror(errno));
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
if (ss.ss_family == AF_INET6 &&
|
||||
if (ss.sa_family == AF_INET6 &&
|
||||
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&ss)->sin6_addr)) {
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr_in *sin;
|
||||
@@ -598,7 +646,7 @@ char *client_name(int fd)
|
||||
|
||||
/* XXX sin6_flowinfo and other fields */
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
if (res->ai_family != ss.ss_family)
|
||||
if (res->ai_family != ss.sa_family)
|
||||
continue;
|
||||
if (res->ai_addrlen != length)
|
||||
continue;
|
||||
@@ -606,79 +654,19 @@ char *client_name(int fd)
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: Do a forward lookup as well to prevent spoofing */
|
||||
/* TODO: Do a forward lookup as well to prevent spoofing */
|
||||
|
||||
if (res == NULL) {
|
||||
strcpy(name_buf, def);
|
||||
rprintf(FERROR,
|
||||
"reverse name lookup mismatch - spoofed address?\n");
|
||||
rprintf(FERROR, RSYNC_NAME ": "
|
||||
"reverse name lookup mismatch on fd%d - spoofed address?\n",
|
||||
fd);
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
return name_buf;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a string to an IP address. The string can be a name or
|
||||
dotted decimal number.
|
||||
|
||||
Returns a pointer to a static in_addr struct -- if you call this
|
||||
more than once then you should copy it.
|
||||
*/
|
||||
struct in_addr *ip_address(const char *str)
|
||||
{
|
||||
static struct in_addr ret;
|
||||
struct hostent *hp;
|
||||
|
||||
if (!str) {
|
||||
rprintf (FERROR, "ip_address received NULL name\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* try as an IP address */
|
||||
if (inet_aton(str, &ret) != 0) {
|
||||
return &ret;
|
||||
}
|
||||
|
||||
/* otherwise assume it's a network name of some sort and use
|
||||
gethostbyname */
|
||||
if ((hp = gethostbyname (str)) == 0) {
|
||||
rprintf(FERROR, "gethostbyname failed for \"%s\": unknown host?\n",str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hp->h_addr == NULL) {
|
||||
rprintf(FERROR, "gethostbyname: host address is invalid for host \"%s\"\n",str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hp->h_length > sizeof ret) {
|
||||
rprintf(FERROR, "gethostbyname: host address for \"%s\" is too large\n",
|
||||
str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (hp->h_addrtype != AF_INET) {
|
||||
rprintf (FERROR, "gethostname: host address for \"%s\" is not IPv4\n",
|
||||
str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is kind of difficult. The only field in ret is
|
||||
s_addr, which is the IP address as a 32-bit int. On
|
||||
UNICOS, s_addr is in fact a *bitfield* for reasons best
|
||||
know to Cray. This means we can't memcpy in to it. On the
|
||||
other hand, h_addr is a char*, so we can't just assign.
|
||||
|
||||
Since there's meant to be only one field inside the in_addr
|
||||
structure we will try just copying over the top and see how
|
||||
that goes. */
|
||||
memcpy (&ret, hp->h_addr, hp->h_length);
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
this is like socketpair but uses tcp. It is used by the Samba
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
#
|
||||
# This program is distributable under the terms of the GNU GPL (see COPYING)
|
||||
|
||||
|
||||
. "$suitedir/rsync.fns"
|
||||
|
||||
set -x
|
||||
|
||||
hands_setup
|
||||
|
||||
LONGDIR=${FROM}/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
|
||||
|
||||
@@ -41,6 +41,11 @@ printmsg() {
|
||||
}
|
||||
|
||||
|
||||
rsync_ls_lR() {
|
||||
find "$@" -print | sort | xargs $TLS
|
||||
}
|
||||
|
||||
|
||||
####################
|
||||
# Build test directories TO and FROM, with FROM full of files.
|
||||
|
||||
@@ -67,7 +72,7 @@ hands_setup() {
|
||||
mkdir ${FROM}/emptydir
|
||||
|
||||
# a hundred lines of text or so
|
||||
ls -lR ${srcdir} > ${FROM}/filelist
|
||||
rsync_ls_lR ${srcdir} > ${FROM}/filelist
|
||||
|
||||
# This might fail on systems that don't have -n
|
||||
echo $ECHO_N "This file has no trailing lf$ECHO_C" > ${FROM}/nolf
|
||||
@@ -95,6 +100,7 @@ hands_setup() {
|
||||
# Many machines do not have "mkdir -p", so we have to build up long paths.
|
||||
# How boring.
|
||||
makepath () {
|
||||
echo " makepath $1"
|
||||
p="$1"
|
||||
(
|
||||
# Absolut Unix.
|
||||
@@ -106,8 +112,12 @@ makepath () {
|
||||
# This will break if $1 contains a space.
|
||||
for c in `echo $p | tr '/' ' '`
|
||||
do
|
||||
[ -d "$c" ] || mkdir "$c" || return $?
|
||||
cd "$c" || return $?
|
||||
if [ -d "$c" ] || mkdir "$c"
|
||||
then
|
||||
cd "$c" || return $?
|
||||
else
|
||||
echo "failed to create $c" >&2; return $?
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
||||
@@ -139,8 +149,8 @@ checkit() {
|
||||
echo "-------------">>${log}
|
||||
echo "check how the directory listings compare with diff:">>${log}
|
||||
echo "">>${log}
|
||||
( cd $2 ; ls -laR ) > ${TMP}/ls-from 2>>${log}
|
||||
( cd $3 ; ls -laR ) > ${TMP}/ls-to 2>>${log}
|
||||
( cd "$2" && rsync_ls_lR ) > ${TMP}/ls-from 2>>${log}
|
||||
( cd "$3" && rsync_ls_lR ) > ${TMP}/ls-to 2>>${log}
|
||||
diff -c ${TMP}/ls-from ${TMP}/ls-to >>${log} 2>&1 || failed=YES
|
||||
if [ -z "${failed}" ] ; then
|
||||
rm $log
|
||||
|
||||
83
tls.c
83
tls.c
@@ -1,6 +1,6 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 2001 by Martin Pool
|
||||
* Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version
|
||||
@@ -27,18 +27,16 @@
|
||||
* our purposes they're the same -- for example, the BSD braindamage
|
||||
* about setting the mode on symlinks based on your current umask.
|
||||
*
|
||||
* There are some restrictions compared to regular ls: all the names
|
||||
* on the command line must be directories rather than files; you
|
||||
* can't give wildcards either.
|
||||
* All the filenames must be given on the command line -- tls does not
|
||||
* even read directories, let alone recurse. The typical usage is
|
||||
* "find|sort|xargs tls".
|
||||
*
|
||||
* We need to recurse downwards and show all the interesting
|
||||
* information and no more.
|
||||
* The format is not exactly the same as any particular Unix ls(1).
|
||||
*
|
||||
* \todo Use readdir64 if available?
|
||||
*
|
||||
* \todo Sort directory entries. Either that, or output file listing
|
||||
* in such a format that we can just pipe the whole lot through sort.
|
||||
*/
|
||||
* A key requirement for this program is that the output be "very
|
||||
* reproducible." So we mask away information that can accidentally
|
||||
* change.
|
||||
**/
|
||||
|
||||
|
||||
|
||||
@@ -62,23 +60,60 @@ static void failed (char const *what,
|
||||
|
||||
|
||||
|
||||
static void list_dir (char const *dn)
|
||||
static void list_file (const char *fname)
|
||||
{
|
||||
DIR *d;
|
||||
struct dirent *de;
|
||||
struct stat buf;
|
||||
char permbuf[PERMSTRING_SIZE];
|
||||
struct tm *mt;
|
||||
char datebuf[50];
|
||||
char linkbuf[4096];
|
||||
|
||||
if (!(d = opendir (dn)))
|
||||
failed ("opendir", dn);
|
||||
if (do_lstat(fname, &buf) == -1)
|
||||
failed ("stat", fname);
|
||||
|
||||
while ((de = readdir (d))) {
|
||||
char *dname = d_name (de);
|
||||
if (!strcmp (dname, ".") || !strcmp (dname, ".."))
|
||||
continue;
|
||||
printf ("%s\n", dname);
|
||||
/* The size of anything but a regular file is probably not
|
||||
* worth thinking about. */
|
||||
if (!S_ISREG(buf.st_mode))
|
||||
buf.st_size = 0;
|
||||
|
||||
/* On some BSD platforms the mode bits of a symlink are
|
||||
* undefined. Also it tends not to be possible to reset a
|
||||
* symlink's mtime, so we have to ignore it too. */
|
||||
if (S_ISLNK(buf.st_mode)) {
|
||||
buf.st_mode &= ~0777;
|
||||
buf.st_mtime = (time_t)0;
|
||||
buf.st_uid = buf.st_gid = 0;
|
||||
strcpy(linkbuf, " -> ");
|
||||
readlink(fname, linkbuf+4, sizeof(linkbuf) - 4);
|
||||
} else {
|
||||
linkbuf[0] = 0;
|
||||
}
|
||||
|
||||
permstring(permbuf, buf.st_mode);
|
||||
|
||||
if (buf.st_mtime) {
|
||||
mt = gmtime(&buf.st_mtime);
|
||||
|
||||
sprintf(datebuf, "%04d-%02d-%02d %02d:%02d:%02d",
|
||||
mt->tm_year + 1900,
|
||||
mt->tm_mon + 1,
|
||||
mt->tm_mday,
|
||||
mt->tm_hour,
|
||||
mt->tm_min,
|
||||
mt->tm_sec);
|
||||
} else {
|
||||
strcpy(datebuf, " ");
|
||||
}
|
||||
|
||||
if (closedir (d) == -1)
|
||||
failed ("closedir", dn);
|
||||
/* TODO: Perhaps escape special characters in fname? */
|
||||
|
||||
|
||||
/* NB: need to pass size as a double because it might be be
|
||||
* too large for a long. */
|
||||
printf("%s %12.0f %6d.%-6d %s %s%s\n",
|
||||
permbuf, (double) buf.st_size,
|
||||
buf.st_uid, buf.st_gid,
|
||||
datebuf, fname, linkbuf);
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +126,7 @@ int main (int argc, char *argv[])
|
||||
}
|
||||
|
||||
for (argv++; *argv; argv++) {
|
||||
list_dir (*argv);
|
||||
list_file (*argv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user