Compare commits

...

61 Commits

Author SHA1 Message Date
rsync-bugs
0b25efc12a Modified file stored as well 2001-11-30 00:31:06 +00:00
rsync-bugs
64cae087b6 preparing for release of 2.5.0 2001-11-30 00:29:46 +00:00
Martin Pool
b7cc59c503 Spec file needs to be generated from a template to include the version
number.
2001-11-30 00:29:20 +00:00
rsync-bugs
7eb8d18a99 preparing for release of 2.5.0 2001-11-30 00:23:11 +00:00
Martin Pool
e7bf3e5e87 Last bug fix for 2.5.0? Make the documentation for -a point out that
it does not in fact propagate hardlinsk.
2001-11-30 00:17:53 +00:00
Martin Pool
5aafd07b37 Note error cases that we ought to improve. 2001-11-30 00:16:14 +00:00
Martin Pool
053f3a831d Note other supported platforms 2001-11-30 00:15:32 +00:00
Martin Pool
a2d2e5c047 Add notes on things to do mentioned on the list in the last few months. 2001-11-29 01:31:31 +00:00
Martin Pool
dd3a922035 IPv6 support is now merged. 2001-11-29 00:23:29 +00:00
Martin Pool
0e916c6038 Just include rsync.h rather than all the individual headers.
(Suggestion from Dave Dykstra.)
2001-11-29 00:15:20 +00:00
Martin Pool
87fcb63975 No need to test for memcmp, because even broken ones are good enough
for our purposes.  (Patch from Dave Dykstra.)
2001-11-29 00:08:36 +00:00
Martin Pool
68b2cc5538 Show version when configuring.
If we don't seem to have an ANSI compiler, then omit a warning as soon
as that is discovered, because it is likely to break later configure
tests.  This doesn't seem to catch the particular HP-UX compiler I was
after, which is non-ANSI but only emits a warning on this configure
test.  Nevertheless probably better to have it in.
2001-11-29 00:04:48 +00:00
Martin Pool
4dcf3697ff Add list of platforms that build. 2001-11-28 07:49:32 +00:00
Martin Pool
ea77525546 Note half-baked Darwin IPv6 support. 2001-11-28 07:12:09 +00:00
Martin Pool
17d5a07ec2 Put back the --disable-ipv6 option. This should only be needed if
your platform seems to support ipv6, but actually it breaks.  This
seems to be the case for "powerpc-apple-darwin1.4".
2001-11-28 06:52:04 +00:00
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
24 changed files with 1093 additions and 384 deletions

27
INSTALL
View File

@@ -13,3 +13,30 @@ 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".
MAC OSX NOTES
-------------
Mac OS X (Darwin) seems to have an IPv6 stack, but it does not
completely implement the "New Sockets" API.
<http://www.ipv6.org/impl/mac.html> says that Apple do not support
IPv6 yet. If your build fails, try again with --disable-ipv6.

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

49
NEWS
View File

@@ -1,4 +1,4 @@
rsync 2.4.7 (sometime in 2001, maybe :)
rsync 2.5.0 (2001-11-30) -*- 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
@@ -32,7 +36,7 @@ rsync 2.4.7 (sometime in 2001, maybe :)
file to get cleaned out by another process.
* Change to using libpopt rather than getopt for processing
options. This makes the code cleaner and the behaviour more
options. This makes the code cleaner and the behaviour more
consistent across platforms. popt is included and built if not
installed on the platform.
@@ -45,7 +49,7 @@ rsync 2.4.7 (sometime in 2001, maybe :)
explain that we do it in a secure way.
* --whole-file is the default when source and target are on the
local machine.
local machine.
BUG FIXES:
@@ -67,11 +71,44 @@ rsync 2.4.7 (sometime in 2001, maybe :)
* Improved support for UNICOS (tested on Cray T3E and Cray SV1)
* autoconf2.52 (or later) is now required to rebuild the autoconf
scripts. It is not required to simply build rsync.
scripts. It is not required to simply build rsync.
* Platforms thought to work in this release:
Cray SV1 UNICOS 10.0.0.8 cc
Debian Linux 2.2 UltraSparc gcc
Debian Linux testing/unstable ARM gcc
FreeBSD 3.3-RELEASE i386 cc
FreeBSD 4.1.1-RELEASE i386 cc
FreeBSD 4.3-STABLE i386 cc
HP PA-RISC HP-UX 10.20 gcc
HP PA-RISC HP-UX 11.11 cc
IRIX 6.5 MIPS cc
IRIX 6.5 MIPS gcc
Mac OS X PPC (--disable-ipv6) cc
NetBSD 1.5 i386 gcc
NetBSD Current i386 cc
OpenBSD 2.5 Sparc gcc
OpenBSD 2.9 i386 cc
OpenBSD Current i386 cc
RedHat 6.2 i386 gcc
RedHat 6.2 i386 insure++
RedHat 7.0 i386 gcc
RedHat 7.1 i386 (Kernel 2.4.10) gcc
Slackware 8.0 i686 (Kernel 2.4.10)
Solaris 8 UltraSparc cc
Solaris 8 UltraSparc gcc
Solaris 8 i386 gcc
SuSE 7.1 i386 gcc2.95.2
SuSE 7.1 ppc gcc2.95.2
i386-pc-sco3.2v5.0.5 cc
i386-pc-sco3.2v5.0.5 gcc
powerpc-ibm-aix4.3.3.0 cc
i686-unknown-sysv5UnixWare7.1.0 gcc
i686-unknown-sysv5UnixWare7.1.0 cc
TESTING:
* The existing test.sh script by Phil Hands has been merged into a
test framework that works from both "make check" and the Samba
build farm.

94
TODO
View File

