From 5b56cc19fbd5ed6626a091aa9c5af7fa371dc73a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Sep 2000 02:12:13 +0000 Subject: [PATCH] added --modify-window option from David Bolen --- generator.c | 5 +++-- options.c | 25 ++++++++++++++++++++++++- rsync.c | 2 +- rsync.yo | 10 +++++++++- util.c | 22 +++++++++++++++++++++- 5 files changed, 58 insertions(+), 6 deletions(-) diff --git a/generator.c b/generator.c index 8aa9c06f..1ab2bddf 100644 --- a/generator.c +++ b/generator.c @@ -35,6 +35,7 @@ extern int size_only; extern int io_timeout; extern int remote_version; extern int always_checksum; +extern int modify_window; extern char *compare_dest; @@ -75,7 +76,7 @@ static int skip_file(char *fname, return 0; } - return (st->st_mtime == file->modtime); + return (cmp_modtime(st->st_mtime,file->modtime) == 0); } @@ -343,7 +344,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out) 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; diff --git a/options.c b/options.c index 6de6641b..4176b328 100644 --- a/options.c +++ b/options.c @@ -67,6 +67,11 @@ int delete_after=0; 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; @@ -85,6 +90,9 @@ int quiet = 0; 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) @@ -144,6 +152,7 @@ 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"); @@ -178,7 +187,8 @@ enum {OPT_VERSION, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE, 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"; @@ -200,6 +210,7 @@ static struct option long_options[] = { {"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'}, @@ -331,6 +342,11 @@ int parse_arguments(int argc, char *argv[], int frommain) size_only = 1; break; + case OPT_MODIFY_WINDOW: + modify_window = atoi(optarg); + modify_window_set = 1; + break; + case 'x': one_file_system=1; break; @@ -598,6 +614,7 @@ void server_options(char **args,int *argc) static char bsize[30]; static char iotime[30]; static char mdelete[30]; + static char mwindow[30]; static char bw[50]; int i, x; @@ -699,6 +716,12 @@ void server_options(char **args,int *argc) 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"; diff --git a/rsync.c b/rsync.c index 63132672..44d54dac 100644 --- a/rsync.c +++ b/rsync.c @@ -162,7 +162,7 @@ int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, } 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 && diff --git a/rsync.yo b/rsync.yo index 1aac6f73..ca8bdc10 100644 --- a/rsync.yo +++ b/rsync.yo @@ -223,7 +223,7 @@ verb( -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 @@ -256,6 +256,7 @@ verb( --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 @@ -316,6 +317,13 @@ regardless of timestamp. This is useful when starting to use rsync 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 diff --git a/util.c b/util.c index bd0af33f..1752faeb 100644 --- a/util.c +++ b/util.c @@ -955,7 +955,27 @@ void msleep(int t) } -#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 /******************************************************************* -- 2.34.1