mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-29 12:19:03 +03:00
csync_update: Remove the check for csync_get_statedb_exists
This always returns true since _csync_statedb_is_empty also always
returns true. This function was initially intended to be a shortcut
in case the database doesn't contain any row, but has been broken since
27fb5d9128
and now won't return false
unless the statement fails.
The _last_db_return_error in _csync_detect_update would take care
of that code path in a more direct and clearer way anyway.
This commit is contained in:
parent
81e32e1a08
commit
4e90bd7a5a
1 changed files with 166 additions and 172 deletions
|
@ -170,183 +170,177 @@ static int _csync_detect_update(CSYNC *ctx, std::unique_ptr<csync_file_stat_t> f
|
|||
* renamed, the db gets queried by the inode of the file as that one
|
||||
* does not change on rename.
|
||||
*/
|
||||
if (csync_get_statedb_exists(ctx)) {
|
||||
tmp = csync_statedb_get_stat_by_path(ctx, fs->path);
|
||||
tmp = csync_statedb_get_stat_by_path(ctx, fs->path);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(tmp && tmp->path == fs->path ) { /* there is an entry in the database */
|
||||
/* we have an update! */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Database entry found, compare: %" PRId64 " <-> %" PRId64
|
||||
", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
|
||||
", size: %" PRId64 " <-> %" PRId64 ", perms: %s <-> %s, ignore: %d",
|
||||
((int64_t) fs->modtime), ((int64_t) tmp->modtime),
|
||||
fs->etag.constData(), tmp->etag.constData(), (uint64_t) fs->inode, (uint64_t) tmp->inode,
|
||||
(uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm.constData(), tmp->remotePerm.constData(), tmp->has_ignored_files );
|
||||
if (ctx->current == REMOTE_REPLICA && fs->etag != tmp->etag) {
|
||||
fs->instruction = CSYNC_INSTRUCTION_EVAL;
|
||||
|
||||
// Preserve the EVAL flag later on if the type has changed.
|
||||
if (tmp->type != fs->type) {
|
||||
fs->child_modified = true;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
if (ctx->current == LOCAL_REPLICA &&
|
||||
(!_csync_mtime_equal(fs->modtime, tmp->modtime)
|
||||
// zero size in statedb can happen during migration
|
||||
|| (tmp->size != 0 && fs->size != tmp->size))) {
|
||||
|
||||
// Checksum comparison at this stage is only enabled for .eml files,
|
||||
// check #4754 #4755
|
||||
bool isEmlFile = csync_fnmatch("*.eml", fs->path, FNM_CASEFOLD) == 0;
|
||||
if (isEmlFile && fs->size == tmp->size && !tmp->checksumHeader.isEmpty()) {
|
||||
if (ctx->callbacks.checksum_hook) {
|
||||
fs->checksumHeader = ctx->callbacks.checksum_hook(
|
||||
_rel_to_abs(ctx, fs->path), tmp->checksumHeader,
|
||||
ctx->callbacks.checksum_userdata);
|
||||
}
|
||||
bool checksumIdentical = false;
|
||||
if (!fs->checksumHeader.isEmpty()) {
|
||||
checksumIdentical = fs->checksumHeader == tmp->checksumHeader;
|
||||
}
|
||||
if (checksumIdentical) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", fs->path.constData());
|
||||
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve the EVAL flag later on if the type has changed.
|
||||
if (tmp->type != fs->type) {
|
||||
fs->child_modified = true;
|
||||
}
|
||||
|
||||
fs->instruction = CSYNC_INSTRUCTION_EVAL;
|
||||
goto out;
|
||||
}
|
||||
bool metadata_differ = (ctx->current == REMOTE_REPLICA && (fs->file_id != tmp->file_id
|
||||
|| fs->remotePerm != tmp->remotePerm))
|
||||
|| (ctx->current == LOCAL_REPLICA && fs->inode != tmp->inode);
|
||||
if (fs->type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
|
||||
&& !metadata_differ && ctx->read_remote_from_db) {
|
||||
/* If both etag and file id are equal for a directory, read all contents from
|
||||
* the database.
|
||||
* The metadata comparison ensure that we fetch all the file id or permission when
|
||||
* upgrading owncloud
|
||||
*/
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", fs->path.constData());
|
||||
ctx->remote.read_from_db = true;
|
||||
}
|
||||
/* If it was remembered in the db that the remote dir has ignored files, store
|
||||
* that so that the reconciler can make advantage of.
|
||||
*/
|
||||
if( ctx->current == REMOTE_REPLICA ) {
|
||||
fs->has_ignored_files = tmp->has_ignored_files;
|
||||
}
|
||||
if (metadata_differ) {
|
||||
/* file id or permissions has changed. Which means we need to update them in the DB. */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", fs->path.constData());
|
||||
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
} else {
|
||||
fs->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
} else {
|
||||
/* check if it's a file and has been renamed */
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||
|
||||
tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Default to NEW unless we're sure it's a rename.
|
||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
|
||||
bool isRename =
|
||||
tmp && tmp->inode == fs->inode && tmp->type == fs->type
|
||||
&& (tmp->modtime == fs->modtime || fs->type == CSYNC_FTW_TYPE_DIR)
|
||||
#ifdef NO_RENAME_EXTENSION
|
||||
&& _csync_sameextension(tmp->path, fs->path)
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
// Verify the checksum where possible
|
||||
if (isRename && !tmp->checksumHeader.isEmpty() && ctx->callbacks.checksum_hook
|
||||
&& fs->type == CSYNC_FTW_TYPE_FILE) {
|
||||
fs->checksumHeader = ctx->callbacks.checksum_hook(
|
||||
_rel_to_abs(ctx, fs->path), tmp->checksumHeader,
|
||||
ctx->callbacks.checksum_userdata);
|
||||
if (!fs->checksumHeader.isEmpty()) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", fs->path.constData(), fs->checksumHeader.constData(), tmp->checksumHeader.constData());
|
||||
isRename = fs->checksumHeader == tmp->checksumHeader;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRename) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||
/* inode found so the file has been renamed */
|
||||
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
||||
if (fs->type == CSYNC_FTW_TYPE_DIR) {
|
||||
csync_rename_record(ctx, tmp->path, fs->path);
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
|
||||
} else {
|
||||
/* Remote Replica Rename check */
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
if(tmp ) { /* tmp existing at all */
|
||||
if (tmp->type != fs->type) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "file types different is not!");
|
||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
goto out;
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "remote rename detected based on fileid %s --> %s", tmp->path.constData(), fs->path.constData());
|
||||
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
||||
if (fs->type == CSYNC_FTW_TYPE_DIR) {
|
||||
csync_rename_record(ctx, tmp->path, fs->path);
|
||||
} else {
|
||||
if( tmp->etag != fs->etag ) {
|
||||
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ETags are different!"); */
|
||||
/* File with different etag, don't do a rename, but download the file again */
|
||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
|
||||
} else {
|
||||
/* file not found in statedb */
|
||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
|
||||
if (fs->type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
|
||||
if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, fs->path, fs->remotePerm)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Unable to open statedb" );
|
||||
if(_last_db_return_error(ctx)) {
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(tmp && tmp->path == fs->path ) { /* there is an entry in the database */
|
||||
/* we have an update! */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "Database entry found, compare: %" PRId64 " <-> %" PRId64
|
||||
", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
|
||||
", size: %" PRId64 " <-> %" PRId64 ", perms: %s <-> %s, ignore: %d",
|
||||
((int64_t) fs->modtime), ((int64_t) tmp->modtime),
|
||||
fs->etag.constData(), tmp->etag.constData(), (uint64_t) fs->inode, (uint64_t) tmp->inode,
|
||||
(uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm.constData(), tmp->remotePerm.constData(), tmp->has_ignored_files );
|
||||
if (ctx->current == REMOTE_REPLICA && fs->etag != tmp->etag) {
|
||||
fs->instruction = CSYNC_INSTRUCTION_EVAL;
|
||||
|
||||
// Preserve the EVAL flag later on if the type has changed.
|
||||
if (tmp->type != fs->type) {
|
||||
fs->child_modified = true;
|
||||
}
|
||||
|
||||
goto out;
|
||||
}
|
||||
if (ctx->current == LOCAL_REPLICA &&
|
||||
(!_csync_mtime_equal(fs->modtime, tmp->modtime)
|
||||
// zero size in statedb can happen during migration
|
||||
|| (tmp->size != 0 && fs->size != tmp->size))) {
|
||||
|
||||
// Checksum comparison at this stage is only enabled for .eml files,
|
||||
// check #4754 #4755
|
||||
bool isEmlFile = csync_fnmatch("*.eml", fs->path, FNM_CASEFOLD) == 0;
|
||||
if (isEmlFile && fs->size == tmp->size && !tmp->checksumHeader.isEmpty()) {
|
||||
if (ctx->callbacks.checksum_hook) {
|
||||
fs->checksumHeader = ctx->callbacks.checksum_hook(
|
||||
_rel_to_abs(ctx, fs->path), tmp->checksumHeader,
|
||||
ctx->callbacks.checksum_userdata);
|
||||
}
|
||||
bool checksumIdentical = false;
|
||||
if (!fs->checksumHeader.isEmpty()) {
|
||||
checksumIdentical = fs->checksumHeader == tmp->checksumHeader;
|
||||
}
|
||||
if (checksumIdentical) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", fs->path.constData());
|
||||
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
// Preserve the EVAL flag later on if the type has changed.
|
||||
if (tmp->type != fs->type) {
|
||||
fs->child_modified = true;
|
||||
}
|
||||
|
||||
fs->instruction = CSYNC_INSTRUCTION_EVAL;
|
||||
goto out;
|
||||
}
|
||||
bool metadata_differ = (ctx->current == REMOTE_REPLICA && (fs->file_id != tmp->file_id
|
||||
|| fs->remotePerm != tmp->remotePerm))
|
||||
|| (ctx->current == LOCAL_REPLICA && fs->inode != tmp->inode);
|
||||
if (fs->type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA
|
||||
&& !metadata_differ && ctx->read_remote_from_db) {
|
||||
/* If both etag and file id are equal for a directory, read all contents from
|
||||
* the database.
|
||||
* The metadata comparison ensure that we fetch all the file id or permission when
|
||||
* upgrading owncloud
|
||||
*/
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Reading from database: %s", fs->path.constData());
|
||||
ctx->remote.read_from_db = true;
|
||||
}
|
||||
/* If it was remembered in the db that the remote dir has ignored files, store
|
||||
* that so that the reconciler can make advantage of.
|
||||
*/
|
||||
if( ctx->current == REMOTE_REPLICA ) {
|
||||
fs->has_ignored_files = tmp->has_ignored_files;
|
||||
}
|
||||
if (metadata_differ) {
|
||||
/* file id or permissions has changed. Which means we need to update them in the DB. */
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Need to update metadata for: %s", fs->path.constData());
|
||||
fs->instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
|
||||
} else {
|
||||
fs->instruction = CSYNC_INSTRUCTION_NONE;
|
||||
}
|
||||
} else {
|
||||
/* check if it's a file and has been renamed */
|
||||
if (ctx->current == LOCAL_REPLICA) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Checking for rename based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||
|
||||
tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Default to NEW unless we're sure it's a rename.
|
||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
|
||||
bool isRename =
|
||||
tmp && tmp->inode == fs->inode && tmp->type == fs->type
|
||||
&& (tmp->modtime == fs->modtime || fs->type == CSYNC_FTW_TYPE_DIR)
|
||||
#ifdef NO_RENAME_EXTENSION
|
||||
&& _csync_sameextension(tmp->path, fs->path)
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
// Verify the checksum where possible
|
||||
if (isRename && !tmp->checksumHeader.isEmpty() && ctx->callbacks.checksum_hook
|
||||
&& fs->type == CSYNC_FTW_TYPE_FILE) {
|
||||
fs->checksumHeader = ctx->callbacks.checksum_hook(
|
||||
_rel_to_abs(ctx, fs->path), tmp->checksumHeader,
|
||||
ctx->callbacks.checksum_userdata);
|
||||
if (!fs->checksumHeader.isEmpty()) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", fs->path.constData(), fs->checksumHeader.constData(), tmp->checksumHeader.constData());
|
||||
isRename = fs->checksumHeader == tmp->checksumHeader;
|
||||
}
|
||||
}
|
||||
|
||||
if (isRename) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "pot rename detected based on inode # %" PRId64 "", (uint64_t) fs->inode);
|
||||
/* inode found so the file has been renamed */
|
||||
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
||||
if (fs->type == CSYNC_FTW_TYPE_DIR) {
|
||||
csync_rename_record(ctx, tmp->path, fs->path);
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
|
||||
} else {
|
||||
/* Remote Replica Rename check */
|
||||
tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
|
||||
|
||||
if(_last_db_return_error(ctx)) {
|
||||
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
|
||||
return -1;
|
||||
}
|
||||
if(tmp ) { /* tmp existing at all */
|
||||
if (tmp->type != fs->type) {
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "file types different is not!");
|
||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
goto out;
|
||||
}
|
||||
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "remote rename detected based on fileid %s --> %s", tmp->path.constData(), fs->path.constData());
|
||||
fs->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
|
||||
if (fs->type == CSYNC_FTW_TYPE_DIR) {
|
||||
csync_rename_record(ctx, tmp->path, fs->path);
|
||||
} else {
|
||||
if( tmp->etag != fs->etag ) {
|
||||
/* CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "ETags are different!"); */
|
||||
/* File with different etag, don't do a rename, but download the file again */
|
||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
|
||||
} else {
|
||||
/* file not found in statedb */
|
||||
fs->instruction = CSYNC_INSTRUCTION_NEW;
|
||||
|
||||
if (fs->type == CSYNC_FTW_TYPE_DIR && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
|
||||
if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, fs->path, fs->remotePerm)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
/* Set the ignored error string. */
|
||||
|
|
Loading…
Reference in a new issue