@@ -16,21 +16,99 @@ Cross-test versions
some testing and also be the most common case for having different
versions and not being able to upgrade.
use chroot
If the platform doesn't support it, then don't even try.
If running as non-root, then don't fail, just give a warning.
(There was a thread about this a while ago?)
http://lists.samba.org/pipermail/rsync/2001-August/thread.html
http://lists.samba.org/pipermail/rsync/2001-September/thread.html
--files-from
Avoids traversal. Better option than a pile of --include statements
for people who want to generate the file list using a find(1)
command or a script.
Performance
Traverse just one directory at a time. Tridge says it's possible.
Can possibly also be smarter about memory use while looking for hard
links by reducing the refcount as we find alternative names.
IPv6
Define a syntax for IPv6 literal addresses. Since they include
colons, they tend to break most naming systems, including ours.
Based on the HTTP IPv6 syntax, I think we should use
rsync://[::1]/foo/bar
[::1]::bar
which should just take a small change to the parser code.
Errors
If we hang or get SIGINT, then explain where we were up to. Perhaps
have a static buffer that contains the current function name, or
some kind of description of what we were trying to do. This is a
little easier on people than needing to run strace/truss.
"The dungeon collapses! You are killed." Rather than "unexpected
eof" give a message that is more detailed if possible and also more
helpful.
PLATFORMS ------------------------------------------------------------
Win32
Don't detach, because this messes up --srvany.
http://sources.redhat.com/ml/cygwin/2001-08/msg00234.html
According to "Effective TCP/IP Programming" (??) close() on a socket
has incorrect behaviour on Windows -- it sends a RST packet to the
other side, which gives a "connection reset by peer" error. On that
platform we should probably do shutdown() instead. However, on Unix
we are correct to call close(), because shutdown() discards
untransmitted data.
BUILD FARM -----------------------------------------------------------
Add machines
AMDAHL UTS (Dave Dykstra)
Cygwin (on different versions of Win32?)
HP-UX variants (via HP?)
SCO
NICE -----------------------------------------------------------------
Merge IPv6 support ***
--no-detach and --no-fork options
A patch is available at
Very useful for debugging. Also good when running under a
daemon-monitoring process that tries to restart the service when the
parent exits.
ftp://ftp.kame.net/pub/kame/misc/rsync-244-v6-20000802.diff.gz
hang/timeout friendliness
but tridge reckons it needs to be cleaned up before it can be
accepted.
On
This is now on the track-kameipv6 branch and can be moved across any
time. The KAME people say that it should work on machines without
IPv6 stacks.
internationalization
Change to using gettext(). Probably need to ship this for platforms
that don't have it.
Solicit translations.
Does anyone care?
rsyncsh

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

@@ -5,6 +5,12 @@ AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.52)
RSYNC_VERSION=2.5.0
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$RSYNC_VERSION"], [rsync release version])
LDFLAGS=${LDFLAGS-""}
AC_CANONICAL_TARGET([])
@@ -13,11 +19,13 @@ dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_CC_STDC
AC_SUBST(SHELL)
RSYNC_VERSION=2.4.7pre2
AC_SUBST(RSYNC_VERSION)
AC_DEFINE_UNQUOTED(RSYNC_VERSION, ["$RSYNC_VERSION"], [rsync release version])
if test "$xac_cv_prog_cc_stdc" = xno
then
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
fi
# compile with optimisation and without debugging by default, unless
# --debug is given. We must decide this before testing the compiler.
@@ -90,29 +98,15 @@ 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_ARG_ENABLE(ipv6,
AC_HELP_STRING([--disable-ipv6], [don't even try to use IPv6]))
if test "x$enable_ipv6" != xno
then
AC_MSG_CHECKING([ipv6 stack type])
for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
case $i in
@@ -197,152 +191,10 @@ yes
fi
done
AC_MSG_RESULT($ipv6type)
AC_SEARCH_LIBS(getaddrinfo, inet6)
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_C_BIGENDIAN
AC_HEADER_DIRENT
AC_HEADER_TIME
@@ -350,7 +202,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 +266,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)
@@ -421,7 +291,11 @@ if test x"$ac_cv_func_strcasecmp" = x"no"; then
AC_CHECK_LIB(resolv, strcasecmp)
fi
AC_FUNC_MEMCMP
dnl At the moment we don't test for a broken memcmp(), because all we
dnl need to do is test for equality, not comparison, and it seems that
dnl every platform has a memcmp that can do at least that.
dnl AC_FUNC_MEMCMP
AC_FUNC_UTIME_NULL
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
@@ -429,12 +303,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 "rsync.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}
};

84
packaging/lsb/rsync.spec Normal file
View File

@@ -0,0 +1,84 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.0
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.0.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
Changed target paths to be Linux Standards Base compliant
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr --mandir=/usr/share/man
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/share/man/man1/rsync.1
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

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

View File

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

View File

@@ -0,0 +1,81 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: PVERSION
Release: PRELEASE
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1*
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

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

View File

@@ -334,8 +334,13 @@ explicitly checked on the receiver and any files of the same name
which already exist and have the same checksum and size on the
receiver are skipped. This option can be quite slow.
dit(bf(-a, --archive)) This is equivalent to -rlptgoD. It is a quick way
of saying you want recursion and want to preserve everything.
dit(bf(-a, --archive)) This is equivalent to -rlptgoD. It is a quick
way of saying you want recursion and want to preserve almost
everything.
Note however that bf(-a) bf(does not preserve hardlinks), because
finding multiply-linked files is expensive. You must separately
specify bf(-H).
dit(bf(-r, --recursive)) This tells rsync to copy directories
recursively. If you don't specify this then rsync won't copy

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;