Delay the renaming of all the temp files until the end of the transfer.
---- options.c 1 Jan 2005 21:08:14 -0000 1.193
-+++ options.c 10 Jan 2005 10:16:54 -0000
+--- orig/options.c 2005-01-17 23:11:45
++++ options.c 2005-01-17 23:15:13
@@ -97,6 +97,7 @@ int modify_window = 0;
int blocking_io = -1;
int checksum_seed = 0;
+
if (inplace) {
#if HAVE_FTRUNCATE
- if (partial_dir) {
+- if (partial_dir) {
++ if (partial_dir || delay_renames) {
snprintf(err_buf, sizeof err_buf,
- "--inplace cannot be used with --partial-dir\n");
+ "--inplace cannot be used with --%s\n",
return 0;
}
keep_partial = 0;
-@@ -1185,6 +1192,8 @@ void server_options(char **args,int *arg
+@@ -1179,6 +1186,8 @@ void server_options(char **args,int *arg
if (partial_dir && am_sender) {
args[ac++] = "--partial-dir";
args[ac++] = partial_dir;
} else if (keep_partial)
args[ac++] = "--partial";
---- receiver.c 10 Jan 2005 10:03:10 -0000 1.113
-+++ receiver.c 10 Jan 2005 10:16:54 -0000
-@@ -52,6 +52,7 @@ extern int orig_umask;
+--- orig/receiver.c 2005-01-17 23:11:45
++++ receiver.c 2005-01-10 10:16:54
+@@ -53,6 +53,7 @@ extern int orig_umask;
extern int keep_partial;
extern int checksum_seed;
extern int inplace;
extern struct exclude_list_struct server_exclude_list;
-@@ -344,6 +345,7 @@ int recv_files(int f_in, struct file_lis
+@@ -345,6 +346,7 @@ int recv_files(int f_in, struct file_lis
char fnametmp[MAXPATHLEN];
char *fnamecmp, *partialptr;
char fnamecmpbuf[MAXPATHLEN];
struct file_struct *file;
struct stats initial_stats;
int save_make_backups = make_backups;
-@@ -357,6 +359,12 @@ int recv_files(int f_in, struct file_lis
+@@ -358,6 +360,12 @@ int recv_files(int f_in, struct file_lis
flist->hlink_pool = NULL;
}
while (1) {
cleanup_disable();
-@@ -566,7 +574,7 @@ int recv_files(int f_in, struct file_lis
+@@ -572,7 +580,7 @@ int recv_files(int f_in, struct file_lis
exit_cleanup(RERR_FILEIO);
}
finish_transfer(fname, fnametmp, file, recv_ok, 1);
if (partialptr != fname && fnamecmp == partialptr) {
do_unlink(partialptr);
-@@ -576,6 +584,8 @@ int recv_files(int f_in, struct file_lis
+@@ -582,6 +590,8 @@ int recv_files(int f_in, struct file_lis
&& handle_partial_dir(partialptr, PDIR_CREATE)) {
finish_transfer(partialptr, fnametmp, file, recv_ok,
!partial_dir);
} else {
partialptr = NULL;
do_unlink(fnametmp);
-@@ -615,6 +625,33 @@ int recv_files(int f_in, struct file_lis
+@@ -621,6 +631,33 @@ int recv_files(int f_in, struct file_lis
}
make_backups = save_make_backups;
if (delete_after && recurse && !local_name && flist->count > 0)
delete_files(flist);
---- rsync.yo 8 Dec 2004 17:30:40 -0000 1.205
-+++ rsync.yo 10 Jan 2005 10:16:56 -0000
+--- orig/rsync.yo 2005-01-17 23:11:46
++++ rsync.yo 2005-01-17 23:13:23
@@ -348,6 +348,7 @@ verb(
--max-size=SIZE don't transfer any file larger than SIZE
--partial keep partially transferred files
--force force deletion of dirs even if not empty
--numeric-ids don't map uid/gid values by user/group name
--timeout=TIME set I/O timeout in seconds
-@@ -544,9 +545,10 @@ or appended data, and also on systems th
+@@ -546,9 +547,9 @@ or appended data, and also on systems th
bound.
The option implies --partial (since an interrupted transfer does not delete
--the file), but conflicts with --partial-dir, --compare-dest, --copy-dest, and
----link-dest (a future rsync version will hopefully update the protocol to
--remove some of these restrictions).
-+the file), but conflicts with --partial-dir, --compare-dest, --copy-dest,
-+--link-dest, and --delay-renames.
-+(A future rsync version will hopefully update the protocol to
-+remove some of these restrictions.)
+-the file), but conflicts with --partial-dir. Prior to rsync 2.6.4
+---inplace was also incompatible with --compare-dest, --copy-dest, and
+---link-dest.
++the file), but conflicts with --partial-dir and --delay-renames.
++Prior to rsync 2.6.4 --inplace was also incompatible with --compare-dest,
++--copy-dest, and --link-dest.
WARNING: The file's data will be in an inconsistent state during the
transfer (and possibly afterward if the transfer gets interrupted), so you
-@@ -967,6 +969,17 @@ environment and then just use the -P opt
+@@ -978,6 +979,17 @@ environment and then just use the -P opt
does not look for this environment value is when --inplace was also
specified (since --inplace conflicts with --partial-dir).
---- orig/options.c 2005-01-01 21:11:00
+--- orig/options.c 2005-01-17 23:11:45
+++ options.c 2004-07-03 20:17:33
@@ -48,6 +48,7 @@ int preserve_devices = 0;
int preserve_uid = 0;
{"checksum", 'c', POPT_ARG_NONE, &always_checksum, 0, 0, 0 },
{"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
{"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
-@@ -1081,6 +1084,8 @@ void server_options(char **args,int *arg
+@@ -1075,6 +1078,8 @@ void server_options(char **args,int *arg
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
if (preserve_perms)
argstr[x++] = 'p';
if (recurse)
---- orig/rsync.c 2004-09-07 21:45:30
+--- orig/rsync.c 2005-01-10 09:50:46
+++ rsync.c 2004-07-03 20:17:33
@@ -25,6 +25,7 @@
extern int verbose;
rsyserr(FERROR, errno, "failed to set times on %s",
full_fname(fname));
return 0;
---- orig/rsync.yo 2005-01-01 21:11:01
+--- orig/rsync.yo 2005-01-17 23:11:46
+++ rsync.yo 2004-08-11 17:27:51
@@ -329,7 +329,8 @@ verb(
-o, --owner preserve owner (root only)
-S, --sparse handle sparse files efficiently
-n, --dry-run show what would have been transferred
-W, --whole-file copy whole files, no incremental checks
-@@ -620,14 +621,23 @@ dit(bf(-D, --devices)) This option cause
+@@ -622,14 +623,23 @@ dit(bf(-D, --devices)) This option cause
block device information to the remote system to recreate these
devices. This option is only available to the super-user.
# The script would have aborted on error, so getting here means we've won.
exit 0
---- orig/testsuite/ssh-basic.test 2004-05-18 09:14:24
-+++ testsuite/ssh-basic.test 2004-07-03 20:17:33
+--- orig/testsuite/ssh-basic.test 2005-01-17 23:11:46
++++ testsuite/ssh-basic.test 2005-01-17 23:18:18
@@ -28,7 +28,7 @@ fi
# nothing to do.
hands_setup
--runtest "ssh: basic test" 'checkit "$RSYNC -avH -e ssh --rsync-path=$RSYNC \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"'
-+runtest "ssh: basic test" 'checkit "$RSYNC -advH -e ssh --rsync-path=$RSYNC \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"'
+-runtest "ssh: basic test" 'checkit "$RSYNC -avH -e ssh --rsync-path=\"$RSYNC\" \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"'
++runtest "ssh: basic test" 'checkit "$RSYNC -advH -e ssh --rsync-path=\"$RSYNC\" \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"'
# Added by Steve Bonds Feb 2 2003
# I assumed that "F1" was intended to hold a single file for testing if
mv "$todir/$F1" "$todir/ThisShouldGo"
--runtest "ssh: renamed file" 'checkit "$RSYNC --delete -avH -e ssh --rsync-path=$RSYNC \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"'
-+runtest "ssh: renamed file" 'checkit "$RSYNC --delete -advH -e ssh --rsync-path=$RSYNC \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"'
+-runtest "ssh: renamed file" 'checkit "$RSYNC --delete -avH -e ssh --rsync-path=\"$RSYNC\" \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"'
++runtest "ssh: renamed file" 'checkit "$RSYNC --delete -advH -e ssh --rsync-path=\"$RSYNC\" \"$fromdir/\" \"localhost:$todir\"" "$fromdir/" "$todir"'
--- orig/testsuite/unsafe-links.test 2004-05-18 09:14:24
+++ testsuite/unsafe-links.test 2004-07-03 20:17:33
@@ -35,33 +35,33 @@ ln -s ../../unsafe/unsafefile "from/safe
FN_LOCAL_STRING(lp_exclude, exclude)
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
FN_LOCAL_STRING(lp_include, include)
---- orig/options.c 2005-01-15 21:23:15
+--- orig/options.c 2005-01-17 23:11:45
+++ options.c 2005-01-16 23:34:15
@@ -144,6 +144,7 @@ int list_only = 0;
char *batch_name = NULL;
case 'P':
do_progress = 1;
keep_partial = 1;
-@@ -972,7 +996,7 @@ int parse_arguments(int *argc, const cha
+@@ -966,7 +990,7 @@ int parse_arguments(int *argc, const cha
partial_dir = NULL;
else if (*partial_dir != '/') {
add_exclude(&exclude_list, partial_dir,
}
keep_partial = 1;
}
---- orig/rsync.h 2005-01-15 21:18:09
+--- orig/rsync.h 2005-01-17 23:11:45
+++ rsync.h 2005-01-17 00:16:04
-@@ -62,7 +62,7 @@
- #define FLAG_MOUNT_POINT (1<<2) /* sender only */
-
- /* update this if you make incompatible changes */
--#define PROTOCOL_VERSION 28
-+#define PROTOCOL_VERSION 29
-
- /* We refuse to interoperate with versions that are not in this range.
- * Note that we assume we'll work with later versions: the onus is on
-@@ -108,9 +108,11 @@
+@@ -109,9 +109,11 @@
#define XFLG_FATAL_ERRORS (1<<0)
#define XFLG_DEF_INCLUDE (1<<1)
#define PERMS_REPORT (1<<0)
#define PERMS_SKIP_MTIME (1<<1)
-@@ -512,11 +514,21 @@ struct map_struct {
+@@ -513,11 +515,21 @@ struct map_struct {
#define MATCHFLG_INCLUDE (1<<4) /* this is an include, not an exclude */
#define MATCHFLG_DIRECTORY (1<<5) /* this matches only directories */
#define MATCHFLG_CLEAR_LIST (1<<6) /* this item is the "!" token */
};
struct exclude_list_struct {
---- orig/rsync.yo 2005-01-15 04:36:32
+--- orig/rsync.yo 2005-01-17 23:11:46
+++ rsync.yo 2005-01-17 07:02:43
@@ -361,6 +361,9 @@ verb(
-P equivalent to --partial --progress
--exclude=PATTERN exclude files matching PATTERN
--exclude-from=FILE exclude patterns listed in FILE
--include=PATTERN don't exclude files matching PATTERN
-@@ -754,14 +757,41 @@ Finally, any file is ignored if it is in
+@@ -756,14 +759,41 @@ Finally, any file is ignored if it is in
.cvsignore file and matches one of the patterns listed therein.
See the bf(cvs(1)) manual for more information.
dit(bf(--exclude-from=FILE)) This option is similar to the --exclude
option, but instead it adds all exclude patterns listed in the file
-@@ -769,11 +799,11 @@ FILE to the exclude list. Blank lines i
+@@ -771,11 +801,11 @@ FILE to the exclude list. Blank lines i
';' or '#' are ignored.
If em(FILE) is bf(-) the list will be read from standard input.
dit(bf(--include-from=FILE)) This specifies a list of include patterns
from a file.
-@@ -818,7 +848,8 @@ was located on the remote "src" host.
+@@ -820,7 +850,8 @@ was located on the remote "src" host.
dit(bf(-0, --from0)) This tells rsync that the filenames it reads from a
file are terminated by a null ('\0') character, not a NL, CR, or CR+LF.
It does not affect --cvs-exclude (since all names read from a .cvsignore
file are split on whitespace).
-@@ -957,8 +988,8 @@ If the partial-dir value is not an absol
+@@ -959,8 +990,8 @@ If the partial-dir value is not an absol
will prevent partial-dir files from being transferred and also prevent the
untimely deletion of partial-dir items on the receiving side. An example:
the above --partial-dir option would add an "--exclude=.rsync-partial/"
rule for this directory exclusion somewhere higher up in the list so that
it has a high enough priority to be effective (e.g., if your rules specify
a trailing --exclude=* rule, the auto-added rule will be ineffective).
-@@ -1108,30 +1139,318 @@ page describing the options available fo
+@@ -1110,30 +1141,318 @@ page describing the options available fo
enddit()
Let's say that we want to match two source files, one with an absolute
path of "/home/me/foo/bar", and one with a path of "/home/you/bar/baz".
-@@ -1163,114 +1482,59 @@ verb(
+@@ -1165,114 +1484,59 @@ verb(
Target file: /dest/you/bar/baz
)
)
manpagesection(BATCH MODE)
-@@ -1439,7 +1703,7 @@ it. The most common cause is incorrectly
+@@ -1441,7 +1705,7 @@ it. The most common cause is incorrectly
scripts (such as .cshrc or .profile) that contain output statements
for non-interactive logins.
Be sure to run "make proto" before "make".
---- orig/generator.c 2005-01-15 21:18:09
-+++ generator.c 2005-01-15 21:20:10
+--- orig/generator.c 2005-01-17 23:11:45
++++ generator.c 2005-01-16 02:16:38
@@ -44,6 +44,7 @@ extern int size_only;
extern OFF_T max_size;
extern int io_timeout;
extern int always_checksum;
extern char *partial_dir;
extern char *basis_dir[];
-@@ -239,6 +240,90 @@ static void generate_and_send_sums(int f
+@@ -242,6 +243,83 @@ static void generate_and_send_sums(int f
}
-+static void split_names(char *fname, char **dirname, char **basename)
-+{
-+ char *slash = strrchr(fname, '/');
-+ if (slash) {
-+ *dirname = fname;
-+ *slash = '\0';
-+ *basename = slash+1;
-+ } else {
-+ *basename = fname;
-+ *dirname = ".";
-+ }
-+}
-+
-+
+static unsigned int measure_name(const char *name, const char *basename,
+ const char *ext)
+{
+{
+ DIR *d;
+ struct dirent *di;
-+ char *basename, *dirname;
-+ char mangled_name[MAXPATHLEN];
++ char *basename, *dirname, *slash;
+ char bestname[MAXPATHLEN];
+ unsigned int bestscore = 0;
+ const char *ext;
+
-+ strlcpy(mangled_name, fname, sizeof mangled_name);
++ strlcpy(buf, fname, MAXPATHLEN);
++ if ((slash = strrchr(buf, '/')) != NULL) {
++ dirname = buf;
++ *slash = '\0';
++ basename = slash + 1;
++ } else {
++ basename = buf;
++ dirname = ".";
++ }
+
-+ split_names(mangled_name, &dirname, &basename);
+ if (!(d = opendir(dirname))) {
+ rsyserr(FERROR, errno, "recv_generator opendir(%s)", dirname);
+ return -1;
+ }
+
+ /* Get final extension, eg. .gz; never full basename though. */
-+ if (!(ext = strrchr(basename + 1, '.')))
++ for (ext = basename; *ext == '.'; ext++) {}
++ if (!(ext = strrchr(ext, '.')))
+ ext = basename + strlen(basename); /* ext = "" */
+
+ while ((di = readdir(d)) != NULL) {
+
+ /* Found a candidate. */
+ if (bestscore != 0) {
-+ pathjoin(buf, MAXPATHLEN, dirname, bestname);
++ strlcpy(basename, MAXPATHLEN - (basename - buf), bestname);
+ if (verbose > 2)
+ rprintf(FINFO, "fuzzy match %s->%s\n", fname, buf);
+ return link_stat(buf, st_ptr, 0);
/*
* Acts on file number @p i from @p flist, whose name is @p fname.
-@@ -493,6 +578,15 @@ static void recv_generator(char *fname,
+@@ -496,6 +574,15 @@ static void recv_generator(char *fname,
} else
partialptr = NULL;
if (statret == -1) {
if (preserve_hard_links && hard_link_check(file, HL_SKIP))
return;
-@@ -521,6 +615,8 @@ static void recv_generator(char *fname,
+@@ -524,6 +611,8 @@ static void recv_generator(char *fname,
if (!compare_dest && fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
;
else if (unchanged_file(fnamecmp, file, &st)) {
if (fnamecmp_type == FNAMECMP_FNAME)
set_perms(fname, file, &st, PERMS_REPORT);
-@@ -593,8 +689,24 @@ prepare_to_open:
-
- notify_others:
+@@ -598,8 +687,24 @@ notify_others:
write_int(f_out, i);
+ if (protocol_version >= 29 && inplace && !read_batch)
+ write_byte(f_out, fnamecmp_type);
- if (f_out_name >= 0)
+ if (f_out_name >= 0) {
write_byte(f_out_name, fnamecmp_type);
if (dry_run || read_batch)
return;
---- orig/main.c 2005-01-14 18:30:18
+--- orig/main.c 2005-01-17 23:11:45
+++ main.c 2005-01-14 18:33:15
@@ -48,6 +48,7 @@ extern int keep_dirlinks;
extern int preserve_hard_links;
/* The receiving side mustn't obey this, or an existing symlink that
* points to an identical file won't be replaced by the referent. */
---- orig/options.c 2005-01-15 21:23:15
+--- orig/options.c 2005-01-17 23:11:45
+++ options.c 2005-01-15 21:08:13
@@ -86,6 +86,7 @@ int copy_unsafe_links = 0;
int size_only = 0;
/* TODO: Should this take an optional int giving the compression level? */
{"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
{"stats", 0, POPT_ARG_NONE, &do_stats, 0, 0, 0 },
-@@ -952,10 +955,10 @@ int parse_arguments(int *argc, const cha
- return 0;
- }
- keep_partial = 0;
-- if (dest_option) {
-+ if (dest_option || fuzzy_basis) {
- snprintf(err_buf, sizeof err_buf,
- "--inplace does not yet work with %s\n",
-- dest_option);
-+ dest_option ? dest_option : "--fuzzy");
- return 0;
- }
- #else
-@@ -1240,6 +1243,9 @@ void server_options(char **args,int *arg
+@@ -1234,6 +1237,9 @@ void server_options(char **args,int *arg
args[ac++] = "--no-relative";
}
*argc = ac;
return;
---- orig/receiver.c 2005-01-15 21:18:09
+--- orig/receiver.c 2005-01-17 23:11:45
+++ receiver.c 2005-01-15 21:21:02
@@ -324,6 +324,27 @@ static int receive_data(int f_in, char *
}
default:
if (j >= basis_dir_cnt) {
rprintf(FERROR,
---- orig/rsync.h 2005-01-15 21:18:09
+--- orig/rsync.h 2005-01-17 23:11:45
+++ rsync.h 2005-01-15 21:24:09
-@@ -127,6 +127,7 @@
+@@ -128,6 +128,7 @@
#define FNAMECMP_FNAME 0x80
#define FNAMECMP_PARTIAL_DIR 0x81
#define FNAMECMP_BACKUP 0x82
/* Log-message categories. FLOG is only used on the daemon side to
---- orig/rsync.yo 2005-01-15 04:36:32
+--- orig/rsync.yo 2005-01-17 23:11:46
+++ rsync.yo 2005-01-15 21:48:52
@@ -358,6 +358,7 @@ verb(
--compare-dest=DIR also compare received files relative to DIR
-P equivalent to --partial --progress
-z, --compress compress file data
-C, --cvs-exclude auto ignore files in the same way CVS does
-@@ -876,6 +877,11 @@ Note that rsync versions prior to 2.6.1
- (or implied by -a). If the receiving rsync is not new enough, you can work
- around this bug by avoiding the -o option.
+@@ -878,6 +879,11 @@ Note that rsync versions prior to 2.6.1
+ (or implied by -a). You can work-around this bug by avoiding the -o option
+ when sending to an old rsync.
+dit(bf(--fuzzy)) This option tells rsync that it should look around for a
+basis file for any destination file that is missing. The current algorithm