Optimize finding the sum that matches our --inplace position.
[rsync/rsync.git] / util.c
diff --git a/util.c b/util.c
index b01e64d..a53ea29 100644 (file)
--- a/util.c
+++ b/util.c
 #include "itypes.h"
 #include "inums.h"
 
-extern int dry_run;
 extern int module_id;
 extern int modify_window;
 extern int relative_paths;
+extern int preserve_times;
 extern int preserve_xattrs;
 extern char *module_dir;
 extern unsigned int module_dirlen;
-extern mode_t orig_umask;
 extern char *partial_dir;
 extern filter_rule_list daemon_filter_list;
 
@@ -123,12 +122,11 @@ NORETURN void overflow_exit(const char *str)
        exit_cleanup(RERR_MALLOC);
 }
 
+/* This returns 0 for success, 1 for a symlink if symlink time-setting
+ * is not possible, or -1 for any other error. */
 int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
 {
-#ifndef CAN_SET_SYMLINK_TIMES
-       if (S_ISLNK(mode))
-               return 1;
-#endif
+       static int switch_step = 0;
 
        if (DEBUG_GTE(TIME, 1)) {
                rprintf(FINFO, "set modtime of %s to (%ld) %s",
@@ -136,60 +134,49 @@ int set_modtime(const char *fname, time_t modtime, uint32 mod_nsec, mode_t mode)
                        asctime(localtime(&modtime)));
        }
 
-       if (dry_run)
-               return 0;
-
-       {
+       switch (switch_step) {
 #ifdef HAVE_UTIMENSAT
-               struct timespec t[2];
-               t[0].tv_sec = 0;
-               t[0].tv_nsec = UTIME_NOW;
-               t[1].tv_sec = modtime;
-               t[1].tv_nsec = mod_nsec;
-               if (utimensat(AT_FDCWD, fname, t, AT_SYMLINK_NOFOLLOW) < 0)
-                       return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1;
-               return 0;
-#elif defined HAVE_UTIMES || defined HAVE_LUTIMES
-               struct timeval t[2];
-               t[0].tv_sec = time(NULL);
-               t[0].tv_usec = 0;
-               t[1].tv_sec = modtime;
-               t[1].tv_usec = mod_nsec / 1000;
-# ifdef HAVE_LUTIMES
-               if (lutimes(fname, t) < 0)
-                       return S_ISLNK(mode) && errno == ENOSYS ? 1 : -1;
-               return 0;
-# else
-               return utimes(fname, t);
-# endif
-#elif defined HAVE_STRUCT_UTIMBUF
-               struct utimbuf tbuf;
-               tbuf.actime = time(NULL);
-               tbuf.modtime = modtime;
-               return utime(fname,&tbuf);
-#elif defined HAVE_UTIME
-               time_t t[2];
-               t[0] = time(NULL);
-               t[1] = modtime;
-               return utime(fname,t);
-#else
-#error No file-time-modification routine found!
+#include "case_N.h"
+               if (do_utimensat(fname, modtime, mod_nsec) == 0)
+                       break;
+               if (errno != ENOSYS)
+                       return -1;
+               switch_step++;
+               /* FALLTHROUGH */
 #endif
-       }
-}
 
-/* This creates a new directory with default permissions.  Since there
- * might be some directory-default permissions affecting this, we can't
- * force the permissions directly using the original umask and mkdir(). */
-int mkdir_defmode(char *fname)
-{
-       int ret;
+#ifdef HAVE_LUTIMES
+#include "case_N.h"
+               if (do_lutimes(fname, modtime, mod_nsec) == 0)
+                       break;
+               if (errno != ENOSYS)
+                       return -1;
+               switch_step++;
+               /* FALLTHROUGH */
+#endif
 
-       umask(orig_umask);
-       ret = do_mkdir(fname, ACCESSPERMS);
-       umask(0);
+#include "case_N.h"
+               switch_step++;
+               if (preserve_times & PRESERVE_LINK_TIMES) {
+                       preserve_times &= ~PRESERVE_LINK_TIMES;
+                       if (S_ISLNK(mode))
+                               return 1;
+               }
+               /* FALLTHROUGH */
 
-       return ret;
+#include "case_N.h"
+#ifdef HAVE_UTIMES
+               if (do_utimes(fname, modtime, mod_nsec) == 0)
+                       break;
+#else
+               if (do_utime(fname, modtime, mod_nsec) == 0)
+                       break;
+#endif
+
+               return -1;
+       }
+
+       return 0;
 }
 
 /* Create any necessary directories in fname.  Any missing directories are
@@ -216,8 +203,6 @@ int make_path(char *fname, int flags)
        } else
                end = fname + strlen(fname);
 
-       umask(orig_umask); /* NOTE: don't return before setting this back to 0! */
-
        /* Try to find an existing dir, starting from the deepest dir. */
        for (p = end; ; ) {
                if (do_mkdir(fname, ACCESSPERMS) == 0) {
@@ -258,8 +243,6 @@ int make_path(char *fname, int flags)
                        ret++;
        }
 
-       umask(0);
-
        if (flags & MKP_DROP_NAME)
                *end = '/';
 
@@ -348,6 +331,11 @@ int copy_file(const char *source, const char *dest, int ofd, mode_t mode)
                        return -1;
                }
 
+#ifdef SUPPORT_XATTRS
+               if (preserve_xattrs)
+                       mode |= S_IWUSR;
+#endif
+               mode &= INITACCESSPERMS;
                if ((ofd = do_open(dest, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, mode)) < 0) {
                        int save_errno = errno;
                        rsyserr(FERROR_XFER, save_errno, "open %s", full_fname(dest));
@@ -1435,11 +1423,11 @@ const char *find_filename_suffix(const char *fn, int fn_len, int *len_ptr)
 
 #define UNIT (1 << 16)
 
-uint32 fuzzy_distance(const char *s1, int len1, const char *s2, int len2)
+uint32 fuzzy_distance(const char *s1, unsigned len1, const char *s2, unsigned len2)
 {
        uint32 a[MAXPATHLEN], diag, above, left, diag_inc, above_inc, left_inc;
        int32 cost;
-       int i1, i2;
+       unsigned i1, i2;
 
        if (!len1 || !len2) {
                if (!len1) {