Call sanitize_path() with updated args.
[rsync/rsync.git] / util.c
diff --git a/util.c b/util.c
index 96b7ac4..449b101 100644 (file)
--- a/util.c
+++ b/util.c
@@ -362,8 +362,8 @@ int robust_unlink(char *fname)
 #endif
 }
 
-/* Returns 0 on success, -1 on most errors, and -2 if we got an error
- * trying to copy the file across file systems. */
+/* Returns 0 on successful rename, 1 if we successfully copied the file
+ * across filesystems, -2 if copy_file() failed, and -1 on other errors. */
 int robust_rename(char *from, char *to, int mode)
 {
        int tries = 4;
@@ -383,7 +383,7 @@ int robust_rename(char *from, char *to, int mode)
                        if (copy_file(from, to, mode) != 0)
                                return -2;
                        do_unlink(from);
-                       return 0;
+                       return 1;
                default:
                        return -1;
                }
@@ -650,13 +650,13 @@ size_t stringjoin(char *dest, size_t destsize, ...)
        return ret;
 }
 
-void clean_fname(char *name)
+unsigned int clean_fname(char *name)
 {
-       char *limit = name, *t = name, *f = name;
+       char *limit = name - 1, *t = name, *f = name;
        int anchored;
 
        if (!name)
-               return;
+               return 0;
 
        if ((anchored = *f == '/') != 0)
                *t++ = *f++;
@@ -669,7 +669,7 @@ void clean_fname(char *name)
                if (*f == '.') {
                        /* discard "." dirs (but NOT a trailing '.'!) */
                        if (f[1] == '/') {
-                               f++; /* not += 2! */
+                               f += 2;
                                continue;
                        }
                        /* collapse ".." dirs */
@@ -680,7 +680,7 @@ void clean_fname(char *name)
                                        continue;
                                }
                                while (s > limit && *--s != '/') {}
-                               if (s != t - 1 && *s == '/') {
+                               if (s != t - 1 && (s < name || *s == '/')) {
                                        t = s + 1;
                                        f += 2;
                                        continue;
@@ -698,6 +698,8 @@ void clean_fname(char *name)
        if (t == name)
                *t++ = '.';
        *t = '\0';
+
+       return t - name;
 }
 
 /* Make path appear as if a chroot had occurred.  This handles a leading
@@ -867,7 +869,7 @@ int push_dir(char *dir)
                curr_dir_len += len;
        }
 
-       clean_fname(curr_dir);
+       curr_dir_len = clean_fname(curr_dir);
 
        return 1;
 }