Compare commits

...

46 Commits

Author SHA1 Message Date
Martin Pool
3966b9c609 Call this 2.4.7pre4 2001-11-28 04:32:33 +00:00
Martin Pool
1c47fbd96b Note on HP-UX's bundled so-called C compiler. 2001-11-28 04:10:39 +00:00
Martin Pool
1691bdcafc HP's cpp apparently can't handle whitespace before #include 2001-11-28 03:12:20 +00:00
Martin Pool
6a5ef41fb3 HP's cpp chokes on preprocessor directives that have whitespace before
the '#'.  Off to the Implant Office with you!
2001-11-28 02:55:20 +00:00
Martin Pool
09b6f4b00d Fix inet_ntop/pton names 2001-11-28 01:29:41 +00:00
Martin Pool
7067b0aa28 Protect AF_INET6 references with #ifdef INET6 2001-11-28 00:36:32 +00:00
Martin Pool
112e731150 Fix sh 2001-11-27 07:59:34 +00:00
Martin Pool
1336e41460 Show symlink targets 2001-11-27 07:56:33 +00:00
Martin Pool
7c1b7890d3 Be a bit more verbose 2001-11-27 07:54:48 +00:00
Martin Pool
dd0700b025 mtime and ownership of symlinks can be random, so don't print them. 2001-11-27 07:54:03 +00:00
Martin Pool
04d8e8b25f Be a bit more verbose 2001-11-27 07:32:42 +00:00
Martin Pool
3723efcb1d Try to fix headers for UNICOS 2001-11-27 07:23:58 +00:00
Martin Pool
054b40b6fa Unbreak recursive ls test 2001-11-27 07:19:37 +00:00
Martin Pool
6773a7798f Oops, fix bash syntax 2001-11-27 07:09:47 +00:00
Martin Pool
2d4c8e5945 The size of anything but a regular file is probably not worth thinking
about.
2001-11-27 07:07:36 +00:00
Martin Pool
087173c887 When producing a ls-style permissions string, also handle
sticky/setuid/setgid bits the same way as GNU ls.
2001-11-27 07:05:33 +00:00
Martin Pool
57835c00ad Use tls rather than the OS's ls(1) so that we have more chance of
reproducible results.
2001-11-27 06:51:51 +00:00
Martin Pool
4ed886ae6e Also list permissions, ownership, size, and mtime. 2001-11-27 06:45:47 +00:00
Martin Pool
740819ef7b Split code to generate "rwx-----" strings into lib/permstring.c so it
can be reused in tls.
2001-11-27 06:43:17 +00:00
Martin Pool
829230689e Build getaddr/nameinfo into lib/. 2001-11-27 06:41:38 +00:00
Martin Pool
77ba4cc2f9 make clean can rm config.cache but not config.h, or it wil jam.
Build getaddr/nameinfo into lib/.

Split code to generate "rwx-----" strings into lib/permstring.c so it
can be reused in tls.
2001-11-27 06:39:02 +00:00
Martin Pool
e94989fe4d Try to fix LIBOBJ detection of ntop/pton. 2001-11-27 06:17:33 +00:00
Martin Pool
c11b88061f Fix missing parameter in log call. 2001-11-27 06:01:05 +00:00
Martin Pool
647c5433f8 Make clean should also remove the autoconf cache etc. 2001-11-27 05:35:14 +00:00
Martin Pool
8f694072a5 Add Paul Vixie's implementation of inet_ntop and inet_pton for
platforms that don't have them.
2001-11-27 05:22:23 +00:00
Martin Pool
9a689986c6 Look in -lresolv for inet_ntop 2001-11-27 04:53:08 +00:00
Martin Pool
3174b31d96 Check for inet_ntop and inet_pton, which may be missing. 2001-11-27 03:49:53 +00:00
Martin Pool
4eb61975b7 Explain IPv6 merge. 2001-11-27 02:28:36 +00:00
David Dykstra
76e26e1042 Better fix for case of excluded symlinks that point nowhere when using
--copy-links.  The readlink_stat() does need to be done in the normal case
before checking the exclude patterns because it needs to know whether or
not a file is a directory in order to properly handle a trailing slash
in an exclude pattern.  This fix makes make_file() go ahead and call
readlink_stat() but then if the latter returns an ENOENT and copy_links is
on then it will only print an error if the path is not excluded.
2001-11-26 19:15:53 +00:00
Martin Pool
9069dfd005 Fix rename of global option 2001-11-26 08:21:30 +00:00
Martin Pool
2be5d2daad Remove kame cruft 2001-11-26 08:21:14 +00:00
Martin Pool
22cd0063e5 Attempted clean up some of the IPv6 tests. 2001-11-26 08:20:13 +00:00
Martin Pool
3d2e458a4d Fix a small memory leak that was causing an Insure warning. 2001-11-26 07:58:47 +00:00
Martin Pool
a57568d716 Oops, no C++ comments. 2001-11-26 07:47:59 +00:00
Martin Pool
61f543cade Kill a function for jra. 2001-11-26 07:11:55 +00:00
Martin Pool
b8771f9615 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.
2001-11-26 07:10:06 +00:00
Martin Pool
d5d4b28220 Put the new address family option into an options struct. We have too
many globals already.

Better error messages for network-related failures.
2001-11-26 04:52:19 +00:00
Martin Pool
a037edaccd Silly autoconf 2001-11-26 01:49:33 +00:00
Martin Pool
356bbb8351 Check for -lnsl, -lsocket, etc, *before* looking for getaddrinfo,
because on Solaris (for one) it's not in libc.
2001-11-26 01:15:12 +00:00
Martin Pool
1f0fa9318a Remove highly suspicious redefinition of sockaddr structure -- there
seems no point using anything but the platform's native definition,
and if we can't get that from the system headers we're hosed anyhow.
2001-11-26 00:41:11 +00:00
Martin Pool
15c1707887 Remove check for buggy getaddrinfo for the time being -- it's unclear
how this is supposed to help.

Check for netdb.h
2001-11-26 00:23:29 +00:00
Martin Pool
9dec7aa9c1 Make some of the headers used by the KAME getaddrinfo implementation
be conditional -- they are missing on e.g. Solaris.  Not sure if this
will fix it.
2001-11-25 09:30:36 +00:00
Martin Pool
bc3d7454e0 Fix KAME patch to use proper autoconf AC_MSG macros rather than just echo/exit. 2001-11-24 05:38:35 +00:00
Martin Pool
56901bc7c3 Call this pre3. 2001-11-24 05:33:35 +00:00
Martin Pool
5c7f570b16 IPv6 is off by default. 2001-11-24 05:31:40 +00:00
Martin Pool
4f6e5fe323 IPv6 is off by default -- it seems to break header files on too many systems. 2001-11-24 05:30:27 +00:00
18 changed files with 761 additions and 363 deletions

15
INSTALL
View File

@@ -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".

View File

@@ -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
View File

@@ -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
View File

@@ -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 *);
],[

View File

@@ -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);
}

View File

@@ -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
View File

@@ -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
View 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
View 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
View 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
View File

@@ -0,0 +1,3 @@
#define PERMSTRING_SIZE 11
void permstring(char *perms, int mode);

View File

@@ -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);
}

View File

@@ -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
View File

@@ -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
View File

@@ -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

View File

@@ -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

View File

@@ -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
View File

@@ -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;