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 io_timeout;
 extern int remote_version;
 extern int always_checksum;
+extern int modify_window;
 extern char *compare_dest;
 
 
 extern char *compare_dest;
 
 
@@ -75,7 +76,7 @@ static int skip_file(char *fname,
                return 0;
        }
 
                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;
        }
 
                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;
                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;
 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 blocking_io=0;
 
 char *backup_suffix = BACKUP_SUFFIX;
@@ -85,6 +90,9 @@ int quiet = 0;
 int always_checksum = 0;
 int list_only = 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)
 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,"     --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");
   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_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";
 
 
 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},
   {"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'},
   {"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;
 
                        size_only = 1;
                        break;
 
+               case OPT_MODIFY_WINDOW:
+                       modify_window = atoi(optarg);
+                       modify_window_set = 1;
+                       break;
+                       
                case 'x':
                        one_file_system=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 bsize[30];
        static char iotime[30];
        static char mdelete[30];
+       static char mwindow[30];
        static char bw[50];
 
        int i, x;
        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 (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 (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) &&
        }
 
        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 &&
                /* 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)
  -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
      --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
      --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
  -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.
 
 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
 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>
 
 /*******************************************************************
 #include <dlfcn.h>
 
 /*******************************************************************