int rc = 0;
csync_file_stat_t *cur = NULL;
CSYNC *ctx = NULL;
- c_rbtree_visit_func *visitor = NULL;
+ csync_treewalk_visit_func *visitor = NULL;
_csync_treewalk_context *twctx = NULL;
- TREE_WALK_FILE trav;
c_rbtree_t *other_tree = NULL;
c_rbnode_t *other_node = NULL;
SAFE_FREE(renamed_path);
}
+ csync_file_stat_t *other = other_node ? (csync_file_stat_t*)other_node->data : NULL;
+
if (obj == NULL || data == NULL) {
ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
return -1;
return 0;
}
- visitor = (c_rbtree_visit_func*)(twctx->user_visitor);
+ visitor = (csync_treewalk_visit_func*)(twctx->user_visitor);
if (visitor != NULL) {
- trav.path = cur->path;
- trav.size = cur->size;
- trav.modtime = cur->modtime;
- trav.type = cur->type;
- trav.instruction = cur->instruction;
- trav.rename_path = cur->rename_path;
- trav.etag = cur->etag;
- trav.file_id = cur->file_id;
- trav.remotePerm = cur->remotePerm;
- trav.directDownloadUrl = cur->directDownloadUrl.data();
- trav.directDownloadCookies = cur->directDownloadCookies.data();
- trav.inode = cur->inode;
-
- trav.error_status = cur->error_status;
- trav.has_ignored_files = cur->has_ignored_files;
- trav.checksumHeader = cur->checksumHeader;
-
- if( other_node ) {
- csync_file_stat_t *other_stat = (csync_file_stat_t*)other_node->data;
- trav.other.etag = other_stat->etag;
- trav.other.file_id = other_stat->file_id;
- trav.other.instruction = other_stat->instruction;
- trav.other.modtime = other_stat->modtime;
- trav.other.size = other_stat->size;
- } else {
- trav.other.etag = 0;
- trav.other.file_id = 0;
- trav.other.instruction = CSYNC_INSTRUCTION_NONE;
- trav.other.modtime = 0;
- trav.other.size = 0;
- }
-
- rc = (*visitor)(&trav, twctx->userdata);
- cur->instruction = trav.instruction;
- if (trav.etag != cur->etag) { // FIXME It would be nice to have this documented
- cur->etag = trav.etag;
- }
+ rc = (*visitor)(cur, other, twctx->userdata);
return rc;
}
{ }
};
-/**
- * CSync File Traversal structure.
- *
- * This structure is passed to the visitor function for every file
- * which is seen.
- *
- */
-
-struct csync_tree_walk_file_s {
- const char *path;
- int64_t size;
- int64_t inode;
- time_t modtime;
- mode_t mode;
- enum csync_ftw_type_e type;
- enum csync_instructions_e instruction;
-
- /* For directories: Does it have children that were ignored (hidden or ignore pattern) */
- int has_ignored_files;
-
- const char *rename_path;
- const char *etag;
- const char *file_id;
- const char *remotePerm;
- char *directDownloadUrl;
- char *directDownloadCookies;
-
- const char *checksumHeader;
-
- struct {
- int64_t size;
- time_t modtime;
- const char *etag;
- const char *file_id;
- enum csync_instructions_e instruction;
- } other;
-
- CSYNC_STATUS error_status;
-};
-typedef struct csync_tree_walk_file_s TREE_WALK_FILE;
-
/**
* csync handle
*/
/* Used for special modes or debugging */
int OCSYNC_EXPORT csync_set_status(CSYNC *ctx, int status);
-typedef int csync_treewalk_visit_func(TREE_WALK_FILE* ,void*);
+typedef int csync_treewalk_visit_func(csync_file_stat_t *cur, csync_file_stat_t *other, void*);
/**
* @brief Walk the local file tree and call a visitor function for each file.
_journal->deleteStaleErrorBlacklistEntries(blacklist_file_paths);
}
-int SyncEngine::treewalkLocal(TREE_WALK_FILE *file, void *data)
+int SyncEngine::treewalkLocal(csync_file_stat_t *file, csync_file_stat_t *other, void *data)
{
- return static_cast<SyncEngine *>(data)->treewalkFile(file, false);
+ return static_cast<SyncEngine *>(data)->treewalkFile(file, other, false);
}
-int SyncEngine::treewalkRemote(TREE_WALK_FILE *file, void *data)
+int SyncEngine::treewalkRemote(csync_file_stat_t *file, csync_file_stat_t *other, void *data)
{
- return static_cast<SyncEngine *>(data)->treewalkFile(file, true);
+ return static_cast<SyncEngine *>(data)->treewalkFile(file, other, true);
}
/**
*
* See doc/dev/sync-algorithm.md for an overview.
*/
-int SyncEngine::treewalkFile(TREE_WALK_FILE *file, bool remote)
+int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other, bool remote)
{
if (!file)
return -1;
}
}
- if (file->file_id && file->file_id[0]) {
+ if (!file->file_id.isEmpty()) {
item->_fileId = file->file_id;
}
- if (file->directDownloadUrl) {
+ if (!file->directDownloadUrl.isEmpty()) {
item->_directDownloadUrl = QString::fromUtf8(file->directDownloadUrl);
}
- if (file->directDownloadCookies) {
+ if (!file->directDownloadCookies.isEmpty()) {
item->_directDownloadCookies = QString::fromUtf8(file->directDownloadCookies);
}
- if (file->remotePerm && file->remotePerm[0]) {
- item->_remotePerm = QByteArray(file->remotePerm);
+ if (!file->remotePerm.isEmpty()) {
+ item->_remotePerm = file->remotePerm;
if (remote)
_remotePerms[item->_file] = item->_remotePerm;
}
}
// Sometimes the discovery computes checksums for local files
- if (!remote && file->checksumHeader) {
- item->_checksumHeader = QByteArray(file->checksumHeader);
+ if (!remote && !file->checksumHeader.isEmpty()) {
+ item->_checksumHeader = file->checksumHeader;
}
// For conflicts, store the remote checksum there
- if (remote && item->_instruction == CSYNC_INSTRUCTION_CONFLICT && file->checksumHeader) {
- item->_checksumHeader = QByteArray(file->checksumHeader);
+ if (remote && item->_instruction == CSYNC_INSTRUCTION_CONFLICT && !file->checksumHeader.isEmpty()) {
+ item->_checksumHeader = file->checksumHeader;
}
// record the seen files to be able to clean the journal later
bool isDirectory = file->type == CSYNC_FTW_TYPE_DIR;
- if (file->etag && file->etag[0]) {
+ if (!file->etag.isEmpty()) {
item->_etag = file->etag;
}
switch (file->instruction) {
case CSYNC_INSTRUCTION_NONE: {
// Any files that are instruction NONE?
- if (!isDirectory && file->other.instruction == CSYNC_INSTRUCTION_NONE) {
+ if (!isDirectory && (!other || other->instruction == CSYNC_INSTRUCTION_NONE)) {
_hasNoneFiles = true;
}
// No syncing or update to be done.
if (remote) {
QString filePath = _localPath + item->_file;
- // Even if the mtime is different on the server, we always want to keep the mtime from
- // the file system in the DB, this is to avoid spurious upload on the next sync
- item->_modtime = file->other.modtime;
- // same for the size
- item->_size = file->other.size;
+ if (other) {
+ // Even if the mtime is different on the server, we always want to keep the mtime from
+ // the file system in the DB, this is to avoid spurious upload on the next sync
+ item->_modtime = other->modtime;
+ // same for the size
+ item->_size = other->size;
+ }
// If the 'W' remote permission changed, update the local filesystem
SyncJournalFileRecord prev = _journal->getFileRecord(item->_file);
// This counts as a NONE for detecting if all the files on the server were changed
_hasNoneFiles = true;
} else if (!isDirectory) {
- auto difftime = std::difftime(file->modtime, file->other.modtime);
+ auto difftime = std::difftime(file->modtime, other ? other->modtime : 0);
if (difftime < -3600 * 2) {
// We are going back on time
// We only increment if the difference is more than two hours to avoid clock skew
_needsUpdate = true;
- item->log._other_etag = file->other.etag;
- item->log._other_fileId = file->other.file_id;
- item->log._other_instruction = file->other.instruction;
- item->log._other_modtime = file->other.modtime;
- item->log._other_size = file->other.size;
+ if (other) {
+ item->log._other_etag = other->etag;
+ item->log._other_fileId = other->file_id;
+ item->log._other_instruction = other->instruction;
+ item->log._other_modtime = other->modtime;
+ item->log._other_size = other->size;
+ }
_syncItemMap.insert(key, item);