Dave Dykstra [[EMAIL PROTECTED]] writes:
> If --size-only is allowing rsync to accept everything and not
> calculate checksums, it's gog to be a timestamp problem. Somebody
> should try modifying rsync to accept any timestamp +-1 second as a
> match. I don't even know if it's worth making it an option or if it
> should just always do that. If VFAT always truncates the second,
> you wouldn't even need to check for +1, just minus 1. Or just
> compare (t1 & ~1) == (t2 & ~1) or (t1 >> 1) == (t2 >> 1).
At least under NT, it's not just a truncation issue (as it may be with
FAT), which is definitely annoying. When they say a granularity of
2s, they mean any timestamp may differ by up to 2s (that is, I've
found the same file copied between systems having a seconds value with
final bits of 00 (0) and 10 (2), so it's not just a last bit
truncation).
I worked on this last night since I needed to fix this for my purposes.
Below is a patch for my addition of a "--modify-window" parameter
which can set the size for a window (in seconds) within which two
timestamps are considered equivalent. When built under Windows, it
defaults to 2s, otherwise the default is 0 (existing behavior). It
doesn't transmit the parameter as a server option unless actually
specified on the command line, so as long as your transfers are one
way it'll continue to interoperate accurately with older versions on
other systems, and each system will use the value appropriate for its
filesystem. If you do set a window size though, both copies of rsync
will need to support the option.
The defaulting to 2s in the Windows case is the only real crufty part
of this - I conditionalize on _WIN32, but it would probably be a
little cleaner to determine it in the configure process. I just don't
have a working autoconf setup to test against, and I needed it working
:-)
-- David
/-----------------------------------------------------------------------\
\ David Bolen \ E-mail: [EMAIL PROTECTED] /
| FitLinxx, Inc. \ Phone: (203) 708-5192 |
/ 860 Canal Street, Stamford, CT 06902 \ Fax: (203) 316-5150 \
\-----------------------------------------------------------------------/
Index: ni/bin/rsync/generator.c
diff -c ni/bin/rsync/generator.c:1.1.1.1 ni/bin/rsync/generator.c:1.2
*** ni/bin/rsync/generator.c:1.1.1.1 Tue May 30 14:08:19 2000
--- ni/bin/rsync/generator.c Thu Jul 06 23:23:40 2000
***************
*** 35,40 ****
--- 35,41 ----
extern int io_timeout;
extern int remote_version;
extern int always_checksum;
+ extern int modify_window;
/* choose whether to skip a particular file */
***************
*** 65,71 ****
return 0;
}
! return (st->st_mtime == file->modtime);
}
--- 66,72 ----
return 0;
}
! return (!cmp_modtime(st->st_mtime,file->modtime));
}
***************
*** 333,339 ****
return;
}
! if (update_only && st.st_mtime > file->modtime && fnamecmp == fname)
{
if (verbose > 1)
rprintf(FINFO,"%s is newer\n",fname);
return;
--- 334,341 ----
return;
}
! if (update_only &&
! st.st_mtime > (file->modtime+modify_window) && fnamecmp ==
fname) {
if (verbose > 1)
rprintf(FINFO,"%s is newer\n",fname);
return;
Index: ni/bin/rsync/options.c
diff -c ni/bin/rsync/options.c:1.1.1.1 ni/bin/rsync/options.c:1.4
*** ni/bin/rsync/options.c:1.1.1.1 Tue May 30 14:08:19 2000
--- ni/bin/rsync/options.c Thu Jul 06 23:23:40 2000
***************
*** 66,71 ****
--- 66,77 ----
int only_existing=0;
int max_delete=0;
int ignore_errors=0;
+ #ifdef _WIN32
+ int modify_window=2;
+ #else
+ int modify_window=0;
+ #endif /* _WIN32 */
+ int modify_window_set=0;
char *backup_suffix = BACKUP_SUFFIX;
char *tmpdir = NULL;
***************
*** 142,147 ****
--- 151,157 ----
rprintf(F," --timeout=TIME set IO timeout in seconds\n");
rprintf(F," -I, --ignore-times don't exclude files that match
length and time\n");
rprintf(F," --size-only only use file size when
determining if a file should be transferred\n");
+ rprintf(F," --modify-window=NUM Timestamp window (s) for file
match (default=%d)\n",modify_window);
rprintf(F," -T --temp-dir=DIR create temporary files in
directory DIR\n");
rprintf(F," --compare-dest=DIR also compare destination files
relative to DIR\n");
rprintf(F," -P equivalent to --partial
--progress\n");
***************
*** 174,180 ****
OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
! OPT_IGNORE_ERRORS};
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
--- 184,190 ----
OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
! OPT_IGNORE_ERRORS, OPT_MODIFY_WINDOW};
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
***************
*** 196,201 ****
--- 207,213 ----
{"one-file-system",0, 0, 'x'},
{"ignore-times",0, 0, 'I'},
{"size-only", 0, 0, OPT_SIZE_ONLY},
+ {"modify-window",1, 0, OPT_MODIFY_WINDOW},
{"help", 0, 0, 'h'},
{"dry-run", 0, 0, 'n'},
{"sparse", 0, 0, 'S'},
***************
*** 325,330 ****
--- 338,354 ----
size_only = 1;
break;
+ case OPT_MODIFY_WINDOW:
+ modify_window = atoi(optarg);
+ if (modify_window < 0) {
+ slprintf(err_buf,sizeof(err_buf),
+ "Invalid modification window '%s'",
+ optarg);
+ return 0;
+ }
+ modify_window_set = 1;
+ break;
+
case 'x':
one_file_system=1;
break;
***************
*** 584,589 ****
--- 612,618 ----
static char bsize[30];
static char iotime[30];
static char mdelete[30];
+ static char mwindow[30];
int i, x;
args[ac++] = "--server";
***************
*** 666,676 ****
--- 695,711 ----
if (delete_excluded)
args[ac++] = "--delete-excluded";
if (size_only)
args[ac++] = "--size-only";
+
+ if (modify_window_set) {
+ slprintf(mwindow,sizeof(mwindow),"--modify-window=%d",
+ modify_window);
+ args[ac++] = mwindow;
+ }
if (keep_partial)
args[ac++] = "--partial";
if (force_delete)
args[ac++] = "--force";
Index: ni/bin/rsync/util.c
diff -c ni/bin/rsync/util.c:1.1.1.1 ni/bin/rsync/util.c:1.2
*** ni/bin/rsync/util.c:1.1.1.1 Tue May 30 14:08:19 2000
--- ni/bin/rsync/util.c Thu Jul 06 23:23:40 2000
***************
*** 25,30 ****
--- 25,31 ----
#include "rsync.h"
extern int verbose;
+ extern int modify_window;
/***************************************************************************
*
***************
*** 227,232 ****
--- 228,249 ----
}
+ /* Determine if two file modification times are equivalent (either exact
*/
+ /* or in the modification timestamp window established by --modify-window)
*/
+ /* Returns 0 if the times should be treated as the same, 1 if not.
*/
+ int cmp_modtime (time_t file1, time_t file2)
+ {
+ time_t diff;
+
+ diff = (file2 > file1) ? (file2-file1) : (file1-file2);
+ if (diff <= modify_window) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+
/***************************************************************************
*
create any necessary directories in fname. Unfortunately we don't know
what perms to give the directory when this is called so we need to rely
Index: ni/bin/rsync/rsync.c
diff -c ni/bin/rsync/rsync.c:1.1.1.1 ni/bin/rsync/rsync.c:1.2
*** ni/bin/rsync/rsync.c:1.1.1.1 Tue May 30 14:08:19 2000
--- ni/bin/rsync/rsync.c Thu Jul 06 23:23:40 2000
***************
*** 163,169 ****
}
if (preserve_times && !S_ISLNK(st->st_mode) &&
! st->st_mtime != file->modtime) {
/* don't complain about not setting times on directories
because some filesystems can't do it */
if (set_modtime(fname,file->modtime) != 0 &&
--- 163,169 ----
}
if (preserve_times && !S_ISLNK(st->st_mode) &&
! cmp_modtime(st->st_mtime,file->modtime)) {
/* don't complain about not setting times on directories
because some filesystems can't do it */
if (set_modtime(fname,file->modtime) != 0 &&
Index: ni/bin/rsync/proto.h
diff -c ni/bin/rsync/proto.h:1.1.1.1 ni/bin/rsync/proto.h:1.2
*** ni/bin/rsync/proto.h:1.1.1.1 Tue May 30 14:08:19 2000
--- ni/bin/rsync/proto.h Thu Jul 06 23:23:40 2000
***************
*** 182,187 ****
--- 182,188 ----
void out_of_memory(char *str);
void overflow(char *str);
int set_modtime(char *fname,time_t modtime);
+ int cmp_modtime (time_t file1, time_t file2);
int create_directory_path(char *fname);
int copy_file(char *source, char *dest, mode_t mode);
int robust_unlink(char *fname);