├── .gitignore ├── COPYING ├── Doxyfile ├── INSTALL ├── Makefile.in ├── NEWS ├── OLDNEWS ├── README ├── README-huai.md ├── TODO ├── access.c ├── 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 ├── getpass.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 ├── m4 ├── have_type.m4 ├── socklen_t.m4 └── validate_cache_system_type.m4 ├── 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 ├── systemd │ └── rsync.service └── 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-ssl.in ├── rsync.c ├── rsync.h ├── rsync.yo ├── rsync3.txt ├── rsyncd.conf.yo ├── rsyncsh.txt ├── runtests.sh ├── sender.c ├── shconfig.in ├── socket.c ├── stunnel-rsync.in ├── stunnel-rsyncd.conf.in ├── support ├── Makefile ├── atomic-rsync ├── cvs2includes ├── deny-rsync ├── file-attr-restore ├── files-to-excludes ├── git-set-file-times ├── instant-rsyncd ├── logfilter ├── lsh ├── lsh.sh ├── mapfrom ├── mapto ├── mnt-excl ├── munge-symlinks ├── rrsync ├── rsync-no-vanished ├── rsync-slash-strip ├── 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 ├── util2.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 ├── gzguts.h ├── 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 | *~ 3 | dummy 4 | ID 5 | Makefile 6 | Makefile.old 7 | configure.sh 8 | configure.sh.old 9 | config.cache 10 | config.h 11 | config.h.in 12 | config.h.in.old 13 | config.log 14 | config.status 15 | aclocal.m4 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 | /rsync-ssl 28 | /stunnel-rsync 29 | /stunnel-rsyncd.conf 30 | /shconfig 31 | /testdir 32 | /tests-dont-exist 33 | /testtmp 34 | /tls 35 | /testrun 36 | /trimslash 37 | /t_unsafe 38 | /wildtest 39 | /getfsdev 40 | /rounding.h 41 | /doc/rsync.pdf 42 | /doc/rsync.ps 43 | /support/savetransfer 44 | /testsuite/chown-fake.test 45 | /testsuite/devices-fake.test 46 | /testsuite/xattrs-hlink.test 47 | /patches 48 | .deps 49 | -------------------------------------------------------------------------------- /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 in Makefile.in to list all the *.c 37 | filenames explicitly in order to avoid this issue. 38 | 39 | RPM NOTES 40 | --------- 41 | 42 | Under packaging you will find .spec files for several distributions. 43 | The .spec file in packaging/lsb can be used for Linux systems that 44 | adhere to the Linux Standards Base (e.g., RedHat and others). 45 | 46 | HP-UX NOTES 47 | ----------- 48 | 49 | The HP-UX 10.10 "bundled" C compiler seems not to be able to cope with 50 | ANSI C. You may see this error message in config.log if ./configure 51 | fails: 52 | 53 | (Bundled) cc: "configure", line 2162: error 1705: Function prototypes are an ANSI feature. 54 | 55 | Install gcc or HP's "ANSI/C Compiler". 56 | 57 | MAC OSX NOTES 58 | ------------- 59 | 60 | Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do 61 | not completely implement the "New Sockets" API. 62 | 63 | says that Apple started to support 64 | IPv6 in 10.2 (Jaguar). If your build fails, try again after running 65 | configure with --disable-ipv6. 66 | 67 | IBM AIX NOTES 68 | ------------- 69 | 70 | IBM AIX has a largefile problem with mkstemp. See IBM PR-51921. 71 | The workaround is to append the below to config.h 72 | #ifdef _LARGE_FILES 73 | #undef HAVE_SECURE_MKSTEMP 74 | #endif 75 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | NEWS for rsync 3.1.3 (UNRELEASED) 2 | Protocol: 31 (unchanged) 3 | Changes since 3.1.2: 4 | 5 | BUG FIXES: 6 | 7 | - Don't output about a new backup dir with appropriate info verbosity. 8 | - Fixed some issues with the sort functions in support/rsyncstats. 9 | - Added a way to specify group names that contain spaces in daemon config. 10 | - If a backup fails (e.g. full disk) rsync exits with an error. 11 | - Avoid invalid output in the summary if either the start or end time had 12 | an error. 13 | 14 | ENHANCEMENTS: 15 | 16 | - Added the ability for rsync to compare nanosecond times in its file-check 17 | comparisons. Also added a short-option (-@) for --modify-window. 18 | - Added the --checksum-choice=NAME[,NAME] option to choose the checksum 19 | algorithms. 20 | 21 | DEVELOPER RELATED: 22 | 23 | - Tweak the "make" output when yodl isn't around to create the man pages. 24 | - Changed an obsolete compile macro in configure. 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /byteorder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Simple byteorder handling. 3 | * 4 | * Copyright (C) 1992-1995 Andrew Tridgell 5 | * Copyright (C) 2007-2015 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 | #if defined __i386__ || defined __i486__ || defined __i586__ || defined __i686__ || __amd64 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 IVAL64(buf,pos) (IVAL(buf,pos)|(int64)IVAL(buf,(pos)+4)<<32) 42 | #define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) 43 | #define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) 44 | #define SIVAL(buf,pos,val) SIVALX(buf,pos,(uint32)(val)) 45 | #define SIVAL64(buf,pos,val) (SIVAL(buf,pos,val),SIVAL(buf,(pos)+4,(val)>>32)) 46 | 47 | #define IVALu(buf,pos) IVAL(buf,pos) 48 | #define SIVALu(buf,pos,val) SIVAL(buf,pos,val) 49 | 50 | #else /* !CAREFUL_ALIGNMENT */ 51 | 52 | /* This handles things for architectures like the 386 that can handle alignment errors. 53 | * WARNING: This section is dependent on the length of an int32 (and thus a uint32) 54 | * being correct (4 bytes)! Set CAREFUL_ALIGNMENT if it is not. */ 55 | 56 | # ifdef AVOID_BYTEORDER_INLINE 57 | 58 | #define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos))) 59 | #define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val)) 60 | 61 | #define IVALu(buf,pos) IVAL(buf,pos) 62 | #define SIVALu(buf,pos,val) SIVAL(buf,pos,val) 63 | 64 | # else /* !AVOID_BYTEORDER_INLINE */ 65 | 66 | static inline uint32 67 | IVALu(const uchar *buf, int pos) 68 | { 69 | union { 70 | const uchar *b; 71 | const uint32 *num; 72 | } u; 73 | u.b = buf + pos; 74 | return *u.num; 75 | } 76 | 77 | static inline void 78 | SIVALu(uchar *buf, int pos, uint32 val) 79 | { 80 | union { 81 | uchar *b; 82 | uint32 *num; 83 | } u; 84 | u.b = buf + pos; 85 | *u.num = val; 86 | } 87 | 88 | static inline uint32 89 | IVAL(const char *buf, int pos) 90 | { 91 | return IVALu((uchar*)buf, pos); 92 | } 93 | 94 | static inline void 95 | SIVAL(char *buf, int pos, uint32 val) 96 | { 97 | SIVALu((uchar*)buf, pos, val); 98 | } 99 | 100 | static inline int64 101 | IVAL64(const char *buf, int pos) 102 | { 103 | union { 104 | const char *b; 105 | const int64 *num; 106 | } u; 107 | u.b = buf + pos; 108 | return *u.num; 109 | } 110 | 111 | static inline void 112 | SIVAL64(char *buf, int pos, int64 val) 113 | { 114 | union { 115 | char *b; 116 | int64 *num; 117 | } u; 118 | u.b = buf + pos; 119 | *u.num = val; 120 | } 121 | 122 | # endif /* !AVOID_BYTEORDER_INLINE */ 123 | 124 | #endif /* !CAREFUL_ALIGNMENT */ 125 | -------------------------------------------------------------------------------- /case_N.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Allow an arbitrary sequence of case labels. 3 | * 4 | * Copyright (C) 2006-2015 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-2015 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-2015 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 | -------------------------------------------------------------------------------- /ifuncs.h: -------------------------------------------------------------------------------- 1 | /* Inline functions for rsync. 2 | * 3 | * Copyright (C) 2007-2015 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 | 89 | static inline void 90 | free_stat_x(stat_x *sx_p) 91 | { 92 | #ifdef SUPPORT_ACLS 93 | { 94 | extern int preserve_acls; 95 | if (preserve_acls) 96 | free_acl(sx_p); 97 | } 98 | #endif 99 | #ifdef SUPPORT_XATTRS 100 | { 101 | extern int preserve_xattrs; 102 | if (preserve_xattrs) 103 | free_xattr(sx_p); 104 | } 105 | #endif 106 | } 107 | -------------------------------------------------------------------------------- /inums.h: -------------------------------------------------------------------------------- 1 | /* Inline functions for rsync. 2 | * 3 | * Copyright (C) 2008-2015 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-2015 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-2015 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/getpass.c: -------------------------------------------------------------------------------- 1 | /* 2 | * An implementation of getpass for systems that lack one. 3 | * 4 | * Copyright (C) 2013 Roman Donchenko 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 21 | #include 22 | #include 23 | 24 | #include "rsync.h" 25 | 26 | char *getpass(const char *prompt) 27 | { 28 | static char password[256]; 29 | 30 | BOOL tty_changed = False, read_success; 31 | struct termios tty_old, tty_new; 32 | FILE *in = stdin, *out = stderr; 33 | FILE *tty = fopen("/dev/tty", "w+"); 34 | 35 | if (tty) 36 | in = out = tty; 37 | 38 | if (tcgetattr(fileno(in), &tty_old) == 0) { 39 | tty_new = tty_old; 40 | tty_new.c_lflag &= ~(ECHO | ISIG); 41 | 42 | if (tcsetattr(fileno(in), TCSAFLUSH, &tty_new) == 0) 43 | tty_changed = True; 44 | } 45 | 46 | if (!tty_changed) 47 | fputs("(WARNING: will be visible) ", out); 48 | fputs(prompt, out); 49 | fflush(out); 50 | 51 | read_success = fgets(password, sizeof password, in) != NULL; 52 | 53 | /* Print the newline that hasn't been echoed. */ 54 | fputc('\n', out); 55 | 56 | if (tty_changed) 57 | tcsetattr(fileno(in), TCSAFLUSH, &tty_old); 58 | 59 | if (tty) 60 | fclose(tty); 61 | 62 | if (read_success) { 63 | /* Remove the trailing newline. */ 64 | size_t password_len = strlen(password); 65 | if (password_len && password[password_len - 1] == '\n') 66 | password[password_len - 1] = '\0'; 67 | 68 | return password; 69 | } 70 | 71 | return NULL; 72 | } 73 | -------------------------------------------------------------------------------- /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-2015 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 | -------------------------------------------------------------------------------- /m4/have_type.m4: -------------------------------------------------------------------------------- 1 | dnl AC_HAVE_TYPE(TYPE,INCLUDES) 2 | AC_DEFUN([AC_HAVE_TYPE], [ 3 | AC_REQUIRE([AC_HEADER_STDC]) 4 | cv=`echo "$1" | sed 'y%./+- %__p__%'` 5 | AC_MSG_CHECKING(for $1) 6 | AC_CACHE_VAL([ac_cv_type_$cv], 7 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 8 | AC_INCLUDES_DEFAULT 9 | $2]], 10 | [[$1 foo;]])], 11 | [eval "ac_cv_type_$cv=yes"], 12 | [eval "ac_cv_type_$cv=no"]))dnl 13 | ac_foo=`eval echo \\$ac_cv_type_$cv` 14 | AC_MSG_RESULT($ac_foo) 15 | if test "$ac_foo" = yes; then 16 | ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'` 17 | if false; then 18 | AC_CHECK_TYPES($1) 19 | fi 20 | AC_DEFINE_UNQUOTED($ac_tr_hdr, 1, [Define if you have type `$1']) 21 | fi 22 | ]) 23 | -------------------------------------------------------------------------------- /m4/socklen_t.m4: -------------------------------------------------------------------------------- 1 | dnl Check for socklen_t: historically on BSD it is an int, and in 2 | dnl POSIX 1g it is a type of its own, but some platforms use different 3 | dnl types for the argument to getsockopt, getpeername, etc. So we 4 | dnl have to test to find something that will work. 5 | 6 | dnl This is no good, because passing the wrong pointer on C compilers is 7 | dnl likely to only generate a warning, not an error. We don't call this at 8 | dnl the moment. 9 | 10 | AC_DEFUN([TYPE_SOCKLEN_T], 11 | [ 12 | AC_CHECK_TYPE([socklen_t], ,[ 13 | AC_MSG_CHECKING([for socklen_t equivalent]) 14 | AC_CACHE_VAL([rsync_cv_socklen_t_equiv], 15 | [ 16 | # Systems have either "struct sockaddr *" or 17 | # "void *" as the second argument to getpeername 18 | rsync_cv_socklen_t_equiv= 19 | for arg2 in "struct sockaddr" void; do 20 | for t in int size_t unsigned long "unsigned long"; do 21 | AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ 22 | #include 23 | #include 24 | 25 | int getpeername (int, $arg2 *, $t *); 26 | ]],[[ 27 | $t len; 28 | getpeername(0,0,&len); 29 | ]])],[ 30 | rsync_cv_socklen_t_equiv="$t" 31 | break 32 | ]) 33 | done 34 | done 35 | 36 | if test "x$rsync_cv_socklen_t_equiv" = x; then 37 | AC_MSG_ERROR([Cannot find a type to use in place of socklen_t]) 38 | fi 39 | ]) 40 | AC_MSG_RESULT($rsync_cv_socklen_t_equiv) 41 | AC_DEFINE_UNQUOTED(socklen_t, $rsync_cv_socklen_t_equiv, 42 | [type to use in place of socklen_t if not defined])], 43 | [#include 44 | #include ]) 45 | ]) 46 | -------------------------------------------------------------------------------- /m4/validate_cache_system_type.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 | -------------------------------------------------------------------------------- /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 | require 'packaging/git-status.pl'; 17 | check_git_state($master_branch, !$skip_branch_check, 1); 18 | 19 | my %local_branch; 20 | open PIPE, '-|', 'git branch -l' or die "Unable to fork: $!\n"; 21 | while () { 22 | if (m# patch/\Q$master_branch\E/(.*)#o) { 23 | $local_branch{$1} = 1; 24 | } 25 | } 26 | close PIPE; 27 | 28 | if ($delete_local_branches) { 29 | foreach my $name (sort keys %local_branch) { 30 | my $branch = "patch/$master_branch/$name"; 31 | system 'git', 'branch', '-D', $branch and exit 1; 32 | } 33 | %local_branch = ( ); 34 | } 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 | 'daemon' => -1, 12 | 'debug' => 1, 13 | 'fake-super' => 0, 14 | 'fuzzy' => 0, 15 | 'group' => 0, 16 | 'hard-links' => 0, 17 | 'ignore-times' => 0, 18 | 'info' => 1, 19 | 'links' => 0, 20 | 'log-file' => 3, 21 | 'one-file-system' => 0, 22 | 'owner' => 0, 23 | 'perms' => 0, 24 | 'recursive' => 0, 25 | 'times' => 0, 26 | ); 27 | our $last_long_opt; 28 | 29 | open(IN, '../options.c') or die "Unable to open ../options.c: $!\n"; 30 | 31 | while () { 32 | if (/\Qargstr[x++]\E = '([^.ie])'/) { 33 | $short_no_arg{$1} = 1; 34 | undef $last_long_opt; 35 | } elsif (/\Qasprintf(\E[^,]+, "-([a-zA-Z0-9])\%l?[ud]"/) { 36 | $short_with_num{$1} = 1; 37 | undef $last_long_opt; 38 | } elsif (/\Qargs[ac++]\E = "--([^"=]+)"/) { 39 | $last_long_opt = $1; 40 | $long_opt{$1} = 0 unless exists $long_opt{$1}; 41 | } elsif (defined($last_long_opt) 42 | && /\Qargs[ac++]\E = ([^["\s]+);/ && $1 ne 'dest_option') { 43 | $long_opt{$last_long_opt} = 2; 44 | undef $last_long_opt; 45 | } elsif (/dest_option = "--([^"]+)"/) { 46 | $long_opt{$1} = 2; 47 | undef $last_long_opt; 48 | } elsif (/\Qasprintf(\E[^,]+, "--([^"=]+)=/ || /\Qargs[ac++]\E = "--([^"=]+)=/) { 49 | $long_opt{$1} = 1; 50 | undef $last_long_opt; 51 | } 52 | } 53 | close IN; 54 | 55 | my $short_no_arg = join('', sort keys %short_no_arg); 56 | my $short_with_num = join('', sort keys %short_with_num); 57 | 58 | print < $val,\n"; 81 | } 82 | 83 | print ");\n\n"; 84 | -------------------------------------------------------------------------------- /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 | (my $branch = $cur_branch) =~ s{^patch/([^/]+)/[^/]+$}{$1}; # change patch/BRANCH/PATCH_NAME into BRANCH 10 | if ($branch ne $master_branch) { 11 | print "The checkout is not on the $master_branch branch.\n"; 12 | exit 1 if $master_branch ne 'master'; 13 | print "Do you want me to continue with --branch=$branch? [n] "; 14 | $_ = ; 15 | exit 1 unless /^y/i; 16 | $_[0] = $master_branch = $branch; # Updates caller's $master_branch too. 17 | } 18 | 19 | if ($check_patches_dir && -d 'patches/.git') { 20 | ($branch) = check_git_status($fatal_unless_clean, 'patches'); 21 | if ($branch ne $master_branch) { 22 | print "The *patches* checkout is on branch $branch, not branch $master_branch.\n"; 23 | print "Do you want to change it to branch $master_branch? [n] "; 24 | $_ = ; 25 | exit 1 unless /^y/i; 26 | system "cd patches && git checkout '$master_branch'"; 27 | } 28 | } 29 | 30 | return $cur_branch; 31 | } 32 | 33 | sub check_git_status 34 | { 35 | my($fatal_unless_clean, $subdir) = @_; 36 | $subdir = '.' unless defined $subdir; 37 | my $status = `cd '$subdir' && git status`; 38 | my $is_clean = $status =~ /\nnothing to commit.+working directory clean/; 39 | my($cur_branch) = $status =~ /^(?:# )?On branch (.+)\n/; 40 | if ($fatal_unless_clean && !$is_clean) { 41 | if ($subdir eq '.') { 42 | $subdir = ''; 43 | } else { 44 | $subdir = " *$subdir*"; 45 | } 46 | die "The$subdir checkout is not clean:\n", $status; 47 | } 48 | ($cur_branch, $is_clean, $status); 49 | } 50 | 51 | 1; 52 | -------------------------------------------------------------------------------- /packaging/lsb/rsync.spec: -------------------------------------------------------------------------------- 1 | Summary: A fast, versatile, remote (and local) file-copying tool 2 | Name: rsync 3 | Version: 3.1.2 4 | %define fullversion %{version} 5 | Release: 1 6 | %define srcdir src 7 | Group: Applications/Internet 8 | License: GPL 9 | Source0: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz 10 | #Source1: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-patches-%{fullversion}.tar.gz 11 | URL: http://rsync.samba.org/ 12 | 13 | Prefix: %{_prefix} 14 | BuildRoot: /var/tmp/%{name}-root 15 | 16 | %package ssl-client 17 | Summary: Provides rsync-ssl 18 | Group: Applications/Internet 19 | Requires: rsync, stunnel >= 4 20 | 21 | %package ssl-daemon 22 | Summary: An stunnel config file to support ssl rsync daemon connections. 23 | Group: Applications/Internet 24 | Requires: rsync, stunnel >= 4 25 | 26 | %description 27 | Rsync is a fast and extraordinarily versatile file copying tool. It can 28 | copy locally, to/from another host over any remote shell, or to/from a 29 | remote rsync daemon. It offers a large number of options that control 30 | every aspect of its behavior and permit very flexible specification of the 31 | set of files to be copied. It is famous for its delta-transfer algorithm, 32 | which reduces the amount of data sent over the network by sending only the 33 | differences between the source files and the existing files in the 34 | destination. Rsync is widely used for backups and mirroring and as an 35 | improved copy command for everyday use. 36 | 37 | %description ssl-client 38 | Provides the rsync-ssl script that makes use of stunnel 4 to open an ssl 39 | connection to an rsync daemon (on port 874). This setup does NOT require 40 | any local stunnel daemon to be running to connect to the remote ssl rsyncd. 41 | 42 | %description ssl-daemon 43 | Provides a config file for stunnel that will (if you start your stunnel 44 | service) cause stunnel to listen for ssl rsync-daemon connections and run 45 | "rsync --daemon" to handle them. 46 | 47 | %prep 48 | # Choose one -- setup source only, or setup source + rsync-patches: 49 | %setup -q -n rsync-%{fullversion} 50 | #%setup -q -b1 -n rsync-%{fullversion} 51 | 52 | # If you you used "%setup -q -b1 ...", choose the patches you wish to apply: 53 | #patch -p1 95 | Released 3.1.2. 96 | 97 | * Fri Mar 21 2008 Wayne Davison 98 | Added installation of /etc/xinetd.d/rsync file and some commented-out 99 | lines that demonstrate how to use the rsync-patches tar file. 100 | -------------------------------------------------------------------------------- /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/systemd/rsync.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=fast remote file copy program daemon 3 | ConditionPathExists=/etc/rsyncd.conf 4 | 5 | [Service] 6 | ExecStart=/usr/bin/rsync --daemon --no-detach 7 | 8 | [Install] 9 | WantedBy=multi-user.target 10 | -------------------------------------------------------------------------------- /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/tuna/rsync/6cadc8e31f1d3882b1bf2eefa0c2587d799e3946/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='[ca]*' 31 | else 32 | files='[cap]*' 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 | aclocal.m4: 4 | aclocal -I m4 5 | 6 | configure.sh: configure.ac aclocal.m4 7 | autoconf -o configure.sh 8 | 9 | config.h.in: configure.ac aclocal.m4 10 | autoheader && touch config.h.in 11 | -------------------------------------------------------------------------------- /rounding.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A pre-compilation helper program to aid in the creation of rounding.h. 3 | * 4 | * Copyright (C) 2007-2015 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 | -------------------------------------------------------------------------------- /rsync-ssl.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script supports using stunnel to secure an rsync daemon connection. 3 | # Note that this requires at least version 4.x of stunnel. 4 | case "$@" in 5 | *rsync://*) ;; 6 | *::*) ;; 7 | *) 8 | echo "You must use rsync-ssl with a daemon-style hostname." 0>&1 9 | exit 1 10 | ;; 11 | esac 12 | exec @bindir@/rsync --rsh=@bindir@/stunnel-rsync "${@}" 13 | -------------------------------------------------------------------------------- /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 | HOST_OS="@host_os@" 12 | SHELL_PATH="@SHELL_PATH@" 13 | FAKEROOT_PATH="@FAKEROOT_PATH@" 14 | 15 | export ECHO_T ECHO_N ECHO_C HOST_OS SHELL_PATH FAKEROOT_PATH 16 | -------------------------------------------------------------------------------- /stunnel-rsync.in: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This must be called as (note the trailing dot): 3 | # 4 | # stunnel-rsync HOSTNAME rsync --server --daemon . 5 | # 6 | # ... which is typically done via the rsync-ssl script, which results in something like this: 7 | # 8 | # rsync --rsh=stunnel-rsync -aiv HOSTNAME::module [ARGS] 9 | # 10 | # This SSL setup based on the files by: http://dozzie.jarowit.net/trac/wiki/RsyncSSL 11 | # Note that this requires at least version 4.x of stunnel. 12 | 13 | # The current environment can override using the RSYNC_SSL_* values: 14 | if [ x"$RSYNC_SSL_CERT" = x ]; then 15 | cert="" 16 | else 17 | cert="cert = $RSYNC_SSL_CERT" 18 | fi 19 | if [ x"$RSYNC_SSL_CA_CERT" ]; then 20 | cafile="" 21 | verify=0 22 | else 23 | cafile="CAfile = $RSYNC_SSL_CA_CERT" 24 | verify=3 25 | fi 26 | port=${RSYNC_SSL_PORT:-874} 27 | 28 | # If the user specified USER@HOSTNAME::module, then rsync passes us 29 | # the -l USER option too, so we must be prepared to ignore it. 30 | if [ x"$1" = x"-l" ]; then 31 | shift 2 32 | fi 33 | 34 | hostname=$1 35 | shift 36 | 37 | if [ x"$hostname" = x -o x"$1" != x"rsync" -o x"$2" != x"--server" -o x"$3" != x"--daemon" ]; then 38 | echo "Usage: stunnel-rsync HOSTNAME rsync --server --daemon ." 1>&2 39 | exit 1 40 | fi 41 | 42 | # devzero@web.de came up with this no-tmpfile calling syntax: 43 | @stunnel4@ -fd 10 11<&0 <> 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/files-to-excludes: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # This script takes an input of filenames and outputs a set of 3 | # include/exclude directives that can be used by rsync to copy 4 | # just the indicated files using an --exclude-from=FILE option. 5 | use strict; 6 | 7 | my %hash; 8 | 9 | while (<>) { 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 | #!/usr/bin/perl 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 -l USER, we try to become the USER, either directly (must 7 | # be root) or by using "sudo -H -u USER" (requires --sudo option). 8 | 9 | use strict; 10 | use warnings; 11 | use Getopt::Long; 12 | use English '-no_match_vars'; 13 | 14 | &Getopt::Long::Configure('bundling'); 15 | &Getopt::Long::Configure('require_order'); 16 | GetOptions( 17 | 'l=s' => \( my $login_name ), 18 | '1|2|4|6|A|a|C|f|g|k|M|N|n|q|s|T|t|V|v|X|x|Y' => sub { }, # Ignore 19 | 'b|c|D|e|F|i|L|m|O|o|p|R|S|w=s' => sub { }, # Ignore 20 | 'no-cd' => \( my $no_chdir ), 21 | 'sudo' => \( my $use_sudo ), 22 | ) or &usage; 23 | &usage unless @ARGV > 1; 24 | 25 | my $host = shift; 26 | if ($host =~ s/^([^@]+)\@//) { 27 | $login_name = $1; 28 | } 29 | if ($host ne 'localhost') { 30 | die "lsh: unable to connect to host $host\n"; 31 | } 32 | 33 | my ($home_dir, @cmd); 34 | if ($login_name) { 35 | my ($uid, $gid); 36 | if ($login_name =~ /\D/) { 37 | $uid = getpwnam($login_name); 38 | die "Unknown user: $login_name\n" unless defined $uid; 39 | } else { 40 | $uid = $login_name; 41 | } 42 | ($login_name, $gid, $home_dir) = (getpwuid($uid))[0,3,7]; 43 | if ($use_sudo) { 44 | unshift @ARGV, "cd '$home_dir' &&" unless $no_chdir; 45 | unshift @cmd, qw( sudo -H -u ), $login_name; 46 | $no_chdir = 1; 47 | } else { 48 | my $groups = "$gid $gid"; 49 | while (my ($grgid, $grmembers) = (getgrent)[2,3]) { 50 | if ($grgid != $gid && $grmembers =~ /(^|\s)\Q$login_name\E(\s|$)/o) { 51 | $groups .= " $grgid"; 52 | } 53 | } 54 | 55 | my ($ruid, $euid) = ($UID, $EUID); 56 | $GID = $EGID = $groups; 57 | $UID = $EUID = $uid; 58 | die "Cannot set ruid: $! (use --sudo?)\n" if $UID == $ruid && $ruid != $uid; 59 | die "Cannot set euid: $! (use --sudo?)\n" if $EUID == $euid && $euid != $uid; 60 | 61 | $ENV{USER} = $ENV{USERNAME} = $login_name; 62 | $ENV{HOME} = $home_dir; 63 | } 64 | } else { 65 | $home_dir = (getpwuid($UID))[7]; 66 | } 67 | 68 | unless ($no_chdir) { 69 | chdir $home_dir or die "Unable to chdir to $home_dir: $!\n"; 70 | } 71 | 72 | push @cmd, '/bin/sh', '-c', "@ARGV"; 73 | exec @cmd; 74 | die "Failed to exec: $!\n"; 75 | 76 | sub usage 77 | { 78 | die <&2; exit 1 ;; 20 | esac 21 | done 22 | 23 | if [ "$user" ]; then 24 | prefix='' 25 | if [ $do_cd = y ]; then 26 | home=`perl -e "print((getpwnam('$user'))[7])"` 27 | prefix="cd '$home' &&" 28 | fi 29 | sudo -H -u "$user" sh -c "$prefix $*" 30 | else 31 | if [ $do_cd = y ]; then 32 | cd || exit 1 33 | fi 34 | eval "${@}" 35 | fi 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 script 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 <&1 | (egrep -v "$IGNOREOUT" || true) 9 | ret=$? 10 | 11 | if [[ $ret == $IGNOREEXIT ]]; then 12 | ret=0 13 | fi 14 | 15 | exit $ret 16 | -------------------------------------------------------------------------------- /support/rsync-slash-strip: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script can be used as an rsync command-line filter that strips a single 3 | # trailing slash from each arg. That treats "src/" the same as "src", thus 4 | # you need to use "src/." or "src//" for just the contents of the "src" dir. 5 | # (Note that command-line dir-excludes would need to use "excl//" too.) 6 | # 7 | # To use this, name it something like "rs", put it somewhere in your path, and 8 | # then use "rs" in place of "rsync" when you are typing your copy commands. 9 | args=() 10 | for arg in "${@}"; do 11 | if [[ "$arg" == / ]]; then 12 | args=("${args[@]}" /) 13 | else 14 | args=("${args[@]}" "${arg%/}") 15 | fi 16 | done 17 | exec /usr/bin/rsync "${args[@]}" 18 | -------------------------------------------------------------------------------- /support/savetransfer.c: -------------------------------------------------------------------------------- 1 | /* This program can record the stream of data flowing to or from a program. 2 | * This allows it to be used to check that rsync's data that is flowing 3 | * through a remote shell is not being corrupted (for example). 4 | * 5 | * Usage: savetransfer [-i|-o] OUTPUT_FILE PROGRAM [ARGS...] 6 | * -i Save the input going to PROGRAM to the OUTPUT_FILE 7 | * -o Save the output coming from PROGRAM to the OUTPUT_FILE 8 | * 9 | * If you want to capture the flow of data for an rsync command, use one of 10 | * the following commands (the resulting files should be identical): 11 | * 12 | * rsync -av --rsh="savetransfer -i /tmp/to.server ssh" 13 | * --rsync-path="savetransfer -i /tmp/from.client rsync" SOURCE DEST 14 | * 15 | * rsync -av --rsh="savetransfer -o /tmp/from.server ssh" 16 | * --rsync-path="savetransfer -o /tmp/to.client rsync" SOURCE DEST 17 | * 18 | * Note that this program aborts after 30 seconds of inactivity, so you'll need 19 | * to change it if that is not enough dead time for your transfer. Also, some 20 | * of the above commands will not notice that the transfer is done (if we're 21 | * saving the input to a PROGRAM and the PROGRAM goes away: we won't notice 22 | * that it's gone unless more data comes in) -- when this happens it will delay 23 | * at the end of the transfer until the timeout period expires. 24 | */ 25 | 26 | #include "../rsync.h" 27 | 28 | #define TIMEOUT_SECONDS 30 29 | 30 | #ifdef HAVE_SIGACTION 31 | static struct sigaction sigact; 32 | #endif 33 | 34 | void run_program(char **command); 35 | 36 | char buf[4096]; 37 | int save_data_from_program = 0; 38 | 39 | int 40 | main(int argc, char *argv[]) 41 | { 42 | int fd_file, len; 43 | struct timeval tv; 44 | fd_set fds; 45 | 46 | argv++; 47 | if (--argc && argv[0][0] == '-') { 48 | if (argv[0][1] == 'o') 49 | save_data_from_program = 1; 50 | else if (argv[0][1] == 'i') 51 | save_data_from_program = 0; 52 | else { 53 | fprintf(stderr, "Unknown option: %s\n", argv[0]); 54 | exit(1); 55 | } 56 | argv++; 57 | argc--; 58 | } 59 | if (argc < 2) { 60 | fprintf(stderr, "Usage: savetransfer [-i|-o] OUTPUT_FILE PROGRAM [ARGS...]\n"); 61 | fprintf(stderr, "-i Save the input going to PROGRAM to the OUTPUT_FILE\n"); 62 | fprintf(stderr, "-o Save the output coming from PROGRAM to the OUTPUT_FILE\n"); 63 | exit(1); 64 | } 65 | if ((fd_file = open(*argv, O_WRONLY|O_TRUNC|O_CREAT|O_BINARY, 0644)) < 0) { 66 | fprintf(stderr, "Unable to write to `%s': %s\n", *argv, strerror(errno)); 67 | exit(1); 68 | } 69 | set_blocking(fd_file); 70 | 71 | SIGACTION(SIGPIPE, SIG_IGN); 72 | 73 | run_program(argv + 1); 74 | 75 | #if defined HAVE_SETMODE && O_BINARY 76 | setmode(STDIN_FILENO, O_BINARY); 77 | setmode(STDOUT_FILENO, O_BINARY); 78 | #endif 79 | set_nonblocking(STDIN_FILENO); 80 | set_blocking(STDOUT_FILENO); 81 | 82 | while (1) { 83 | FD_ZERO(&fds); 84 | FD_SET(STDIN_FILENO, &fds); 85 | tv.tv_sec = TIMEOUT_SECONDS; 86 | tv.tv_usec = 0; 87 | if (!select(STDIN_FILENO+1, &fds, NULL, NULL, &tv)) 88 | break; 89 | if (!FD_ISSET(STDIN_FILENO, &fds)) 90 | break; 91 | if ((len = read(STDIN_FILENO, buf, sizeof buf)) <= 0) 92 | break; 93 | if (write(STDOUT_FILENO, buf, len) != len) { 94 | fprintf(stderr, "Failed to write data to stdout: %s\n", strerror(errno)); 95 | exit(1); 96 | } 97 | if (write(fd_file, buf, len) != len) { 98 | fprintf(stderr, "Failed to write data to fd_file: %s\n", strerror(errno)); 99 | exit(1); 100 | } 101 | } 102 | return 0; 103 | } 104 | 105 | void 106 | run_program(char **command) 107 | { 108 | int pipe_fds[2], ret; 109 | pid_t pid; 110 | 111 | if (pipe(pipe_fds) < 0) { 112 | fprintf(stderr, "pipe failed: %s\n", strerror(errno)); 113 | exit(1); 114 | } 115 | 116 | if ((pid = fork()) < 0) { 117 | fprintf(stderr, "fork failed: %s\n", strerror(errno)); 118 | exit(1); 119 | } 120 | 121 | if (pid == 0) { 122 | if (save_data_from_program) 123 | ret = dup2(pipe_fds[1], STDOUT_FILENO); 124 | else 125 | ret = dup2(pipe_fds[0], STDIN_FILENO); 126 | if (ret < 0) { 127 | fprintf(stderr, "Failed to dup (in child): %s\n", strerror(errno)); 128 | exit(1); 129 | } 130 | close(pipe_fds[0]); 131 | close(pipe_fds[1]); 132 | set_blocking(STDIN_FILENO); 133 | set_blocking(STDOUT_FILENO); 134 | execvp(command[0], command); 135 | fprintf(stderr, "Failed to exec %s: %s\n", command[0], strerror(errno)); 136 | exit(1); 137 | } 138 | 139 | if (save_data_from_program) 140 | ret = dup2(pipe_fds[0], STDIN_FILENO); 141 | else 142 | ret = dup2(pipe_fds[1], STDOUT_FILENO); 143 | if (ret < 0) { 144 | fprintf(stderr, "Failed to dup (in parent): %s\n", strerror(errno)); 145 | exit(1); 146 | } 147 | close(pipe_fds[0]); 148 | close(pipe_fds[1]); 149 | } 150 | 151 | void 152 | set_nonblocking(int fd) 153 | { 154 | int val; 155 | 156 | if ((val = fcntl(fd, F_GETFL, 0)) == -1) 157 | return; 158 | if (!(val & NONBLOCK_FLAG)) { 159 | val |= NONBLOCK_FLAG; 160 | fcntl(fd, F_SETFL, val); 161 | } 162 | } 163 | 164 | void 165 | set_blocking(int fd) 166 | { 167 | int val; 168 | 169 | if ((val = fcntl(fd, F_GETFL, 0)) < 0) 170 | return; 171 | if (val & NONBLOCK_FLAG) { 172 | val &= ~NONBLOCK_FLAG; 173 | fcntl(fd, F_SETFL, val); 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /t_stub.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file contains really simple implementations for rsync global 3 | * functions, so that module test harnesses can run standalone. 4 | * 5 | * Copyright (C) 2001, 2002 Martin Pool 6 | * Copyright (C) 2003-2015 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 inplace = 0; 25 | int modify_window = 0; 26 | int preallocate_files = 0; 27 | int protect_args = 0; 28 | int module_id = -1; 29 | int relative_paths = 0; 30 | int module_dirlen = 0; 31 | int preserve_acls = 0; 32 | int preserve_times = 0; 33 | int preserve_xattrs = 0; 34 | char *partial_dir; 35 | char *module_dir; 36 | filter_rule_list daemon_filter_list; 37 | 38 | void rprintf(UNUSED(enum logcode code), const char *format, ...) 39 | { 40 | va_list ap; 41 | va_start(ap, format); 42 | vfprintf(stderr, format, ap); 43 | va_end(ap); 44 | } 45 | 46 | void rsyserr(UNUSED(enum logcode code), int errcode, const char *format, ...) 47 | { 48 | va_list ap; 49 | fputs(RSYNC_NAME ": ", stderr); 50 | va_start(ap, format); 51 | vfprintf(stderr, format, ap); 52 | va_end(ap); 53 | fprintf(stderr, ": %s (%d)\n", strerror(errcode), errcode); 54 | } 55 | 56 | void _exit_cleanup(int code, const char *file, int line) 57 | { 58 | fprintf(stderr, "exit(%d): %s(%d)\n", 59 | code, file, line); 60 | exit(code); 61 | } 62 | 63 | int check_filter(UNUSED(filter_rule_list *listp), UNUSED(enum logcode code), 64 | UNUSED(const char *name), UNUSED(int name_is_dir)) 65 | { 66 | /* This function doesn't really get called in this test context, so 67 | * just return 0. */ 68 | return 0; 69 | } 70 | 71 | int copy_xattrs(UNUSED(const char *source), UNUSED(const char *dest)) 72 | { 73 | return -1; 74 | } 75 | 76 | void free_xattr(UNUSED(stat_x *sxp)) 77 | { 78 | return; 79 | } 80 | 81 | void free_acl(UNUSED(stat_x *sxp)) 82 | { 83 | return; 84 | } 85 | 86 | char *lp_name(UNUSED(int mod)) 87 | { 88 | return NULL; 89 | } 90 | 91 | BOOL lp_use_chroot(UNUSED(int mod)) 92 | { 93 | return 0; 94 | } 95 | 96 | const char *who_am_i(void) 97 | { 98 | return "tester"; 99 | } 100 | 101 | int csum_len_for_type(int cst) 102 | { 103 | return cst ? 16 : 1; 104 | } 105 | -------------------------------------------------------------------------------- /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-2015 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 %d: %s\n", (int)pid, strerror(errno)); 50 | else 51 | fprintf(stderr, "TESTRUN INFO: killed pid %d\n", (int)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`" || test_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" || test_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 "$HOST_OS" in 22 | darwin*) 23 | chown() { 24 | own=$1 25 | shift 26 | xattr -s 'rsync.%stat' "100644 0,0 $own" "${@}" 27 | } 28 | ;; 29 | solaris*) 30 | chown() { 31 | own=$1 32 | shift 33 | for fn in "${@}"; do 34 | runat "$fn" "$SHELL_PATH" < rsync.%stat 36 | EOF 37 | done 38 | } 39 | ;; 40 | *) 41 | chown() { 42 | own=$1 43 | shift 44 | setfattr -n 'user.rsync.%stat' -v "100644 0,0 $own" "${@}" 45 | } 46 | ;; 47 | esac 48 | ;; 49 | *) 50 | RSYNC="$RSYNC --super" 51 | case `get_testuid` in 52 | '') ;; # If "id" failed, try to continue... 53 | 0) ;; 54 | *) if [ -e "$FAKEROOT_PATH" ]; then 55 | echo "Let's try re-running the script under fakeroot..." 56 | exec "$FAKEROOT_PATH" "$SHELL_PATH" "$0" 57 | fi 58 | ;; 59 | esac 60 | ;; 61 | esac 62 | 63 | # Build some hardlinks 64 | 65 | mkdir "$fromdir" 66 | name1="$fromdir/name1" 67 | name2="$fromdir/name2" 68 | echo "This is the file" > "$name1" 69 | echo "This is the other file" > "$name2" 70 | 71 | chown 5000:5002 "$name1" || test_skipped "Can't chown (probably need root)" 72 | chown 5001:5003 "$name2" || test_skipped "Can't chown (probably need root)" 73 | 74 | cd "$fromdir/.." 75 | checkit "$RSYNC -aHvv from/ to/" "$fromdir" "$todir" 76 | 77 | # The script would have aborted on error, so getting here means we've won. 78 | exit 0 79 | -------------------------------------------------------------------------------- /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 -avvvvzz 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 -avvvvzz '$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.sh --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 | # These have a space-padded 15-char name, then a tab, then a comment. 54 | sed 's/NOCOMMENT//' <"$chkfile" 55 | test-from r/o 56 | test-to r/w 57 | test-scratch NOCOMMENT 58 | EOT 59 | 60 | $RSYNC -ve "$SSH" --rsync-path="$RSYNC$confopt" localhost:: | tee "$outfile" 61 | echo '====' 62 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 0 failed" 63 | 64 | RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon" 65 | export RSYNC_CONNECT_PROG 66 | 67 | $RSYNC -v localhost:: | tee "$outfile" 68 | echo '====' 69 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed" 70 | 71 | $RSYNC -r localhost::test-hidden \ 72 | | sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \ 73 | | tee "$outfile" 74 | cat <"$chkfile" 75 | drwxr-xr-x DIR ####/##/## ##:##:## . 76 | drwxr-xr-x DIR ####/##/## ##:##:## bar 77 | -rw-r--r-- 4 ####/##/## ##:##:## bar/two 78 | drwxr-xr-x DIR ####/##/## ##:##:## bar/baz 79 | -rw-r--r-- 6 ####/##/## ##:##:## bar/baz/three 80 | drwxr-xr-x DIR ####/##/## ##:##:## foo 81 | -rw-r--r-- 4 ####/##/## ##:##:## foo/one 82 | EOT 83 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed" 84 | 85 | $RSYNC -r localhost::test-from/f* \ 86 | | sed "$FILE_REPL" | sed "$DIR_REPL" | sed "$LS_REPL" \ 87 | | tee "$outfile" 88 | cat <"$chkfile" 89 | drwxr-xr-x DIR ####/##/## ##:##:## foo 90 | -rw-r--r-- 4 ####/##/## ##:##:## foo/one 91 | EOT 92 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed" 93 | 94 | -------------------------------------------------------------------------------- /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 "$HOST_OS" in 23 | darwin*) 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 | solaris*) 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 | runat "$fn" "$SHELL_PATH" < rsync.%stat 50 | EOF 51 | } 52 | ;; 53 | *) 54 | mknod() { 55 | fn="$1" 56 | case "$2" in 57 | p) mode=10644 ;; 58 | c) mode=20644 ;; 59 | b) mode=60644 ;; 60 | esac 61 | maj="${3:-0}" 62 | min="${4:-0}" 63 | touch "$fn" 64 | setfattr -n 'user.rsync.%stat' -v "$mode $maj,$min 0:0" "$fn" 65 | } 66 | ;; 67 | esac 68 | ;; 69 | *) 70 | case `get_testuid` in 71 | '') ;; # If "id" failed, try to continue... 72 | 0) ;; 73 | *) if [ -e "$FAKEROOT_PATH" ]; then 74 | echo "Let's try re-running the script under fakeroot..." 75 | exec "$FAKEROOT_PATH" "$SHELL_PATH" $RUNSHFLAGS "$0" 76 | fi 77 | test_skipped "Rsync needs root/fakeroot for device tests" 78 | ;; 79 | esac 80 | ;; 81 | esac 82 | 83 | # TODO: Need to test whether hardlinks are possible on this OS/filesystem 84 | 85 | mkdir "$fromdir" 86 | mkdir "$todir" 87 | mknod "$fromdir/char" c 41 67 || test_skipped "Can't create char device node" 88 | mknod "$fromdir/char2" c 42 68 || test_skipped "Can't create char device node" 89 | mknod "$fromdir/char3" c 42 69 || test_skipped "Can't create char device node" 90 | mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node" 91 | mknod "$fromdir/block2" b 42 73 || test_skipped "Can't create block device node" 92 | mknod "$fromdir/block3" b 105 73 || test_skipped "Can't create block device node" 93 | ln "$fromdir/block3" "$fromdir/block3.5" || echo "Skipping hard-linked device test..." 94 | mkfifo "$fromdir/fifo" || mknod "$fromdir/fifo" p || test_skipped "Can't run mkfifo" 95 | # Work around time rounding/truncating issue by touching both files. 96 | touch -r "$fromdir/block" "$fromdir/block" "$fromdir/block2" 97 | 98 | $RSYNC -ai "$fromdir/block" "$todir/block2" \ 99 | | tee "$outfile" 100 | cat <"$chkfile" 101 | cD$all_plus block 102 | EOT 103 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 1 failed" 104 | 105 | $RSYNC -ai "$fromdir/block2" "$todir/block" \ 106 | | tee "$outfile" 107 | cat <"$chkfile" 108 | cD$all_plus block2 109 | EOT 110 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 2 failed" 111 | 112 | sleep 1 113 | 114 | $RSYNC -Di "$fromdir/block3" "$todir/block" \ 115 | | tee "$outfile" 116 | cat <"$chkfile" 117 | cDc.T.$dots block3 118 | EOT 119 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 3 failed" 120 | 121 | $RSYNC -aiHvv "$fromdir/" "$todir/" \ 122 | | tee "$outfile" 123 | filter_outfile 124 | cat <"$chkfile" 125 | .d..t.$dots ./ 126 | cDc.t.$dots block 127 | cDc...$dots block2 128 | cD$all_plus block3 129 | hD$all_plus block3.5 => block3 130 | cD$all_plus char 131 | cD$all_plus char2 132 | cD$all_plus char3 133 | cS$all_plus fifo 134 | EOT 135 | if test ! -r "$fromdir/block3.5"; then 136 | grep -v block3.5 <"$chkfile" >"$chkfile.new" 137 | mv "$chkfile.new" "$chkfile" 138 | fi 139 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 4 failed" 140 | 141 | echo "check how the directory listings compare with diff:" 142 | echo "" 143 | ( cd "$fromdir" && rsync_ls_lR . ) > "$tmpdir/ls-from" 144 | ( cd "$todir" && rsync_ls_lR . ) > "$tmpdir/ls-to" 145 | diff $diffopt "$tmpdir/ls-from" "$tmpdir/ls-to" 146 | 147 | if test -r "$fromdir/block3.5"; then 148 | set -x 149 | $RSYNC -aii --link-dest="$todir" "$fromdir/" "$chkdir/" \ 150 | | tee "$outfile" 151 | cat <"$chkfile" 152 | cd$allspace ./ 153 | hD$allspace block 154 | hD$allspace block2 155 | hD$allspace block3 156 | hD$allspace block3.5 157 | hD$allspace char 158 | hD$allspace char2 159 | hD$allspace char3 160 | hS$allspace fifo 161 | EOT 162 | diff $diffopt "$chkfile" "$outfile" || test_fail "test 5 failed" 163 | fi 164 | 165 | # The script would have aborted on error, so getting here means we've won. 166 | exit 0 167 | -------------------------------------------------------------------------------- /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 u=rwx,g=rw,g+s,o=r "$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 u=rwx,g=rw,g+s,o-rwx 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" || test_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.sh" 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.sh" 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" || test_skipped "Can't create hardlink" 32 | ln "$name2" "$name3" || test_fail "Can't create hardlink" 33 | cp "$name2" "$name4" || test_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" || test_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 | # Work around time rounding/truncating issue by touching both dirs. 37 | touch -r $deepstr/dir $deepstr/dir ../chk/$deepstr/dir 38 | runtest "hard links" 'checkit "$RSYNC -avHR ./$deepstr/ \"$todir\"" "$chkdir" "$todir"' 39 | 40 | cp "$deepdir/text" "$todir/$deepstr/ThisShouldGo" 41 | cp "$deepdir/text" "$todir/$deepstr/dir/ThisShouldGoToo" 42 | runtest "deletion" 'checkit "$RSYNC -avHR --del ./$deepstr/ \"$todir\"" "$chkdir" "$todir"' 43 | 44 | runtest "non-deletion" 'checkit "$RSYNC -aiHR --del ./$deepstr/ \"$todir\"" "$chkdir" "$todir"' \ 45 | | tee "$outfile" 46 | 47 | # Make sure no files were deleted 48 | grep 'deleting ' "$outfile" && test_fail "Erroneous deletions occurred!" 49 | 50 | # Relative with merging. 51 | $RSYNC -ai "$extradir/down" "$chkdir/" 52 | 53 | checkit "$RSYNC -aiR $deepstr '$extrafile' '$todir'" "$chkdir" "$todir" 54 | 55 | checkit "$RSYNC -aiR --del $deepstr '$extrafile' '$todir'" "$chkdir" "$todir" \ 56 | | tee "$outfile" 57 | 58 | # Make sure no files were deleted 59 | grep 'deleting ' "$outfile" && test_fail "Erroneous deletions occurred! (2)" 60 | 61 | # The script would have aborted on error, so getting here means we've won. 62 | exit 0 63 | -------------------------------------------------------------------------------- /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.sh" 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" - < 7 | * Copyright (C) 2003-2015 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 | #include "ifuncs.h" 25 | #include "itypes.h" 26 | #include "inums.h" 27 | 28 | /** 29 | * Sleep for a specified number of milliseconds. 30 | * 31 | * Always returns TRUE. (In the future it might return FALSE if 32 | * interrupted.) 33 | **/ 34 | int msleep(int t) 35 | { 36 | #ifdef HAVE_USLEEP 37 | usleep(t*1000); 38 | #else 39 | int tdiff = 0; 40 | struct timeval tval, t1, t2; 41 | 42 | gettimeofday(&t1, NULL); 43 | 44 | while (tdiff < t) { 45 | tval.tv_sec = (t-tdiff)/1000; 46 | tval.tv_usec = 1000*((t-tdiff)%1000); 47 | 48 | errno = 0; 49 | select(0,NULL,NULL, NULL, &tval); 50 | 51 | gettimeofday(&t2, NULL); 52 | tdiff = (t2.tv_sec - t1.tv_sec)*1000 + 53 | (t2.tv_usec - t1.tv_usec)/1000; 54 | if (tdiff < 0) 55 | t1 = t2; /* Time went backwards, so start over. */ 56 | } 57 | #endif 58 | 59 | return True; 60 | } 61 | 62 | #define MALLOC_MAX 0x40000000 63 | 64 | void *_new_array(unsigned long num, unsigned int size, int use_calloc) 65 | { 66 | if (num >= MALLOC_MAX/size) 67 | return NULL; 68 | return use_calloc ? calloc(num, size) : malloc(num * size); 69 | } 70 | 71 | void *_realloc_array(void *ptr, unsigned int size, size_t num) 72 | { 73 | if (num >= MALLOC_MAX/size) 74 | return NULL; 75 | if (!ptr) 76 | return malloc(size * num); 77 | return realloc(ptr, size * num); 78 | } 79 | 80 | const char *sum_as_hex(int csum_type, const char *sum) 81 | { 82 | static char buf[MAX_DIGEST_LEN*2+1]; 83 | int i, x1, x2; 84 | int checksum_len = csum_len_for_type(csum_type); 85 | char *c = buf + checksum_len*2; 86 | 87 | assert(c - buf < (int)sizeof buf); 88 | 89 | *c = '\0'; 90 | 91 | for (i = checksum_len; --i >= 0; ) { 92 | x1 = CVAL(sum, i); 93 | x2 = x1 >> 4; 94 | x1 &= 0xF; 95 | *--c = x1 <= 9 ? x1 + '0' : x1 + 'a' - 10; 96 | *--c = x2 <= 9 ? x2 + '0' : x2 + 'a' - 10; 97 | } 98 | 99 | return buf; 100 | } 101 | 102 | NORETURN void out_of_memory(const char *str) 103 | { 104 | rprintf(FERROR, "ERROR: out of memory in %s [%s]\n", str, who_am_i()); 105 | exit_cleanup(RERR_MALLOC); 106 | } 107 | 108 | NORETURN void overflow_exit(const char *str) 109 | { 110 | rprintf(FERROR, "ERROR: buffer overflow in %s [%s]\n", str, who_am_i()); 111 | exit_cleanup(RERR_MALLOC); 112 | } 113 | -------------------------------------------------------------------------------- /wildtest.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuna/rsync/6cadc8e31f1d3882b1bf2eefa0c2587d799e3946/wildtest.txt -------------------------------------------------------------------------------- /zlib/ChangeLog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tuna/rsync/6cadc8e31f1d3882b1bf2eefa0c2587d799e3946/zlib/ChangeLog -------------------------------------------------------------------------------- /zlib/README: -------------------------------------------------------------------------------- 1 | ZLIB DATA COMPRESSION LIBRARY 2 | 3 | zlib 1.2.8 is a general purpose data compression library. All the code is 4 | thread safe. The data format used by the zlib library is described by RFCs 5 | (Request for Comments) 1950 to 1952 in the files 6 | http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and 7 | rfc1952 (gzip format). 8 | 9 | All functions of the compression library are documented in the file zlib.h 10 | (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example 11 | of the library is given in the file test/example.c which also tests that 12 | the library is working correctly. Another example is given in the file 13 | test/minigzip.c. The compression library itself is composed of all source 14 | files in the root directory. 15 | 16 | To compile all files and run the test program, follow the instructions given at 17 | the top of Makefile.in. In short "./configure; make test", and if that goes 18 | well, "make install" should work for most flavors of Unix. For Windows, use 19 | one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use 20 | make_vms.com. 21 | 22 | Questions about zlib should be sent to , or to Gilles Vollant 23 | for the Windows DLL version. The zlib home page is 24 | http://zlib.net/ . Before reporting a problem, please check this site to 25 | verify that you have the latest version of zlib; otherwise get the latest 26 | version and check whether the problem still exists or not. 27 | 28 | PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. 29 | 30 | Mark Nelson wrote an article about zlib for the Jan. 1997 31 | issue of Dr. Dobb's Journal; a copy of the article is available at 32 | http://marknelson.us/1997/01/01/zlib-engine/ . 33 | 34 | The changes made in version 1.2.8 are documented in the file ChangeLog. 35 | 36 | Unsupported third party contributions are provided in directory contrib/ . 37 | 38 | zlib is available in Java using the java.util.zip package, documented at 39 | http://java.sun.com/developer/technicalArticles/Programming/compression/ . 40 | 41 | A Perl interface to zlib written by Paul Marquess is available 42 | at CPAN (Comprehensive Perl Archive Network) sites, including 43 | http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . 44 | 45 | A Python interface to zlib written by A.M. Kuchling is 46 | available in Python 1.5 and later versions, see 47 | http://docs.python.org/library/zlib.html . 48 | 49 | zlib is built into tcl: http://wiki.tcl.tk/4610 . 50 | 51 | An experimental package to read and write files in .zip format, written on top 52 | of zlib by Gilles Vollant , is available in the 53 | contrib/minizip directory of zlib. 54 | 55 | 56 | Notes for some targets: 57 | 58 | - For Windows DLL versions, please see win32/DLL_FAQ.txt 59 | 60 | - For 64-bit Irix, deflate.c must be compiled without any optimization. With 61 | -O, one libpng test fails. The test works in 32 bit mode (with the -n32 62 | compiler flag). The compiler bug has been reported to SGI. 63 | 64 | - zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works 65 | when compiled with cc. 66 | 67 | - On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is 68 | necessary to get gzprintf working correctly. This is done by configure. 69 | 70 | - zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with 71 | other compilers. Use "make test" to check your compiler. 72 | 73 | - gzdopen is not supported on RISCOS or BEOS. 74 | 75 | - For PalmOs, see http://palmzlib.sourceforge.net/ 76 | 77 | 78 | Acknowledgments: 79 | 80 | The deflate format used by zlib was defined by Phil Katz. The deflate and 81 | zlib specifications were written by L. Peter Deutsch. Thanks to all the 82 | people who reported problems and suggested various improvements in zlib; they 83 | are too numerous to cite here. 84 | 85 | Copyright notice: 86 | 87 | (C) 1995-2013 Jean-loup Gailly and Mark Adler 88 | 89 | This software is provided 'as-is', without any express or implied 90 | warranty. In no event will the authors be held liable for any damages 91 | arising from the use of this software. 92 | 93 | Permission is granted to anyone to use this software for any purpose, 94 | including commercial applications, and to alter it and redistribute it 95 | freely, subject to the following restrictions: 96 | 97 | 1. The origin of this software must not be misrepresented; you must not 98 | claim that you wrote the original software. If you use this software 99 | in a product, an acknowledgment in the product documentation would be 100 | appreciated but is not required. 101 | 2. Altered source versions must be plainly marked as such, and must not be 102 | misrepresented as being the original software. 103 | 3. This notice may not be removed or altered from any source distribution. 104 | 105 | Jean-loup Gailly Mark Adler 106 | jloup@gzip.org madler@alumni.caltech.edu 107 | 108 | If you use the zlib library in a product, we would appreciate *not* receiving 109 | lengthy legal documents to sign. The sources are provided for free but without 110 | warranty of any kind. The library has been entirely written by Jean-loup 111 | Gailly and Mark Adler; it does not include third-party code. 112 | 113 | If you redistribute modified sources, we would appreciate that you include in 114 | the file ChangeLog history information documenting your changes. Please read 115 | the FAQ for more information on the distribution of modified source versions. 116 | -------------------------------------------------------------------------------- /zlib/README.rsync: -------------------------------------------------------------------------------- 1 | READ THIS BEFORE TRYING TO DYNAMICALLY LINK RSYNC AND ZLIB! 2 | 3 | zlib has been adapted slightly for use in rsync. Please don't bother 4 | the zlib authors with problems related to the use of zlib in rsync as 5 | any bugs are likely to be our fault and not theirs. 6 | 7 | Specific changes that have been made to zlib for rsync include: 8 | 9 | - add Z_INSERT_ONLY to allow for efficient history updating without 10 | actually emitting any data. This is used to compress the matched 11 | blocks that don't cross the wire, which gives better compression 12 | ratios on the literal data. 13 | 14 | - fixed a number of minor compilation issues. (redefinition of MAX and 15 | other such trivial things) 16 | 17 | - include rsync.h to ensure that we get a consistent set of includes 18 | for all C code in rsync and to take advantage of autoconf 19 | 20 | As a result of the first item, the streams from rsync's version of 21 | zlib are *not compatible* with those produced by the upstream version 22 | of rsync. In other words, if you link rsync against your system's 23 | copy, it will not be able to interoperate with any other version if 24 | the -z option is used. (Sorry. Sometimes standard is better than 25 | better.) 26 | 27 | The rsync maintainers hope to fix this problem in the future by either 28 | merging our changes into the upstream version, or backing them out of 29 | rsync in a way that preserves wire compatibility. But in the meantime 30 | this version must be maintained in parallel. 31 | 32 | -------------------------------------------------------------------------------- /zlib/compress.c: -------------------------------------------------------------------------------- 1 | /* compress.c -- compress a memory buffer 2 | * Copyright (C) 1995-2005 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 = (z_const 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) + 79 | (sourceLen >> 25) + 13; 80 | } 81 | -------------------------------------------------------------------------------- /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, 2010 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 ZLIB_INTERNAL 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, 2010 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 the dynamic table. The maximum number of code structures is 39 | 1444, which is the sum of 852 for literal/length codes and 592 for distance 40 | codes. These values were found by exhaustive searches using the program 41 | examples/enough.c found in the zlib distribtution. The arguments to that 42 | program are the number of symbols, the initial root table size, and the 43 | maximum bit length of a code. "enough 286 9 15" for literal/length codes 44 | returns returns 852, and "enough 30 6 15" for distance codes returns 592. 45 | The initial root table size (9 or 6) is found in the fifth argument of the 46 | inflate_table() calls in inflate.c and infback.c. If the root table size is 47 | changed, then these maximum sizes would be need to be recalculated and 48 | updated. */ 49 | #define ENOUGH_LENS 852 50 | #define ENOUGH_DISTS 592 51 | #define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) 52 | 53 | /* Type of code to build for inflate_table() */ 54 | typedef enum { 55 | CODES, 56 | LENS, 57 | DISTS 58 | } codetype; 59 | 60 | int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, 61 | unsigned codes, code FAR * FAR *table, 62 | unsigned FAR *bits, unsigned short FAR *work)); 63 | --------------------------------------------------------------------------------