extern int io_timeout;
extern int remote_version;
extern int always_checksum;
+extern int modify_window;
extern char *compare_dest;
return 0;
}
- return (st->st_mtime == file->modtime);
+ return (cmp_modtime(st->st_mtime,file->modtime) == 0);
}
return;
}
- if (update_only && st.st_mtime > file->modtime && fnamecmp == fname) {
+ if (update_only && cmp_modtime(st.st_mtime,file->modtime)>0 && fnamecmp == fname) {
if (verbose > 1)
rprintf(FINFO,"%s is newer\n",fname);
return;
int only_existing=0;
int max_delete=0;
int ignore_errors=0;
+#ifdef _WIN32
+int modify_window=2;
+#else
+int modify_window=0;
+#endif
int blocking_io=0;
char *backup_suffix = BACKUP_SUFFIX;
int always_checksum = 0;
int list_only = 0;
+static int modify_window_set;
+
+
struct in_addr socket_address = {INADDR_ANY};
void usage(enum logcode F)
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 (seconds) 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");
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_BWLIMIT, OPT_BLOCKING_IO};
+ OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO,
+ OPT_MODIFY_WINDOW};
static char *short_options = "oblLWHpguDCtcahvqrRIxnSe:B:T:zP";
{"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'},
size_only = 1;
break;
+ case OPT_MODIFY_WINDOW:
+ modify_window = atoi(optarg);
+ modify_window_set = 1;
+ break;
+
case 'x':
one_file_system=1;
break;
static char bsize[30];
static char iotime[30];
static char mdelete[30];
+ static char mwindow[30];
static char bw[50];
int i, x;
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 (preserve_times && !S_ISLNK(st->st_mode) &&
- st->st_mtime != file->modtime) {
+ cmp_modtime(st->st_mtime, file->modtime) != 0) {
/* don't complain about not setting times on directories
because some filesystems can't do it */
if (set_modtime(fname,file->modtime) != 0 &&
-r, --recursive recurse into directories
-R, --relative use relative path names
-b, --backup make backups (default ~ suffix)
- --backup-dir=DIR put backups in the specified directory
+ --backup-dir make backups into this directory
--suffix=SUFFIX override backup suffix
-u, --update update only (don't overwrite newer files)
-l, --links preserve soft links
--timeout=TIME set IO timeout in seconds
-I, --ignore-times don't exclude files that match length and time
--size-only only use file size when determining if a file should be transferred
+ --modify-window=NUM Timestamp window (seconds) for file match (default=0)
-T --temp-dir=DIR create temporary files in directory DIR
--compare-dest=DIR also compare destination files relative to DIR
-P equivalent to --partial --progress
after using another mirroring system which may not preserve timestamps
exactly.
+dit(bf(--modify-window)) When comparing two timestamps rsync treats
+the timestamps as being equal if they are within the value of
+modify_window. This is normally zero, but you may find it useful to
+set this to a larger value in some situations. In particular, when
+transferring to/from FAT filesystems which cannot represent times with
+a 1 second resolution this option is useful.
+
dit(bf(-c, --checksum)) This forces the sender to checksum all files using
a 128-bit MD4 checksum before transfer. The checksum is then
explicitly checked on the receiver and any files of the same name
}
-#ifdef __INSURE__
+/*******************************************************************
+ 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 the
+ first is later and -1 if the 2nd is later
+ *******************************************************************/
+int cmp_modtime(time_t file1, time_t file2)
+{
+ time_t diff;
+ extern int modify_window;
+
+ if (file2 > file1) {
+ if (file2 - file1 <= modify_window) return 0;
+ return -1;
+ }
+ if (file1 - file2 <= modify_window) return 0;
+ return 1;
+}
+
+
+#ifdef __INSURE__XX
#include <dlfcn.h>
/*******************************************************************