Get rid of eol whitespace.
[rsync/rsync.git] / flist.c
diff --git a/flist.c b/flist.c
index d91d90b..11aeef0 100644 (file)
--- a/flist.c
+++ b/flist.c
@@ -1,18 +1,18 @@
-/* 
+/*
    Copyright (C) Andrew Tridgell 1996
    Copyright (C) Paul Mackerras 1996
    Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -65,7 +65,7 @@ static struct exclude_struct **local_exclude_list;
 
 static struct file_struct null_file;
 
-static void clean_flist(struct file_list *flist, int strip_root);
+static void clean_flist(struct file_list *flist, int strip_root, int no_dups);
 
 
 static int show_filelist_p(void)
@@ -216,12 +216,12 @@ int readlink_stat(const char *path, STRUCT_STAT * buffer, char *linkbuf)
        if (S_ISLNK(buffer->st_mode)) {
                int l;
                l = readlink((char *) path, linkbuf, MAXPATHLEN - 1);
-               if (l == -1) 
+               if (l == -1)
                        return -1;
                linkbuf[l] = 0;
                if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) {
                        if (verbose > 1) {
-                               rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n", 
+                               rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
                                        path, linkbuf);
                        }
                        return do_stat(path, buffer);
@@ -307,14 +307,14 @@ static void flist_expand(struct file_list *flist)
        if (flist->count >= flist->malloced) {
                size_t new_bytes;
                void *new_ptr;
-               
+
                if (flist->malloced < 1000)
                        flist->malloced += 1000;
                else
                        flist->malloced *= 2;
 
                new_bytes = sizeof(flist->files[0]) * flist->malloced;
-               
+
                if (flist->files)
                        new_ptr = realloc(flist->files, new_bytes);
                else
@@ -325,7 +325,7 @@ static void flist_expand(struct file_list *flist)
                                (double) new_bytes,
                                (new_ptr == flist->files) ? " not" : "");
                }
-               
+
                flist->files = (struct file_struct **) new_ptr;
 
                if (!flist->files)
@@ -374,7 +374,7 @@ static void send_file_entry(struct file_struct *file, int f,
 
        for (l1 = 0;
             lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);
-            l1++);
+            l1++) {}
        l2 = strlen(fname) - l1;
 
        if (l1 > 0)
@@ -662,7 +662,7 @@ struct file_struct *make_file(int f, char *fname, struct string_area **ap,
        if (readlink_stat(fname, &st, linkbuf) != 0) {
                int save_errno = errno;
                if ((errno == ENOENT) && !noexcludes) {
-                       /* either symlink pointing nowhere or file that 
+                       /* either symlink pointing nowhere or file that
                         * was removed during rsync run; see if excluded
                         * before reporting an error */
                        memset((char *) &st, 0, sizeof(st));
@@ -942,31 +942,37 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                                        dir = fname;
                                fname = p + 1;
                        }
-               } else if (f != -1 && (p = strrchr(fname, '/'))) {
+               } else if (f != -1 && (p=strrchr(fname,'/')) && p != fname) {
                        /* this ensures we send the intermediate directories,
                           thus getting their permissions right */
+                       char *lp = lastpath, *fn = fname, *slash = fname;
                        *p = 0;
-                       if (strcmp(lastpath, fname)) {
-                               strlcpy(lastpath, fname, sizeof(lastpath));
-                               *p = '/';
-                               for (p = fname + 1; (p = strchr(p, '/'));
-                                    p++) {
-                                       int copy_links_saved = copy_links;
-                                       int recurse_saved = recurse;
-                                       *p = 0;
-                                       copy_links = copy_unsafe_links;
-                                       /* set recurse to 1 to prevent make_file
-                                          from ignoring directory, but still
-                                          turn off the recursive parameter to
-                                          send_file_name */
-                                       recurse = 1;
-                                       send_file_name(f, flist, fname, 0,
-                                                      0);
-                                       copy_links = copy_links_saved;
-                                       recurse = recurse_saved;
-                                       *p = '/';
+                       /* Skip any initial directories in our path that we
+                        * have in common with lastpath. */
+                       while (*fn && *lp == *fn) {
+                               if (*fn == '/')
+                                       slash = fn;
+                               lp++, fn++;
+                       }
+                       *p = '/';
+                       if (fn != p || (*lp && *lp != '/')) {
+                               int copy_links_saved = copy_links;
+                               int recurse_saved = recurse;
+                               copy_links = copy_unsafe_links;
+                               /* set recurse to 1 to prevent make_file
+                                * from ignoring directory, but still
+                                * turn off the recursive parameter to
+                                * send_file_name */
+                               recurse = 1;
+                               while ((slash = strchr(slash+1, '/')) != 0) {
+                                       *slash = 0;
+                                       send_file_name(f, flist, fname, 0, 0);
+                                       *slash = '/';
                                }
-                       } else {
+                               copy_links = copy_links_saved;
+                               recurse = recurse_saved;
+                               *p = 0;
+                               strlcpy(lastpath, fname, sizeof lastpath);
                                *p = '/';
                        }
                }
@@ -1010,7 +1016,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
                finish_filelist_progress(flist);
        }
 
-       clean_flist(flist, 0);
+       clean_flist(flist, 0, 0);
 
        /* now send the uid/gid list. This was introduced in protocol
           version 15 */
@@ -1066,7 +1072,7 @@ struct file_list *recv_file_list(int f)
 
        for (flags = read_byte(f); flags; flags = read_byte(f)) {
                int i = flist->count;
-               
+
                flist_expand(flist);
 
                receive_file_entry(&flist->files[i], flags, f);
@@ -1087,7 +1093,7 @@ struct file_list *recv_file_list(int f)
        if (verbose > 2)
                rprintf(FINFO, "received %d names\n", flist->count);
 
-       clean_flist(flist, relative_paths);
+       clean_flist(flist, relative_paths, 1);
 
        if (show_filelist_p()) {
                finish_filelist_progress(flist);
@@ -1244,9 +1250,9 @@ void flist_free(struct file_list *flist)
 
 /*
  * This routine ensures we don't have any duplicate names in our file list.
- * duplicate names can cause corruption because of the pipelining 
+ * duplicate names can cause corruption because of the pipelining
  */
-static void clean_flist(struct file_list *flist, int strip_root)
+static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
 {
        int i;
        char *name, *prev_name = NULL;
@@ -1257,7 +1263,7 @@ static void clean_flist(struct file_list *flist, int strip_root)
        qsort(flist->files, flist->count,
              sizeof(flist->files[0]), (int (*)()) file_compare);
 
-       for (i = 0; i < flist->count; i++) {
+       for (i = no_dups? 0 : flist->count; i < flist->count; i++) {
                if (flist->files[i]->basename) {
                        prev_name = f_name(flist->files[i]);
                        break;