[Pkg-owncloud-commits] [owncloud-client] 294/333: Make sure we do not remove files that are replaced by a symlink

Sandro Knauß hefee-guest at moszumanska.debian.org
Thu Apr 17 23:17:06 UTC 2014


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository owncloud-client.

commit 20e850501d624ea10116ec0c2d7f4598e4e57f11
Author: Olivier Goffart <ogoffart at woboq.com>
Date:   Thu Apr 3 17:42:08 2014 +0200

    Make sure we do not remove files that are replaced by a symlink
    
    As we ignore symlink, we should not remove on the server the files that
    are ignored.
    
    Change tested in t4.pl
    
    Relates to #1299
---
 csync/src/csync_reconcile.c | 38 ++++++++++++++++++++++++++++++++++++++
 csync/tests/ownCloud/t4.pl  | 24 ++++++++++++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/csync/src/csync_reconcile.c b/csync/src/csync_reconcile.c
index a3f094f..038b5c0 100644
--- a/csync/src/csync_reconcile.c
+++ b/csync/src/csync_reconcile.c
@@ -35,6 +35,39 @@
 #define ACCEPTED_TIME_DIFF 5
 #define ONE_HOUR 3600
 
+
+/* Check if a file is ignored because one parent is ignored.
+ * return the node of the ignored directoy if it's the case, or NULL if it is not ignored */
+static c_rbnode_t *_csync_check_ignored(c_rbtree_t *tree, const char *path, int pathlen) {
+    uint64_t h = 0;
+    c_rbnode_t *node = NULL;
+
+    /* compute the size of the parent directory */
+    int parentlen = pathlen - 1;
+    while (parentlen > 0 && path[parentlen] != '/') {
+        parentlen--;
+    }
+    if (parentlen <= 0) {
+        return NULL;
+    }
+
+    h = c_jhash64((uint8_t *) path, parentlen, 0);
+    node = c_rbtree_find(tree, &h);
+    if (node) {
+        csync_file_stat_t *n = (csync_file_stat_t*)node->data;
+        if (n->instruction == CSYNC_INSTRUCTION_IGNORE) {
+            /* Yes, we are ignored */
+            return node;
+        } else {
+            /* Not ignored */
+            return NULL;
+        }
+    } else {
+        /* Try if the parent itself is ignored */
+        return _csync_check_ignored(tree, path, parentlen);
+    }
+}
+
 /*
  * We merge replicas at the file level. The merged replica contains the
  * superset of files that are on the local machine and server copies of
@@ -86,6 +119,11 @@ static int _csync_merge_algorithm_visitor(void *obj, void *data) {
         }
         SAFE_FREE(renamed_path);
     }
+    if (!node) {
+        /* Check if it is ignored */
+        node = _csync_check_ignored(tree, cur->path, cur->pathlen);
+        /* If it is ignored, other->instruction will be  IGNORE so this one will also be ignored */
+    }
 
     /* file only found on current replica */
     if (node == NULL) {
diff --git a/csync/tests/ownCloud/t4.pl b/csync/tests/ownCloud/t4.pl
index 9f7efa8..5c8a115 100755
--- a/csync/tests/ownCloud/t4.pl
+++ b/csync/tests/ownCloud/t4.pl
@@ -108,6 +108,12 @@ remoteCleanup('test_stat');
 system( "echo echo hello >> " . localDir() . 'echo.sh' );
 chmod 0751, localDir() . 'echo.sh';
 
+#and add a file in anotherdir for the next test
+mkdir( localDir() . 'anotherdir' );
+mkdir( localDir() . 'anotherdir/sub' );
+system( "echo foobar > " . localDir() . 'anotherdir/file1.txt' );
+system( "echo foobar > " . localDir() . 'anotherdir/sub/file2.txt' );
+
 csync();
 assertLocalAndRemoteDir( '', 0 );
 
@@ -126,6 +132,24 @@ open(my $fh, "<", localDir() . 'echo.sh');
 my $perm = (stat $fh)[2] & 07777;
 assert( $perm eq 0751, "permissions not kept" );
 
+printInfo("Remove a directory and make it a symlink instead\n");
+system( "rm -rf " . localDir() . 'anotherdir' );
+system( "ln -s /bin " . localDir() . 'anotherdir' );
+# remember the fileid of the file on the server
+my $oldfileid1 = remoteFileId( 'anotherdir/', 'file1.txt' );
+my $oldfileid2 = remoteFileId( 'anotherdir/sub', 'file2.txt' );
+csync();
+
+#check that the files in ignored directory has NOT been removed
+my $newfileid1 = remoteFileId( 'anotherdir/', 'file1.txt' );
+my $newfileid2 = remoteFileId( 'anotherdir/sub', 'file2.txt' );
+assert( $oldfileid1 eq $newfileid1, "File removed (file1.txt)" );
+assert( $oldfileid2 eq $newfileid2, "File removed (file2.txt)" );
+
+printInfo("Now remove the symlink\n");
+system( "rm -f " . localDir() . 'anotherdir' );
+csync();
+assertLocalAndRemoteDir( '', 0 );
 
 cleanup();
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud-client.git



More information about the Pkg-owncloud-commits mailing list