mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-27 09:30:13 +03:00
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
This commit is contained in:
parent
462ba7d942
commit
20e850501d
2 changed files with 62 additions and 0 deletions
|
@ -35,6 +35,39 @@
|
||||||
#define ACCEPTED_TIME_DIFF 5
|
#define ACCEPTED_TIME_DIFF 5
|
||||||
#define ONE_HOUR 3600
|
#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
|
* 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
|
* 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);
|
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 */
|
/* file only found on current replica */
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
|
|
|
@ -108,6 +108,12 @@ remoteCleanup('test_stat');
|
||||||
system( "echo echo hello >> " . localDir() . 'echo.sh' );
|
system( "echo echo hello >> " . localDir() . 'echo.sh' );
|
||||||
chmod 0751, 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();
|
csync();
|
||||||
assertLocalAndRemoteDir( '', 0 );
|
assertLocalAndRemoteDir( '', 0 );
|
||||||
|
|
||||||
|
@ -126,6 +132,24 @@ open(my $fh, "<", localDir() . 'echo.sh');
|
||||||
my $perm = (stat $fh)[2] & 07777;
|
my $perm = (stat $fh)[2] & 07777;
|
||||||
assert( $perm eq 0751, "permissions not kept" );
|
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();
|
cleanup();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue