diff options
author | Christian Kamm <mail@ckamm.de> | 2016-01-20 12:47:01 +0300 |
---|---|---|
committer | Christian Kamm <mail@ckamm.de> | 2016-01-20 15:21:48 +0300 |
commit | 62ded39416885ae28e625e6a94e06f0a57afab83 (patch) | |
tree | 507c109c5892bb10a090637e6ee4adf584342e5b /csync | |
parent | f705c56cb33efbd5ed9ee6fe1744dfa224351ff2 (diff) |
Update: Check checksum for renamed files #2983
This currently doesn't do much because we only compute content
checksums for .eml files.
Diffstat (limited to 'csync')
-rw-r--r-- | csync/src/csync_update.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/csync/src/csync_update.c b/csync/src/csync_update.c index 44c97038e..a7a76c5f1 100644 --- a/csync/src/csync_update.c +++ b/csync/src/csync_update.c @@ -351,24 +351,41 @@ static int _csync_detect_update(CSYNC *ctx, const char *file, tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN; } - if (tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type + // Default to NEW unless we're sure it's a rename. + st->instruction = CSYNC_INSTRUCTION_NEW; + + bool isRename = + tmp && tmp->inode == fs->inode && tmp_vio_type == fs->type && (tmp->modtime == fs->mtime || fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) #ifdef NO_RENAME_EXTENSION && _csync_sameextension(tmp->path, path) #endif - ) { + ; + + + // Verify the checksum where possible + if (isRename && tmp->checksumTypeId && ctx->callbacks.checksum_hook + && fs->type == CSYNC_VIO_FILE_TYPE_REGULAR) { + st->checksum = ctx->callbacks.checksum_hook( + file, tmp->checksumTypeId, + ctx->callbacks.checksum_userdata); + if (st->checksum) { + CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", path, st->checksum, tmp->checksum); + st->checksumTypeId = tmp->checksumTypeId; + isRename = strncmp(st->checksum, tmp->checksum, 1000) == 0; + } + } + + 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 */ st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME; if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) { csync_rename_record(ctx, tmp->path, path); } - goto out; - } else { - /* file not found in statedb */ - st->instruction = CSYNC_INSTRUCTION_NEW; - goto out; } + goto out; + } else { /* Remote Replica Rename check */ tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id); |