added --modify-window option from David Bolen <db3l@fitlinxx.com>
authorAndrew Tridgell <tridge@samba.org>
Wed, 6 Sep 2000 02:12:13 +0000 (02:12 +0000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 6 Sep 2000 02:12:13 +0000 (02:12 +0000)
generator.c
options.c
rsync.c
rsync.yo
util.c

index 8aa9c06..1ab2bdd 100644 (file)
@@ -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;
index 6de6641..4176b32 100644 (file)
--- 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 6313267..44d54da 100644 (file)
--- 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 &&
index 1aac6f7..ca8bdc1 100644 (file)
--- 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 bd0af33..1752fae 100644 (file)
--- 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 <dlfcn.h>
 
 /*******************************************************************