├── .gitignore ├── COPYING ├── Doxyfile ├── INSTALL ├── Makefile.in ├── NEWS ├── OLDNEWS ├── README ├── TODO ├── access.c ├── aclocal.m4 ├── acls.c ├── authenticate.c ├── backup.c ├── batch.c ├── byteorder.h ├── case_N.h ├── checksum.c ├── chmod.c ├── cleanup.c ├── clientname.c ├── clientserver.c ├── compat.c ├── config.guess ├── config.sub ├── configure ├── configure.ac ├── connection.c ├── csprotocol.txt ├── delete.c ├── doc ├── README-SGML ├── profile.txt └── rsync.sgml ├── errcode.h ├── exclude.c ├── fileio.c ├── flist.c ├── generator.c ├── getfsdev.c ├── getgroups.c ├── hashtable.c ├── hlink.c ├── ifuncs.h ├── install-sh ├── inums.h ├── io.c ├── io.h ├── itypes.h ├── lib ├── addrinfo.h ├── compat.c ├── dummy.in ├── getaddrinfo.c ├── inet_ntop.c ├── inet_pton.c ├── md5.c ├── mdfour.c ├── mdigest.h ├── permstring.c ├── permstring.h ├── pool_alloc.3 ├── pool_alloc.c ├── pool_alloc.h ├── snprintf.c ├── sysacls.c ├── sysacls.h ├── sysxattrs.c ├── sysxattrs.h ├── wildmatch.c └── wildmatch.h ├── loadparm.c ├── log.c ├── main.c ├── match.c ├── mkproto.pl ├── options.c ├── packaging ├── bin │ └── gpg ├── branch-from-patch ├── cull_options ├── git-status.pl ├── lsb │ ├── rsync.spec │ └── rsync.xinetd ├── nightly-rsync ├── patch-update ├── release-rsync ├── solaris │ └── build_pkg.sh └── var-checker ├── params.c ├── pipe.c ├── popt ├── CHANGES ├── COPYING ├── README ├── README.rsync ├── dummy.in ├── findme.c ├── findme.h ├── popt.c ├── popt.h ├── poptconfig.c ├── popthelp.c ├── poptint.h ├── poptparse.c └── system.h ├── prepare-source ├── prepare-source.mak ├── progress.c ├── receiver.c ├── rounding.c ├── rsync.c ├── rsync.h ├── rsync.yo ├── rsync3.txt ├── rsyncd.conf.yo ├── rsyncsh.txt ├── runtests.sh ├── sender.c ├── shconfig.in ├── socket.c ├── support ├── Makefile ├── atomic-rsync ├── cvs2includes ├── deny-rsync ├── file-attr-restore ├── files-to-excludes ├── git-set-file-times ├── instant-rsyncd ├── logfilter ├── lsh ├── mapfrom ├── mapto ├── mnt-excl ├── munge-symlinks ├── rrsync ├── rsyncstats └── savetransfer.c ├── syscall.c ├── t_stub.c ├── t_unsafe.c ├── tech_report.tex ├── testhelp └── maketree.py ├── testrun.c ├── testsuite ├── 00-hello.test ├── README.testsuite ├── acls.test ├── backup.test ├── batch-mode.test ├── chgrp.test ├── chmod-option.test ├── chmod-temp-dir.test ├── chmod.test ├── chown.test ├── compare-dest.test ├── daemon-gzip-download.test ├── daemon-gzip-upload.test ├── daemon.test ├── default-acls.test ├── delete.test ├── devices.test ├── dir-sgid.test ├── duplicates.test ├── exclude.test ├── executability.test ├── files-from.test ├── fuzzy.test ├── hands.test ├── hardlinks.test ├── itemize.test ├── longdir.test ├── merge.test ├── missing.test ├── relative.test ├── rsync.fns ├── ssh-basic.test ├── symlink-ignore.test ├── trimslash.test ├── unsafe-byname.test ├── unsafe-links.test ├── wildmatch.test └── xattrs.test ├── tls.c ├── token.c ├── trimslash.c ├── tweak_manpage ├── uidlist.c ├── util.c ├── wildtest.c ├── wildtest.txt ├── xattrs.c └── zlib ├── ChangeLog ├── README ├── README.rsync ├── adler32.c ├── compress.c ├── crc32.c ├── crc32.h ├── deflate.c ├── deflate.h ├── dummy.in ├── inffast.c ├── inffast.h ├── inffixed.h ├── inflate.c ├── inflate.h ├── inftrees.c ├── inftrees.h ├── trees.c ├── trees.h ├── zconf.h ├── zlib.h ├── zutil.c └── zutil.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.[oa] 2 | *.dSYM 3 | *~ 4 | dummy 5 | ID 6 | Makefile 7 | Makefile.old 8 | configure.sh 9 | configure.sh.old 10 | config.cache 11 | config.h 12 | config.h.in 13 | config.h.in.old 14 | config.log 15 | config.status 16 | /proto.h 17 | /proto.h-tstamp 18 | /rsync.1 19 | /rsyncd.conf.5 20 | /autom4te*.cache 21 | /confdefs.h 22 | /conftest* 23 | /dox 24 | /getgroups 25 | /gmon.out 26 | /rsync 27 | /shconfig 28 | /testdir 29 | /tests-dont-exist 30 | /testtmp 31 | /tls 32 | /testrun 33 | /trimslash 34 | /t_unsafe 35 | /wildtest 36 | /getfsdev 37 | /rounding.h 38 | /doc/rsync.pdf 39 | /doc/rsync.ps 40 | /support/savetransfer 41 | /testsuite/chown-fake.test 42 | /testsuite/devices-fake.test 43 | /patches 44 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | To build and install rsync: 2 | 3 | $ ./configure 4 | $ make 5 | # make install 6 | 7 | You may set the installation directory and other parameters by options 8 | to ./configure. To see them, use: 9 | 10 | $ ./configure --help 11 | 12 | Configure tries to figure out if the local system uses group "nobody" or 13 | "nogroup" by looking in the /etc/group file. (This is only used for the 14 | default group of an rsync daemon, which attempts to run with "nobody" 15 | user and group permissions.) You can change the default user and group 16 | for the daemon by editing the NOBODY_USER and NOBODY_GROUP defines in 17 | config.h, or just override them in your /etc/rsyncd.conf file. 18 | 19 | As of 2.4.7, rsync uses Eric Troan's popt option-parsing library. A 20 | cut-down copy of a recent release is included in the rsync distribution, 21 | and will be used if there is no popt library on your build host, or if 22 | the --with-included-popt option is passed to ./configure. 23 | 24 | If you configure using --enable-maintainer-mode, then rsync will try 25 | to pop up an xterm on DISPLAY=:0 if it crashes. You might find this 26 | useful, but it should be turned off for production builds. 27 | 28 | MAKE COMPATIBILITY 29 | ------------------ 30 | 31 | Note that Makefile.in has a rule that uses a wildcard in a prerequisite. If 32 | your make has a problem with this rule, you will see an error like this: 33 | 34 | Don't know how to make ./*.c 35 | 36 | You can change the "proto.h-tstamp" target to omit its prerequisite args, 37 | but keep in mind that this will make a manual removal of "proto.h-tstamp" 38 | necessary anytime the function prototypes change. 39 | 40 | RPM NOTES 41 | --------- 42 | 43 | Under packaging you will find .spec files for several distributions. 44 | The .spec file in packaging/lsb can be used for Linux systems that 45 | adhere to the Linux Standards Base (e.g., RedHat and others). 46 | 47 | HP-UX NOTES 48 | ----------- 49 | 50 | The HP-UX 10.10 "bundled" C compiler seems not to be able to cope with 51 | ANSI C. You may see this error message in config.log if ./configure 52 | fails: 53 | 54 | (Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature. 55 | 56 | Install gcc or HP's "ANSI/C Compiler". 57 | 58 | MAC OSX NOTES 59 | ------------- 60 | 61 | Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do 62 | not completely implement the "New Sockets" API. 63 | 64 | says that Apple started to support 65 | IPv6 in 10.2 (Jaguar). If your build fails, try again after running 66 | configure with --disable-ipv6. 67 | 68 | IBM AIX NOTES 69 | ------------- 70 | 71 | IBM AIX has a largefile problem with mkstemp. See IBM PR-51921. 72 | The workaround is to append the below to config.h 73 | #ifdef _LARGE_FILES 74 | #undef HAVE_SECURE_MKSTEMP 75 | #endif 76 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | WHAT IS RSYNC? 2 | -------------- 3 | 4 | Rsync is a fast and extraordinarily versatile file copying tool for 5 | both remote and local files. 6 | 7 | Rsync uses a delta-transfer algorithm which provides a very fast method 8 | for bringing remote files into sync. It does this by sending just the 9 | differences in the files across the link, without requiring that both 10 | sets of files are present at one of the ends of the link beforehand. At 11 | first glance this may seem impossible because the calculation of diffs 12 | between two files normally requires local access to both files. 13 | 14 | A technical report describing the rsync algorithm is included with this 15 | package. 16 | 17 | 18 | USAGE 19 | ----- 20 | 21 | Basically you use rsync just like scp, but rsync has many additional 22 | options. To get a complete list of supported options type: 23 | 24 | rsync --help 25 | 26 | See the manpage for more detailed information. 27 | 28 | 29 | SETUP 30 | ----- 31 | 32 | Rsync normally uses ssh or rsh for communication with remote systems. 33 | It does not need to be setuid and requires no special privileges for 34 | installation. You must, however, have a working ssh or rsh system. 35 | Using ssh is recommended for its security features. 36 | 37 | Alternatively, rsync can run in `daemon' mode, listening on a socket. 38 | This is generally used for public file distribution, although 39 | authentication and access control are available. 40 | 41 | To install rsync, first run the "configure" script. This will create a 42 | Makefile and config.h appropriate for your system. Then type "make". 43 | 44 | Note that on some systems you will have to force configure not to use 45 | gcc because gcc may not support some features (such as 64 bit file 46 | offsets) that your system may support. Set the environment variable CC 47 | to the name of your native compiler before running configure in this 48 | case. 49 | 50 | Once built put a copy of rsync in your search path on the local and 51 | remote systems (or use "make install"). That's it! 52 | 53 | 54 | RSYNC DAEMONS 55 | ------------- 56 | 57 | Rsync can also talk to "rsync daemons" which can provide anonymous or 58 | authenticated rsync. See the rsyncd.conf(5) man page for details on how 59 | to setup an rsync daemon. See the rsync(1) man page for info on how to 60 | connect to an rsync daemon. 61 | 62 | 63 | WEB SITE 64 | -------- 65 | 66 | The main rsync web site is here: 67 | 68 | http://rsync.samba.org/ 69 | 70 | You'll find a FAQ list, downloads, resources, HTML versions of the 71 | manpages, etc. 72 | 73 | 74 | MAILING LISTS 75 | ------------- 76 | 77 | There is a mailing list for the discussion of rsync and its applications 78 | that is open to anyone to join. New releases are announced on this 79 | list, and there is also an announcement-only mailing list for those that 80 | want official announcements. See the mailing-list page for full 81 | details: 82 | 83 | http://rsync.samba.org/lists.html 84 | 85 | 86 | BUG REPORTS 87 | ----------- 88 | 89 | To visit this web page for full the details on bug reporting: 90 | 91 | http://rsync.samba.org/bugzilla.html 92 | 93 | That page contains links to the current bug list, and information on how 94 | to report a bug well. You might also like to try searching the Internet 95 | for the error message you've received, or looking in the mailing list 96 | archives at: 97 | 98 | http://mail-archive.com/rsync@lists.samba.org/ 99 | 100 | To send a bug report, follow the instructions on the bug-tracking 101 | page of the web site. 102 | 103 | Alternately, email your bug report to rsync@lists.samba.org . 104 | 105 | 106 | GIT REPOSITORY 107 | -------------- 108 | 109 | If you want to get the very latest version of rsync direct from the 110 | source code repository then you can use git: 111 | 112 | git clone git://git.samba.org/rsync.git 113 | 114 | See the download page for full details on all the ways to grab the 115 | source, including nightly tar files, web-browsing of the git repository, 116 | etc.: 117 | 118 | http://rsync.samba.org/download.html 119 | 120 | 121 | COPYRIGHT 122 | --------- 123 | 124 | Rsync was originally written by Andrew Tridgell and is currently 125 | maintained by Wayne Davison. It has been improved by many developers 126 | from around the world. 127 | 128 | Rsync may be used, modified and redistributed only under the terms of 129 | the GNU General Public License, found in the file COPYING in this 130 | distribution, or at: 131 | 132 | http://www.fsf.org/licenses/gpl.html 133 | 134 | 135 | AVAILABILITY 136 | ------------ 137 | 138 | The main web site for rsync is http://rsync.samba.org/ 139 | The main ftp site is ftp://rsync.samba.org/pub/rsync/ 140 | This is also available as rsync://rsync.samba.org/rsyncftp/ 141 | -------------------------------------------------------------------------------- /aclocal.m4: -------------------------------------------------------------------------------- 1 | dnl AC_VALIDATE_CACHE_SYSTEM_TYPE[(cmd)] 2 | dnl if the cache file is inconsistent with the current host, 3 | dnl target and build system types, execute CMD or print a default 4 | dnl error message. 5 | AC_DEFUN(AC_VALIDATE_CACHE_SYSTEM_TYPE, [ 6 | AC_REQUIRE([AC_CANONICAL_SYSTEM]) 7 | AC_MSG_CHECKING([config.cache system type]) 8 | if { test x"${ac_cv_host_system_type+set}" = x"set" && 9 | test x"$ac_cv_host_system_type" != x"$host"; } || 10 | { test x"${ac_cv_build_system_type+set}" = x"set" && 11 | test x"$ac_cv_build_system_type" != x"$build"; } || 12 | { test x"${ac_cv_target_system_type+set}" = x"set" && 13 | test x"$ac_cv_target_system_type" != x"$target"; }; then 14 | AC_MSG_RESULT([different]) 15 | ifelse($#, 1, [$1], 16 | [AC_MSG_ERROR(["you must remove config.cache and restart configure"])]) 17 | else 18 | AC_MSG_RESULT([same]) 19 | fi 20 | ac_cv_host_system_type="$host" 21 | ac_cv_build_system_type="$build" 22 | ac_cv_target_system_type="$target" 23 | ]) 24 | 25 | dnl Check for socklen_t: historically on BSD it is an int, and in 26 | dnl POSIX 1g it is a type of its own, but some platforms use different 27 | dnl types for the argument to getsockopt, getpeername, etc. So we 28 | dnl have to test to find something that will work. 29 | 30 | dnl This is no good, because passing the wrong pointer on C compilers is 31 | dnl likely to only generate a warning, not an error. We don't call this at 32 | dnl the moment. 33 | 34 | AC_DEFUN([TYPE_SOCKLEN_T], 35 | [ 36 | AC_CHECK_TYPE([socklen_t], ,[ 37 | AC_MSG_CHECKING([for socklen_t equivalent]) 38 | AC_CACHE_VAL([rsync_cv_socklen_t_equiv], 39 | [ 40 | # Systems have either "struct sockaddr *" or 41 | # "void *" as the second argument to getpeername 42 | rsync_cv_socklen_t_equiv= 43 | for arg2 in "struct sockaddr" void; do 44 | for t in int size_t unsigned long "unsigned long"; do 45 | AC_TRY_COMPILE([ 46 | #include 47 | #include 48 | 49 | int getpeername (int, $arg2 *, $t *); 50 | ],[ 51 | $t len; 52 | getpeername(0,0,&len); 53 | ],[ 54 | rsync_cv_socklen_t_equiv="$t" 55 | break 56 | ]) 57 | done 58 | done 59 | 60 | if test "x$rsync_cv_socklen_t_equiv" = x; then 61 | AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) 62 | fi 63 | ]) 64 | AC_MSG_RESULT($rsync_cv_socklen_t_equiv) 65 | AC_DEFINE_UNQUOTED(socklen_t, $rsync_cv_socklen_t_equiv, 66 | [type to use in place of socklen_t if not defined])], 67 | [#include 68 | #include ]) 69 | ]) 70 | 71 | dnl AC_HAVE_TYPE(TYPE,INCLUDES) 72 | AC_DEFUN([AC_HAVE_TYPE], [ 73 | AC_REQUIRE([AC_HEADER_STDC]) 74 | cv=`echo "$1" | sed 'y%./+- %__p__%'` 75 | AC_MSG_CHECKING(for $1) 76 | AC_CACHE_VAL([ac_cv_type_$cv], 77 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 78 | AC_INCLUDES_DEFAULT 79 | $2]], 80 | [[$1 foo;]])], 81 | [eval "ac_cv_type_$cv=yes"], 82 | [eval "ac_cv_type_$cv=no"]))dnl 83 | ac_foo=`eval echo \\$ac_cv_type_$cv` 84 | AC_MSG_RESULT($ac_foo) 85 | if test "$ac_foo" = yes; then 86 | ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'` 87 | if false; then 88 | AC_CHECK_TYPES($1) 89 | fi 90 | AC_DEFINE_UNQUOTED($ac_tr_hdr, 1, [Define if you have type `$1']) 91 | fi 92 | ]) 93 | -------------------------------------------------------------------------------- /byteorder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple byteorder handling. 3 | * 4 | * Copyright (C) 1992-1995 Andrew Tridgell 5 | * Copyright (C) 2007-2008 Wayne Davison 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License along 18 | * with this program; if not, visit the http://fsf.org website. 19 | */ 20 | 21 | #undef CAREFUL_ALIGNMENT 22 | #undef AVOID_BYTEORDER_INLINE 23 | 24 | /* We know that the x86 can handle misalignment and has the same 25 | * byte order (LSB-first) as the 32-bit numbers we transmit. */ 26 | #ifdef __i386__ 27 | #define CAREFUL_ALIGNMENT 0 28 | #endif 29 | 30 | #ifndef CAREFUL_ALIGNMENT 31 | #define CAREFUL_ALIGNMENT 1 32 | #endif 33 | 34 | #define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) 35 | #define UVAL(buf,pos) ((uint32)CVAL(buf,pos)) 36 | 37 | #if CAREFUL_ALIGNMENT 38 | 39 | #define PVAL(buf,pos) (UVAL(buf,pos)|UVAL(buf,(pos)+1)<<8) 40 | #define IVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+2)<<16) 41 | #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) 42 | #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) 43 | #define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val))) 44 | 45 | #define IVALu(buf,pos) IVAL(buf,pos) 46 | #define SIVALu(buf,pos,val) SIVAL(buf,pos,val) 47 | 48 | #else /* !CAREFUL_ALIGNMENT */ 49 | 50 | /* This handles things for architectures like the 386 that can handle alignment errors. 51 | * WARNING: This section is dependent on the length of an int32 (and thus a uint32) 52 | * being correct (4 bytes)! Set CAREFUL_ALIGNMENT if it is not. */ 53 | 54 | # ifdef AVOID_BYTEORDER_INLINE 55 | 56 | #define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos))) 57 | #define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val)) 58 | 59 | #define IVALu(buf,pos) IVAL(buf,pos) 60 | #define SIVALu(buf,pos,val) SIVAL(buf,pos,val) 61 | 62 | # else /* !AVOID_BYTEORDER_INLINE */ 63 | 64 | static inline uint32 65 | IVALu(const uchar *buf, int pos) 66 | { 67 | union { 68 | const uchar *b; 69 | const uint32 *num; 70 | } u; 71 | u.b = buf + pos; 72 | return *u.num; 73 | } 74 | 75 | static inline void 76 | SIVALu(uchar *buf, int pos, uint32 val) 77 | { 78 | union { 79 | uchar *b; 80 | uint32 *num; 81 | } u; 82 | u.b = buf + pos; 83 | *u.num = val; 84 | } 85 | 86 | static inline uint32 87 | IVAL(const char *buf, int pos) 88 | { 89 | return IVALu((uchar*)buf, pos); 90 | } 91 | 92 | static inline void 93 | SIVAL(char *buf, int pos, uint32 val) 94 | { 95 | SIVALu((uchar*)buf, pos, val); 96 | } 97 | 98 | # endif /* !AVOID_BYTEORDER_INLINE */ 99 | 100 | #endif /* !CAREFUL_ALIGNMENT */ 101 | -------------------------------------------------------------------------------- /case_N.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Allow an arbitrary sequence of case labels. 3 | * 4 | * Copyright (C) 2006-2010 Wayne Davison 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, visit the http://fsf.org website. 18 | */ 19 | 20 | /* This is included multiple times, once for every segement in a switch statement. 21 | * This produces the next "case N:" statement in sequence. */ 22 | 23 | #if !defined CASE_N_STATE_0 24 | #define CASE_N_STATE_0 25 | case 0: 26 | #elif !defined CASE_N_STATE_1 27 | #define CASE_N_STATE_1 28 | case 1: 29 | #elif !defined CASE_N_STATE_2 30 | #define CASE_N_STATE_2 31 | case 2: 32 | #elif !defined CASE_N_STATE_3 33 | #define CASE_N_STATE_3 34 | case 3: 35 | #elif !defined CASE_N_STATE_4 36 | #define CASE_N_STATE_4 37 | case 4: 38 | #elif !defined CASE_N_STATE_5 39 | #define CASE_N_STATE_5 40 | case 5: 41 | #elif !defined CASE_N_STATE_6 42 | #define CASE_N_STATE_6 43 | case 6: 44 | #elif !defined CASE_N_STATE_7 45 | #define CASE_N_STATE_7 46 | case 7: 47 | #elif !defined CASE_N_STATE_8 48 | #define CASE_N_STATE_8 49 | case 8: 50 | #elif !defined CASE_N_STATE_9 51 | #define CASE_N_STATE_9 52 | case 9: 53 | #elif !defined CASE_N_STATE_10 54 | #define CASE_N_STATE_10 55 | case 10: 56 | #elif !defined CASE_N_STATE_11 57 | #define CASE_N_STATE_11 58 | case 11: 59 | #elif !defined CASE_N_STATE_12 60 | #define CASE_N_STATE_12 61 | case 12: 62 | #elif !defined CASE_N_STATE_13 63 | #define CASE_N_STATE_13 64 | case 13: 65 | #elif !defined CASE_N_STATE_14 66 | #define CASE_N_STATE_14 67 | case 14: 68 | #elif !defined CASE_N_STATE_15 69 | #define CASE_N_STATE_15 70 | case 15: 71 | #elif !defined CASE_N_STATE_16 72 | #define CASE_N_STATE_16 73 | case 16: 74 | #else 75 | #error Need to add more case statements! 76 | #endif 77 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | # This configure script ensures that the configure.sh script exists, and 3 | # if not, it tries to fetch rsync's generated files or build them. We 4 | # then transfer control to the configure.sh script to do the real work. 5 | 6 | dir=`dirname $0` 7 | realconfigure="$dir/configure.sh" 8 | 9 | if test ! -f "$realconfigure"; then 10 | if test -f "$HOME/build_farm/build_test.fns"; then 11 | # Test the included popt 12 | set -- --with-included-popt "${@}" 13 | # Allow the build farm to grab latest files via rsync. 14 | actions='build fetch' 15 | else 16 | actions='build' 17 | fi 18 | if "$dir/prepare-source" $actions; then 19 | : 20 | else 21 | echo 'Failed to build configure.sh and/or config.h.in -- giving up.' >&2 22 | rm -f "$realconfigure" 23 | exit 1 24 | fi 25 | fi 26 | 27 | exec "$realconfigure" "${@}" 28 | -------------------------------------------------------------------------------- /connection.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Support the max connections option. 3 | * 4 | * Copyright (C) 1998 Andrew Tridgell 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, visit the http://fsf.org website. 18 | */ 19 | 20 | #include "rsync.h" 21 | 22 | /* A simple routine to do connection counting. This returns 1 on success 23 | * and 0 on failure, with errno also being set if the open() failed (errno 24 | * will be 0 if the lock request failed). */ 25 | int claim_connection(char *fname, int max_connections) 26 | { 27 | int fd, i; 28 | 29 | if (max_connections == 0) 30 | return 1; 31 | 32 | if ((fd = open(fname, O_RDWR|O_CREAT, 0600)) < 0) 33 | return 0; 34 | 35 | /* Find a free spot. */ 36 | for (i = 0; i < max_connections; i++) { 37 | if (lock_range(fd, i*4, 4)) 38 | return 1; 39 | } 40 | 41 | close(fd); 42 | 43 | /* A lock failure needs to return an errno of 0. */ 44 | errno = 0; 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /csprotocol.txt: -------------------------------------------------------------------------------- 1 | This is kind of informal and may be wrong, but it helped me. It's 2 | basically a summary of clientserver.c and authenticate.c. 3 | 4 | -- Martin Pool 5 | 6 | 7 | This is the protocol used for rsync --daemon; i.e. connections to port 8 | 873 rather than invocations over a remote shell. 9 | 10 | When the server accepts a connection, it prints a greeting 11 | 12 | @RSYNCD: . 13 | 14 | where is the numeric version (see PROTOCOL_VERSION in rsync.h) 15 | '.' is a literal period, and is the numeric subprotocol 16 | version (see SUBPROTOCOL_VERSION -- it will be 0 for final releases). 17 | Protocols prior to 30 only output alone. The daemon expects 18 | to see a similar greeting back from the client. For protocols prior to 19 | 30, an absent "." value is assumed to be 0. For protocol 20 | 30, an absent value is a fatal error. The daemon then follows this line 21 | with a free-format text message-of-the-day (if any is defined). 22 | 23 | The server is now in the connected state. The client can either send 24 | the command 25 | 26 | #list 27 | 28 | to get a listing of modules, or the name of a module. After this, the 29 | connection is now bound to a particular module. Access per host for 30 | this module is now checked, as is per-module connection limits. 31 | 32 | If authentication is required to use this module, the server will say 33 | 34 | @RSYNCD: AUTHREQD 35 | 36 | where is a random string of base64 characters. The client 37 | must respond with 38 | 39 | 40 | 41 | where is the username they claim to be, and is the 42 | base64 form of the MD4 hash of challenge+password. 43 | 44 | At this point the server applies all remaining constraints before 45 | handing control to the client, including switching uid/gid, setting up 46 | include and exclude lists, moving to the root of the module, and doing 47 | chroot. 48 | 49 | If the login is acceptable, then the server will respond with 50 | 51 | @RSYNCD: OK 52 | 53 | The client now writes some rsync options, as if it were remotely 54 | executing the command. The server parses these arguments as if it had 55 | just been invoked with them, but they're added to the existing state. 56 | So if the client specifies a list of files to be included or excluded, 57 | they'll defer to existing limits specified in the server 58 | configuration. 59 | 60 | At this point the client and server both switch to using a 61 | multiplexing layer across the socket. The main point of this is to 62 | allow the server to asynchronously pass errors back, while still 63 | allowing streamed and pipelined data. 64 | 65 | Unfortunately, the multiplex protocol is not used at every stage. We 66 | start up in plain socket mode and then change over by calling 67 | io_start_buffering. Of course both the client and the server have to 68 | do this at the same point. 69 | 70 | The server then talks to the client as normal across the socket, 71 | passing checksums, file lists and so on. For documentation of that, 72 | stay tuned (or write it yourself!). 73 | 74 | 75 | 76 | ------------ 77 | Protocol version changes 78 | 79 | 30 (2007-10-04, 3.0.0pre1) 80 | 81 | The use of a "." number was added to 82 | @RSYNCD: . 83 | 84 | 25 (2001-08-20, 2.4.7pre2) 85 | 86 | Send an explicit "@RSYNC EXIT" command at the end of the 87 | module listing. We never intentionally end the transmission 88 | by just closing the socket anymore. 89 | -------------------------------------------------------------------------------- /doc/README-SGML: -------------------------------------------------------------------------------- 1 | Handling the rsync SGML documentation 2 | 3 | rsync documentation is now primarily in Docbook format. Docbook is an 4 | SGML/XML documentation format that is becoming standard on free 5 | operating systems. It's also used for Samba documentation. 6 | 7 | The SGML files are source code that can be translated into various 8 | useful output formats, primarily PDF, HTML, Postscript and plain text. 9 | 10 | To do this transformation on Debian, you should install the 11 | docbook-utils package. Having done that, you can say 12 | 13 | docbook2pdf rsync.sgml 14 | 15 | and so on. 16 | 17 | On other systems you probably need James Clark's "sp" and "JadeTeX" 18 | packages. Work it out for yourself and send a note to the mailing 19 | list. 20 | 21 | -------------------------------------------------------------------------------- /doc/profile.txt: -------------------------------------------------------------------------------- 1 | Notes on rsync profiling 2 | 3 | strlcpy is hot: 4 | 5 | 0.00 0.00 1/7735635 push_dir [68] 6 | 0.00 0.00 1/7735635 pop_dir [71] 7 | 0.00 0.00 1/7735635 send_file_list [15] 8 | 0.01 0.00 18857/7735635 send_files [4] 9 | 0.04 0.00 129260/7735635 send_file_entry [18] 10 | 0.04 0.00 129260/7735635 make_file [20] 11 | 0.04 0.00 141666/7735635 send_directory [36] 12 | 2.29 0.00 7316589/7735635 f_name [13] 13 | [14] 11.7 2.42 0.00 7735635 strlcpy [14] 14 | 15 | 16 | Here's the top few functions: 17 | 18 | 46.23 9.57 9.57 13160929 0.00 0.00 mdfour64 19 | 14.78 12.63 3.06 13160929 0.00 0.00 copy64 20 | 11.69 15.05 2.42 7735635 0.00 0.00 strlcpy 21 | 10.05 17.13 2.08 41438 0.05 0.38 sum_update 22 | 4.11 17.98 0.85 13159996 0.00 0.00 mdfour_update 23 | 1.50 18.29 0.31 file_compare 24 | 1.45 18.59 0.30 129261 0.00 0.01 send_file_entry 25 | 1.23 18.84 0.26 2557585 0.00 0.00 f_name 26 | 1.11 19.07 0.23 1483750 0.00 0.00 u_strcmp 27 | 1.11 19.30 0.23 118129 0.00 0.00 writefd_unbuffered 28 | 0.92 19.50 0.19 1085011 0.00 0.00 writefd 29 | 0.43 19.59 0.09 156987 0.00 0.00 read_timeout 30 | 0.43 19.68 0.09 129261 0.00 0.00 clean_fname 31 | 0.39 19.75 0.08 32887 0.00 0.38 matched 32 | 0.34 19.82 0.07 1 70.00 16293.92 send_files 33 | 0.29 19.89 0.06 129260 0.00 0.00 make_file 34 | 0.29 19.95 0.06 75430 0.00 0.00 read_unbuffered 35 | 36 | 37 | 38 | mdfour could perhaps be made faster: 39 | 40 | /* NOTE: This code makes no attempt to be fast! */ 41 | 42 | There might be an optimized version somewhere that we can borrow. 43 | -------------------------------------------------------------------------------- /errcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Error codes returned by rsync. 3 | * 4 | * Copyright (C) 1998-2000 Andrew Tridgell 5 | * Copyright (C) 2003-2008 Wayne Davison 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License along 18 | * with this program; if not, visit the http://fsf.org website. 19 | */ 20 | 21 | /* If you change these, please also update the string mappings in log.c and 22 | * the EXIT VALUES in rsync.yo. */ 23 | 24 | #define RERR_OK 0 25 | #define RERR_SYNTAX 1 /* syntax or usage error */ 26 | #define RERR_PROTOCOL 2 /* protocol incompatibility */ 27 | #define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */ 28 | #define RERR_UNSUPPORTED 4 /* requested action not supported */ 29 | #define RERR_STARTCLIENT 5 /* error starting client-server protocol */ 30 | 31 | #define RERR_SOCKETIO 10 /* error in socket IO */ 32 | #define RERR_FILEIO 11 /* error in file IO */ 33 | #define RERR_STREAMIO 12 /* error in rsync protocol data stream */ 34 | #define RERR_MESSAGEIO 13 /* errors with program diagnostics */ 35 | #define RERR_IPC 14 /* error in IPC code */ 36 | #define RERR_CRASHED 15 /* sibling crashed */ 37 | #define RERR_TERMINATED 16 /* sibling terminated abnormally */ 38 | 39 | #define RERR_SIGNAL1 19 /* status returned when sent SIGUSR1 */ 40 | #define RERR_SIGNAL 20 /* status returned when sent SIGINT, SIGTERM, SIGHUP */ 41 | #define RERR_WAITCHILD 21 /* some error returned by waitpid() */ 42 | #define RERR_MALLOC 22 /* error allocating core memory buffers */ 43 | #define RERR_PARTIAL 23 /* partial transfer */ 44 | #define RERR_VANISHED 24 /* file(s) vanished on sender side */ 45 | #define RERR_DEL_LIMIT 25 /* skipped some deletes due to --max-delete */ 46 | 47 | #define RERR_TIMEOUT 30 /* timeout in data send/receive */ 48 | #define RERR_CONTIMEOUT 35 /* timeout waiting for daemon connection */ 49 | 50 | /* Although it doesn't seem to be specified anywhere, 51 | * ssh and the shell seem to return these values: 52 | * 53 | * 124 if the command exited with status 255 54 | * 125 if the command is killed by a signal 55 | * 126 if the command cannot be run 56 | * 127 if the command is not found 57 | * 58 | * and we could use this to give a better explanation if the remote 59 | * command is not found. 60 | */ 61 | #define RERR_CMD_FAILED 124 62 | #define RERR_CMD_KILLED 125 63 | #define RERR_CMD_RUN 126 64 | #define RERR_CMD_NOTFOUND 127 65 | -------------------------------------------------------------------------------- /getfsdev.c: -------------------------------------------------------------------------------- 1 | #include "rsync.h" 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | STRUCT_STAT st; 6 | int ret; 7 | 8 | while (--argc > 0) { 9 | #ifdef USE_STAT64_FUNCS 10 | ret = stat64(*++argv, &st); 11 | #else 12 | ret = stat(*++argv, &st); 13 | #endif 14 | if (ret < 0) { 15 | fprintf(stderr, "Unable to stat `%s'\n", *argv); 16 | exit(1); 17 | } 18 | printf("%ld/%ld\n", (long)major(st.st_dev), 19 | (long)minor(st.st_dev)); 20 | } 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /getgroups.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Print out the gids of all groups for the current user. This is like 3 | * `id -G` on Linux, but it's too hard to find a portable equivalent. 4 | * 5 | * Copyright (C) 2002 Martin Pool 6 | * Copyright (C) 2003-2008 Wayne Davison 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License version 3 as 10 | * published by the Free Software Foundation. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License along 18 | * with this program; if not, visit the http://fsf.org website. 19 | */ 20 | 21 | #include "rsync.h" 22 | 23 | int 24 | main(UNUSED(int argc), UNUSED(char *argv[])) 25 | { 26 | int n, i; 27 | gid_t *list; 28 | gid_t gid = MY_GID(); 29 | int gid_in_list = 0; 30 | 31 | #ifdef HAVE_GETGROUPS 32 | if ((n = getgroups(0, NULL)) < 0) { 33 | perror("getgroups"); 34 | return 1; 35 | } 36 | #else 37 | n = 0; 38 | #endif 39 | 40 | list = (gid_t*)malloc(sizeof (gid_t) * (n + 1)); 41 | if (!list) { 42 | fprintf(stderr, "out of memory!\n"); 43 | exit(1); 44 | } 45 | 46 | #ifdef HAVE_GETGROUPS 47 | if (n > 0) 48 | n = getgroups(n, list); 49 | #endif 50 | 51 | for (i = 0; i < n; i++) { 52 | printf("%lu ", (unsigned long)list[i]); 53 | if (list[i] == gid) 54 | gid_in_list = 1; 55 | } 56 | /* The default gid might not be in the list on some systems. */ 57 | if (!gid_in_list) 58 | printf("%lu", (unsigned long)gid); 59 | printf("\n"); 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /hashtable.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Routines to provide a memory-efficient hashtable. 3 | * 4 | * Copyright (C) 2007-2009 Wayne Davison 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, visit the http://fsf.org website. 18 | */ 19 | 20 | #include "rsync.h" 21 | 22 | #define HASH_LOAD_LIMIT(size) ((size)*3/4) 23 | 24 | struct hashtable *hashtable_create(int size, int key64) 25 | { 26 | int req = size; 27 | struct hashtable *tbl; 28 | int node_size = key64 ? sizeof (struct ht_int64_node) 29 | : sizeof (struct ht_int32_node); 30 | 31 | /* Pick a power of 2 that can hold the requested size. */ 32 | if (size & (size-1) || size < 16) { 33 | size = 16; 34 | while (size < req) 35 | size *= 2; 36 | } 37 | 38 | if (!(tbl = new(struct hashtable)) 39 | || !(tbl->nodes = new_array0(char, size * node_size))) 40 | out_of_memory("hashtable_create"); 41 | tbl->size = size; 42 | tbl->entries = 0; 43 | tbl->node_size = node_size; 44 | tbl->key64 = key64 ? 1 : 0; 45 | 46 | if (DEBUG_GTE(HASH, 1)) { 47 | char buf[32]; 48 | if (req != size) 49 | snprintf(buf, sizeof buf, "req: %d, ", req); 50 | else 51 | *buf = '\0'; 52 | rprintf(FINFO, "[%s] created hashtable %lx (%ssize: %d, keys: %d-bit)\n", 53 | who_am_i(), (long)tbl, buf, size, key64 ? 64 : 32); 54 | } 55 | 56 | return tbl; 57 | } 58 | 59 | void hashtable_destroy(struct hashtable *tbl) 60 | { 61 | if (DEBUG_GTE(HASH, 1)) { 62 | rprintf(FINFO, "[%s] destroyed hashtable %lx (size: %d, keys: %d-bit)\n", 63 | who_am_i(), (long)tbl, tbl->size, tbl->key64 ? 64 : 32); 64 | } 65 | free(tbl->nodes); 66 | free(tbl); 67 | } 68 | 69 | /* This returns the node for the indicated key, either newly created or 70 | * already existing. Returns NULL if not allocating and not found. */ 71 | void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing) 72 | { 73 | int key64 = tbl->key64; 74 | struct ht_int32_node *node; 75 | uint32 ndx; 76 | 77 | if (key64 ? key == 0 : (int32)key == 0) { 78 | rprintf(FERROR, "Internal hashtable error: illegal key supplied!\n"); 79 | exit_cleanup(RERR_MESSAGEIO); 80 | } 81 | 82 | if (allocate_if_missing && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) { 83 | void *old_nodes = tbl->nodes; 84 | int size = tbl->size * 2; 85 | int i; 86 | 87 | if (!(tbl->nodes = new_array0(char, size * tbl->node_size))) 88 | out_of_memory("hashtable_node"); 89 | tbl->size = size; 90 | tbl->entries = 0; 91 | 92 | if (DEBUG_GTE(HASH, 1)) { 93 | rprintf(FINFO, "[%s] growing hashtable %lx (size: %d, keys: %d-bit)\n", 94 | who_am_i(), (long)tbl, size, key64 ? 64 : 32); 95 | } 96 | 97 | for (i = size / 2; i-- > 0; ) { 98 | struct ht_int32_node *move_node = HT_NODE(tbl, old_nodes, i); 99 | int64 move_key = HT_KEY(move_node, key64); 100 | if (move_key == 0) 101 | continue; 102 | node = hashtable_find(tbl, move_key, 1); 103 | node->data = move_node->data; 104 | } 105 | 106 | free(old_nodes); 107 | } 108 | 109 | if (!key64) { 110 | /* Based on Jenkins One-at-a-time hash. */ 111 | uchar buf[4], *keyp = buf; 112 | int i; 113 | 114 | SIVALu(buf, 0, key); 115 | for (ndx = 0, i = 0; i < 4; i++) { 116 | ndx += keyp[i]; 117 | ndx += (ndx << 10); 118 | ndx ^= (ndx >> 6); 119 | } 120 | ndx += (ndx << 3); 121 | ndx ^= (ndx >> 11); 122 | ndx += (ndx << 15); 123 | } else { 124 | /* Based on Jenkins hashword() from lookup3.c. */ 125 | uint32 a, b, c; 126 | 127 | /* Set up the internal state */ 128 | a = b = c = 0xdeadbeef + (8 << 2); 129 | 130 | #define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k)))) 131 | #if SIZEOF_INT64 >= 8 132 | b += (uint32)(key >> 32); 133 | #endif 134 | a += (uint32)key; 135 | c ^= b; c -= rot(b, 14); 136 | a ^= c; a -= rot(c, 11); 137 | b ^= a; b -= rot(a, 25); 138 | c ^= b; c -= rot(b, 16); 139 | a ^= c; a -= rot(c, 4); 140 | b ^= a; b -= rot(a, 14); 141 | c ^= b; c -= rot(b, 24); 142 | #undef rot 143 | ndx = c; 144 | } 145 | 146 | /* If it already exists, return the node. If we're not 147 | * allocating, return NULL if the key is not found. */ 148 | while (1) { 149 | int64 nkey; 150 | 151 | ndx &= tbl->size - 1; 152 | node = HT_NODE(tbl, tbl->nodes, ndx); 153 | nkey = HT_KEY(node, key64); 154 | 155 | if (nkey == key) 156 | return node; 157 | if (nkey == 0) { 158 | if (!allocate_if_missing) 159 | return NULL; 160 | break; 161 | } 162 | ndx++; 163 | } 164 | 165 | /* Take over this empty spot and then return the node. */ 166 | if (key64) 167 | ((struct ht_int64_node*)node)->key = key; 168 | else 169 | node->key = (int32)key; 170 | tbl->entries++; 171 | return node; 172 | } 173 | -------------------------------------------------------------------------------- /ifuncs.h: -------------------------------------------------------------------------------- 1 | /* Inline functions for rsync. 2 | * 3 | * Copyright (C) 2007-2008 Wayne Davison 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, visit the http://fsf.org website. 17 | */ 18 | 19 | static inline void 20 | alloc_xbuf(xbuf *xb, size_t sz) 21 | { 22 | if (!(xb->buf = new_array(char, sz))) 23 | out_of_memory("alloc_xbuf"); 24 | xb->size = sz; 25 | xb->len = xb->pos = 0; 26 | } 27 | 28 | static inline void 29 | realloc_xbuf(xbuf *xb, size_t sz) 30 | { 31 | char *bf = realloc_array(xb->buf, char, sz); 32 | if (!bf) 33 | out_of_memory("realloc_xbuf"); 34 | xb->buf = bf; 35 | xb->size = sz; 36 | } 37 | 38 | static inline void 39 | free_xbuf(xbuf *xb) 40 | { 41 | if (xb->buf) 42 | free(xb->buf); 43 | memset(xb, 0, sizeof (xbuf)); 44 | } 45 | 46 | static inline int 47 | to_wire_mode(mode_t mode) 48 | { 49 | #ifdef SUPPORT_LINKS 50 | #if _S_IFLNK != 0120000 51 | if (S_ISLNK(mode)) 52 | return (mode & ~(_S_IFMT)) | 0120000; 53 | #endif 54 | #endif 55 | return mode; 56 | } 57 | 58 | static inline mode_t 59 | from_wire_mode(int mode) 60 | { 61 | #if _S_IFLNK != 0120000 62 | if ((mode & (_S_IFMT)) == 0120000) 63 | return (mode & ~(_S_IFMT)) | _S_IFLNK; 64 | #endif 65 | return mode; 66 | } 67 | 68 | static inline char * 69 | d_name(struct dirent *di) 70 | { 71 | #ifdef HAVE_BROKEN_READDIR 72 | return (di->d_name - 2); 73 | #else 74 | return di->d_name; 75 | #endif 76 | } 77 | 78 | static inline void 79 | init_stat_x(stat_x *sx_p) 80 | { 81 | #ifdef SUPPORT_ACLS 82 | sx_p->acc_acl = sx_p->def_acl = NULL; 83 | #endif 84 | #ifdef SUPPORT_XATTRS 85 | sx_p->xattr = NULL; 86 | #endif 87 | } 88 | -------------------------------------------------------------------------------- /inums.h: -------------------------------------------------------------------------------- 1 | /* Inline functions for rsync. 2 | * 3 | * Copyright (C) 2008 Wayne Davison 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, visit the http://fsf.org website. 17 | */ 18 | 19 | static inline char * 20 | big_num(int64 num) 21 | { 22 | return do_big_num(num, 0, NULL); 23 | } 24 | 25 | static inline char * 26 | comma_num(int64 num) 27 | { 28 | extern int human_readable; 29 | return do_big_num(num, human_readable != 0, NULL); 30 | } 31 | 32 | static inline char * 33 | human_num(int64 num) 34 | { 35 | extern int human_readable; 36 | return do_big_num(num, human_readable, NULL); 37 | } 38 | 39 | static inline char * 40 | big_dnum(double dnum, int decimal_digits) 41 | { 42 | return do_big_dnum(dnum, 0, decimal_digits); 43 | } 44 | 45 | static inline char * 46 | comma_dnum(double dnum, int decimal_digits) 47 | { 48 | extern int human_readable; 49 | return do_big_dnum(dnum, human_readable != 0, decimal_digits); 50 | } 51 | 52 | static inline char * 53 | human_dnum(double dnum, int decimal_digits) 54 | { 55 | extern int human_readable; 56 | return do_big_dnum(dnum, human_readable, decimal_digits); 57 | } 58 | -------------------------------------------------------------------------------- /io.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007-2008 Wayne Davison 3 | * 4 | * This program is free software; you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation; either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along 15 | * with this program; if not, visit the http://fsf.org website. 16 | */ 17 | 18 | extern int protocol_version; 19 | 20 | static inline int32 21 | read_varint30(int f) 22 | { 23 | if (protocol_version < 30) 24 | return read_int(f); 25 | return read_varint(f); 26 | } 27 | 28 | static inline int64 29 | read_varlong30(int f, uchar min_bytes) 30 | { 31 | if (protocol_version < 30) 32 | return read_longint(f); 33 | return read_varlong(f, min_bytes); 34 | } 35 | 36 | static inline void 37 | write_varint30(int f, int32 x) 38 | { 39 | if (protocol_version < 30) 40 | write_int(f, x); 41 | else 42 | write_varint(f, x); 43 | } 44 | 45 | static inline void 46 | write_varlong30(int f, int64 x, uchar min_bytes) 47 | { 48 | if (protocol_version < 30) 49 | write_longint(f, x); 50 | else 51 | write_varlong(f, x, min_bytes); 52 | } 53 | -------------------------------------------------------------------------------- /itypes.h: -------------------------------------------------------------------------------- 1 | /* Inline functions for rsync. 2 | * 3 | * Copyright (C) 2007-2008 Wayne Davison 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License along 16 | * with this program; if not, visit the http://fsf.org website. 17 | */ 18 | 19 | static inline int 20 | isDigit(const char *ptr) 21 | { 22 | return isdigit(*(unsigned char *)ptr); 23 | } 24 | 25 | static inline int 26 | isPrint(const char *ptr) 27 | { 28 | return isprint(*(unsigned char *)ptr); 29 | } 30 | 31 | static inline int 32 | isSpace(const char *ptr) 33 | { 34 | return isspace(*(unsigned char *)ptr); 35 | } 36 | 37 | static inline int 38 | isLower(const char *ptr) 39 | { 40 | return islower(*(unsigned char *)ptr); 41 | } 42 | 43 | static inline int 44 | isUpper(const char *ptr) 45 | { 46 | return isupper(*(unsigned char *)ptr); 47 | } 48 | 49 | static inline int 50 | toLower(const char *ptr) 51 | { 52 | return tolower(*(unsigned char *)ptr); 53 | } 54 | 55 | static inline int 56 | toUpper(const char *ptr) 57 | { 58 | return toupper(*(unsigned char *)ptr); 59 | } 60 | -------------------------------------------------------------------------------- /lib/addrinfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | PostgreSQL Database Management System 3 | (formerly known as Postgres, then as Postgres95) 4 | 5 | Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group 6 | 7 | Portions Copyright (c) 1994, The Regents of the University of California 8 | 9 | Permission to use, copy, modify, and distribute this software and its 10 | documentation for any purpose, without fee, and without a written agreement 11 | is hereby granted, provided that the above copyright notice and this paragraph 12 | and the following two paragraphs appear in all copies. 13 | 14 | IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR 15 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING 16 | LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, 17 | EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 18 | SUCH DAMAGE. 19 | 20 | THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 21 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 22 | AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 23 | ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS 24 | TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | 26 | */ 27 | 28 | /*------------------------------------------------------------------------- 29 | * 30 | * getaddrinfo.h 31 | * Support getaddrinfo() on platforms that don't have it. 32 | * 33 | * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO, 34 | * whether or not the library routine getaddrinfo() can be found. This 35 | * policy is needed because on some platforms a manually installed libbind.a 36 | * may provide getaddrinfo(), yet the system headers may not provide the 37 | * struct definitions needed to call it. To avoid conflict with the libbind 38 | * definition in such cases, we rename our routines to pg_xxx() via macros. 39 | * 40 | * This code will also work on platforms where struct addrinfo is defined 41 | * in the system headers but no getaddrinfo() can be located. 42 | * 43 | * Copyright (c) 2003-2007, PostgreSQL Global Development Group 44 | * 45 | *------------------------------------------------------------------------- 46 | */ 47 | #ifndef ADDRINFO_H 48 | #define ADDRINFO_H 49 | 50 | 51 | /* Various macros that ought to be in , but might not be */ 52 | 53 | #ifndef EAI_FAIL 54 | #define EAI_BADFLAGS (-1) 55 | #define EAI_NONAME (-2) 56 | #define EAI_AGAIN (-3) 57 | #define EAI_FAIL (-4) 58 | #define EAI_FAMILY (-6) 59 | #define EAI_SOCKTYPE (-7) 60 | #define EAI_SERVICE (-8) 61 | #define EAI_MEMORY (-10) 62 | #define EAI_SYSTEM (-11) 63 | #endif /* !EAI_FAIL */ 64 | 65 | #ifndef AI_PASSIVE 66 | #define AI_PASSIVE 0x0001 67 | #endif 68 | 69 | #ifndef AI_NUMERICHOST 70 | /* 71 | * some platforms don't support AI_NUMERICHOST; define as zero if using 72 | * the system version of getaddrinfo... 73 | */ 74 | #if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) 75 | #define AI_NUMERICHOST 0 76 | #else 77 | #define AI_NUMERICHOST 0x0004 78 | #endif 79 | #endif 80 | 81 | #ifndef AI_CANONNAME 82 | #if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) 83 | #define AI_CANONNAME 0 84 | #else 85 | #define AI_CANONNAME 0x0008 86 | #endif 87 | #endif 88 | 89 | #ifndef AI_NUMERICSERV 90 | #if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) 91 | #define AI_NUMERICSERV 0 92 | #else 93 | #define AI_NUMERICSERV 0x0010 94 | #endif 95 | #endif 96 | 97 | #ifndef NI_NUMERICHOST 98 | #define NI_NUMERICHOST 1 99 | #endif 100 | 101 | #ifndef NI_NUMERICSERV 102 | #define NI_NUMERICSERV 2 103 | #endif 104 | 105 | #ifndef NI_NOFQDN 106 | #define NI_NOFQDN 4 107 | #endif 108 | 109 | #ifndef NI_NAMEREQD 110 | #define NI_NAMEREQD 8 111 | #endif 112 | 113 | #ifndef NI_DGRAM 114 | #define NI_DGRAM 16 115 | #endif 116 | 117 | 118 | #ifndef NI_MAXHOST 119 | #define NI_MAXHOST 1025 120 | #endif 121 | 122 | #ifndef NI_MAXSERV 123 | #define NI_MAXSERV 32 124 | #endif 125 | 126 | #ifndef HAVE_STRUCT_ADDRINFO 127 | struct addrinfo 128 | { 129 | int ai_flags; 130 | int ai_family; 131 | int ai_socktype; 132 | int ai_protocol; 133 | size_t ai_addrlen; 134 | struct sockaddr *ai_addr; 135 | char *ai_canonname; 136 | struct addrinfo *ai_next; 137 | }; 138 | #endif /* !HAVE_STRUCT_ADDRINFO */ 139 | 140 | #ifndef HAVE_STRUCT_SOCKADDR_STORAGE 141 | struct sockaddr_storage { 142 | unsigned short ss_family; 143 | unsigned long ss_align; 144 | char ss_padding[128 - sizeof (unsigned long)]; 145 | }; 146 | #endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ 147 | 148 | #ifndef HAVE_GETADDRINFO 149 | 150 | /* Rename private copies per comments above */ 151 | #ifdef getaddrinfo 152 | #undef getaddrinfo 153 | #endif 154 | #define getaddrinfo pg_getaddrinfo 155 | 156 | #ifdef freeaddrinfo 157 | #undef freeaddrinfo 158 | #endif 159 | #define freeaddrinfo pg_freeaddrinfo 160 | 161 | #ifdef gai_strerror 162 | #undef gai_strerror 163 | #endif 164 | #define gai_strerror pg_gai_strerror 165 | 166 | #ifdef getnameinfo 167 | #undef getnameinfo 168 | #endif 169 | #define getnameinfo pg_getnameinfo 170 | 171 | extern int getaddrinfo(const char *node, const char *service, 172 | const struct addrinfo * hints, struct addrinfo ** res); 173 | extern void freeaddrinfo(struct addrinfo * res); 174 | extern const char *gai_strerror(int errcode); 175 | extern int getnameinfo(const struct sockaddr * sa, socklen_t salen, 176 | char *node, size_t nodelen, 177 | char *service, size_t servicelen, int flags); 178 | #endif /* !HAVE_GETADDRINFO */ 179 | 180 | #endif /* ADDRINFO_H */ 181 | -------------------------------------------------------------------------------- /lib/dummy.in: -------------------------------------------------------------------------------- 1 | This is a dummy file to ensure that the lib directory gets created 2 | by configure when a VPATH is used. 3 | -------------------------------------------------------------------------------- /lib/inet_ntop.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 1996-2001 Internet Software Consortium. 3 | * 4 | * Permission to use, copy, modify, and distribute this software for any 5 | * purpose with or without fee is hereby granted, provided that the above 6 | * copyright notice and this permission notice appear in all copies. 7 | * 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM 9 | * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 10 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 11 | * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, 12 | * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 13 | * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 14 | * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 15 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | */ 17 | 18 | 19 | #include "rsync.h" 20 | 21 | #define NS_INT16SZ 2 22 | #define NS_IN6ADDRSZ 16 23 | 24 | /* 25 | * WARNING: Don't even consider trying to compile this on a system where 26 | * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. 27 | */ 28 | 29 | static const char *inet_ntop4(const unsigned char *src, char *dst, 30 | size_t size); 31 | 32 | #ifdef AF_INET6 33 | static const char *inet_ntop6(const unsigned char *src, char *dst, 34 | size_t size); 35 | #endif 36 | 37 | /* char * 38 | * isc_net_ntop(af, src, dst, size) 39 | * convert a network format address to presentation format. 40 | * return: 41 | * pointer to presentation format address (`dst'), or NULL (see errno). 42 | * author: 43 | * Paul Vixie, 1996. 44 | */ 45 | const char * 46 | inet_ntop(int af, const void *src, char *dst, size_t size) 47 | { 48 | switch (af) { 49 | case AF_INET: 50 | return (inet_ntop4(src, dst, size)); 51 | #ifdef AF_INET6 52 | case AF_INET6: 53 | return (inet_ntop6(src, dst, size)); 54 | #endif 55 | default: 56 | errno = EAFNOSUPPORT; 57 | return (NULL); 58 | } 59 | /* NOTREACHED */ 60 | } 61 | 62 | /* const char * 63 | * inet_ntop4(src, dst, size) 64 | * format an IPv4 address 65 | * return: 66 | * `dst' (as a const) 67 | * notes: 68 | * (1) uses no statics 69 | * (2) takes a unsigned char* not an in_addr as input 70 | * author: 71 | * Paul Vixie, 1996. 72 | */ 73 | static const char * 74 | inet_ntop4(const unsigned char *src, char *dst, size_t size) 75 | { 76 | static const char *fmt = "%u.%u.%u.%u"; 77 | char tmp[sizeof "255.255.255.255"]; 78 | size_t len; 79 | 80 | len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]); 81 | if (len >= size) { 82 | errno = ENOSPC; 83 | return (NULL); 84 | } 85 | memcpy(dst, tmp, len + 1); 86 | 87 | return (dst); 88 | } 89 | 90 | /* const char * 91 | * isc_inet_ntop6(src, dst, size) 92 | * convert IPv6 binary address into presentation (printable) format 93 | * author: 94 | * Paul Vixie, 1996. 95 | */ 96 | #ifdef AF_INET6 97 | static const char * 98 | inet_ntop6(const unsigned char *src, char *dst, size_t size) 99 | { 100 | /* 101 | * Note that int32_t and int16_t need only be "at least" large enough 102 | * to contain a value of the specified size. On some systems, like 103 | * Crays, there is no such thing as an integer variable with 16 bits. 104 | * Keep this in mind if you think this function should have been coded 105 | * to use pointer overlays. All the world's not a VAX. 106 | */ 107 | char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; 108 | struct { int base, len; } best, cur; 109 | unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; 110 | int i, inc; 111 | 112 | /* 113 | * Preprocess: 114 | * Copy the input (bytewise) array into a wordwise array. 115 | * Find the longest run of 0x00's in src[] for :: shorthanding. 116 | */ 117 | memset(words, '\0', sizeof words); 118 | for (i = 0; i < NS_IN6ADDRSZ; i++) 119 | words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); 120 | best.base = -1; 121 | cur.base = -1; 122 | for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { 123 | if (words[i] == 0) { 124 | if (cur.base == -1) 125 | cur.base = i, cur.len = 1; 126 | else 127 | cur.len++; 128 | } else { 129 | if (cur.base != -1) { 130 | if (best.base == -1 || cur.len > best.len) 131 | best = cur; 132 | cur.base = -1; 133 | } 134 | } 135 | } 136 | if (cur.base != -1) { 137 | if (best.base == -1 || cur.len > best.len) 138 | best = cur; 139 | } 140 | if (best.base != -1 && best.len < 2) 141 | best.base = -1; 142 | 143 | /* 144 | * Format the result. 145 | */ 146 | tp = tmp; 147 | for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { 148 | /* Are we inside the best run of 0x00's? */ 149 | if (best.base != -1 && i >= best.base && 150 | i < (best.base + best.len)) { 151 | if (i == best.base) 152 | *tp++ = ':'; 153 | continue; 154 | } 155 | /* Are we following an initial run of 0x00s or any real hex? */ 156 | if (i != 0) 157 | *tp++ = ':'; 158 | /* Is this address an encapsulated IPv4? */ 159 | if (i == 6 && best.base == 0 && 160 | (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { 161 | if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) 162 | return (NULL); 163 | tp += strlen(tp); 164 | break; 165 | } 166 | inc = snprintf(tp, 5, "%x", words[i]); 167 | assert(inc < 5); 168 | tp += inc; 169 | } 170 | /* Was it a trailing run of 0x00's? */ 171 | if (best.base != -1 && (best.base + best.len) == 172 | (NS_IN6ADDRSZ / NS_INT16SZ)) 173 | *tp++ = ':'; 174 | *tp++ = '\0'; 175 | 176 | /* 177 | * Check for overflow, copy, and we're done. 178 | */ 179 | if ((size_t)(tp - tmp) > size) { 180 | errno = ENOSPC; 181 | return (NULL); 182 | } 183 | memcpy(dst, tmp, tp - tmp); 184 | return (dst); 185 | } 186 | #endif /* AF_INET6 */ 187 | -------------------------------------------------------------------------------- /lib/mdigest.h: -------------------------------------------------------------------------------- 1 | /* The include file for both the MD4 and MD5 routines. */ 2 | 3 | #define MD4_DIGEST_LEN 16 4 | #define MD5_DIGEST_LEN 16 5 | #define MAX_DIGEST_LEN MD5_DIGEST_LEN 6 | 7 | #define CSUM_CHUNK 64 8 | 9 | typedef struct { 10 | uint32 A, B, C, D; 11 | uint32 totalN; /* bit count, lower 32 bits */ 12 | uint32 totalN2; /* bit count, upper 32 bits */ 13 | uchar buffer[CSUM_CHUNK]; 14 | } md_context; 15 | 16 | void mdfour_begin(md_context *md); 17 | void mdfour_update(md_context *md, const uchar *in, uint32 length); 18 | void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN]); 19 | 20 | void get_mdfour(uchar digest[MD4_DIGEST_LEN], const uchar *in, int length); 21 | 22 | void md5_begin(md_context *ctx); 23 | void md5_update(md_context *ctx, const uchar *input, uint32 length); 24 | void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN]); 25 | 26 | void get_md5(uchar digest[MD5_DIGEST_LEN], const uchar *input, int n); 27 | -------------------------------------------------------------------------------- /lib/permstring.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A single utility routine. 3 | * 4 | * Copyright (C) 1996 Andrew Tridgell 5 | * Copyright (C) 1996 Paul Mackerras 6 | * Copyright (C) 2001 Martin Pool 7 | * Copyright (C) 2003, 2006 Wayne Davison 8 | * 9 | * This program is free software; you can redistribute it and/or modify 10 | * it under the terms of the GNU General Public License as published by 11 | * the Free Software Foundation; either version 3 of the License, or 12 | * (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License along 20 | * with this program; if not, visit the http://fsf.org website. 21 | */ 22 | 23 | #include "rsync.h" 24 | 25 | /* Produce a string representation of Unix mode bits like that used by ls(1). 26 | * The "buf" buffer must be at least 11 characters. */ 27 | void permstring(char *perms, mode_t mode) 28 | { 29 | static const char *perm_map = "rwxrwxrwx"; 30 | int i; 31 | 32 | strlcpy(perms, "----------", 11); 33 | 34 | for (i = 0; i < 9; i++) { 35 | if (mode & (1 << i)) 36 | perms[9-i] = perm_map[8-i]; 37 | } 38 | 39 | /* Handle setuid/sticky bits. You might think the indices are 40 | * off by one, but remember there's a type char at the 41 | * start. */ 42 | if (mode & S_ISUID) 43 | perms[3] = (mode & S_IXUSR) ? 's' : 'S'; 44 | 45 | if (mode & S_ISGID) 46 | perms[6] = (mode & S_IXGRP) ? 's' : 'S'; 47 | 48 | #ifdef S_ISVTX 49 | if (mode & S_ISVTX) 50 | perms[9] = (mode & S_IXOTH) ? 't' : 'T'; 51 | #endif 52 | 53 | if (S_ISDIR(mode)) 54 | perms[0] = 'd'; 55 | else if (S_ISLNK(mode)) 56 | perms[0] = 'l'; 57 | else if (S_ISBLK(mode)) 58 | perms[0] = 'b'; 59 | else if (S_ISCHR(mode)) 60 | perms[0] = 'c'; 61 | else if (S_ISSOCK(mode)) 62 | perms[0] = 's'; 63 | else if (S_ISFIFO(mode)) 64 | perms[0] = 'p'; 65 | } 66 | -------------------------------------------------------------------------------- /lib/permstring.h: -------------------------------------------------------------------------------- 1 | #define PERMSTRING_SIZE 11 2 | 3 | void permstring(char *perms, mode_t mode); 4 | -------------------------------------------------------------------------------- /lib/pool_alloc.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define POOL_CLEAR (1<<0) /* zero fill allocations */ 4 | #define POOL_NO_QALIGN (1<<1) /* don't align data to quanta */ 5 | #define POOL_INTERN (1<<2) /* Allocate extent structures */ 6 | #define POOL_PREPEND (1<<3) /* or prepend to extent data */ 7 | 8 | typedef void *alloc_pool_t; 9 | 10 | alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags); 11 | void pool_destroy(alloc_pool_t pool); 12 | void *pool_alloc(alloc_pool_t pool, size_t size, const char *bomb_msg); 13 | void pool_free(alloc_pool_t pool, size_t size, void *addr); 14 | void pool_free_old(alloc_pool_t pool, void *addr); 15 | void *pool_boundary(alloc_pool_t pool, size_t size); 16 | 17 | #define pool_talloc(pool, type, count, bomb_msg) \ 18 | ((type *)pool_alloc(pool, sizeof(type) * count, bomb_msg)) 19 | 20 | #define pool_tfree(pool, type, count, addr) \ 21 | (pool_free(pool, sizeof(type) * count, addr)) 22 | -------------------------------------------------------------------------------- /lib/sysxattrs.h: -------------------------------------------------------------------------------- 1 | #ifdef SUPPORT_XATTRS 2 | 3 | #if defined HAVE_ATTR_XATTR_H 4 | #include 5 | #elif defined HAVE_SYS_XATTR_H 6 | #include 7 | #elif defined HAVE_SYS_EXTATTR_H 8 | #include 9 | #endif 10 | 11 | /* Linux 2.4 does not define this as a distinct errno value: */ 12 | #ifndef ENOATTR 13 | #define ENOATTR ENODATA 14 | #endif 15 | 16 | ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size); 17 | ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size); 18 | int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size); 19 | int sys_lremovexattr(const char *path, const char *name); 20 | ssize_t sys_llistxattr(const char *path, char *list, size_t size); 21 | 22 | #else 23 | 24 | /* No xattrs available */ 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /lib/wildmatch.h: -------------------------------------------------------------------------------- 1 | /* wildmatch.h */ 2 | 3 | int wildmatch(const char *pattern, const char *text); 4 | int iwildmatch(const char *pattern, const char *text); 5 | int wildmatch_array(const char *pattern, const char*const *texts, int where); 6 | int litmatch_array(const char *string, const char*const *texts, int where); 7 | -------------------------------------------------------------------------------- /mkproto.pl: -------------------------------------------------------------------------------- 1 | # generate prototypes for rsync 2 | 3 | $old_protos = ''; 4 | if (open(IN, 'proto.h')) { 5 | $old_protos = join('', ); 6 | close IN; 7 | } 8 | 9 | %FN_MAP = ( 10 | BOOL => 'BOOL ', 11 | CHAR => 'char ', 12 | INTEGER => 'int ', 13 | STRING => 'char *', 14 | ); 15 | 16 | $inheader = 0; 17 | $protos = qq|/* This file is automatically generated with "make proto". DO NOT EDIT */\n\n|; 18 | 19 | while (<>) { 20 | if ($inheader) { 21 | if (/[)][ \t]*$/) { 22 | $inheader = 0; 23 | s/$/;/; 24 | } 25 | $protos .= $_; 26 | } elsif (/^FN_(LOCAL|GLOBAL)_([^(]+)\(([^,()]+)/) { 27 | $ret = $FN_MAP{$2}; 28 | $func = $3; 29 | $arg = $1 eq 'LOCAL' ? 'int module_id' : 'void'; 30 | $protos .= "$ret$func($arg);\n"; 31 | } elsif (/^static|^extern/ || /[;]/ || !/^[A-Za-z][A-Za-z0-9_]* /) { 32 | ; 33 | } elsif (/[(].*[)][ \t]*$/) { 34 | s/$/;/; 35 | $protos .= $_; 36 | } elsif (/[(]/) { 37 | $inheader = 1; 38 | $protos .= $_; 39 | } 40 | } 41 | 42 | if ($old_protos ne $protos) { 43 | open(OUT, '>proto.h') or die $!; 44 | print OUT $protos; 45 | close OUT; 46 | } 47 | 48 | open(OUT, '>proto.h-tstamp') and close OUT; 49 | -------------------------------------------------------------------------------- /packaging/bin/gpg: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | # This script gets git to run gpg with a --passphrase-file option. 3 | 4 | PATH=`echo $PATH | sed 's/^[^:]*://'` 5 | 6 | gpg --batch --passphrase-file=$GPG_PASSFILE "${@}" 7 | -------------------------------------------------------------------------------- /packaging/branch-from-patch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use Getopt::Long; 6 | 7 | &Getopt::Long::Configure('bundling'); 8 | &usage if !&GetOptions( 9 | 'branch|b=s' => \( my $master_branch = 'master' ), 10 | 'skip-check' => \( my $skip_branch_check ), 11 | 'delete' => \( my $delete_local_branches ), 12 | 'help|h' => \( my $help_opt ), 13 | ); 14 | &usage if $help_opt; 15 | 16 | my %local_branch; 17 | open PIPE, '-|', 'git branch -l' or die "Unable to fork: $!\n"; 18 | while () { 19 | if (m# patch/\Q$master_branch\E/(.*)#o) { 20 | $local_branch{$1} = 1; 21 | } 22 | } 23 | close PIPE; 24 | 25 | if ($delete_local_branches) { 26 | foreach my $name (sort keys %local_branch) { 27 | my $branch = "patch/$master_branch/$name"; 28 | system 'git', 'branch', '-D', $branch and exit 1; 29 | } 30 | %local_branch = ( ); 31 | } 32 | 33 | require 'packaging/git-status.pl'; 34 | check_git_state($master_branch, !$skip_branch_check, 1); 35 | 36 | my @patch_list; 37 | foreach (@ARGV) { 38 | if (!-f $_) { 39 | die "File not found: $_\n"; 40 | } 41 | die "Filename is not a .diff file: $_\n" unless /\.diff$/; 42 | push @patch_list, $_; 43 | } 44 | 45 | exit unless @patch_list; 46 | 47 | my(%scanned, %created, %info); 48 | 49 | foreach my $patch (@patch_list) { 50 | my($where, $name) = $patch =~ m{^(.*?)([^/]+)\.diff$}; 51 | next if $scanned{$name}++; 52 | 53 | open IN, '<', $patch or die "Unable to open $patch: $!\n"; 54 | 55 | my $info = ''; 56 | my $commit; 57 | while () { 58 | if (m#^based-on: (\S+)#) { 59 | $commit = $1; 60 | last; 61 | } 62 | last if m#^index .*\.\..* \d#; 63 | last if m#^diff --git #; 64 | last if m#^--- (old|a)/#; 65 | $info .= $_; 66 | } 67 | close IN; 68 | 69 | $info =~ s/\s+\Z/\n/; 70 | 71 | my $parent = $master_branch; 72 | my @patches = $info =~ m#patch -p1 ', "PATCH.$name" or die $!; 134 | print OUT $info; 135 | close OUT; 136 | system 'git', 'add', "PATCH.$name" and exit 1; 137 | 138 | open IN, '<', $patch or die "Unable to open $patch: $!\n"; 139 | $_ = join('', ); 140 | close IN; 141 | 142 | open PIPE, '|-', 'patch -p1' or die $!; 143 | print PIPE $_; 144 | close PIPE; 145 | 146 | system 'rm -f *.orig */*.orig'; 147 | 148 | while (m#\nnew file mode (\d+)\s+--- /dev/null\s+\Q+++\E b/(.*)#g) { 149 | chmod oct($1), $2; 150 | system 'git', 'add', $2; 151 | } 152 | 153 | while (1) { 154 | system 'git status'; 155 | print 'Press Enter to commit, Ctrl-C to abort, or type a wild-name to add a new file: '; 156 | $_ = ; 157 | last if /^$/; 158 | chomp; 159 | system "git add $_"; 160 | } 161 | 162 | while (system 'git', 'commit', '-a', '-m', "Creating branch from $name.diff.") { 163 | exit 1 if system '/bin/zsh'; 164 | } 165 | } 166 | 167 | sub usage 168 | { 169 | die < -1, 11 | 'fake-super' => 0, 12 | 'log-file' => 3, 13 | ); 14 | our $last_long_opt; 15 | 16 | open(IN, '../options.c') or die "Unable to open ../options.c: $!\n"; 17 | 18 | while () { 19 | if (/\Qargstr[x++]\E = '([^.ie])'/) { 20 | $short_no_arg{$1} = 1; 21 | undef $last_long_opt; 22 | } elsif (/\Qasprintf(\E[^,]+, "-([a-zA-Z0-9])\%l?[ud]"/) { 23 | $short_with_num{$1} = 1; 24 | undef $last_long_opt; 25 | } elsif (/\Qargs[ac++]\E = "--([^"=]+)"/) { 26 | $last_long_opt = $1; 27 | $long_opt{$1} = 0 unless exists $long_opt{$1}; 28 | } elsif (defined($last_long_opt) 29 | && /\Qargs[ac++]\E = ([^["\s]+);/ && $1 ne 'dest_option') { 30 | $long_opt{$last_long_opt} = 2; 31 | undef $last_long_opt; 32 | } elsif (/dest_option = "--([^"]+)"/) { 33 | $long_opt{$1} = 2; 34 | undef $last_long_opt; 35 | } elsif (/\Qasprintf(\E[^,]+, "--([^"=]+)=/ || /\Qargs[ac++]\E = "--([^"=]+)=/) { 36 | $long_opt{$1} = 1; 37 | undef $last_long_opt; 38 | } 39 | } 40 | close IN; 41 | 42 | my $short_no_arg = join('', sort keys %short_no_arg); 43 | my $short_with_num = join('', sort keys %short_with_num); 44 | 45 | print < $val,\n"; 68 | } 69 | 70 | print ");\n\n"; 71 | -------------------------------------------------------------------------------- /packaging/git-status.pl: -------------------------------------------------------------------------------- 1 | # Do some git-status checking for the current dir and (optionally) 2 | # the patches dir. 3 | 4 | sub check_git_state 5 | { 6 | my($master_branch, $fatal_unless_clean, $check_patches_dir) = @_; 7 | 8 | my($cur_branch) = check_git_status($fatal_unless_clean); 9 | if ($cur_branch ne $master_branch) { 10 | print "The checkout is not on the $master_branch branch.\n"; 11 | exit 1 if $master_branch ne 'master'; 12 | print "Do you want me to continue with --branch=$cur_branch? [n] "; 13 | $_ = ; 14 | exit 1 unless /^y/i; 15 | $_[0] = $master_branch = $cur_branch; # Updates caller's $master_branch too. 16 | } 17 | 18 | if ($check_patches_dir && -d 'patches/.git') { 19 | ($cur_branch) = check_git_status($fatal_unless_clean, 'patches'); 20 | if ($cur_branch ne $master_branch) { 21 | print "The *patches* checkout is on branch $cur_branch, not branch $master_branch.\n"; 22 | print "Do you want to change it to branch $master_branch? [n] "; 23 | $_ = ; 24 | exit 1 unless /^y/i; 25 | system "cd patches && git checkout '$master_branch'"; 26 | } 27 | } 28 | } 29 | 30 | sub check_git_status 31 | { 32 | my($fatal_unless_clean, $subdir) = @_; 33 | $subdir = '.' unless defined $subdir; 34 | my $status = `cd '$subdir' && git status`; 35 | my $is_clean = $status =~ /\nnothing to commit \(working directory clean\)/; 36 | my($cur_branch) = $status =~ /^# On branch (.+)\n/; 37 | if ($fatal_unless_clean && !$is_clean) { 38 | if ($subdir eq '.') { 39 | $subdir = ''; 40 | } else { 41 | $subdir = " *$subdir*"; 42 | } 43 | die "The$subdir checkout is not clean:\n", $status; 44 | } 45 | ($cur_branch, $is_clean, $status); 46 | } 47 | 48 | 1; 49 | -------------------------------------------------------------------------------- /packaging/lsb/rsync.spec: -------------------------------------------------------------------------------- 1 | Summary: A fast, versatile, remote (and local) file-copying tool 2 | Name: rsync 3 | Version: 3.0.3 4 | %define fullversion %{version} 5 | Release: 1 6 | %define srcdir src 7 | Group: Applications/Internet 8 | Source0: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz 9 | #Source1: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-patches-%{fullversion}.tar.gz 10 | URL: http://rsync.samba.org/ 11 | 12 | Prefix: %{_prefix} 13 | BuildRoot: /var/tmp/%{name}-root 14 | License: GPL 15 | 16 | %description 17 | Rsync is a fast and extraordinarily versatile file copying tool. It can 18 | copy locally, to/from another host over any remote shell, or to/from a 19 | remote rsync daemon. It offers a large number of options that control 20 | every aspect of its behavior and permit very flexible specification of the 21 | set of files to be copied. It is famous for its delta-transfer algorithm, 22 | which reduces the amount of data sent over the network by sending only the 23 | differences between the source files and the existing files in the 24 | destination. Rsync is widely used for backups and mirroring and as an 25 | improved copy command for everyday use. 26 | 27 | %prep 28 | # Choose one -- setup source only, or setup source + rsync-patches: 29 | %setup -q -n rsync-%{fullversion} 30 | #%setup -q -b1 -n rsync-%{fullversion} 31 | 32 | # If you you used "%setup -q -b1", choose the patches you wish to apply: 33 | #patch -p1 70 | Released 3.0.3. 71 | 72 | * Fri Mar 21 2008 Wayne Davison 73 | Added installation of /etc/xinetd.d/rsync file and some commented-out 74 | lines that demonstrate how to use the rsync-patches tar file. 75 | -------------------------------------------------------------------------------- /packaging/lsb/rsync.xinetd: -------------------------------------------------------------------------------- 1 | # default: off 2 | # description: The rsync server is a good addition to an ftp server, as it 3 | # allows crc checksumming etc. 4 | service rsync 5 | { 6 | disable = yes 7 | socket_type = stream 8 | wait = no 9 | user = root 10 | server = /usr/bin/rsync 11 | server_args = --daemon 12 | log_on_failure += USERID 13 | } 14 | -------------------------------------------------------------------------------- /packaging/solaris/build_pkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Shell script for building Solaris package of rsync 3 | # Author: Jens Apel 4 | # License: GPL 5 | # 6 | # BASEDIR is /usr/local and should be the same as the 7 | # --prefix parameter of configure 8 | # 9 | # this script should be copied under 10 | # packaging/solaris/5.8/build_pkg.sh 11 | 12 | # Definitions start here 13 | # you can edit this, if you like 14 | 15 | # The Package name under which rsync will b installed 16 | PKGNAME=SMBrsync 17 | 18 | # Extract common info requires for the 'info' part of the package. 19 | # This should be made generic and generated by the configure script 20 | # but for now it is hard coded 21 | BASEDIR=/usr/local 22 | VERSION="2.5.5" 23 | ARCH=`uname -p` 24 | NAME=rsync 25 | 26 | # Definitions end here 27 | # Please do not edit below this line or you know what you do. 28 | 29 | ## Start by faking root install 30 | echo "Creating install directory (fake $BASEDIR)..." 31 | START=`pwd` 32 | FAKE_ROOT=$START/${PKGNAME} 33 | mkdir $FAKE_ROOT 34 | 35 | # copy the binary and the man page to their places 36 | mkdir $FAKE_ROOT/bin 37 | mkdir -p $FAKE_ROOT/doc/rsync 38 | mkdir -p $FAKE_ROOT/man/man1 39 | mkdir -p $FAKE_ROOT/man/man5 40 | 41 | cp ../../../rsync $FAKE_ROOT/bin/rsync 42 | cp ../../../rsync.1 $FAKE_ROOT/man/man1/rsync.1 43 | cp ../../../rsyncd.conf.5 $FAKE_ROOT/man/man5/rsyncd.conf.5 44 | cp ../../../README $FAKE_ROOT/doc/rsync/README 45 | cp ../../../COPYING $FAKE_ROOT/doc/rsync/COPYING 46 | cp ../../../tech_report.pdf $FAKE_ROOT/doc/rsync/tech_report.pdf 47 | cp ../../../COPYING $FAKE_ROOT/COPYING 48 | 49 | ## Build info file 50 | echo "Building pkginfo file..." 51 | cat > $FAKE_ROOT/pkginfo << EOF_INFO 52 | PKG=$PKGNAME 53 | NAME=$NAME 54 | DESC="Program for efficient remote updates of files." 55 | VENDOR="Samba Team URL: http://samba.anu.edu.au/rsync/" 56 | BASEDIR=$BASEDIR 57 | ARCH=$ARCH 58 | VERSION=$VERSION 59 | CATEGORY=application 60 | CLASSES=none 61 | EOF_INFO 62 | 63 | ## Build prototype file 64 | cat > $FAKE_ROOT/prototype << EOFPROTO 65 | i copyright=COPYING 66 | i pkginfo=pkginfo 67 | d none bin 0755 bin bin 68 | f none bin/rsync 0755 bin bin 69 | d none doc 0755 bin bin 70 | d none doc/$NAME 0755 bin bin 71 | f none doc/$NAME/README 0644 bin bin 72 | f none doc/$NAME/COPYING 0644 bin bin 73 | f none doc/$NAME/tech_report.pdf 0644 bin bin 74 | d none man 0755 bin bin 75 | d none man/man1 0755 bin bin 76 | f none man/man1/rsync.1 0644 bin bin 77 | d none man/man5 0755 bin bin 78 | f none man/man5/rsyncd.conf.5 0644 bin bin 79 | EOFPROTO 80 | 81 | ## And now build the package. 82 | OUTPUTFILE=$PKGNAME-$VERSION-sol8-$ARCH-local.pkg 83 | echo "Building package.." 84 | echo FAKE_ROOT = $FAKE_ROOT 85 | cd $FAKE_ROOT 86 | pkgmk -d . -r . -f ./prototype -o 87 | pkgtrans -os . $OUTPUTFILE $PKGNAME 88 | 89 | mv $OUTPUTFILE .. 90 | cd .. 91 | 92 | # Comment this out if you want to see, which file structure has been created 93 | rm -rf $FAKE_ROOT 94 | 95 | -------------------------------------------------------------------------------- /packaging/var-checker: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # This script checks the *.c files for extraneous "extern" variables, 3 | # for vars that are defined but not used, and for inconsistent array 4 | # sizes. Run it from inside the main rsync directory. 5 | 6 | use strict; 7 | use warnings; 8 | 9 | my %add_syscall_c = map { $_ => 1 } qw( t_stub.c t_unsafe.c tls.c trimslash.c ); 10 | my %add_compat_c = map { $_ => 1 } qw( t_stub.c tls.c trimslash.c wildtest.c ); 11 | my %add_util_c = map { $_ => 1 } qw( t_stub.c t_unsafe.c ); 12 | my %sizes; 13 | 14 | open(IN, '<', 'syscall.c') or die $!; 15 | undef $/; my $syscall_c = ; $/ = "\n"; 16 | close IN; 17 | $syscall_c =~ s/^extern\s.*//mg; 18 | 19 | open(IN, '<', 'lib/compat.c') or die $!; 20 | undef $/; my $compat_c = ; $/ = "\n"; 21 | close IN; 22 | $compat_c =~ s/^extern\s.*//mg; 23 | 24 | open(IN, '<', 'util.c') or die $!; 25 | undef $/; my $util_c = ; $/ = "\n"; 26 | close IN; 27 | $util_c =~ s/^extern\s.*//mg; 28 | 29 | my @files = glob('*.c'); 30 | 31 | foreach my $fn (@files) { 32 | open(IN, '<', $fn) or die $!; 33 | undef $/; $_ = ; $/ = "\n"; 34 | close IN; 35 | 36 | my @vars = /^(?!(?:extern|enum)\s)([a-zA-Z]\S*\s+.*);/mg; 37 | my @externs = /^extern\s+(.*);/mg; 38 | 39 | $_ .= $syscall_c if $add_syscall_c{$fn}; 40 | $_ .= $compat_c if $add_compat_c{$fn}; 41 | $_ .= $util_c if $add_util_c{$fn}; 42 | s/INFO_GTE/info_levels/g; 43 | s/DEBUG_GTE/debug_levels/g; 44 | 45 | check_vars($fn, 'var', @vars); 46 | check_vars($fn, 'extern', @externs); 47 | } 48 | 49 | exit; 50 | 51 | # The file's contents are in $_. 52 | sub check_vars 53 | { 54 | my $fn = shift; 55 | my $type = shift; 56 | 57 | foreach my $line (@_) { 58 | $line =~ s/\s*\{.*\}//; 59 | $line =~ s/\s*\(.*\)//; 60 | foreach my $item (split(/\s*,\s*/, $line)) { 61 | $item =~ s/\s*=.*//; 62 | my $sz = $item =~ s/(\[.*?\])// ? $1 : ''; 63 | my($var) = $item =~ /([^*\s]+)$/; 64 | if (!defined $var) { 65 | print "Bogus match? ($item)\n"; 66 | next; 67 | } 68 | if ($sz) { 69 | if (defined $sizes{$var}) { 70 | if ($sizes{$var} ne $sz) { 71 | print $fn, ' has inconsistent size for "', $var, 72 | "\": $sizes{$var} vs $sz\n"; 73 | } 74 | } else { 75 | $sizes{$var} = $sz; 76 | } 77 | } 78 | my @matches = /(? 1.6 2 | - add ability to perform callbacks for every, not just first, match. 3 | 4 | 1.3 -> 1.5 5 | - heavy dose of const's 6 | - poptParseArgvString() now NULL terminates the list 7 | 8 | 1.2.3 -> 1.3 9 | - added support for single - 10 | - misc bug fixes 11 | - portability improvements 12 | 13 | 1.2.2 -> 1.2.3 14 | - fixed memset() in help message generation (Dale Hawkins) 15 | - added extern "C" stuff to popt.h for C++ compilers (Dale Hawkins) 16 | - const'ified poptParseArgvString (Jeff Garzik) 17 | 18 | 1.2.1 -> 1.2.2 19 | - fixed bug in chaind alias happens which seems to have only 20 | affected --triggers in rpm 21 | - added POPT_ARG_VAL 22 | - popt.3 installed by default 23 | 24 | 1.2 -> 1.2.1 25 | - added POPT_ARG_INTL_DOMAIN (Elliot Lee) 26 | - updated Makefile's to be more GNUish (Elliot Lee) 27 | 28 | 1.1 -> 1.2 29 | - added popt.3 man page (Robert Lynch) 30 | - don't use mmap anymore (its lack of portability isn't worth the 31 | trouble) 32 | - added test script 33 | - added support for exec 34 | - removed support for *_POPT_ALIASES env variable -- it was a bad 35 | idea 36 | - reorganized into multiple source files 37 | - added automatic help generation, POPT_AUTOHELP 38 | - added table callbacks 39 | - added table inclusion 40 | - updated man page for new features 41 | - added test scripts 42 | 43 | 1.0 -> 1.1 44 | - moved to autoconf (Fred Fish) 45 | - added STRERROR replacement (Norbert Warmuth) 46 | - added const keywords (Bruce Perens) 47 | -------------------------------------------------------------------------------- /popt/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 1998 Red Hat Software 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 17 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | 20 | Except as contained in this notice, the name of the X Consortium shall not be 21 | used in advertising or otherwise to promote the sale, use or other dealings 22 | in this Software without prior written authorization from the X Consortium. 23 | -------------------------------------------------------------------------------- /popt/README: -------------------------------------------------------------------------------- 1 | This is the popt command line option parsing library. While it is similiar 2 | to getopt(3), it contains a number of enhancements, including: 3 | 4 | 1) popt is fully reentrant 5 | 2) popt can parse arbitrary argv[] style arrays while 6 | getopt(2) makes this quite difficult 7 | 3) popt allows users to alias command line arguments 8 | 4) popt provides convience functions for parsing strings 9 | into argv[] style arrays 10 | 11 | popt is used by rpm, the Red Hat install program, and many other Red Hat 12 | utilities, all of which provide excellent examples of how to use popt. 13 | Complete documentation on popt is available in popt.ps (included in this 14 | tarball), which is excerpted with permission from the book "Linux 15 | Application Development" by Michael K. Johnson and Erik Troan (availble 16 | from Addison Wesley in May, 1998). 17 | 18 | Comments on popt should be addressed to ewt@redhat.com. 19 | -------------------------------------------------------------------------------- /popt/README.rsync: -------------------------------------------------------------------------------- 1 | This is a perfectly ordinary copy of libpopt. It is only used on platforms 2 | that do not have a sufficiently up-to-date copy of their own. If you build 3 | rsync on a platform which has popt, this directory should not be used. (You 4 | can control that using the --with-included-popt configure flag.) 5 | -------------------------------------------------------------------------------- /popt/dummy.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AndyA/rsync/9d96ce6a626bda1cd5df866e66159e75782df6f5/popt/dummy.in -------------------------------------------------------------------------------- /popt/findme.c: -------------------------------------------------------------------------------- 1 | /** \ingroup popt 2 | * \file popt/findme.c 3 | */ 4 | 5 | /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING 6 | file accompanying popt source distributions, available from 7 | ftp://ftp.rpm.org/pub/rpm/dist. */ 8 | 9 | #include "system.h" 10 | #include "findme.h" 11 | 12 | const char * findProgramPath(const char * argv0) 13 | { 14 | char * path = getenv("PATH"); 15 | char * pathbuf; 16 | char * start, * chptr; 17 | char * buf; 18 | size_t bufsize; 19 | 20 | if (argv0 == NULL) return NULL; /* XXX can't happen */ 21 | /* If there is a / in the argv[0], it has to be an absolute path */ 22 | if (strchr(argv0, '/')) 23 | return xstrdup(argv0); 24 | 25 | if (path == NULL) return NULL; 26 | 27 | bufsize = strlen(path) + 1; 28 | start = pathbuf = alloca(bufsize); 29 | if (pathbuf == NULL) return NULL; /* XXX can't happen */ 30 | strlcpy(pathbuf, path, bufsize); 31 | bufsize += sizeof "/" - 1 + strlen(argv0); 32 | buf = malloc(bufsize); 33 | if (buf == NULL) return NULL; /* XXX can't happen */ 34 | 35 | chptr = NULL; 36 | /*@-branchstate@*/ 37 | do { 38 | if ((chptr = strchr(start, ':'))) 39 | *chptr = '\0'; 40 | snprintf(buf, bufsize, "%s/%s", start, argv0); 41 | 42 | if (!access(buf, X_OK)) 43 | return buf; 44 | 45 | if (chptr) 46 | start = chptr + 1; 47 | else 48 | start = NULL; 49 | } while (start && *start); 50 | /*@=branchstate@*/ 51 | 52 | free(buf); 53 | 54 | return NULL; 55 | } 56 | -------------------------------------------------------------------------------- /popt/findme.h: -------------------------------------------------------------------------------- 1 | /** \ingroup popt 2 | * \file popt/findme.h 3 | */ 4 | 5 | /* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING 6 | file accompanying popt source distributions, available from 7 | ftp://ftp.rpm.org/pub/rpm/dist. */ 8 | 9 | #ifndef H_FINDME 10 | #define H_FINDME 11 | 12 | /** 13 | * Return absolute path to executable by searching PATH. 14 | * @param argv0 name of executable 15 | * @return (malloc'd) absolute path to executable (or NULL) 16 | */ 17 | /*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0) 18 | /*@*/; 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /popt/poptconfig.c: -------------------------------------------------------------------------------- 1 | /** \ingroup popt 2 | * \file popt/poptconfig.c 3 | */ 4 | 5 | /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING 6 | file accompanying popt source distributions, available from 7 | ftp://ftp.rpm.org/pub/rpm/dist. */ 8 | 9 | #include "system.h" 10 | #include "poptint.h" 11 | /*@access poptContext @*/ 12 | 13 | /*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */ 14 | static void configLine(poptContext con, char * line) 15 | /*@modifies con @*/ 16 | { 17 | size_t nameLength; 18 | const char * entryType; 19 | const char * opt; 20 | poptItem item = (poptItem) alloca(sizeof(*item)); 21 | int i, j; 22 | 23 | if (con->appName == NULL) 24 | return; 25 | nameLength = strlen(con->appName); 26 | 27 | /*@-boundswrite@*/ 28 | memset(item, 0, sizeof(*item)); 29 | 30 | if (strncmp(line, con->appName, nameLength)) return; 31 | 32 | line += nameLength; 33 | if (*line == '\0' || !isSpace(line)) return; 34 | 35 | while (*line != '\0' && isSpace(line)) line++; 36 | entryType = line; 37 | while (*line == '\0' || !isSpace(line)) line++; 38 | *line++ = '\0'; 39 | 40 | while (*line != '\0' && isSpace(line)) line++; 41 | if (*line == '\0') return; 42 | opt = line; 43 | while (*line == '\0' || !isSpace(line)) line++; 44 | *line++ = '\0'; 45 | 46 | while (*line != '\0' && isSpace(line)) line++; 47 | if (*line == '\0') return; 48 | 49 | /*@-temptrans@*/ /* FIX: line alias is saved */ 50 | if (opt[0] == '-' && opt[1] == '-') 51 | item->option.longName = opt + 2; 52 | else if (opt[0] == '-' && opt[2] == '\0') 53 | item->option.shortName = opt[1]; 54 | /*@=temptrans@*/ 55 | 56 | if (poptParseArgvString(line, &item->argc, &item->argv)) return; 57 | 58 | /*@-modobserver@*/ 59 | item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN; 60 | for (i = 0, j = 0; i < item->argc; i++, j++) { 61 | const char * f; 62 | if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) { 63 | f = item->argv[i] + sizeof("--POPTdesc="); 64 | if (f[0] == '$' && f[1] == '"') f++; 65 | item->option.descrip = f; 66 | item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; 67 | j--; 68 | } else 69 | if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) { 70 | f = item->argv[i] + sizeof("--POPTargs="); 71 | if (f[0] == '$' && f[1] == '"') f++; 72 | item->option.argDescrip = f; 73 | item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN; 74 | item->option.argInfo |= POPT_ARG_STRING; 75 | j--; 76 | } else 77 | if (j != i) 78 | item->argv[j] = item->argv[i]; 79 | } 80 | if (j != i) { 81 | item->argv[j] = NULL; 82 | item->argc = j; 83 | } 84 | /*@=modobserver@*/ 85 | /*@=boundswrite@*/ 86 | 87 | /*@-nullstate@*/ /* FIX: item->argv[] may be NULL */ 88 | if (!strcmp(entryType, "alias")) 89 | (void) poptAddItem(con, item, 0); 90 | else if (!strcmp(entryType, "exec")) 91 | (void) poptAddItem(con, item, 1); 92 | /*@=nullstate@*/ 93 | } 94 | /*@=compmempass@*/ 95 | 96 | int poptReadConfigFile(poptContext con, const char * fn) 97 | { 98 | const char * file, * chptr, * end; 99 | char * buf; 100 | /*@dependent@*/ char * dst; 101 | int fd, rc; 102 | off_t fileLength; 103 | 104 | fd = open(fn, O_RDONLY); 105 | if (fd < 0) 106 | return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO); 107 | 108 | fileLength = lseek(fd, 0, SEEK_END); 109 | if (fileLength == -1 || lseek(fd, 0, 0) == -1) { 110 | rc = errno; 111 | (void) close(fd); 112 | errno = rc; 113 | return POPT_ERROR_ERRNO; 114 | } 115 | 116 | file = alloca(fileLength + 1); 117 | if (read(fd, (char *)file, fileLength) != fileLength) { 118 | rc = errno; 119 | (void) close(fd); 120 | errno = rc; 121 | return POPT_ERROR_ERRNO; 122 | } 123 | if (close(fd) == -1) 124 | return POPT_ERROR_ERRNO; 125 | 126 | /*@-boundswrite@*/ 127 | dst = buf = alloca(fileLength + 1); 128 | 129 | chptr = file; 130 | end = (file + fileLength); 131 | /*@-infloops@*/ /* LCL: can't detect chptr++ */ 132 | while (chptr < end) { 133 | switch (*chptr) { 134 | case '\n': 135 | *dst = '\0'; 136 | dst = buf; 137 | while (*dst && isSpace(dst)) dst++; 138 | if (*dst && *dst != '#') 139 | configLine(con, dst); 140 | chptr++; 141 | /*@switchbreak@*/ break; 142 | case '\\': 143 | *dst++ = *chptr++; 144 | if (chptr < end) { 145 | if (*chptr == '\n') 146 | dst--, chptr++; 147 | /* \ at the end of a line does not insert a \n */ 148 | else 149 | *dst++ = *chptr++; 150 | } 151 | /*@switchbreak@*/ break; 152 | default: 153 | *dst++ = *chptr++; 154 | /*@switchbreak@*/ break; 155 | } 156 | } 157 | /*@=infloops@*/ 158 | /*@=boundswrite@*/ 159 | 160 | return 0; 161 | } 162 | 163 | int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv)) 164 | { 165 | char * fn, * home; 166 | int rc; 167 | 168 | if (con->appName == NULL) return 0; 169 | 170 | rc = poptReadConfigFile(con, "/etc/popt"); 171 | if (rc) return rc; 172 | 173 | if ((home = getenv("HOME"))) { 174 | size_t bufsize = strlen(home) + 20; 175 | fn = alloca(bufsize); 176 | if (fn == NULL) return 0; 177 | snprintf(fn, bufsize, "%s/.popt", home); 178 | rc = poptReadConfigFile(con, fn); 179 | if (rc) return rc; 180 | } 181 | 182 | return 0; 183 | } 184 | -------------------------------------------------------------------------------- /popt/poptint.h: -------------------------------------------------------------------------------- 1 | /** \ingroup popt 2 | * \file popt/poptint.h 3 | */ 4 | 5 | /* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING 6 | file accompanying popt source distributions, available from 7 | ftp://ftp.rpm.org/pub/rpm/dist. */ 8 | 9 | #ifndef H_POPTINT 10 | #define H_POPTINT 11 | 12 | /** 13 | * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL. 14 | * @param p memory to free 15 | * @retval NULL always 16 | */ 17 | /*@unused@*/ static inline /*@null@*/ void * 18 | _free(/*@only@*/ /*@null@*/ const void * p) 19 | /*@modifies p @*/ 20 | { 21 | if (p != NULL) free((void *)p); 22 | return NULL; 23 | } 24 | 25 | static inline int 26 | isSpace(const char *ptr) 27 | { 28 | return isspace(*(unsigned char *)ptr); 29 | } 30 | 31 | /* Bit mask macros. */ 32 | /*@-exporttype -redef @*/ 33 | typedef unsigned int __pbm_bits; 34 | /*@=exporttype =redef @*/ 35 | #define __PBM_NBITS (8 * sizeof (__pbm_bits)) 36 | #define __PBM_IX(d) ((d) / __PBM_NBITS) 37 | #define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS)) 38 | /*@-exporttype -redef @*/ 39 | typedef struct { 40 | __pbm_bits bits[1]; 41 | } pbm_set; 42 | /*@=exporttype =redef @*/ 43 | #define __PBM_BITS(set) ((set)->bits) 44 | 45 | #define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits)) 46 | #define PBM_FREE(s) _free(s); 47 | #define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d)) 48 | #define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d)) 49 | #define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0) 50 | 51 | struct optionStackEntry { 52 | int argc; 53 | /*@only@*/ /*@null@*/ 54 | const char ** argv; 55 | /*@only@*/ /*@null@*/ 56 | pbm_set * argb; 57 | int next; 58 | /*@only@*/ /*@null@*/ 59 | const char * nextArg; 60 | /*@observer@*/ /*@null@*/ 61 | const char * nextCharArg; 62 | /*@dependent@*/ /*@null@*/ 63 | poptItem currAlias; 64 | int stuffed; 65 | }; 66 | 67 | struct poptContext_s { 68 | struct optionStackEntry optionStack[POPT_OPTION_DEPTH]; 69 | /*@dependent@*/ 70 | struct optionStackEntry * os; 71 | /*@owned@*/ /*@null@*/ 72 | const char ** leftovers; 73 | int numLeftovers; 74 | int nextLeftover; 75 | /*@keep@*/ 76 | const struct poptOption * options; 77 | int restLeftover; 78 | /*@only@*/ /*@null@*/ 79 | const char * appName; 80 | /*@only@*/ /*@null@*/ 81 | poptItem aliases; 82 | int numAliases; 83 | int flags; 84 | /*@owned@*/ /*@null@*/ 85 | poptItem execs; 86 | int numExecs; 87 | /*@only@*/ /*@null@*/ 88 | const char ** finalArgv; 89 | int finalArgvCount; 90 | int finalArgvAlloced; 91 | /*@dependent@*/ /*@null@*/ 92 | poptItem doExec; 93 | /*@only@*/ 94 | const char * execPath; 95 | int execAbsolute; 96 | /*@only@*/ /*@relnull@*/ 97 | const char * otherHelp; 98 | /*@null@*/ 99 | pbm_set * arg_strip; 100 | }; 101 | 102 | #ifdef HAVE_LIBINTL_H 103 | #include 104 | #endif 105 | 106 | #if defined(HAVE_GETTEXT) && !defined(__LCLINT__) 107 | #define _(foo) gettext(foo) 108 | #else 109 | #define _(foo) foo 110 | #endif 111 | 112 | #if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__) 113 | #define D_(dom, str) dgettext(dom, str) 114 | #define POPT_(foo) D_("popt", foo) 115 | #else 116 | #define D_(dom, str) str 117 | #define POPT_(foo) foo 118 | #endif 119 | 120 | #define N_(foo) foo 121 | 122 | #endif 123 | -------------------------------------------------------------------------------- /popt/system.h: -------------------------------------------------------------------------------- 1 | #ifdef HAVE_CONFIG_H 2 | #include "config.h" 3 | #endif 4 | 5 | #if defined (__GLIBC__) && defined(__LCLINT__) 6 | /*@-declundef@*/ 7 | /*@unchecked@*/ 8 | extern __const __int32_t *__ctype_tolower; 9 | /*@unchecked@*/ 10 | extern __const __int32_t *__ctype_toupper; 11 | /*@=declundef@*/ 12 | #endif 13 | 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #if HAVE_MCHECK_H 21 | #include 22 | #endif 23 | 24 | #include 25 | #ifdef HAVE_SYS_TYPES_H 26 | # include 27 | #endif 28 | #ifdef STDC_HEADERS 29 | # include 30 | # include 31 | #else 32 | # ifdef HAVE_STDLIB_H 33 | # include 34 | # endif 35 | #endif 36 | #ifdef HAVE_STRING_H 37 | # if !defined STDC_HEADERS && defined HAVE_MEMORY_H 38 | # include 39 | # endif 40 | # include 41 | #endif 42 | #ifdef HAVE_STRINGS_H 43 | # include 44 | #endif 45 | #ifdef HAVE_UNISTD_H 46 | # include 47 | #endif 48 | 49 | #ifndef __GNUC__ 50 | #define __attribute__(x) 51 | #endif 52 | 53 | #ifdef __NeXT 54 | /* access macros are not declared in non posix mode in unistd.h - 55 | don't try to use posix on NeXTstep 3.3 ! */ 56 | #include 57 | #endif 58 | 59 | #if defined(__LCLINT__) 60 | /*@-declundef -incondefs @*/ /* LCL: missing annotation */ 61 | /*@only@*/ /*@out@*/ 62 | void * alloca (size_t __size) 63 | /*@ensures MaxSet(result) == (__size - 1) @*/ 64 | /*@*/; 65 | /*@=declundef =incondefs @*/ 66 | #endif 67 | 68 | /* AIX requires this to be the first thing in the file. */ 69 | #ifndef __GNUC__ 70 | # if HAVE_ALLOCA_H 71 | # include 72 | # else 73 | # ifdef _AIX 74 | #pragma alloca 75 | # else 76 | # ifdef HAVE_ALLOCA 77 | # ifndef alloca /* predefined by HP cc +Olibcalls */ 78 | char *alloca(size_t size); 79 | # endif 80 | # else 81 | # ifdef alloca 82 | # undef alloca 83 | # endif 84 | # define alloca(sz) malloc(sz) /* Kludge this for now */ 85 | # endif 86 | # endif 87 | # endif 88 | #elif !defined(alloca) 89 | #define alloca __builtin_alloca 90 | #endif 91 | 92 | #ifndef HAVE_STRLCPY 93 | size_t strlcpy(char *d, const char *s, size_t bufsize); 94 | #endif 95 | 96 | #ifndef HAVE_STRLCAT 97 | size_t strlcat(char *d, const char *s, size_t bufsize); 98 | #endif 99 | 100 | #if HAVE_MCHECK_H && defined(__GNUC__) 101 | static inline char * 102 | xstrdup(const char *s) 103 | { 104 | size_t memsize = strlen(s) + 1; 105 | char *ptr = malloc(memsize); 106 | if (!ptr) { 107 | fprintf(stderr, "virtual memory exhausted.\n"); 108 | exit(EXIT_FAILURE); 109 | } 110 | strlcpy(ptr, s, memsize); 111 | return ptr; 112 | } 113 | #else 114 | #define xstrdup(_str) strdup(_str) 115 | #endif /* HAVE_MCHECK_H && defined(__GNUC__) */ 116 | 117 | #if HAVE___SECURE_GETENV && !defined(__LCLINT__) 118 | #define getenv(_s) __secure_getenv(_s) 119 | #endif 120 | 121 | #if !defined HAVE_SNPRINTF || !defined HAVE_C99_VSNPRINTF 122 | #define snprintf rsync_snprintf 123 | int snprintf(char *str,size_t count,const char *fmt,...); 124 | #endif 125 | 126 | #define UNUSED(x) x __attribute__((__unused__)) 127 | 128 | #define PACKAGE "rsync" 129 | 130 | #include "popt.h" 131 | -------------------------------------------------------------------------------- /prepare-source: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Either use autoconf and autoheader to create configure.sh and config.h.in 3 | # or (optionally) fetch the latest development versions of generated files. 4 | # 5 | # Specify one action or more than one to provide a fall-back: 6 | # 7 | # build build the config files [the default w/no arg] 8 | # fetch fetch the latest dev config files 9 | # fetchgen fetch all the latest dev generated files 10 | # fetchSRC fetch the latest dev source files [NON-GENERATED FILES] 11 | # 12 | # The script stops after the first successful action. 13 | 14 | dir=`dirname $0` 15 | if test x"$dir" != x -a x"$dir" != x.; then 16 | cd "$dir" 17 | fi 18 | 19 | if test $# = 0; then 20 | set -- build 21 | fi 22 | 23 | for action in "${@}"; do 24 | case "$action" in 25 | build|make) 26 | make -f prepare-source.mak 27 | ;; 28 | fetch) 29 | if perl --version >/dev/null 2>/dev/null; then 30 | files='c*' 31 | else 32 | files='[cp]*' 33 | fi 34 | rsync -pvz rsync://rsync.samba.org/rsyncftp/generated-files/"$files" . 35 | ;; 36 | fetchgen) 37 | rsync -pvz rsync://rsync.samba.org/rsyncftp/generated-files/'*' . 38 | ;; 39 | fetchSRC) 40 | rsync -pvrz --exclude=/.git/ rsync://rsync.samba.org/ftp/pub/unpacked/rsync/ . 41 | ;; 42 | *) 43 | echo "Unknown action: $action" 44 | exit 1 45 | esac 46 | if test $? = 0; then 47 | exit 48 | fi 49 | done 50 | 51 | exit 1 52 | -------------------------------------------------------------------------------- /prepare-source.mak: -------------------------------------------------------------------------------- 1 | conf: configure.sh config.h.in 2 | 3 | configure.sh: configure.ac aclocal.m4 4 | autoconf -o configure.sh 5 | 6 | config.h.in: configure.ac aclocal.m4 7 | autoheader && touch config.h.in 8 | -------------------------------------------------------------------------------- /rounding.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A pre-compilation helper program to aid in the creation of rounding.h. 3 | * 4 | * Copyright (C) 2007-2009 Wayne Davison 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License along 17 | * with this program; if not, visit the http://fsf.org website. 18 | */ 19 | 20 | #include "rsync.h" 21 | 22 | #define ARRAY_LEN (EXTRA_ROUNDING+1) 23 | #define SIZEOF(x) ((long int)sizeof (x)) 24 | 25 | struct test { 26 | union file_extras extras[ARRAY_LEN]; 27 | struct file_struct file; 28 | }; 29 | 30 | #define ACTUAL_SIZE SIZEOF(struct test) 31 | #define EXPECTED_SIZE (SIZEOF(union file_extras) * ARRAY_LEN + SIZEOF(struct file_struct)) 32 | 33 | int main(UNUSED(int argc), UNUSED(char *argv[])) 34 | { 35 | static int test_array[1 - 2 * (ACTUAL_SIZE != EXPECTED_SIZE)]; 36 | test_array[0] = 0; 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /rsyncsh.txt: -------------------------------------------------------------------------------- 1 | rsyncsh 2 | Copyright (C) 2001 by Martin Pool 3 | 4 | This is a quick hack to build an interactive shell around rsync, the 5 | same way we have the ftp, lftp and ncftp programs for the FTP 6 | protocol. The key application for this is connecting to a public 7 | rsync server, such as rsync.kernel.org, change down through and list 8 | directories, and finally pull down the file you want. 9 | 10 | rsync is somewhat ill-at-ease as an interactive operation, since every 11 | network connection is used to carry out exactly one operation. rsync 12 | kind of "forks across the network" passing the options and filenames 13 | to operate upon, and the connection is closed when the transfer is 14 | complete. (This might be fixed in the future, either by adapting the 15 | current protocol to allow chained operations over a single socket, or 16 | by writing a new protocol that better supports interactive use.) 17 | 18 | So, rsyncsh runs a new rsync command and opens a new socket for every 19 | (network-based) command you type. 20 | 21 | This has two consequences. Firstly, there is more command latency 22 | than is really desirable. More seriously, if the connection cannot be 23 | done automatically, because for example it uses SSH with a password, 24 | then you will need to enter the password every time. We might even 25 | fix this in the future, though, by having a way to automatically feed 26 | the password to SSH if it's entered once. 27 | -------------------------------------------------------------------------------- /shconfig.in: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # config.sh.in 4 | 5 | # This file is processed by config.status to produce config.status, 6 | # containing autoconf-determined values needed by the test scripts. 7 | 8 | ECHO_T="@ECHO_T@" 9 | ECHO_N="@ECHO_N@" 10 | ECHO_C="@ECHO_C@" 11 | 12 | export ECHO_T ECHO_N ECHO_C 13 | -------------------------------------------------------------------------------- /support/Makefile: -------------------------------------------------------------------------------- 1 | all: savetransfer 2 | 3 | savetransfer: savetransfer.o 4 | 5 | clean: 6 | rm -f *.o savetransfer 7 | -------------------------------------------------------------------------------- /support/atomic-rsync: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # This script lets you update a hierarchy of files in an atomic way by 4 | # first creating a new hierarchy using rsync's --link-dest option, and 5 | # then swapping the hierarchy into place. **See the usage message for 6 | # more details and some important caveats!** 7 | 8 | use strict; 9 | use warnings; 10 | use Cwd 'abs_path'; 11 | 12 | my $RSYNC_PROG = '/usr/bin/rsync'; 13 | my $RM_PROG = '/bin/rm'; 14 | 15 | my $dest_dir = $ARGV[-1]; 16 | &usage if !defined $dest_dir || $dest_dir =~ /(^-|^$)/ || grep(/^--help/, @ARGV); 17 | $dest_dir =~ s{(?<=.)/+$} {}; 18 | 19 | if (!-d $dest_dir) { 20 | die "$dest_dir is not a directory.\nUse --help for help.\n"; 21 | } 22 | 23 | if (@_ = grep(/^--[a-z]+-dest\b/, @ARGV)) { 24 | $_ = join(' or ', @_); 25 | die "You cannot use the $_ option with atomic-rsync.\nUse --help for help.\n"; 26 | } 27 | 28 | my $symlink_content = readlink $dest_dir; # undef when a real dir 29 | 30 | my $dest_arg = $dest_dir; 31 | # This gives us the real destination dir, with all symlinks dereferenced. 32 | $dest_dir = abs_path($dest_dir); 33 | if ($dest_dir eq '/') { 34 | die qq|You must not use "/" as the destination directory.\nUse --help for help.\n|; 35 | } 36 | 37 | my($old_dir, $new_dir); 38 | if (defined $symlink_content && $dest_dir =~ /-([12])$/) { 39 | my $num = 3 - $1; 40 | $old_dir = undef; 41 | ($new_dir = $dest_dir) =~ s/-[12]$/-$num/; 42 | $symlink_content =~ s/-[12]$/-$num/; 43 | } else { 44 | $old_dir = "$dest_dir~old~"; 45 | $new_dir = "$dest_dir~new~"; 46 | } 47 | 48 | $ARGV[-1] = "$new_dir/"; 49 | 50 | system($RM_PROG, '-rf', $old_dir) if defined $old_dir && -d $old_dir; 51 | system($RM_PROG, '-rf', $new_dir) if -d $new_dir; 52 | 53 | if (system($RSYNC_PROG, "--link-dest=$dest_dir", @ARGV)) { 54 | if ($? == -1) { 55 | print "failed to execute $RSYNC_PROG: $!\n"; 56 | } elsif ($? & 127) { 57 | printf "child died with signal %d, %s coredump\n", 58 | ($? & 127), ($? & 128) ? 'with' : 'without'; 59 | } else { 60 | printf "child exited with value %d\n", $? >> 8; 61 | } 62 | exit $?; 63 | } 64 | 65 | if (!defined $old_dir) { 66 | atomic_symlink($symlink_content, $dest_arg); 67 | exit; 68 | } 69 | 70 | rename($dest_dir, $old_dir) or die "Unable to rename $dest_dir to $old_dir: $!"; 71 | rename($new_dir, $dest_dir) or die "Unable to rename $new_dir to $dest_dir: $!"; 72 | 73 | exit; 74 | 75 | sub atomic_symlink 76 | { 77 | my($target, $link) = @_; 78 | my $newlink = "$link~new~"; 79 | 80 | unlink($newlink); # Just in case 81 | symlink($target, $newlink) or die "Unable to symlink $newlink -> $target: $!\n"; 82 | rename($newlink, $link) or die "Unable to rename $newlink to $link: $!\n"; 83 | } 84 | 85 | 86 | sub usage 87 | { 88 | die <) { 19 | chomp; 20 | s#^\./##; 21 | 22 | my $entries = "$_/Entries"; 23 | s/CVS$/.cvsinclude/; 24 | my $filter = $_; 25 | 26 | open(ENTRIES, $entries) or die "Unable to open $entries: $!\n"; 27 | my @includes; 28 | while () { 29 | push(@includes, $1) if m#/(.+?)/#; 30 | } 31 | close ENTRIES; 32 | if (@includes) { 33 | open(FILTER, ">$filter") or die "Unable to write $filter: $!\n"; 34 | print FILTER map "+ /$_\n", @includes; 35 | close FILTER; 36 | print "Updated $filter\n"; 37 | } elsif (-f $filter) { 38 | unlink($filter); 39 | print "Removed $filter\n"; 40 | } 41 | } 42 | close FIND; 43 | -------------------------------------------------------------------------------- /support/deny-rsync: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Send an error message via the rsync-protocol to a non-daemon client rsync. 3 | # 4 | # Usage: deny-rsync "message" 5 | 6 | protocol_version=29 7 | exit_code=4 # same as a daemon that refuses an option 8 | 9 | # e.g. byte_escape 29 => \035 10 | function byte_escape { 11 | echo -ne "\\0$(printf "%o" $1)" 12 | } 13 | 14 | msg="$1" 15 | if [ "${#msg}" -gt 254 ]; then 16 | # truncate a message that is too long for this naive script to handle 17 | msg="${msg:0:251}..." 18 | fi 19 | msglen=$(( ${#msg} + 1 )) # add 1 for the newline we append below 20 | 21 | # Send protocol version. All numbers are LSB-first 4-byte ints. 22 | echo -ne "$(byte_escape $protocol_version)\\000\\000\\000" 23 | 24 | # Send a zero checksum seed. 25 | echo -ne "\\000\\000\\000\\000" 26 | 27 | # The following is equivalent to rprintf(FERROR_XFER, "%s\n", $msg). 28 | # 1. Message header: ((MPLEX_BASE + FERROR_XFER) << 24) + $msglen. 29 | echo -ne "$(byte_escape $msglen)\\000\\000\\010" 30 | # 2. The actual data. 31 | echo -E "$msg" 32 | 33 | # Make sure the client gets our message, not a write failure. 34 | sleep 1 35 | 36 | exit $exit_code 37 | -------------------------------------------------------------------------------- /support/file-attr-restore: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # This script will parse the output of "find ARG [ARG...] -ls" and 3 | # apply (at your discretion) the permissions, owner, and group info 4 | # it reads onto any existing files and dirs (it doesn't try to affect 5 | # symlinks). Run this with --help (-h) for a usage summary. 6 | 7 | use strict; 8 | use Getopt::Long; 9 | 10 | our($p_opt, $o_opt, $g_opt, $map_file, $dry_run, $verbosity, $help_opt); 11 | 12 | &Getopt::Long::Configure('bundling'); 13 | &usage if !&GetOptions( 14 | 'all|a' => sub { $p_opt = $o_opt = $g_opt = 1 }, 15 | 'perms|p' => \$p_opt, 16 | 'owner|o' => \$o_opt, 17 | 'groups|g' => \$g_opt, 18 | 'map|m=s' => \$map_file, 19 | 'dry-run|n' => \$dry_run, 20 | 'help|h' => \$help_opt, 21 | 'verbose|v+' => \$verbosity, 22 | ) || $help_opt; 23 | 24 | our(%uid_hash, %gid_hash); 25 | 26 | $" = ', '; # How to join arrays referenced in double-quotes. 27 | 28 | &parse_map_file($map_file) if defined $map_file; 29 | 30 | my $detail_line = qr{ 31 | ^ \s* \d+ \s+ # ignore inode 32 | \d+ \s+ # ignore size 33 | ([-bcdlps]) # 1. File type 34 | ( [-r][-w][-xsS] # 2. user-permissions 35 | [-r][-w][-xsS] # group-permissions 36 | [-r][-w][-xtT] ) \s+ # other-permissions 37 | \d+ \s+ # ignore number of links 38 | (\S+) \s+ # 3. owner 39 | (\S+) \s+ # 4. group 40 | (?: \d+ \s+ )? # ignore size (when present) 41 | \w+ \s+ \d+ \s+ # ignore month and date 42 | \d+ (?: : \d+ )? \s+ # ignore time or year 43 | ([^\r\n]+) $ # 5. name 44 | }x; 45 | 46 | while (<>) { 47 | my($type, $perms, $owner, $group, $name) = /$detail_line/; 48 | die "Invalid input line $.:\n$_" unless defined $name; 49 | die "A filename is not properly escaped:\n$_" unless $name =~ /^[^"\\]*(\\(\d\d\d|\D)[^"\\]*)*$/; 50 | my $fn = $name; 51 | $fn =~ s/\\(\d+|.)/ eval "\"\\$1\"" /eg; 52 | if ($type eq '-') { 53 | undef $type unless -f $fn; 54 | } elsif ($type eq 'd') { 55 | undef $type unless -d $fn; 56 | } elsif ($type eq 'b') { 57 | undef $type unless -b $fn; 58 | } elsif ($type eq 'c') { 59 | undef $type unless -c $fn; 60 | } elsif ($type eq 'p') { 61 | undef $type unless -p $fn; 62 | } elsif ($type eq 's') { 63 | undef $type unless -S $fn; 64 | } else { 65 | if ($verbosity) { 66 | if ($type eq 'l') { 67 | $name =~ s/ -> .*//; 68 | $type = 'symlink'; 69 | } else { 70 | $type = "type '$type'"; 71 | } 72 | print "Skipping $name ($type ignored)\n"; 73 | } 74 | next; 75 | } 76 | if (!defined $type) { 77 | my $reason = -e _ ? "types don't match" : 'missing'; 78 | print "Skipping $name ($reason)\n"; 79 | next; 80 | } 81 | my($cur_mode, $cur_uid, $cur_gid) = (stat(_))[2,4,5]; 82 | $cur_mode &= 07777; 83 | my $highs = join('', $perms =~ /..(.)..(.)..(.)/); 84 | $highs =~ tr/-rwxSTst/00001111/; 85 | $perms =~ tr/-STrwxst/00011111/; 86 | my $mode = $p_opt ? oct('0b' . $highs . $perms) : $cur_mode; 87 | my $uid = $o_opt ? $uid_hash{$owner} : $cur_uid; 88 | if (!defined $uid) { 89 | if ($owner =~ /^\d+$/) { 90 | $uid = $owner; 91 | } else { 92 | $uid = getpwnam($owner); 93 | } 94 | $uid_hash{$owner} = $uid; 95 | } 96 | my $gid = $g_opt ? $gid_hash{$group} : $cur_gid; 97 | if (!defined $gid) { 98 | if ($group =~ /^\d+$/) { 99 | $gid = $group; 100 | } else { 101 | $gid = getgrnam($group); 102 | } 103 | $gid_hash{$group} = $gid; 104 | } 105 | 106 | my @changes; 107 | if ($mode != $cur_mode) { 108 | push(@changes, 'permissions'); 109 | if (!$dry_run && !chmod($mode, $fn)) { 110 | warn "chmod($mode, \"$name\") failed: $!\n"; 111 | } 112 | } 113 | if ($uid != $cur_uid || $gid != $cur_gid) { 114 | push(@changes, 'owner') if $uid != $cur_uid; 115 | push(@changes, 'group') if $gid != $cur_gid; 116 | if (!$dry_run) { 117 | if (!chown($uid, $gid, $fn)) { 118 | warn "chown($uid, $gid, \"$name\") failed: $!\n"; 119 | } 120 | if (($mode & 06000) && !chmod($mode, $fn)) { 121 | warn "post-chown chmod($mode, \"$name\") failed: $!\n"; 122 | } 123 | } 124 | } 125 | if (@changes) { 126 | print "$name: changed @changes\n"; 127 | } elsif ($verbosity) { 128 | print "$name: OK\n"; 129 | } 130 | } 131 | exit; 132 | 133 | sub parse_map_file 134 | { 135 | my($fn) = @_; 136 | open(IN, $fn) or die "Unable to open $fn: $!\n"; 137 | while () { 138 | if (/^user\s+(\S+)\s+(\S+)/) { 139 | $uid_hash{$1} = $2; 140 | } elsif (/^group\s+(\S+)\s+(\S+)/) { 141 | $gid_hash{$1} = $2; 142 | } else { 143 | die "Invalid line #$. in mapfile `$fn':\n$_"; 144 | } 145 | } 146 | close IN; 147 | } 148 | 149 | sub usage 150 | { 151 | die <) { 10 | chomp; 11 | s#^/+##; 12 | my $path = '/'; 13 | while (m#([^/]+/)/*#g) { 14 | $path .= $1; 15 | print "+ $path\n" unless $hash{$path}++; 16 | } 17 | if (m#([^/]+)$#) { 18 | print "+ $path$1\n"; 19 | } else { 20 | delete $hash{$path}; 21 | } 22 | } 23 | 24 | foreach (sort keys %hash) { 25 | print "- $_*\n"; 26 | } 27 | print "- /*\n"; 28 | -------------------------------------------------------------------------------- /support/git-set-file-times: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use warnings; 4 | 5 | # Sets mtime and atime of files to the latest commit time in git. 6 | # 7 | # This is useful after the first clone of the rsync repository BEFORE you 8 | # do any building. It is also safe if you have done a "make distclean". 9 | 10 | my %ls; 11 | my $commit_time; 12 | my $prefix = @ARGV && $ARGV[0] =~ s/^--prefix=// ? shift : ''; 13 | 14 | $/ = "\0"; 15 | open FH, 'git ls-files -z|' or die $!; 16 | while () { 17 | chomp; 18 | $ls{$_} = $_; 19 | } 20 | close FH; 21 | 22 | $/ = "\n"; 23 | open FH, "git log -r --name-only --no-color --pretty=raw -z @ARGV |" or die $!; 24 | while () { 25 | chomp; 26 | if (/^committer .*? (\d+) (?:[\-\+]\d+)$/) { 27 | $commit_time = $1; 28 | } elsif (s/\0\0commit [a-f0-9]{40}$// or s/\0$//) { 29 | my @files = delete @ls{split(/\0/, $_)}; 30 | @files = grep { defined $_ } @files; 31 | next unless @files; 32 | map { s/^/$prefix/ } @files; 33 | utime $commit_time, $commit_time, @files; 34 | } 35 | last unless %ls; 36 | } 37 | close FH; 38 | -------------------------------------------------------------------------------- /support/instant-rsyncd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # instant-rsyncd lets you quickly set up and start a simple, unprivileged rsync 4 | # daemon with a single module in the current directory. I've found it 5 | # invaluable for quick testing, and I use it when writing a list of commands 6 | # that people can paste into a terminal to reproduce a daemon-related bug. 7 | # Sysadmins deploying an rsync daemon for the first time may find it helpful as 8 | # a starting point. 9 | # 10 | # Usage: instant-rsyncd MODULE PORT RSYNCD-USERNAME [RSYNC-PATH] 11 | # The script asks for the rsyncd user's password twice on stdin, once to set it 12 | # and once to log in to test the daemon. 13 | # -- Matt McCutchen 14 | 15 | set -e 16 | 17 | dir="$(pwd)" 18 | 19 | echo 20 | echo "This will setup an rsync daemon in $dir" 21 | 22 | if [ $# = 0 ]; then 23 | IFS='' read -p 'Module name to create (or return to exit): ' module 24 | [ ! "$module" ] && exit 25 | else 26 | module="$1" 27 | shift 28 | fi 29 | 30 | if [ $# = 0 ]; then 31 | IFS='' read -p 'Port number the daemon should listen on [873]: ' port 32 | else 33 | port="$1" 34 | shift 35 | fi 36 | [ "$port" ] || port=873 37 | 38 | if [ $# = 0 ]; then 39 | IFS='' read -p 'User name for authentication (empty for none): ' user 40 | else 41 | user="$1" 42 | shift 43 | fi 44 | 45 | if [ "$user" ]; then 46 | IFS='' read -s -p 'Desired password: ' password 47 | echo 48 | fi 49 | 50 | rsync="$1" 51 | [ "$rsync" ] || rsync=rsync 52 | 53 | moduledir="${dir%/}/$module" 54 | 55 | mkdir "$module" 56 | 57 | cat >rsyncd.conf <>rsyncd.conf <<-EOF 70 | auth users = $user 71 | secrets file = $module.secrets 72 | EOF 73 | touch "$module".secrets 74 | chmod go-rwx "$module".secrets 75 | echo "$user:$password" >"$module".secrets 76 | user="$user@" 77 | fi 78 | 79 | cat >start <stop <<"EOF" 92 | #!/bin/bash 93 | set -e 94 | cd `dirname $0` 95 | ! [ -e rsyncd.pid ] || kill -s SIGTERM $(< rsyncd.pid) 96 | EOF 97 | chmod +x stop 98 | 99 | path="rsync://$user$(hostname):$port/$module/" 100 | 101 | if ./start; then 102 | sleep .2 103 | echo 104 | echo "I ran the start command for the daemon. The log file rsyncd.log says:" 105 | echo 106 | cat rsyncd.log 107 | echo 108 | echo "You can start and stop it with ./start and ./stop respectively." 109 | echo "You can customize the configuration file rsyncd.conf." 110 | echo 111 | echo "Give rsync the following path to access the module:" 112 | echo " $path" 113 | echo 114 | if [ "$user" ]; then 115 | echo "Let's test the daemon now. Enter the password you chose at the prompt." 116 | else 117 | echo "Let's test the daemon now." 118 | fi 119 | echo 120 | echo '$' $rsync --list-only "$path" 121 | $rsync --list-only "$path" 122 | echo 123 | echo "You should see an empty folder; it's $moduledir." 124 | else 125 | echo "Something went wrong. Do you see an error message?" 126 | fi 127 | -------------------------------------------------------------------------------- /support/logfilter: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # Filter the rsync daemon log messages by module name. The log file can be 3 | # in either syslog format or rsync's own log-file format. Note that the 4 | # MODULE_NAME parameter is used in a regular-expression match in order to 5 | # allow regex wildcards to be used. You can also limit the output by 6 | # directory hierarchy in a module. Examples: 7 | # 8 | # logfilter foo /var/log/rsyncd.log # output lines for module foo 9 | # logfilter foo/dir /var/log/syslog # limit lines to those in dir of foo 10 | 11 | use strict; 12 | 13 | my $match = shift; 14 | die "Usage: logfilter MODULE_NAME [LOGFILE ...]\n" unless defined $match; 15 | 16 | my $syslog_prefix = '\w\w\w +\d+ \d\d:\d\d:\d\d \S+ rsyncd'; 17 | my $rsyncd_prefix = '\d\d\d\d/\d\d/\d\d \d\d:\d\d:\d\d '; 18 | 19 | my %pids; 20 | 21 | while (<>) { 22 | my($pid,$msg) = /^(?:$syslog_prefix|$rsyncd_prefix)\[(\d+)\]:? (.*)/o; 23 | next unless defined $pid; 24 | my($mod_spec) = $msg =~ /^rsync (?:on|to) (\S+) from /; 25 | if (defined $mod_spec) { 26 | if ($mod_spec =~ /^$match(\/\S*)?$/o) { 27 | $pids{$pid} = 1; 28 | } else { 29 | delete $pids{$pid}; 30 | } 31 | } 32 | next unless $pids{$pid}; 33 | print $_; 34 | } 35 | -------------------------------------------------------------------------------- /support/lsh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # This script can be used as a "remote shell" command that is only 3 | # capable of pretending to connect to "localhost". This is useful 4 | # for testing or for running a local copy where the sender and the 5 | # receiver needs to use different options (e.g. --fake-super). If 6 | # we get a -l USER option, we try to use "sudo -u USER" to run the 7 | # command. 8 | 9 | user='' 10 | prefix='' 11 | do_cd=y # Default path is user's home dir, just like ssh. 12 | 13 | while : ; do 14 | case "$1" in 15 | -l) user="$2"; shift; shift ;; 16 | -l*) user=`echo "$1" | sed 's/^-l//'`; shift ;; 17 | --no-cd) do_cd=n; shift ;; 18 | -*) shift ;; 19 | localhost) shift; break ;; 20 | *) echo "lsh: unable to connect to host $1" 1>&2; exit 1 ;; 21 | esac 22 | done 23 | 24 | if [ "$user" ]; then 25 | prefix="sudo -H -u '$user'" 26 | if [ $do_cd = y ]; then 27 | home=`perl -e "print((getpwnam('$user'))[7])"` 28 | # Yeah, this may fail, but attempts to get sudo to cd are harder. 29 | cd $home 30 | fi 31 | elif [ $do_cd = y ]; then 32 | cd 33 | fi 34 | 35 | eval $prefix "${@}" 36 | -------------------------------------------------------------------------------- /support/mapfrom: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # This helper script makes it easy to use a passwd or group file to map 3 | # values in a LOCAL transfer. For instance, if you mount a backup that 4 | # does not have the same passwd setup as the local machine, you can do 5 | # a copy FROM the backup area as follows and get the differing ID values 6 | # mapped just like a remote transfer FROM the backed-up machine would do: 7 | # 8 | # rsync -av --usermap=`mapfrom /mnt/backup/etc/passwd` \ 9 | # --groupmap=`mapfrom /mnt/backup/etc/group` \ 10 | # /mnt/backup/some/src/ /some/dest/ 11 | 12 | while (<>) { 13 | push @_, "$2:$1" if /^(\w+):[^:]+:(\d+)/; 14 | } 15 | print join(',', @_), "\n"; 16 | -------------------------------------------------------------------------------- /support/mapto: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # This helper script makes it easy to use a passwd or group file to map 3 | # values in a LOCAL transfer. For instance, if you mount a backup that 4 | # does not have the same passwd setup as the local machine, you can do 5 | # a copy TO the backup area as follows and get the differing ID values 6 | # mapped just like a remote transfer TO the backed-up machine would do: 7 | # 8 | # rsync -av --usermap=`mapto /mnt/backup/etc/passwd` \ 9 | # --groupmap=`mapto /mnt/backup/etc/group` \ 10 | # /some/src/ /mnt/backup/some/dest/ 11 | 12 | while (<>) { 13 | push @_, "$1:$2" if /^(\w+):[^:]+:(\d+)/; 14 | } 15 | print join(',', @_), "\n"; 16 | -------------------------------------------------------------------------------- /support/mnt-excl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # This script takes a command-line arg of a source directory 3 | # that will be passed to rsync, and generates a set of excludes 4 | # that will exclude all mount points from the list. This is 5 | # useful if you have "bind" mounts since the --one-file-system 6 | # option won't notice the transition to a different spot on 7 | # the same disk. For example: 8 | # 9 | # mnt-excl /dir | rsync --exclude-from=- ... /dir /dest/ 10 | # mnt-excl /dir/ | rsync --exclude-from=- ... /dir/ /dest/ 11 | # ssh host mnt-excl /dir | rsync --exclude-from=- ... host:/dir /dest/ 12 | # 13 | # Imagine that /dir/foo is a mount point: the first invocation of 14 | # mnt-excl would have output /dir/foo, while the second would have 15 | # output /foo (which are the properly anchored excludes). 16 | # 17 | # NOTE: This script expects /proc/mounts to exist, but could be 18 | # easily adapted to read /etc/mtab or similar. 19 | # 20 | # ADDENDUM: The addition of the --filter option (which has support for 21 | # absolute-anchored excludes) can make this screen unneeded in some 22 | # scenarios. If you don't need delete protection on the receiving side 23 | # (or if the destination path is identical to the source path), then you 24 | # can exclude some absolute paths from the transfer based on the mount 25 | # dirs. For instance: 26 | # 27 | # awk '{print $2}' /proc/mounts | grep -v '^/$' | \ 28 | # rsync -avf 'merge,/- -' /dir host:/dest/ 29 | 30 | use strict; 31 | use warnings; 32 | use Cwd 'abs_path'; 33 | 34 | my $file = '/proc/mounts'; 35 | my $dir = shift || '/'; 36 | my $trailing_slash = $dir =~ m{./$} ? '/' : ''; 37 | $dir = abs_path($dir) . $trailing_slash; 38 | $dir =~ s{([^/]*)$}{}; 39 | my $trailing = $1; 40 | $trailing = '' if $trailing eq '.' || !-d "$dir$trailing"; 41 | $trailing .= '/' if $trailing ne ''; 42 | 43 | open(IN, $file) or die "Unable to open $file: $!\n"; 44 | while () { 45 | $_ = (split)[1]; 46 | next unless s{^\Q$dir$trailing\E}{}o && $_ ne ''; 47 | print "- /$trailing$_\n"; 48 | } 49 | close IN; 50 | -------------------------------------------------------------------------------- /support/munge-symlinks: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # This script will either prefix all symlink values with the string 3 | # "/rsyncd-munged/" or remove that prefix. 4 | 5 | use strict; 6 | use Getopt::Long; 7 | 8 | my $SYMLINK_PREFIX = '/rsyncd-munged/'; 9 | 10 | my $munge_opt; 11 | 12 | &GetOptions( 13 | 'munge' => sub { $munge_opt = 1 }, 14 | 'unmunge' => sub { $munge_opt = 0 }, 15 | 'all' => \( my $all_opt ), 16 | 'help|h' => \( my $help_opt ), 17 | ) or &usage; 18 | 19 | &usage if $help_opt || !defined $munge_opt; 20 | 21 | my $munged_re = $all_opt ? qr/^($SYMLINK_PREFIX)+(?=.)/ : qr/^$SYMLINK_PREFIX(?=.)/; 22 | 23 | push(@ARGV, '.') unless @ARGV; 24 | 25 | open(PIPE, '-|', 'find', @ARGV, '-type', 'l') or die $!; 26 | 27 | while () { 28 | chomp; 29 | my $lnk = readlink($_) or next; 30 | if ($munge_opt) { 31 | next if !$all_opt && $lnk =~ /$munged_re/; 32 | $lnk =~ s/^/$SYMLINK_PREFIX/; 33 | } else { 34 | next unless $lnk =~ s/$munged_re//; 35 | } 36 | if (!unlink($_)) { 37 | warn "Unable to unlink symlink: $_ ($!)\n"; 38 | } elsif (!symlink($lnk, $_)) { 39 | warn "Unable to recreate symlink: $_ -> $lnk ($!)\n"; 40 | } else { 41 | print "$_ -> $lnk\n"; 42 | } 43 | } 44 | 45 | close PIPE; 46 | exit; 47 | 48 | sub usage 49 | { 50 | die < 6 | * Copyright (C) 2003-2009 Wayne Davison 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 3 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | * GNU General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License along 19 | * with this program; if not, visit the http://fsf.org website. 20 | */ 21 | 22 | #include "rsync.h" 23 | 24 | int modify_window = 0; 25 | int module_id = -1; 26 | int relative_paths = 0; 27 | int module_dirlen = 0; 28 | int preserve_times = 0; 29 | int preserve_xattrs = 0; 30 | char number_separator = ','; 31 | char *partial_dir; 32 | char *module_dir; 33 | filter_rule_list daemon_filter_list; 34 | 35 | void rprintf(UNUSED(enum logcode code), const char *format, ...) 36 | { 37 | va_list ap; 38 | va_start(ap, format); 39 | vfprintf(stderr, format, ap); 40 | va_end(ap); 41 | } 42 | 43 | void rsyserr(UNUSED(enum logcode code), int errcode, const char *format, ...) 44 | { 45 | va_list ap; 46 | fputs(RSYNC_NAME ": ", stderr); 47 | va_start(ap, format); 48 | vfprintf(stderr, format, ap); 49 | va_end(ap); 50 | fprintf(stderr, ": %s (%d)\n", strerror(errcode), errcode); 51 | } 52 | 53 | void _exit_cleanup(int code, const char *file, int line) 54 | { 55 | fprintf(stderr, "exit(%d): %s(%d)\n", 56 | code, file, line); 57 | exit(code); 58 | } 59 | 60 | int check_filter(UNUSED(filter_rule_list *listp), UNUSED(enum logcode code), 61 | UNUSED(const char *name), UNUSED(int name_is_dir)) 62 | { 63 | /* This function doesn't really get called in this test context, so 64 | * just return 0. */ 65 | return 0; 66 | } 67 | 68 | int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest)) 69 | { 70 | return -1; 71 | } 72 | 73 | char *lp_name(UNUSED(int mod)) 74 | { 75 | return NULL; 76 | } 77 | 78 | BOOL lp_use_chroot(UNUSED(int mod)) 79 | { 80 | return 0; 81 | } 82 | 83 | const char *who_am_i(void) 84 | { 85 | return "tester"; 86 | } 87 | -------------------------------------------------------------------------------- /t_unsafe.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Test harness for unsafe_symlink(). Not linked into rsync itself. 3 | * 4 | * Copyright (C) 2002 Martin Pool 5 | * Copyright (C) 2003-2009 Wayne Davison 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License along 18 | * with this program; if not, visit the http://fsf.org website. 19 | */ 20 | 21 | /* Prints either "safe" or "unsafe" depending on the two arguments. 22 | * Always returns 0 unless something extraordinary happens. */ 23 | 24 | #include "rsync.h" 25 | 26 | int dry_run = 0; 27 | int am_root = 0; 28 | int am_sender = 1; 29 | int read_only = 0; 30 | int list_only = 0; 31 | int human_readable = 0; 32 | int preserve_perms = 0; 33 | int preserve_executability = 0; 34 | short info_levels[COUNT_INFO], debug_levels[COUNT_DEBUG]; 35 | 36 | int 37 | main(int argc, char **argv) 38 | { 39 | if (argc != 3) { 40 | fprintf(stderr, "usage: t_unsafe LINKDEST SRCDIR\n"); 41 | return 1; 42 | } 43 | 44 | printf("%s\n", 45 | unsafe_symlink(argv[1], argv[2]) ? "unsafe" : "safe"); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /testhelp/maketree.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python2.2 2 | 3 | # Copyright (C) 2002 by Martin Pool 4 | 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License version 7 | # 2 as published by the Free Software Foundation. 8 | # 9 | # This program is distributed in the hope that it will be useful, but 10 | # WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 | 18 | # Populate a tree with pseudo-randomly distributed files to test 19 | # rsync. 20 | 21 | from __future__ import generators 22 | import random, string, os, os.path 23 | 24 | nfiles = 10000 25 | depth = 5 26 | n_children = 20 27 | n_files = 20 28 | n_symlinks = 10 29 | 30 | name_chars = string.digits + string.letters 31 | 32 | abuffer = 'a' * 1024 33 | 34 | def random_name_chars(): 35 | a = "" 36 | for i in range(10): 37 | a = a + random.choice(name_chars) 38 | return a 39 | 40 | 41 | def generate_names(): 42 | n = 0 43 | while 1: 44 | yield "%05d_%s" % (n, random_name_chars()) 45 | n += 1 46 | 47 | 48 | class TreeBuilder: 49 | def __init__(self): 50 | self.n_children = 20 51 | self.n_files = 100 52 | self.total_entries = 100000 # long(1e8) 53 | self.actual_size = 0 54 | self.name_gen = generate_names() 55 | self.all_files = [] 56 | self.all_dirs = [] 57 | self.all_symlinks = [] 58 | 59 | 60 | def random_size(self): 61 | return random.lognormvariate(4, 4) 62 | 63 | 64 | def random_symlink_target(self): 65 | what = random.choice(['directory', 'file', 'symlink', 'none']) 66 | try: 67 | if what == 'directory': 68 | return random.choice(self.all_dirs) 69 | elif what == 'file': 70 | return random.choice(self.all_files) 71 | elif what == 'symlink': 72 | return random.choice(self.all_symlinks) 73 | elif what == 'none': 74 | return self.name_gen.next() 75 | except IndexError: 76 | return self.name_gen.next() 77 | 78 | 79 | def can_continue(self): 80 | self.total_entries -= 1 81 | return self.total_entries > 0 82 | 83 | 84 | def build_tree(self, prefix, depth): 85 | """Generate a breadth-first tree""" 86 | for count, function in [[n_files, self.make_file], 87 | [n_children, self.make_child_recurse], 88 | [n_symlinks, self.make_symlink]]: 89 | for i in range(count): 90 | if not self.can_continue(): 91 | return 92 | name = os.path.join(prefix, self.name_gen.next()) 93 | function(name, depth) 94 | 95 | 96 | def print_summary(self): 97 | print "total bytes: %d" % self.actual_size 98 | 99 | 100 | def make_child_recurse(self, dname, depth): 101 | if depth > 1: 102 | self.make_dir(dname) 103 | self.build_tree(dname, depth-1) 104 | 105 | 106 | def make_dir(self, dname, depth='ignore'): 107 | print "%s/" % (dname) 108 | os.mkdir(dname) 109 | self.all_dirs.append(dname) 110 | 111 | 112 | def make_symlink(self, lname, depth='ignore'): 113 | print "%s -> %s" % (lname, self.random_symlink_target()) 114 | 115 | 116 | def make_file(self, fname, depth='ignore'): 117 | size = long(self.random_size()) 118 | print "%-70s %d" % (fname, size) 119 | f = open(fname, 'w') 120 | f.truncate(size) 121 | self.fill_file(f, size) 122 | self.all_files.append(fname) 123 | self.actual_size += size 124 | 125 | def fill_file(self, f, size): 126 | while size > 0: 127 | f.write(abuffer[:size]) 128 | size -= len(abuffer) 129 | 130 | 131 | tb = TreeBuilder() 132 | tb.build_tree('/tmp/foo', 3) 133 | tb.print_summary() 134 | -------------------------------------------------------------------------------- /testrun.c: -------------------------------------------------------------------------------- 1 | /* Run a testsuite script with a timeout. */ 2 | 3 | #include "rsync.h" 4 | 5 | #define DEFAULT_TIMEOUT_SECS (5*60) 6 | #define TIMEOUT_ENV "TESTRUN_TIMEOUT" 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | pid_t pid; 11 | char *timeout_env; 12 | int status, timeout_secs, slept = 0; 13 | 14 | if (argc < 2) { 15 | fprintf(stderr, "Usage: testrun [SHELL_OPTIONS] TESTSUITE_SCRIPT [ARGS]\n"); 16 | exit(1); 17 | } 18 | 19 | if ((timeout_env = getenv(TIMEOUT_ENV)) != NULL) 20 | timeout_secs = atoi(timeout_env); 21 | else 22 | timeout_secs = DEFAULT_TIMEOUT_SECS; 23 | 24 | if ((pid = fork()) < 0) { 25 | fprintf(stderr, "TESTRUN ERROR: fork failed: %s\n", strerror(errno)); 26 | exit(1); 27 | } 28 | 29 | if (pid == 0) { 30 | argv[0] = "sh"; 31 | execvp(argv[0], argv); 32 | fprintf(stderr, "TESTRUN ERROR: failed to exec %s: %s\n", argv[0], strerror(errno)); 33 | _exit(1); 34 | } 35 | 36 | while (1) { 37 | int ret = waitpid(pid, &status, WNOHANG); 38 | if (ret > 0) 39 | break; 40 | if (ret < 0) { 41 | if (errno == EINTR) 42 | continue; 43 | fprintf(stderr, "TESTRUN ERROR: waitpid failed: %s\n", strerror(errno)); 44 | exit(1); 45 | } 46 | if (slept++ > timeout_secs) { 47 | fprintf(stderr, "TESTRUN TIMEOUT: test took over %d seconds.\n", timeout_secs); 48 | if (kill(pid, SIGTERM) < 0) 49 | fprintf(stderr, "TESTRUN ERROR: failed to kill pid %ld: %s\n", (long)pid, strerror(errno)); 50 | else 51 | fprintf(stderr, "TESTRUN INFO: killed pid %ld\n", (long)pid); 52 | exit(1); 53 | } 54 | sleep(1); 55 | } 56 | 57 | if (!WIFEXITED(status)) 58 | exit(255); 59 | 60 | return WEXITSTATUS(status); 61 | } 62 | -------------------------------------------------------------------------------- /testsuite/00-hello.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | test_fail() { 4 | echo "$@" >&2 5 | exit 1 6 | } 7 | 8 | echo $0 running 9 | 10 | $RSYNC --version || test_fail '--version output failed' 11 | 12 | $RSYNC --info=help || test_fail '--info=help output failed' 13 | 14 | $RSYNC --debug=help || test_fail '--debug=help output failed' 15 | -------------------------------------------------------------------------------- /testsuite/README.testsuite: -------------------------------------------------------------------------------- 1 | automatic testsuite for rsync -*- text -*- 2 | 3 | We're trying to develop some more substantial tests to prevent rsync 4 | regressions. Ideally, all code changes or bug reports would come with 5 | an appropriate test suite. 6 | 7 | You can run these tests by typing "make check" in the build directory. 8 | The tests will run using the rsync binary in the build directory, so 9 | you do not need to do "make install" first. Indeed, you probably 10 | should not install rsync before running the tests. 11 | 12 | If you instead type "make installcheck" then the suite will test the 13 | rsync binary from its installed location (e.g. /usr/local/bin/rsync). 14 | You can use this to test a distribution build, or perhaps to run a new 15 | test suite against an old version of rsync. Note that in accordance 16 | with the GNU Standards, installcheck does not look for rsync on the 17 | path. 18 | 19 | If the tests pass, you should see a report to that effect. Some tests 20 | require being root or some other precondition, and so will normally not 21 | be checked -- look at the test scripts for more information. 22 | 23 | If the tests fail, you will see rather more output. The scratch 24 | directory will remain in the build directory. It would be useful if 25 | you could include the log messages when reporting a failure. 26 | 27 | These tests also run automatically on the build farm, and you can see 28 | the results on http://build.samba.org/. 29 | 30 | 31 | -------------------------------------------------------------------------------- /testsuite/acls.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # This program is distributable under the terms of the GNU GPL (see 4 | # COPYING). 5 | 6 | # Test that rsync handles basic ACL preservation. 7 | 8 | . $suitedir/rsync.fns 9 | 10 | $RSYNC --version | grep ", ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support" 11 | 12 | makepath "$fromdir/foo" 13 | echo something >"$fromdir/file1" 14 | echo else >"$fromdir/file2" 15 | 16 | files='foo file1 file2' 17 | 18 | case "$setfacl_nodef" in 19 | true) 20 | if ! chmod --help 2>&1 | fgrep +a >/dev/null; then 21 | test_skipped "I don't know how to use setfacl or chmod for ACLs" 22 | fi 23 | chmod +a "root allow read,write,execute" "$fromdir/foo" || test_skipped "Your filesystem has ACLs disabled" 24 | chmod +a "root allow read,execute" "$fromdir/file1" 25 | chmod +a "admin allow read" "$fromdir/file1" 26 | chmod +a "daemon allow read,write" "$fromdir/file1" 27 | chmod +a "root allow read,execute" "$fromdir/file2" 28 | 29 | see_acls() { 30 | ls -le "${@}" 31 | } 32 | ;; 33 | *) 34 | setfacl -m u:0:7 "$fromdir/foo" || test_skipped "Your filesystem has ACLs disabled" 35 | setfacl -m g:1:5 "$fromdir/foo" 36 | setfacl -m g:2:1 "$fromdir/foo" 37 | setfacl -m g:0:7 "$fromdir/foo" 38 | setfacl -m u:2:1 "$fromdir/foo" 39 | setfacl -m u:1:5 "$fromdir/foo" 40 | 41 | setfacl -m u:0:5 "$fromdir/file1" 42 | setfacl -m g:0:4 "$fromdir/file1" 43 | setfacl -m u:1:6 "$fromdir/file1" 44 | 45 | setfacl -m u:0:5 "$fromdir/file2" 46 | 47 | see_acls() { 48 | getfacl "${@}" 49 | } 50 | ;; 51 | esac 52 | 53 | cd "$fromdir" 54 | $RSYNC -avvA $files "$todir/" 55 | 56 | see_acls $files >"$scratchdir/acls.txt" 57 | 58 | cd "$todir" 59 | see_acls $files | diff $diffopt "$scratchdir/acls.txt" - 60 | 61 | # The script would have aborted on error, so getting here means we've won. 62 | exit 0 63 | -------------------------------------------------------------------------------- /testsuite/backup.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2004 by Wayne Davison 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test that the --backup option works right. 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | bakdir="$tmpdir/bak" 13 | 14 | makepath "$fromdir/deep" "$bakdir/dname" 15 | name1="$fromdir/deep/name1" 16 | name2="$fromdir/deep/name2" 17 | 18 | outfile="$scratchdir/rsync.out" 19 | 20 | cat "$srcdir"/[gr]*.[ch] > "$name1" 21 | cat "$srcdir"/[et]*.[ch] > "$name2" 22 | 23 | checkit "$RSYNC -ai --info=backup '$fromdir/' '$todir/'" "$fromdir" "$todir" 24 | 25 | checkit "$RSYNC -ai --info=backup '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir" 26 | cat "$srcdir"/[fgpr]*.[ch] > "$name1" 27 | cat "$srcdir"/[etw]*.[ch] > "$name2" 28 | 29 | $RSYNC -ai --info=backup --no-whole-file --backup "$fromdir/" "$todir/" \ 30 | | tee "$outfile" 31 | for fn in deep/name1 deep/name2; do 32 | grep "backed up $fn to $fn~" "$outfile" >/dev/null || test_fail "no backup message output for $fn" 33 | diff $diffopt "$fromdir/$fn" "$todir/$fn" || test_fail "copy of $fn failed" 34 | diff $diffopt "$chkdir/$fn" "$todir/$fn~" || test_fail "backup of $fn to $fn~ failed" 35 | mv "$todir/$fn~" "$todir/$fn" 36 | done 37 | 38 | echo deleted-file >"$todir/dname" 39 | cp_touch "$todir/dname" "$chkdir" 40 | 41 | checkit "$RSYNC -ai --info=backup --no-whole-file --delete-delay \ 42 | --backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \ 43 | | tee "$outfile" 44 | 45 | for fn in deep/name1 deep/name2; do 46 | grep "backed up $fn to .*/$fn$" "$outfile" >/dev/null || test_fail "no backup message output for $fn" 47 | done 48 | diff -r $diffopt "$chkdir" "$bakdir" || test_fail "backup dir contents are bogus" 49 | rm "$bakdir/dname" 50 | 51 | checkit "$RSYNC -ai --info=backup --del '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir" 52 | cat "$srcdir"/[efgr]*.[ch] > "$name1" 53 | cat "$srcdir"/[ew]*.[ch] > "$name2" 54 | 55 | checkit "$RSYNC -ai --info=backup --inplace --no-whole-file --backup --backup-dir='$bakdir' '$fromdir/' '$todir/'" "$fromdir" "$todir" \ 56 | | tee "$outfile" 57 | 58 | for fn in deep/name1 deep/name2; do 59 | grep "backed up $fn to .*/$fn$" "$outfile" >/dev/null || test_fail "no backup message output for $fn" 60 | done 61 | diff -r $diffopt "$chkdir" "$bakdir" || test_fail "backup dir contents are bogus" 62 | 63 | checkit "$RSYNC -ai --info=backup --inplace --no-whole-file '$fromdir/' '$bakdir/'" "$fromdir" "$bakdir" 64 | 65 | # The script would have aborted on error, so getting here means we've won. 66 | exit 0 67 | -------------------------------------------------------------------------------- /testsuite/batch-mode.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2004 by Chris Shoemaker 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test rsync's --write-batch and --read-batch options 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | hands_setup 13 | 14 | cd "$tmpdir" 15 | 16 | # Build chkdir for the daemon tests using a normal rsync and an --exclude. 17 | $RSYNC -av --exclude=foobar.baz "$fromdir/" "$chkdir/" 18 | 19 | $RSYNC -av --only-write-batch=BATCH --exclude=foobar.baz "$fromdir/" "$todir/missing/" 20 | test -d "$todir/missing" && test_fail "--only-write-batch should not have created destination dir" 21 | 22 | runtest "--read-batch (only)" 'checkit "$RSYNC -av --read-batch=BATCH \"$todir\"" "$chkdir" "$todir"' 23 | 24 | rm -rf "$todir" BATCH* 25 | runtest "local --write-batch" 'checkit "$RSYNC -av --write-batch=BATCH \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"' 26 | 27 | rm -rf "$todir" 28 | runtest "--read-batch" 'checkit "$RSYNC -av --read-batch=BATCH \"$todir\"" "$fromdir" "$todir"' 29 | 30 | build_rsyncd_conf 31 | 32 | RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon" 33 | export RSYNC_CONNECT_PROG 34 | 35 | rm -rf "$todir" 36 | runtest "daemon sender --write-batch" 'checkit "$RSYNC -av --write-batch=BATCH rsync://localhost/test-from/ \"$todir\"" "$chkdir" "$todir"' 37 | 38 | rm -rf "$todir" 39 | runtest "--read-batch from daemon" 'checkit "$RSYNC -av --read-batch=BATCH \"$todir\"" "$chkdir" "$todir"' 40 | 41 | rm -rf "$todir" 42 | runtest "BATCH.sh use of --read-batch" 'checkit "./BATCH.sh" "$chkdir" "$todir"' 43 | 44 | runtest "do-nothing re-run of batch" 'checkit "./BATCH.sh" "$chkdir" "$todir"' 45 | 46 | rm -rf "$todir" 47 | mkdir "$todir" || test_fail "failed to restore empty destination directory" 48 | runtest "daemon recv --write-batch" 'checkit "\"$ignore23\" $RSYNC -av --write-batch=BATCH \"$fromdir/\" rsync://localhost/test-to" "$chkdir" "$todir"' 49 | 50 | # The script would have aborted on error, so getting here means we pass. 51 | exit 0 52 | -------------------------------------------------------------------------------- /testsuite/chgrp.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2002 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test that rsync with -gr will preserve groups when the user running 9 | # the test is a member of them. Hopefully they're in at least one 10 | # test. 11 | 12 | . "$suitedir/rsync.fns" 13 | 14 | # Build some hardlinks 15 | 16 | mygrps="`rsync_getgroups`" || fail "Can't get groups" 17 | mkdir "$fromdir" 18 | 19 | for g in $mygrps 20 | do 21 | name="$fromdir/foo-$g" 22 | date > "$name" 23 | chgrp "$g" "$name" || fail "Can't chgrp" 24 | done 25 | sleep 2 26 | 27 | checkit "$RSYNC -rtgpvvv '$fromdir/' '$todir/'" "$fromdir" "$todir" 28 | 29 | # The script would have aborted on error, so getting here means we've won. 30 | exit 0 31 | -------------------------------------------------------------------------------- /testsuite/chmod-option.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2002 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test that the --chmod option functions correctly. 9 | 10 | . $suitedir/rsync.fns 11 | 12 | # Build some files 13 | 14 | fromdir="$scratchdir/from" 15 | todir="$scratchdir/to" 16 | checkdir="$scratchdir/check" 17 | 18 | mkdir "$fromdir" 19 | name1="$fromdir/name1" 20 | name2="$fromdir/name2" 21 | dir1="$fromdir/dir1" 22 | dir2="$fromdir/dir2" 23 | echo "This is the file" > "$name1" 24 | echo "This is the other file" > "$name2" 25 | mkdir "$dir1" "$dir2" 26 | 27 | chmod 4700 "$name1" || test_skipped "Can't chmod" 28 | chmod 700 "$dir1" 29 | chmod 770 "$dir2" 30 | 31 | # Copy the files we've created over to another directory 32 | checkit "$RSYNC -avv '$fromdir/' '$checkdir/'" "$fromdir" "$checkdir" 33 | 34 | # And then manually make the changes which should occur 35 | umask 002 36 | chmod ug-s,a+rX "$checkdir"/* 37 | chmod +w "$checkdir" "$checkdir"/dir* 38 | 39 | checkit "$RSYNC -avv --chmod ug-s,a+rX,D+w '$fromdir/' '$todir/'" "$checkdir" "$todir" 40 | 41 | rm -r "$fromdir" "$checkdir" "$todir" 42 | makepath "$todir" "$fromdir/foo" 43 | touch "$fromdir/bar" 44 | 45 | checkit "$RSYNC -avv '$fromdir/' '$checkdir/'" "$fromdir" "$checkdir" 46 | chmod o+x "$fromdir"/bar 47 | 48 | checkit "$RSYNC -avv --chmod=Fo-x '$fromdir/' '$todir/'" "$checkdir" "$todir" 49 | 50 | # Tickle a bug in rsync 2.6.8: if you push a new directory with --perms off to 51 | # a daemon with an incoming chmod, the daemon pretends the directory is a file 52 | # for the purposes of the second application of the incoming chmod. 53 | 54 | build_rsyncd_conf 55 | cat >>"$scratchdir/test-rsyncd.conf" < 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test that various read-only and set[ug]id permissions work properly, 9 | # even when using a --temp-dir option (which we try to point at a 10 | # different filesystem than the destination dir). 11 | 12 | . "$suitedir/rsync.fns" 13 | 14 | hands_setup 15 | 16 | tmpdir2=$RSYNC_TEST_TMP 17 | if [ x"$tmpdir2" = x ]; then 18 | tmpdir2=/tmp 19 | fi 20 | sdev=`$TOOLDIR/getfsdev $scratchdir` 21 | tdev=`$TOOLDIR/getfsdev $tmpdir2` 22 | if [ x$sdev = x$tdev ]; then 23 | tmpdir2=/var/tmp 24 | if [ -d $tmpdir2 ]; then 25 | tdev=`$TOOLDIR/getfsdev $tmpdir2` 26 | else 27 | tdev="$sdev" 28 | fi 29 | [ x$sdev = x$tdev ] && test_skipped "Can't find a tmp dir on a different file system" 30 | fi 31 | 32 | chmod 440 "$fromdir/text" 33 | chmod 500 "$fromdir/dir/text" 34 | e="$fromdir/dir/subdir/foobar.baz" 35 | chmod 6450 "$e" || chmod 2450 "$e" || chmod 1450 "$e" || chmod 450 "$e" 36 | e="$fromdir/dir/subdir/subsubdir/etc-ltr-list" 37 | chmod 2670 "$e" || chmod 1670 "$e" || chmod 670 "$e" 38 | 39 | # First a normal copy. 40 | runtest "normal copy" 'checkit "$RSYNC -avv --temp-dir=\"$tmpdir2\" \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"' 41 | 42 | # Then we update all the files. 43 | runtest "update copy" 'checkit "$RSYNC -avvI --no-whole-file --temp-dir=\"$tmpdir2\" \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"' 44 | 45 | # The script would have aborted on error, so getting here means we've won. 46 | exit 0 47 | -------------------------------------------------------------------------------- /testsuite/chmod.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2004 by Wayne Davison 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test that various read-only and set[ug]id permissions work properly, 9 | # even when using a --temp-dir option (which we try to point at a 10 | # different filesystem than the destination dir). 11 | 12 | . "$suitedir/rsync.fns" 13 | 14 | hands_setup 15 | 16 | chmod 440 "$fromdir/text" 17 | chmod 500 "$fromdir/dir/text" 18 | e="$fromdir/dir/subdir/foobar.baz" 19 | chmod 6450 "$e" || chmod 2450 "$e" || chmod 1450 "$e" || chmod 450 "$e" 20 | e="$fromdir/dir/subdir/subsubdir/etc-ltr-list" 21 | chmod 2670 "$e" || chmod 1670 "$e" || chmod 670 "$e" 22 | 23 | # First a normal copy. 24 | runtest "normal copy" 'checkit "$RSYNC -avv \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"' 25 | 26 | # Then we update all the files. 27 | runtest "update copy" 'checkit "$RSYNC -avvI --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir" "$todir"' 28 | 29 | # The script would have aborted on error, so getting here means we've won. 30 | exit 0 31 | -------------------------------------------------------------------------------- /testsuite/chown.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2002 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test that when rsync is running as root and has -a it correctly sets 9 | # the ownership of the destination. 10 | 11 | # We don't know what users will be present on this system, so we just 12 | # use random numeric uids and gids. 13 | 14 | . "$suitedir/rsync.fns" 15 | 16 | case $0 in 17 | *fake*) 18 | $RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests" 19 | RSYNC="$RSYNC --fake-super" 20 | TLS_ARGS="$TLS_ARGS --fake-super" 21 | case "`xattr 2>&1`" in 22 | *--list:*) 23 | chown() { 24 | own=$1 25 | shift 26 | xattr -s 'rsync.%stat' "100644 0,0 $own" "${@}" 27 | } 28 | ;; 29 | *) 30 | chown() { 31 | own=$1 32 | shift 33 | setfattr -n 'user.rsync.%stat' -v "100644 0,0 $own" "${@}" 34 | } 35 | ;; 36 | esac 37 | ;; 38 | *) 39 | RSYNC="$RSYNC --super" 40 | case `get_testuid` in 41 | '') ;; # If "id" failed, try to continue... 42 | 0) ;; 43 | *) if [ -f /usr/bin/fakeroot ]; then 44 | echo "Let's try re-running the script under fakeroot..." 45 | exec /usr/bin/fakeroot /bin/sh "$0" 46 | fi 47 | ;; 48 | esac 49 | ;; 50 | esac 51 | 52 | # Build some hardlinks 53 | 54 | mkdir "$fromdir" 55 | name1="$fromdir/name1" 56 | name2="$fromdir/name2" 57 | echo "This is the file" > "$name1" 58 | echo "This is the other file" > "$name2" 59 | 60 | chown 5000:5002 "$name1" || test_skipped "Can't chown (probably need root)" 61 | chown 5001:5003 "$name2" || test_skipped "Can't chown (probably need root)" 62 | 63 | cd "$fromdir/.." 64 | checkit "$RSYNC -aHvv from/ to/" "$fromdir" "$todir" 65 | 66 | # The script would have aborted on error, so getting here means we've won. 67 | exit 0 68 | -------------------------------------------------------------------------------- /testsuite/compare-dest.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2004 by Wayne Davison 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test rsync handling of the --compare-dest option. 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | alt1dir="$tmpdir/alt1" 13 | alt2dir="$tmpdir/alt2" 14 | 15 | # Build some files/dirs/links to copy 16 | 17 | hands_setup 18 | 19 | # Setup the alt and chk dirs 20 | $RSYNC -av --include=text --include='*/' --exclude='*' "$fromdir/" "$alt1dir/" 21 | $RSYNC -av --include=etc-ltr-list --include='*/' --exclude='*' "$fromdir/" "$alt2dir/" 22 | 23 | sleep 1 24 | touch "$fromdir/dir/text" 25 | 26 | $RSYNC -av --exclude=/text --exclude=etc-ltr-list "$fromdir/" "$chkdir/" 27 | 28 | # Let's do it! 29 | checkit "$RSYNC -avv --no-whole-file \ 30 | --compare-dest='$alt1dir' --compare-dest='$alt2dir' \ 31 | '$fromdir/' '$todir/'" "$chkdir" "$todir" 32 | checkit "$RSYNC -avv --no-whole-file \ 33 | --copy-dest='$alt1dir' --copy-dest='$alt2dir' \ 34 | '$fromdir/' '$todir/'" "$fromdir" "$todir" 35 | 36 | # The script would have aborted on error, so getting here means we've won. 37 | exit 0 38 | -------------------------------------------------------------------------------- /testsuite/daemon-gzip-download.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 2001, 2002 by Martin Pool 4 | 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | # GNU General Public License for more details. 14 | 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 | 19 | # This test tries to download a tree over a compressed connection from 20 | # the server. This ought to exercise (exorcise?) a bug in 2.5.3. 21 | 22 | . "$suitedir/rsync.fns" 23 | 24 | build_rsyncd_conf 25 | 26 | RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon" 27 | export RSYNC_CONNECT_PROG 28 | 29 | hands_setup 30 | 31 | # Build chkdir with a normal rsync and an --exclude. 32 | $RSYNC -av --exclude=foobar.baz "$fromdir/" "$chkdir/" 33 | 34 | checkit "$RSYNC -avvvvz localhost::test-from/ '$todir/'" "$chkdir" "$todir" 35 | 36 | # The script would have aborted on error, so getting here means we've won. 37 | exit 0 38 | -------------------------------------------------------------------------------- /testsuite/daemon-gzip-upload.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 2001, 2002 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING) 7 | 8 | # We don't really want to start the server listening, because that 9 | # might interfere with the security or operation of the test machine. 10 | # Instead we use the fake-connect feature to dynamically assign a pair 11 | # of ports. 12 | 13 | # This test tries to upload a file over a compressed connection to the 14 | # server. This ought to exercise (exorcise?) a bug in 2.5.3. 15 | 16 | . "$suitedir/rsync.fns" 17 | 18 | build_rsyncd_conf 19 | 20 | RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon" 21 | export RSYNC_CONNECT_PROG 22 | 23 | hands_setup 24 | 25 | # Build chkdir with a normal rsync and an --exclude. 26 | $RSYNC -av --exclude=foobar.baz "$fromdir/" "$chkdir/" 27 | 28 | checkit "'$ignore23' $RSYNC -avvvvz '$fromdir/' localhost::test-to/" "$chkdir" "$todir" 29 | 30 | # The script would have aborted on error, so getting here means we've won. 31 | exit 0 32 | -------------------------------------------------------------------------------- /testsuite/daemon.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 2001 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING) 7 | 8 | # We don't really want to start the server listening, because that 9 | # might interfere with the security or operation of the test machine. 10 | # Instead we use the fake-connect feature to dynamically assign a pair 11 | # of ports. 12 | 13 | # Having started the server we try some basic operations against it: 14 | 15 | # getting a list of module 16 | # listing files in a module 17 | # retrieving a module 18 | # uploading to a module 19 | # checking the log file 20 | # password authentication 21 | 22 | . "$suitedir/rsync.fns" 23 | 24 | chkfile="$scratchdir/rsync.chk" 25 | outfile="$scratchdir/rsync.out" 26 | 27 | SSH="src/support/lsh --no-cd" 28 | FILE_REPL='s/^\([^d][^ ]*\) *\(..........[0-9]\) /\1 \2 /' 29 | DIR_REPL='s/^\(d[^ ]*\) *[0-9][.,0-9]* /\1 DIR /' 30 | LS_REPL='s;[0-9][0-9][0-9][0-9]/[0-9][0-9]/[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9];####/##/## ##:##:##;' 31 | 32 | build_rsyncd_conf 33 | 34 | makepath "$fromdir/foo" "$fromdir/bar/baz" 35 | makepath "$todir" 36 | echo one >"$fromdir/foo/one" 37 | echo two >"$fromdir/bar/two" 38 | echo three >"$fromdir/bar/baz/three" 39 | 40 | cd "$scratchdir" 41 | 42 | ln -s test-rsyncd.conf rsyncd.conf 43 | 44 | confopt='' 45 | case `get_testuid` in 46 | 0) 47 | # Root needs to specify the config file, or it uses /etc/rsyncd.conf. 48 | echo "Forcing --config=$conf" 49 | confopt=" --config=$conf" 50 | ;; 51 | esac 52 | 53 | $RSYNC -ve "$SSH" --rsync-path="$RSYNC$confopt" localhost:: 54 | 55 | RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon" 56 | export RSYNC_CONNECT_PROG 57 | 58 | $RSYNC -v localhost:: \ 59 | | tee "$outfile" 60 | # These have a space-padded 15-char name, then a tab, then a comment. 61 | sed 's/NOCOMMENT//' <"$chkfile" 62 | test-from r/o 63 | test-to r/w 64 | test-scratch NOCOMMENT 65 | EOT 66 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed" 67 | 68 | $RSYNC -r localhost::test-hidden \ 69 | | sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \ 70 | | tee "$outfile" 71 | cat <"$chkfile" 72 | drwxr-xr-x DIR ####/##/## ##:##:## . 73 | drwxr-xr-x DIR ####/##/## ##:##:## bar 74 | -rw-r--r-- 4 ####/##/## ##:##:## bar/two 75 | drwxr-xr-x DIR ####/##/## ##:##:## bar/baz 76 | -rw-r--r-- 6 ####/##/## ##:##:## bar/baz/three 77 | drwxr-xr-x DIR ####/##/## ##:##:## foo 78 | -rw-r--r-- 4 ####/##/## ##:##:## foo/one 79 | EOT 80 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed" 81 | 82 | $RSYNC -r localhost::test-from/f* \ 83 | | sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \ 84 | | tee "$outfile" 85 | cat <"$chkfile" 86 | drwxr-xr-x DIR ####/##/## ##:##:## foo 87 | -rw-r--r-- 4 ####/##/## ##:##:## foo/one 88 | EOT 89 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed" 90 | 91 | -------------------------------------------------------------------------------- /testsuite/default-acls.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # This program is distributable under the terms of the GNU GPL (see 4 | # COPYING). 5 | 6 | # Test that rsync obeys default ACLs. -- Matt McCutchen 7 | 8 | . $suitedir/rsync.fns 9 | 10 | $RSYNC --version | grep ", ACLs" >/dev/null || test_skipped "Rsync is configured without ACL support" 11 | 12 | case "$setfacl_nodef" in 13 | true) test_skipped "I don't know how to use your setfacl command" ;; 14 | *-k*) opts='-dm u::7,g::5,o:5' ;; 15 | *) opts='-m d:u::7,d:g::5,d:o:5' ;; 16 | esac 17 | setfacl $opts "$scratchdir" || test_skipped "Your filesystem has ACLs disabled" 18 | 19 | # Call as: testit 20 | testit() { 21 | todir="$scratchdir/$1" 22 | mkdir "$todir" 23 | $setfacl_nodef "$todir" 24 | if [ "$2" ]; then 25 | case "$setfacl_nodef" in 26 | *-k*) opts="-dm $2" ;; 27 | *) opts="-m `echo $2 | sed 's/\([ugom]:\)/d:\1/g'`" 28 | esac 29 | setfacl $opts "$todir" 30 | fi 31 | # Make sure we obey ACLs when creating a directory to hold multiple transferred files, 32 | # even though the directory itself is outside the transfer 33 | $RSYNC -rvv "$scratchdir/dir" "$scratchdir/file" "$scratchdir/program" "$todir/to/" 34 | check_perms "$todir/to" $4 "Target $1" 35 | check_perms "$todir/to/dir" $4 "Target $1" 36 | check_perms "$todir/to/file" $3 "Target $1" 37 | check_perms "$todir/to/program" $4 "Target $1" 38 | # Make sure get_local_name doesn't mess us up when transferring only one file 39 | $RSYNC -rvv "$scratchdir/file" "$todir/to/anotherfile" 40 | check_perms "$todir/to/anotherfile" $3 "Target $1" 41 | # Make sure we obey default ACLs when not transferring a regular file 42 | $RSYNC -rvv "$scratchdir/dir/" "$todir/to/anotherdir/" 43 | check_perms "$todir/to/anotherdir" $4 "Target $1" 44 | } 45 | 46 | mkdir "$scratchdir/dir" 47 | echo "File!" >"$scratchdir/file" 48 | echo "#!/bin/sh" >"$scratchdir/program" 49 | chmod 777 "$scratchdir/dir" 50 | chmod 666 "$scratchdir/file" 51 | chmod 777 "$scratchdir/program" 52 | 53 | # Test some target directories 54 | umask 0077 55 | testit da777 u::7,g::7,o:7 rw-rw-rw- rwxrwxrwx 56 | testit da775 u::7,g::7,o:5 rw-rw-r-- rwxrwxr-x 57 | testit da750 u::7,g::5,o:0 rw-r----- rwxr-x--- 58 | testit da750mask u::7,u:0:7,g::7,m:5,o:0 rw-r----- rwxr-x--- 59 | testit noda1 '' rw------- rwx------ 60 | umask 0000 61 | testit noda2 '' rw-rw-rw- rwxrwxrwx 62 | umask 0022 63 | testit noda3 '' rw-r--r-- rwxr-xr-x 64 | 65 | # Hooray 66 | exit 0 67 | -------------------------------------------------------------------------------- /testsuite/delete.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2005 by Wayne Davison 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test rsync handling of various delete directives. 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | hands_setup 13 | 14 | makepath "$chkdir" "$todir/extradir" "$todir/emptydir/subdir" 15 | 16 | echo extra >"$todir"/remove1 17 | echo extra >"$todir"/remove2 18 | echo extra >"$todir"/extradir/remove3 19 | echo extra >"$todir"/emptydir/subdir/remove4 20 | 21 | # Create two chk dirs, one with a copy of the source files, and one with 22 | # what we expect to be left behind by the copy using --remove-source-files. 23 | # Also, make sure that --dry-run --del doesn't output anything extraneous. 24 | $RSYNC -av "$fromdir/" "$chkdir/copy/" >"$tmpdir/copy.out" 2>&1 25 | cat "$tmpdir/copy.out" 26 | egrep -v '^(created directory|sent|total size) ' "$tmpdir/copy.out" >"$tmpdir/copy.new" 27 | mv "$tmpdir/copy.new" "$tmpdir/copy.out" 28 | 29 | $RSYNC -avn --del "$fromdir/" "$chkdir/copy2/" >"$tmpdir/copy2.out" 2>&1 || true 30 | cat "$tmpdir/copy2.out" 31 | egrep -v '^(created directory|sent|total size) ' "$tmpdir/copy2.out" >"$tmpdir/copy2.new" 32 | mv "$tmpdir/copy2.new" "$tmpdir/copy2.out" 33 | 34 | diff $diffopt "$tmpdir/copy.out" "$tmpdir/copy2.out" 35 | 36 | $RSYNC -av -f 'exclude,! */' "$fromdir/" "$chkdir/empty/" 37 | 38 | checkit "$RSYNC -avv --del --remove-source-files '$fromdir/' '$todir/'" "$chkdir/copy" "$todir" 39 | 40 | diff -r "$chkdir/empty" "$fromdir" 41 | 42 | # Make sure that "P" but not "-" per-dir merge-file filters take effect with 43 | # --delete-excluded. 44 | cat >"$todir/filters" < 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test rsync handling of devices. This can only run if you're root. 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | chkfile="$scratchdir/rsync.chk" 13 | outfile="$scratchdir/rsync.out" 14 | 15 | # Build some hardlinks 16 | 17 | case $0 in 18 | *fake*) 19 | $RSYNC --version | grep ", xattrs" >/dev/null || test_skipped "Rsync needs xattrs for fake device tests" 20 | RSYNC="$RSYNC --fake-super" 21 | TLS_ARGS="$TLS_ARGS --fake-super" 22 | case "`xattr 2>&1`" in 23 | *--list:*) 24 | mknod() { 25 | fn="$1" 26 | case "$2" in 27 | p) mode=10644 ;; 28 | c) mode=20644 ;; 29 | b) mode=60644 ;; 30 | esac 31 | maj="${3:-0}" 32 | min="${4:-0}" 33 | touch "$fn" 34 | xattr -s 'rsync.%stat' "$mode $maj,$min 0:0" "$fn" 35 | } 36 | ;; 37 | *) 38 | mknod() { 39 | fn="$1" 40 | case "$2" in 41 | p) mode=10644 ;; 42 | c) mode=20644 ;; 43 | b) mode=60644 ;; 44 | esac 45 | maj="${3:-0}" 46 | min="${4:-0}" 47 | touch "$fn" 48 | setfattr -n 'user.rsync.%stat' -v "$mode $maj,$min 0:0" "$fn" 49 | } 50 | ;; 51 | esac 52 | ;; 53 | *) 54 | case `get_testuid` in 55 | '') ;; # If "id" failed, try to continue... 56 | 0) ;; 57 | *) if [ -f /usr/bin/fakeroot ]; then 58 | echo "Let's try re-running the script under fakeroot..." 59 | exec /usr/bin/fakeroot /bin/sh $RUNSHFLAGS "$0" 60 | fi 61 | test_skipped "Rsync needs root/fakeroot for device tests" 62 | ;; 63 | esac 64 | ;; 65 | esac 66 | 67 | # TODO: Need to test whether hardlinks are possible on this OS/filesystem 68 | 69 | mkdir "$fromdir" 70 | mkdir "$todir" 71 | mknod "$fromdir/char" c 41 67 || test_skipped "Can't create char device node" 72 | mknod "$fromdir/char2" c 42 68 || test_skipped "Can't create char device node" 73 | mknod "$fromdir/char3" c 42 69 || test_skipped "Can't create char device node" 74 | mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node" 75 | mknod "$fromdir/block2" b 42 73 || test_skipped "Can't create block device node" 76 | mknod "$fromdir/block3" b 105 73 || test_skipped "Can't create block device node" 77 | ln "$fromdir/block3" "$fromdir/block2.5" || echo "Skipping hard-linked device test..." 78 | mkfifo "$fromdir/fifo" || mknod "$fromdir/fifo" p || test_skipped "Can't run mkfifo" 79 | # Work around time rounding/truncating issue by touching both files. 80 | touch -r "$fromdir/block" "$fromdir/block" "$fromdir/block2" 81 | 82 | $RSYNC -ai "$fromdir/block" "$todir/block2" \ 83 | | tee "$outfile" 84 | cat <"$chkfile" 85 | cD$all_plus block 86 | EOT 87 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed" 88 | 89 | $RSYNC -ai "$fromdir/block2" "$todir/block" \ 90 | | tee "$outfile" 91 | cat <"$chkfile" 92 | cD$all_plus block2 93 | EOT 94 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed" 95 | 96 | sleep 1 97 | 98 | $RSYNC -Di "$fromdir/block3" "$todir/block" \ 99 | | tee "$outfile" 100 | cat <"$chkfile" 101 | cDc.T.$dots block3 102 | EOT 103 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed" 104 | 105 | $RSYNC -aiHvv "$fromdir/" "$todir/" \ 106 | | tee "$outfile" 107 | filter_outfile 108 | cat <"$chkfile" 109 | .d..t.$dots ./ 110 | cDc.t.$dots block 111 | cDc...$dots block2 112 | cD$all_plus block2.5 113 | hD$all_plus block3 => block2.5 114 | cD$all_plus char 115 | cD$all_plus char2 116 | cD$all_plus char3 117 | cS$all_plus fifo 118 | EOT 119 | if test ! -r "$fromdir/block2.5"; then 120 | sed -e '/block2\.5/d' <"$chkfile" >"$chkfile.new" 121 | mv "$chkfile.new" "$chkfile" 122 | fi 123 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed" 124 | 125 | echo "check how the directory listings compare with diff:" 126 | echo "" 127 | ( cd "$fromdir" && rsync_ls_lR . ) > "$tmpdir/ls-from" 128 | ( cd "$todir" && rsync_ls_lR . ) > "$tmpdir/ls-to" 129 | diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" 130 | 131 | if test -b "$fromdir/block2.5"; then 132 | set -x 133 | $RSYNC -aii --link-dest="$todir" "$fromdir/" "$chkdir/" \ 134 | | tee "$outfile" 135 | cat <"$chkfile" 136 | cd$allspace ./ 137 | hD$allspace block 138 | hD$allspace block2 139 | hD$allspace block2.5 140 | hD$allspace block3 141 | hD$allspace char 142 | hD$allspace char2 143 | hD$allspace char3 144 | hS$allspace fifo 145 | EOT 146 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed" 147 | fi 148 | 149 | # The script would have aborted on error, so getting here means we've won. 150 | exit 0 151 | -------------------------------------------------------------------------------- /testsuite/dir-sgid.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # This program is distributable under the terms of the GNU GPL (see 4 | # COPYING). 5 | 6 | # Test that rsync obeys directory setgid. -- Matt McCutchen 7 | 8 | . $suitedir/rsync.fns 9 | 10 | umask 077 11 | 12 | # Call as: testit 13 | testit() { 14 | todir="$scratchdir/$1" 15 | mkdir "$todir" 16 | chmod $2 "$todir" 17 | # Make sure we obey directory setgid when creating a directory to hold multiple transferred files, 18 | # even though the directory itself is outside the transfer 19 | $RSYNC -rvv "$scratchdir/dir" "$scratchdir/file" "$scratchdir/program" "$todir/to/" 20 | check_perms "$todir/to" $5 "Target $1" 21 | check_perms "$todir/to/dir" $5 "Target $1" 22 | check_perms "$todir/to/file" $3 "Target $1" 23 | check_perms "$todir/to/program" $4 "Target $1" 24 | } 25 | 26 | echo "File!" >"$scratchdir/file" 27 | echo "#!/bin/sh" >"$scratchdir/program" 28 | mkdir "$scratchdir/dir" 29 | chmod 2764 "$scratchdir/dir" || test_skipped "Can't chmod" 30 | chmod 664 "$scratchdir/file" 31 | chmod 775 "$scratchdir/program" 32 | [ -g "$scratchdir/dir" ] || test_skipped "The directory setgid bit vanished!" 33 | mkdir "$scratchdir/dir/blah" 34 | [ -g "$scratchdir/dir/blah" ] || test_skipped "Your filesystem doesn't use directory setgid; maybe it's BSD." 35 | 36 | # Test some target directories 37 | testit setgid-off 700 rw------- rwx------ rwx------ 38 | testit setgid-on 2700 rw------- rwx------ rwx--S--- 39 | 40 | # Hooray 41 | exit 0 42 | -------------------------------------------------------------------------------- /testsuite/duplicates.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2002 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test rsync handling of duplicate filenames. 9 | 10 | # It's quite possible that the user might specify the same source file 11 | # more than once on the command line, perhaps through shell variables 12 | # or wildcard expansions. It might cause problems for rsync if the 13 | # same name occurred more than once in the file list, because we might 14 | # be trying to update the first copy and generate checksums for the 15 | # second copy at the same time. See clean_flist() for the implementation. 16 | 17 | # We don't need to worry about hardlinks or symlinks. Because we 18 | # always rename-and-replace the new copy, they can't affect us. 19 | 20 | # This test is not great, because it is a timing-dependent bug. 21 | 22 | . "$suitedir/rsync.fns" 23 | 24 | # Build some hardlinks 25 | 26 | mkdir "$fromdir" 27 | name1="$fromdir/name1" 28 | name2="$fromdir/name2" 29 | echo "This is the file" > "$name1" 30 | ln -s "$name1" "$name2" || fail "can't create symlink" 31 | 32 | outfile="$scratchdir/rsync.out" 33 | 34 | checkit "$RSYNC -avv '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$fromdir/' '$todir/'" "$fromdir" "$todir" \ 35 | | tee "$outfile" 36 | 37 | # Make sure each file was only copied once... 38 | if [ `grep -c '^name1$' "$outfile"` != 1 ] 39 | then 40 | test_fail "name1 was not copied exactly once" 41 | fi 42 | if [ `grep -c '^name2 -> ' "$outfile"` != 1 ] 43 | then 44 | test_fail "name2 was not copied exactly once" 45 | fi 46 | 47 | # The script would have aborted on error, so getting here means we've won. 48 | exit 0 49 | -------------------------------------------------------------------------------- /testsuite/executability.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # This program is distributable under the terms of the GNU GPL (see 4 | # COPYING). 5 | 6 | # Test the --executability or -E option. -- Matt McCutchen 7 | 8 | . $suitedir/rsync.fns 9 | 10 | # Put some files in the From directory 11 | mkdir "$fromdir" 12 | cat <"$fromdir/1" 13 | #!/bin/sh 14 | echo 'Program One!' 15 | EOF 16 | cat <"$fromdir/2" 17 | #!/bin/sh 18 | echo 'Program Two!' 19 | EOF 20 | 21 | chmod 1700 "$fromdir/1" || test_skipped "Can't chmod" 22 | chmod 600 "$fromdir/2" 23 | 24 | $RSYNC -rvv "$fromdir/" "$todir/" 25 | 26 | check_perms "$todir/1" rwx------ 1 27 | check_perms "$todir/2" rw------- 1 28 | 29 | # Mix up the permissions a bit 30 | chmod 600 "$fromdir/1" 31 | chmod 601 "$fromdir/2" 32 | chmod 604 "$todir/2" 33 | 34 | $RSYNC -rvv "$fromdir/" "$todir/" 35 | 36 | # No -E, so nothing should have changed 37 | check_perms "$todir/1" rwx------ 2 38 | check_perms "$todir/2" rw----r-- 2 39 | 40 | $RSYNC -rvvE "$fromdir/" "$todir/" 41 | 42 | # Now things should have happened! 43 | check_perms "$todir/1" rw------- 3 44 | check_perms "$todir/2" rwx---r-x 3 45 | 46 | # Hooray 47 | exit 0 48 | -------------------------------------------------------------------------------- /testsuite/files-from.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 2008 by Wayne Davison 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test that --files-from=FILE works right. 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | SSH="$scratchdir/src/support/lsh" 13 | 14 | hands_setup 15 | 16 | # This list of files skips the contents of "subsubdir" but includes 17 | # the contents of "subsubdir2" due to its trailing slash. 18 | cat >"$scratchdir/filelist" < 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test rsync handling of the --fuzzy option. 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | mkdir "$fromdir" 13 | mkdir "$todir" 14 | 15 | cp -p "$srcdir"/rsync.c "$fromdir"/rsync.c 16 | cp_touch "$fromdir"/rsync.c "$todir"/rsync2.c 17 | sleep 1 18 | 19 | # Let's do it! 20 | checkit "$RSYNC -avvi --no-whole-file --fuzzy --delete-delay \ 21 | '$fromdir/' '$todir/'" "$fromdir" "$todir" 22 | 23 | # The script would have aborted on error, so getting here means we've won. 24 | exit 0 25 | -------------------------------------------------------------------------------- /testsuite/hands.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 1998, 1999 by Philip Hands 4 | # Copyright (C) 2001, 2002 by Martin Pool 5 | # 6 | # This program is distributable under the terms of the GNU GPL (see COPYING) 7 | 8 | . "$suitedir/rsync.fns" 9 | 10 | hands_setup 11 | 12 | DEBUG_OPTS="--debug=all0,deltasum0" 13 | 14 | # Main script starts here 15 | 16 | runtest "basic operation" 'checkit "$RSYNC -av \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"' 17 | 18 | ln "$fromdir/filelist" "$fromdir/dir" 19 | runtest "hard links" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"' 20 | 21 | rm "$todir/text" 22 | runtest "one file" 'checkit "$RSYNC -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"' 23 | 24 | echo "extra line" >> "$todir/text" 25 | runtest "extra data" 'checkit "$RSYNC -avH $DEBUG_OPTS --no-whole-file \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"' 26 | 27 | cp "$fromdir/text" "$todir/ThisShouldGo" 28 | runtest " --delete" 'checkit "$RSYNC --delete -avH $DEBUG_OPTS \"$fromdir/\" \"$todir\"" "$fromdir/" "$todir"' 29 | 30 | cd "$tmpdir" 31 | rm -rf to from/*dir 32 | 33 | # Do the real copy, touch up the parent-dir's time, and then check the copy. 34 | $RSYNC -av from/* to/ 35 | checkit "$RSYNC -av --exclude='*' from/ to/" "$fromdir" "$todir" 36 | 37 | # The script would have aborted on error, so getting here means we've won. 38 | exit 0 39 | -------------------------------------------------------------------------------- /testsuite/hardlinks.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2002 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test rsync handling of hardlinks. By default, rsync does not detect 9 | # hard links and they get sent as separate files. If you specify -H, 10 | # then hard links are detected and linked together on the receiver. 11 | 12 | . "$suitedir/rsync.fns" 13 | 14 | SSH="$scratchdir/src/support/lsh" 15 | 16 | outfile="$scratchdir/rsync.out" 17 | 18 | # Build some hardlinks 19 | 20 | fromdir="$scratchdir/from" 21 | todir="$scratchdir/to" 22 | 23 | # TODO: Need to test whether hardlinks are possible on this OS/filesystem 24 | 25 | mkdir "$fromdir" 26 | name1="$fromdir/name1" 27 | name2="$fromdir/name2" 28 | name3="$fromdir/name3" 29 | name4="$fromdir/name4" 30 | echo "This is the file" > "$name1" 31 | ln "$name1" "$name2" || fail "Can't create hardlink" 32 | ln "$name2" "$name3" || fail "Can't create hardlink" 33 | cp "$name2" "$name4" || fail "Can't copy file" 34 | cat $srcdir/*.c >"$fromdir/text" 35 | 36 | checkit "$RSYNC -aHivv --debug=HLINK5 '$fromdir/' '$todir/'" "$fromdir" "$todir" 37 | 38 | echo "extra extra" >>"$todir/name1" 39 | 40 | checkit "$RSYNC -aHivv --debug=HLINK5 --no-whole-file '$fromdir/' '$todir/'" "$fromdir" "$todir" 41 | 42 | # Add a new link in a new subdirectory to test that we don't try to link 43 | # the files before the directory gets created. We also create a bunch of 44 | # extra files to ensure that an incremental-recursion transfer works across 45 | # distant files. 46 | makepath "$fromdir/subdir/down/deep" 47 | 48 | files='' 49 | for x in a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9; do 50 | for y in a b c d e f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9; do 51 | files="$files $x$y" 52 | done 53 | done 54 | (cd "$fromdir/subdir"; touch $files) 55 | 56 | ln "$name1" "$fromdir/subdir/down/deep/new-file" 57 | rm "$todir/text" 58 | 59 | checkit "$RSYNC -aHivve '$SSH' --debug=HLINK5 --rsync-path='$RSYNC' '$fromdir/' localhost:'$todir/'" "$fromdir" "$todir" 60 | 61 | # Do some duplicate copies using --link-dest and --copy-dest to test that 62 | # we hard-link all locally-inherited items. 63 | checkit "$RSYNC -aHivv --debug=HLINK5 --link-dest='$todir' '$fromdir/' '$chkdir/'" "$todir" "$chkdir" 64 | 65 | rm -rf "$chkdir" 66 | checkit "$RSYNC -aHivv --debug=HLINK5 --copy-dest='$todir' '$fromdir/' '$chkdir/'" "$fromdir" "$chkdir" 67 | 68 | # Create a hard link that has only one part in the hierarchy. 69 | echo "This is another file" >"$fromdir/solo" 70 | ln "$fromdir/solo" "$chkdir/solo" || fail "Can't create hardlink" 71 | 72 | # Make sure that the checksum data doesn't slide due to an HLINK_BUMP() change. 73 | $RSYNC -aHivc --debug=HLINK5 "$fromdir/" "$chkdir/" | tee "$outfile" 74 | grep solo "$outfile" && test_fail "Erroneous copy of solo file occurred!" 75 | 76 | # Make sure there's nothing wrong with sending a single file with -H 77 | # enabled (this has broken twice so far, so we need this test). 78 | rm -rf "$todir" 79 | $RSYNC -aHivv --debug=HLINK5 "$name1" "$todir/" 80 | diff $diffopt "$name1" "$todir" || test_fail "solo copy of name1 failed" 81 | 82 | # The script would have aborted on error, so getting here means we've won. 83 | exit 0 84 | -------------------------------------------------------------------------------- /testsuite/longdir.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 1998,1999 Philip Hands 4 | # Copyright (C) 2001 by Martin Pool 5 | # 6 | # This program is distributable under the terms of the GNU GPL (see COPYING) 7 | 8 | . "$suitedir/rsync.fns" 9 | 10 | hands_setup 11 | 12 | longname=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 13 | longdir="$fromdir/$longname/$longname/$longname" 14 | 15 | makepath "$longdir" || test_skipped "unable to create long directory" 16 | touch "$longdir/1" || test_skipped "unable to create files in long directory" 17 | date > "$longdir/1" 18 | if [ -r /etc ]; then 19 | ls -la /etc >"$longdir/2" 20 | else 21 | ls -la / >"$longdir/2" 22 | fi 23 | checkit "$RSYNC --delete -avH '$fromdir/' '$todir'" "$fromdir/" "$todir" 24 | 25 | # The script would have aborted on error, so getting here means we've won. 26 | exit 0 27 | -------------------------------------------------------------------------------- /testsuite/merge.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2004 by Wayne Davison 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Make sure we can merge files from multiple directories into one. 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | # Build some files/dirs/links to copy 13 | 14 | # Use local dirnames to better exercise the arg-parsing code. 15 | cd "$tmpdir" 16 | 17 | mkdir from1 from2 from3 deep 18 | mkdir from2/sub1 from3/sub1 19 | mkdir from3/sub2 from1/dir-and-not-dir 20 | mkdir chk chk/sub1 chk/sub2 chk/dir-and-not-dir 21 | echo "one" >from1/one 22 | cp_touch from1/one from2/one 23 | cp_touch from1/one from3/one 24 | echo "two" >from1/two 25 | echo "three" >from2/three 26 | echo "four" >from3/four 27 | echo "five" >from1/five 28 | echo "six" >from3/six 29 | echo "sub1" >from2/sub1/uno 30 | cp_touch from2/sub1/uno from3/sub1/uno 31 | echo "sub2" >from3/sub1/dos 32 | echo "sub3" >from2/sub1/tres 33 | echo "subby" >from3/sub2/subby 34 | echo "extra" >from1/dir-and-not-dir/inside 35 | echo "not-dir" >from3/dir-and-not-dir 36 | echo "arg-test" >deep/arg-test 37 | echo "shallow" >shallow 38 | 39 | cp_touch from1/one from1/two from2/three from3/four from1/five from3/six chk 40 | cp_touch deep/arg-test shallow chk 41 | cp_touch from1/dir-and-not-dir/inside chk/dir-and-not-dir 42 | cp_touch from2/sub1/uno from3/sub1/dos from2/sub1/tres chk/sub1 43 | cp_touch from3/sub2/subby chk/sub2 44 | 45 | # Make sure that time has moved on. 46 | sleep 1 47 | 48 | # Get rid of any directory-time differences 49 | $RSYNC -av --existing -f 'exclude,! */' from1/ from2/ 50 | $RSYNC -av --existing -f 'exclude,! */' from2/ from3/ 51 | $RSYNC -av --existing -f 'exclude,! */' from1/ chk/ 52 | $RSYNC -av --existing -f 'exclude,! */' from3/ chk/ 53 | 54 | checkit "$RSYNC -avv deep/arg-test shallow from1/ from2/ from3/ to/" "$chkdir" "$todir" 55 | 56 | # The script would have aborted on error, so getting here means we've won. 57 | exit 0 58 | -------------------------------------------------------------------------------- /testsuite/missing.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # This program is distributable under the terms of the GNU GPL (see 4 | # COPYING). 5 | 6 | # Test three bugs fixed by my redoing of the missing_below logic. 7 | 8 | . $suitedir/rsync.fns 9 | 10 | makepath "$fromdir/subdir" "$todir" 11 | echo data >"$fromdir/subdir/file" 12 | echo data >"$todir/other" 13 | 14 | # Test 1: Too much "not creating new..." output on a dry run 15 | $RSYNC -n -r --ignore-non-existing -vv "$fromdir/" "$todir/" | tee "$scratchdir/out" 16 | if grep 'not creating new.*subdir/file' "$scratchdir/out" >/dev/null; then 17 | test_fail 'test 1 failed' 18 | fi 19 | 20 | # Test 2: Attempt to make a fuzzy dirlist for a dir not created on a dry run 21 | $RSYNC -n -r -R --no-implied-dirs -y "$fromdir/./subdir/file" "$todir/" \ 22 | || test_fail 'test 2 failed' 23 | 24 | # Test 3: --delete-after pass skipped when last dir is dry-missing 25 | $RSYNC -n -r --delete-after -i "$fromdir/" "$todir/" | tee "$scratchdir/out" 26 | grep '^\*deleting * other' "$scratchdir/out" >/dev/null \ 27 | || test_fail 'test 3 failed' 28 | -------------------------------------------------------------------------------- /testsuite/relative.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 2005 by Wayne Davison 4 | # 5 | # This program is distributable under the terms of the GNU GPL (see COPYING) 6 | 7 | . "$suitedir/rsync.fns" 8 | 9 | deepstr='down/3/deep' 10 | deepdir="$fromdir/$deepstr" 11 | extradir="$fromdir/extra" 12 | makepath "$deepdir" "$extradir/$deepstr" "$chkdir" 13 | 14 | fromdir="$deepdir" 15 | hands_setup 16 | fromdir="$tmpdir/from" 17 | 18 | extrafile="$extradir/./$deepstr/extra.added.value" 19 | echo wowza >"$extrafile" 20 | 21 | $RSYNC -av --existing --include='*/' --exclude='*' "$fromdir/" "$extradir/" 22 | 23 | outfile="$scratchdir/rsync.out" 24 | 25 | cd "$fromdir" 26 | 27 | # Main script starts here 28 | 29 | $RSYNC -ai --include=/down/ --exclude='/*' "$fromdir/" "$chkdir/" 30 | 31 | sleep 1 32 | runtest "basic relative" 'checkit "$RSYNC -avR ./$deepstr \"$todir\"" "$chkdir" "$todir"' 33 | 34 | ln $deepstr/filelist $deepstr/dir 35 | ln ../chk/$deepstr/filelist ../chk/$deepstr/dir 36 | runtest "hard links" 'checkit "$RSYNC -avHR ./$deepstr/ \"$todir\"" "$chkdir" "$todir"' 37 | 38 | cp "$deepdir/text" "$todir/$deepstr/ThisShouldGo" 39 | cp "$deepdir/text" "$todir/$deepstr/dir/ThisShouldGoToo" 40 | runtest "deletion" 'checkit "$RSYNC -avHR --del ./$deepstr/ \"$todir\"" "$chkdir" "$todir"' 41 | 42 | runtest "non-deletion" 'checkit "$RSYNC -aiHR --del ./$deepstr/ \"$todir\"" "$chkdir" "$todir"' \ 43 | | tee "$outfile" 44 | 45 | # Make sure no files were deleted 46 | grep 'deleting ' "$outfile" && test_fail "Erroneous deletions occurred!" 47 | 48 | # Relative with merging. 49 | $RSYNC -ai "$extradir/down" "$chkdir/" 50 | 51 | checkit "$RSYNC -aiR $deepstr '$extrafile' '$todir'" "$chkdir" "$todir" 52 | 53 | checkit "$RSYNC -aiR --del $deepstr '$extrafile' '$todir'" "$chkdir" "$todir" \ 54 | | tee "$outfile" 55 | 56 | # Make sure no files were deleted 57 | grep 'deleting ' "$outfile" && test_fail "Erroneous deletions occurred! (2)" 58 | 59 | # The script would have aborted on error, so getting here means we've won. 60 | exit 0 61 | -------------------------------------------------------------------------------- /testsuite/ssh-basic.test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Copyright (C) 1998,1999 Philip Hands 4 | # Copyright (C) 2001 by Martin Pool 5 | 6 | # This program is distributable under the terms of the GNU GPL (see 7 | # COPYING) 8 | 9 | # This script tests ssh, if possible. It's called by runtests.sh 10 | 11 | . "$suitedir/rsync.fns" 12 | 13 | SSH="$scratchdir/src/support/lsh" 14 | 15 | if test x"$rsync_enable_ssh_tests" = xyes; then 16 | if type ssh >/dev/null ; then 17 | SSH=ssh 18 | fi 19 | fi 20 | 21 | if [ "`$SSH -o'BatchMode yes' localhost echo yes`" != "yes" ]; then 22 | test_skipped "Skipping SSH tests because ssh conection to localhost not authorised" 23 | fi 24 | 25 | echo "Using remote shell: $SSH" 26 | 27 | # Create some files for rsync to copy 28 | hands_setup 29 | 30 | runtest "ssh: basic test" 'checkit "$RSYNC -avH -e \"$SSH\" --rsync-path=\"$RSYNC\" \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"' 31 | 32 | mv "$todir/text" "$todir/ThisShouldGo" 33 | 34 | runtest "ssh: renamed file" 'checkit "$RSYNC --delete -avH -e \"$SSH\" --rsync-path=\"$RSYNC\" \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"' 35 | -------------------------------------------------------------------------------- /testsuite/symlink-ignore.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2001 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test rsync's somewhat over-featured symlink control: the default 9 | # behaviour is that symlinks should not be copied at all. 10 | 11 | . "$suitedir/rsync.fns" 12 | 13 | build_symlinks || test_fail "failed to build symlinks" 14 | 15 | # Copy recursively, but without -l or -L or -a, and all the symlinks 16 | # should be missing. 17 | $RSYNC -r "$fromdir/" "$todir" || test_fail "$RSYNC returned $?" 18 | 19 | [ -f "$todir/referent" ] || test_fail "referent was not copied" 20 | [ -d "$todir/from" ] && test_fail "extra level of directories" 21 | if is_a_link "$todir/dangling" 22 | then 23 | test_fail "dangling symlink was copied" 24 | fi 25 | 26 | if is_a_link "$todir/relative" 27 | then 28 | test_fail "relative symlink was copied" 29 | fi 30 | 31 | if is_a_link "$todir/absolute" 32 | then 33 | test_fail "absolute symlink was copied" 34 | fi 35 | 36 | # The script would have aborted on error, so getting here means we've won. 37 | exit 0 38 | -------------------------------------------------------------------------------- /testsuite/trimslash.test: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (C) 2002 by Martin Pool 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test tiny function to trim trailing slashes. 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | "$TOOLDIR/trimslash" "/usr/local/bin" "/usr/local/bin/" "/usr/local/bin///" \ 13 | "//a//" "////" \ 14 | "/Users/Wierd Macintosh Name/// Ooh, translucent plastic/" \ 15 | > "$scratchdir/slash.out" 16 | diff $diffopt "$scratchdir/slash.out" - < 4 | 5 | # This program is distributable under the terms of the GNU GPL (see 6 | # COPYING). 7 | 8 | # Test the wildmatch functionality 9 | 10 | . "$suitedir/rsync.fns" 11 | 12 | # This test exercises the wildmatch() function (with no options) and the 13 | # wildmatch_join() function (using -x and/or -e). 14 | for opts in "" -x1 "-x1 -e1" "-x1 -e1se" -x2 "-x2 -ese" -x3 "-x3 -e1" -x4 "-x4 -e2e" -x5 "-x5 -es"; do 15 | echo Running wildtest with "$opts" 16 | "$TOOLDIR/wildtest" $opts "$srcdir/wildtest.txt" >"$scratchdir/wild.out" 17 | diff $diffopt "$scratchdir/wild.out" - </dev/null || test_skipped "Rsync is configured without xattr support" 11 | 12 | case "`xattr 2>&1`" in 13 | *--list:*) 14 | xset() { 15 | xnam="$1" 16 | xval="$2" 17 | shift 2 18 | xattr -s "$xnam" "$xval" "${@}" 19 | } 20 | xls() { 21 | xattr -l "${@}" 22 | } 23 | RUSR='rsync.nonuser' 24 | ;; 25 | *) 26 | xset() { 27 | xnam="$1" 28 | xval="$2" 29 | shift 2 30 | setfattr -n "$xnam" -v "$xval" "${@}" 31 | } 32 | xls() { 33 | getfattr -d "${@}" 34 | } 35 | RUSR='user.rsync' 36 | ;; 37 | esac 38 | 39 | makepath "$fromdir/foo/bar" 40 | echo now >"$fromdir/file0" 41 | echo something >"$fromdir/file1" 42 | echo else >"$fromdir/file2" 43 | echo deep >"$fromdir/foo/file3" 44 | echo normal >"$fromdir/file4" 45 | echo deeper >"$fromdir/foo/bar/file5" 46 | 47 | makepath "$chkdir/foo" 48 | echo wow >"$chkdir/file1" 49 | cp_touch "$fromdir/foo/file3" "$chkdir/foo" 50 | 51 | dirs='foo foo/bar' 52 | files='file0 file1 file2 foo/file3 file4 foo/bar/file5' 53 | 54 | uid_gid=`"$TOOLDIR/tls" "$fromdir/foo" | sed 's/^.* \([0-9][0-9]*\)\.\([0-9][0-9]*\) .*/\1:\2/'` 55 | 56 | cd "$fromdir" 57 | 58 | xset user.foo foo file0 2>/dev/null || test_skipped "Unable to set an xattr" 59 | xset user.bar bar file0 60 | 61 | xset user.short 'this is short' file1 62 | xset user.long 'this is a long attribute that will be truncated in the initial data send' file1 63 | xset user.good 'this is good' file1 64 | xset user.nice 'this is nice' file1 65 | 66 | xset user.foo foo file2 67 | xset user.bar bar file2 68 | xset user.long 'a long attribute for our new file that tests to ensure that this works' file2 69 | 70 | xset user.dir1 'need to test directory xattrs too' foo 71 | xset user.dir2 'another xattr' foo 72 | xset user.dir3 'this is one last one for the moment' foo 73 | 74 | xset user.foo 'new foo' foo/file3 foo/bar/file5 75 | xset user.bar 'new bar' foo/file3 foo/bar/file5 76 | xset user.long 'this is also a long attribute that will be truncated in the initial data send' foo/file3 foo/bar/file5 77 | xset $RUSR.equal 'this long attribute should remain the same and not need to be transferred' foo/file3 foo/bar/file5 78 | 79 | xset user.short 'old short' "$chkdir/file1" 80 | xset user.extra 'remove me' "$chkdir/file1" 81 | 82 | xset user.foo 'old foo' "$chkdir/foo/file3" 83 | xset $RUSR.equal 'this long attribute should remain the same and not need to be transferred' "$chkdir/foo/file3" 84 | 85 | xls $dirs $files >"$scratchdir/xattrs.txt" 86 | 87 | # OK, let's try a simple xattr copy. 88 | checkit "$RSYNC -avX --super . '$chkdir/'" "$fromdir" "$chkdir" 89 | 90 | cd "$chkdir" 91 | xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" - 92 | 93 | cd "$fromdir" 94 | 95 | checkit "$RSYNC -aiX --super --copy-dest=../chk . ../to" "$fromdir" "$todir" 96 | 97 | cd "$todir" 98 | xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" - 99 | 100 | cd "$fromdir" 101 | rm -rf "$todir" 102 | 103 | xset user.nice 'this is nice, but different' file1 104 | 105 | xls $dirs $files >"$scratchdir/xattrs.txt" 106 | 107 | checkit "$RSYNC -aiX --fake-super --link-dest=../chk . ../to" "$chkdir" "$todir" 108 | 109 | cd "$todir" 110 | xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" - 111 | 112 | sed -n -e '/^[^ ][^ ]* *[^ ][^ ]* *[^ ][^ ]* *1 /p' "$scratchdir/ls-to" >"$scratchdir/ls-diff-all" 113 | fgrep -v './file1' "$scratchdir/ls-diff-all" >"$scratchdir/ls-diff" || : 114 | if [ -s "$scratchdir/ls-diff" ]; then 115 | echo "Missing hard links on:" 116 | cat "$scratchdir/ls-diff" 117 | exit 1 118 | fi 119 | if [ ! -s "$scratchdir/ls-diff-all" ]; then 120 | echo "Too many hard links on file1!" 121 | exit 1 122 | fi 123 | 124 | cd "$chkdir" 125 | chmod go-rwx . $dirs $files 126 | 127 | xset user.nice 'this is nice, but different' file1 128 | xset user.rsync.%stat "40000 0,0 $uid_gid" $dirs 129 | xset user.rsync.%stat "100000 0,0 $uid_gid" $files 130 | 131 | xls $dirs $files >"$scratchdir/xattrs.txt" 132 | 133 | cd "$fromdir" 134 | rm -rf "$todir" 135 | 136 | # When run by a non-root tester, this checks if no-user-perm files/dirs can be copied. 137 | checkit "$RSYNC -aiX --fake-super --chmod=a= . ../to" "$chkdir" "$todir" # 2>"$scratchdir/errors.txt" 138 | 139 | cd "$todir" 140 | xls $dirs $files | diff $diffopt "$scratchdir/xattrs.txt" - 141 | 142 | cd "$fromdir" 143 | rm -rf "$todir" "$chkdir" 144 | 145 | $RSYNC -aX file1 file2 146 | $RSYNC -aX file1 file2 ../chk/ 147 | $RSYNC -aX --del ../chk/ . 148 | $RSYNC -aX file1 ../lnk/ 149 | 150 | xls file1 file2 >"$scratchdir/xattrs.txt" 151 | 152 | checkit "$RSYNC -aiiX --copy-dest=../lnk . ../to" "$chkdir" "$todir" 153 | 154 | cd "$todir" 155 | xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" - 156 | 157 | cd "$fromdir" 158 | rm "$todir/file2" 159 | 160 | echo extra >file1 161 | $RSYNC -aX . ../chk/ 162 | 163 | checkit "$RSYNC -aiiX . ../to" "$chkdir" "$todir" 164 | 165 | cd "$todir" 166 | xls file1 file2 | diff $diffopt "$scratchdir/xattrs.txt" - 167 | 168 | # The script would have aborted on error, so getting here means we've won. 169 | exit 0 170 | -------------------------------------------------------------------------------- /trimslash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple utility used only by the test harness. 3 | * 4 | * Copyright (C) 2002 Martin Pool 5 | * Copyright (C) 2003 Wayne Davison 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License along 18 | * with this program; if not, visit the http://fsf.org website. 19 | */ 20 | 21 | #include "rsync.h" 22 | 23 | /* These are to make syscall.o shut up. */ 24 | int dry_run = 0; 25 | int am_root = 0; 26 | int am_sender = 1; 27 | int read_only = 1; 28 | int list_only = 0; 29 | int preserve_perms = 0; 30 | int preserve_executability = 0; 31 | char number_separator = ','; 32 | 33 | int 34 | main(int argc, char **argv) 35 | { 36 | int i; 37 | 38 | if (argc <= 1) { 39 | fprintf(stderr, "trimslash: needs at least one argument\n"); 40 | return 1; 41 | } 42 | 43 | for (i = 1; i < argc; i++) { 44 | trim_trailing_slashes(argv[i]); /* modify in place */ 45 | printf("%s\n", argv[i]); 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /tweak_manpage: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -i -p 2 | 3 | # Make some hyphens unbreakable. 4 | s{(--\w[-\w]+)}{ $x = $1; $x =~ s/-/\\-/g; $x }eg; 5 | s/(?= (BASE << 16)) a -= (BASE << 16); \ 26 | if (a >= (BASE << 15)) a -= (BASE << 15); \ 27 | if (a >= (BASE << 14)) a -= (BASE << 14); \ 28 | if (a >= (BASE << 13)) a -= (BASE << 13); \ 29 | if (a >= (BASE << 12)) a -= (BASE << 12); \ 30 | if (a >= (BASE << 11)) a -= (BASE << 11); \ 31 | if (a >= (BASE << 10)) a -= (BASE << 10); \ 32 | if (a >= (BASE << 9)) a -= (BASE << 9); \ 33 | if (a >= (BASE << 8)) a -= (BASE << 8); \ 34 | if (a >= (BASE << 7)) a -= (BASE << 7); \ 35 | if (a >= (BASE << 6)) a -= (BASE << 6); \ 36 | if (a >= (BASE << 5)) a -= (BASE << 5); \ 37 | if (a >= (BASE << 4)) a -= (BASE << 4); \ 38 | if (a >= (BASE << 3)) a -= (BASE << 3); \ 39 | if (a >= (BASE << 2)) a -= (BASE << 2); \ 40 | if (a >= (BASE << 1)) a -= (BASE << 1); \ 41 | if (a >= BASE) a -= BASE; \ 42 | } while (0) 43 | # define MOD4(a) \ 44 | do { \ 45 | if (a >= (BASE << 4)) a -= (BASE << 4); \ 46 | if (a >= (BASE << 3)) a -= (BASE << 3); \ 47 | if (a >= (BASE << 2)) a -= (BASE << 2); \ 48 | if (a >= (BASE << 1)) a -= (BASE << 1); \ 49 | if (a >= BASE) a -= BASE; \ 50 | } while (0) 51 | #else 52 | # define MOD(a) a %= BASE 53 | # define MOD4(a) a %= BASE 54 | #endif 55 | 56 | /* ========================================================================= */ 57 | uLong ZEXPORT adler32(adler, buf, len) 58 | uLong adler; 59 | const Bytef *buf; 60 | uInt len; 61 | { 62 | unsigned long sum2; 63 | unsigned n; 64 | 65 | /* split Adler-32 into component sums */ 66 | sum2 = (adler >> 16) & 0xffff; 67 | adler &= 0xffff; 68 | 69 | /* in case user likes doing a byte at a time, keep it fast */ 70 | if (len == 1) { 71 | adler += buf[0]; 72 | if (adler >= BASE) 73 | adler -= BASE; 74 | sum2 += adler; 75 | if (sum2 >= BASE) 76 | sum2 -= BASE; 77 | return adler | (sum2 << 16); 78 | } 79 | 80 | /* initial Adler-32 value (deferred check for len == 1 speed) */ 81 | if (buf == Z_NULL) 82 | return 1L; 83 | 84 | /* in case short lengths are provided, keep it somewhat fast */ 85 | if (len < 16) { 86 | while (len--) { 87 | adler += *buf++; 88 | sum2 += adler; 89 | } 90 | if (adler >= BASE) 91 | adler -= BASE; 92 | MOD4(sum2); /* only added so many BASE's */ 93 | return adler | (sum2 << 16); 94 | } 95 | 96 | /* do length NMAX blocks -- requires just one modulo operation */ 97 | while (len >= NMAX) { 98 | len -= NMAX; 99 | n = NMAX / 16; /* NMAX is divisible by 16 */ 100 | do { 101 | DO16(buf); /* 16 sums unrolled */ 102 | buf += 16; 103 | } while (--n); 104 | MOD(adler); 105 | MOD(sum2); 106 | } 107 | 108 | /* do remaining bytes (less than NMAX, still just one modulo) */ 109 | if (len) { /* avoid modulos if none remaining */ 110 | while (len >= 16) { 111 | len -= 16; 112 | DO16(buf); 113 | buf += 16; 114 | } 115 | while (len--) { 116 | adler += *buf++; 117 | sum2 += adler; 118 | } 119 | MOD(adler); 120 | MOD(sum2); 121 | } 122 | 123 | /* return recombined sums */ 124 | return adler | (sum2 << 16); 125 | } 126 | 127 | /* ========================================================================= */ 128 | uLong ZEXPORT adler32_combine(adler1, adler2, len2) 129 | uLong adler1; 130 | uLong adler2; 131 | z_off_t len2; 132 | { 133 | unsigned long sum1; 134 | unsigned long sum2; 135 | unsigned rem; 136 | 137 | /* the derivation of this formula is left as an exercise for the reader */ 138 | rem = (unsigned)(len2 % BASE); 139 | sum1 = adler1 & 0xffff; 140 | sum2 = rem * sum1; 141 | MOD(sum2); 142 | sum1 += (adler2 & 0xffff) + BASE - 1; 143 | sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; 144 | if (sum1 > BASE) sum1 -= BASE; 145 | if (sum1 > BASE) sum1 -= BASE; 146 | if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); 147 | if (sum2 > BASE) sum2 -= BASE; 148 | return sum1 | (sum2 << 16); 149 | } 150 | -------------------------------------------------------------------------------- /zlib/compress.c: -------------------------------------------------------------------------------- 1 | /* compress.c -- compress a memory buffer 2 | * Copyright (C) 1995-2003 Jean-loup Gailly. 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* @(#) $Id$ */ 7 | 8 | #define ZLIB_INTERNAL 9 | #include "zlib.h" 10 | 11 | /* =========================================================================== 12 | Compresses the source buffer into the destination buffer. The level 13 | parameter has the same meaning as in deflateInit. sourceLen is the byte 14 | length of the source buffer. Upon entry, destLen is the total size of the 15 | destination buffer, which must be at least 0.1% larger than sourceLen plus 16 | 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. 17 | 18 | compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough 19 | memory, Z_BUF_ERROR if there was not enough room in the output buffer, 20 | Z_STREAM_ERROR if the level parameter is invalid. 21 | */ 22 | int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) 23 | Bytef *dest; 24 | uLongf *destLen; 25 | const Bytef *source; 26 | uLong sourceLen; 27 | int level; 28 | { 29 | z_stream stream; 30 | int err; 31 | 32 | stream.next_in = (Bytef*)source; 33 | stream.avail_in = (uInt)sourceLen; 34 | #ifdef MAXSEG_64K 35 | /* Check for source > 64K on 16-bit machine: */ 36 | if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; 37 | #endif 38 | stream.next_out = dest; 39 | stream.avail_out = (uInt)*destLen; 40 | if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; 41 | 42 | stream.zalloc = (alloc_func)0; 43 | stream.zfree = (free_func)0; 44 | stream.opaque = (voidpf)0; 45 | 46 | err = deflateInit(&stream, level); 47 | if (err != Z_OK) return err; 48 | 49 | err = deflate(&stream, Z_FINISH); 50 | if (err != Z_STREAM_END) { 51 | deflateEnd(&stream); 52 | return err == Z_OK ? Z_BUF_ERROR : err; 53 | } 54 | *destLen = stream.total_out; 55 | 56 | err = deflateEnd(&stream); 57 | return err; 58 | } 59 | 60 | /* =========================================================================== 61 | */ 62 | int ZEXPORT compress (dest, destLen, source, sourceLen) 63 | Bytef *dest; 64 | uLongf *destLen; 65 | const Bytef *source; 66 | uLong sourceLen; 67 | { 68 | return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); 69 | } 70 | 71 | /* =========================================================================== 72 | If the default memLevel or windowBits for deflateInit() is changed, then 73 | this function needs to be updated. 74 | */ 75 | uLong ZEXPORT compressBound (sourceLen) 76 | uLong sourceLen; 77 | { 78 | return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; 79 | } 80 | -------------------------------------------------------------------------------- /zlib/dummy.in: -------------------------------------------------------------------------------- 1 | This is a dummy file to ensure that the lib directory gets created 2 | by configure when a VPATH is used. 3 | -------------------------------------------------------------------------------- /zlib/inffast.h: -------------------------------------------------------------------------------- 1 | /* inffast.h -- header to use inffast.c 2 | * Copyright (C) 1995-2003 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | void inflate_fast OF((z_streamp strm, unsigned start)); 12 | -------------------------------------------------------------------------------- /zlib/inftrees.h: -------------------------------------------------------------------------------- 1 | /* inftrees.h -- header to use inftrees.c 2 | * Copyright (C) 1995-2005 Mark Adler 3 | * For conditions of distribution and use, see copyright notice in zlib.h 4 | */ 5 | 6 | /* WARNING: this file should *not* be used by applications. It is 7 | part of the implementation of the compression library and is 8 | subject to change. Applications should only use zlib.h. 9 | */ 10 | 11 | /* Structure for decoding tables. Each entry provides either the 12 | information needed to do the operation requested by the code that 13 | indexed that table entry, or it provides a pointer to another 14 | table that indexes more bits of the code. op indicates whether 15 | the entry is a pointer to another table, a literal, a length or 16 | distance, an end-of-block, or an invalid code. For a table 17 | pointer, the low four bits of op is the number of index bits of 18 | that table. For a length or distance, the low four bits of op 19 | is the number of extra bits to get after the code. bits is 20 | the number of bits in this code or part of the code to drop off 21 | of the bit buffer. val is the actual byte to output in the case 22 | of a literal, the base length or distance, or the offset from 23 | the current table to the next table. Each entry is four bytes. */ 24 | typedef struct { 25 | unsigned char op; /* operation, extra bits, table bits */ 26 | unsigned char bits; /* bits in this part of the code */ 27 | unsigned short val; /* offset in table or code value */ 28 | } code; 29 | 30 | /* op values as set by inflate_table(): 31 | 00000000 - literal 32 | 0000tttt - table link, tttt != 0 is the number of table index bits 33 | 0001eeee - length or distance, eeee is the number of extra bits 34 | 01100000 - end of block 35 | 01000000 - invalid code 36 | */ 37 | 38 | /* Maximum size of dynamic tree. The maximum found in a long but non- 39 | exhaustive search was 1444 code structures (852 for length/literals 40 | and 592 for distances, the latter actually the result of an 41 | exhaustive search). The true maximum is not known, but the value 42 | below is more than safe. */ 43 | #define ENOUGH 2048 44 | #define MAXD 592 45 | 46 | /* Type of code to build for inftable() */ 47 | typedef enum { 48 | CODES, 49 | LENS, 50 | DISTS 51 | } codetype; 52 | 53 | extern int inflate_table OF((codetype type, unsigned short FAR *lens, 54 | unsigned codes, code FAR * FAR *table, 55 | unsigned FAR *bits, unsigned short FAR *work)); 56 | --------------------------------------------------------------------------------