trav.path = cur->path;
trav.size = cur->size;
trav.modtime = cur->modtime;
- trav.mode = cur->mode;
trav.type = cur->type;
trav.instruction = cur->instruction;
- trav.rename_path = cur->destpath;
+ trav.rename_path = cur->rename_path;
trav.etag = cur->etag;
trav.file_id = cur->file_id;
trav.remotePerm = cur->remotePerm;
- trav.directDownloadUrl = cur->directDownloadUrl;
- trav.directDownloadCookies = cur->directDownloadCookies;
+ trav.directDownloadUrl = cur->directDownloadUrl.data();
+ trav.directDownloadCookies = cur->directDownloadCookies.data();
trav.inode = cur->inode;
trav.error_status = cur->error_status;
rc = (*visitor)(&trav, twctx->userdata);
cur->instruction = trav.instruction;
if (trav.etag != cur->etag) { // FIXME It would be nice to have this documented
- SAFE_FREE(cur->etag);
- cur->etag = c_strdup(trav.etag);
+ cur->etag = trav.etag;
}
return rc;
csync_file_stat_t *freedata = NULL;
freedata = (csync_file_stat_t *) data;
- csync_file_stat_free(freedata);
+ delete freedata;
}
/* reset all the list to empty.
return (1 == 0);
}
}
-
-void csync_file_stat_free(csync_file_stat_t *st)
-{
- if (st) {
- SAFE_FREE(st->directDownloadUrl);
- SAFE_FREE(st->directDownloadCookies);
- SAFE_FREE(st->etag);
- SAFE_FREE(st->destpath);
- SAFE_FREE(st->checksumHeader);
- SAFE_FREE(st);
- }
-}
#include <stdint.h>
#include <sys/types.h>
#include <config_csync.h>
+#include <QByteArray>
enum csync_status_codes_e {
CSYNC_STATUS_OK = 0,
time_t atime;
time_t mtime;
time_t ctime;
-
int64_t size;
mode_t mode;
char *checksumHeader;
};
+typedef struct csync_file_stat_s csync_file_stat_t;
+
+struct csync_file_stat_s {
+ uint64_t phash;
+ time_t modtime;
+ int64_t size;
+ uint64_t inode;
+ enum csync_ftw_type_e type : 4;
+ bool child_modified : 1;
+ bool has_ignored_files : 1; /* specify that a directory, or child directory contains ignored files */
+
+ QByteArray path;
+ QByteArray rename_path;
+ QByteArray etag;
+ QByteArray file_id;
+ QByteArray directDownloadUrl;
+ QByteArray directDownloadCookies;
+ QByteArray remotePerm;
+
+ // In the local tree, this can hold a checksum and its type if it is
+ // computed during discovery for some reason.
+ // In the remote tree, this will have the server checksum, if available.
+ // In both cases, the format is "SHA1:baff".
+ QByteArray checksumHeader;
+
+ CSYNC_STATUS error_status;
+
+ enum csync_instructions_e instruction; /* u32 */
+
+ csync_file_stat_s()
+ : phash(0)
+ , modtime(0)
+ , size(0)
+ , inode(0)
+ , type(CSYNC_FTW_TYPE_SKIP)
+ , child_modified(false)
+ , has_ignored_files(false)
+ , error_status(CSYNC_STATUS_OK)
+ , instruction(CSYNC_INSTRUCTION_NONE)
+ { }
+};
+
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_new(void);
csync_vio_file_stat_t OCSYNC_EXPORT *csync_vio_file_stat_copy(csync_vio_file_stat_t *file_stat);
void *userdata);
/* Compute the checksum of the given \a checksumTypeId for \a path. */
-typedef const char *(*csync_checksum_hook)(
- const char *path, const char *otherChecksumHeader, void *userdata);
+typedef QByteArray (*csync_checksum_hook)(
+ const QByteArray &path, const QByteArray &otherChecksumHeader, void *userdata);
/**
* @brief Allocate a csync context.
REMOTE_REPLICA
};
-typedef struct csync_file_stat_s csync_file_stat_t;
-
/**
* @brief csync public structure
*/
bool ignore_hidden_files;
};
-
-#ifdef _MSC_VER
-#pragma pack(1)
-#endif
-struct csync_file_stat_s {
- uint64_t phash; /* u64 */
- time_t modtime; /* u64 */
- int64_t size; /* u64 */
- size_t pathlen; /* u64 */
- uint64_t inode; /* u64 */
- mode_t mode; /* u32 */
- enum csync_ftw_type_e type : 4;
- unsigned int child_modified : 1;
- unsigned int has_ignored_files : 1; /* specify that a directory, or child directory contains ignored files */
-
- char *destpath; /* for renames */
- const char *etag;
- char file_id[FILE_ID_BUF_SIZE+1]; /* the ownCloud file id is fixed width in ownCloud. */
- char *directDownloadUrl;
- char *directDownloadCookies;
- char remotePerm[REMOTE_PERM_BUF_SIZE+1];
-
- // In the local tree, this can hold a checksum and its type if it is
- // computed during discovery for some reason.
- // In the remote tree, this will have the server checksum, if available.
- // In both cases, the format is "SHA1:baff".
- const char *checksumHeader;
-
- CSYNC_STATUS error_status;
-
- enum csync_instructions_e instruction; /* u32 */
- char path[1]; /* u8 */
-}
-#if !defined(__SUNPRO_C) && !defined(_MSC_VER)
-__attribute__ ((packed))
-#endif
-#ifdef _MSC_VER
-#pragma pack()
-#endif
-;
-
-OCSYNC_EXPORT void csync_file_stat_free(csync_file_stat_t *st);
-
/*
* context for the treewalk function
*/
static int _csync_merge_algorithm_visitor(void *obj, void *data) {
csync_file_stat_t *cur = NULL;
csync_file_stat_t *other = NULL;
- csync_file_stat_t *tmp = NULL;
+ std::unique_ptr<csync_file_stat_t> tmp;
uint64_t h = 0;
int len = 0;
if (!node) {
/* Check the renamed path as well. */
char *renamed_path = csync_rename_adjust_path(ctx, cur->path);
- if (!c_streq(renamed_path, cur->path)) {
+ if (renamed_path != cur->path) {
len = strlen( renamed_path );
h = c_jhash64((uint8_t *) renamed_path, len, 0);
node = c_rbtree_find(tree, &h);
}
if (!node) {
/* Check if it is ignored */
- node = _csync_check_ignored(tree, cur->path, cur->pathlen);
+ node = _csync_check_ignored(tree, cur->path, cur->path.size());
/* If it is ignored, other->instruction will be IGNORE so this one will also be ignored */
}
} else if( ctx->current == REMOTE_REPLICA ) {
tmp = csync_statedb_get_stat_by_file_id(ctx, cur->file_id);
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Finding opposite temp through file ID %s: %s",
- cur->file_id, tmp ? "true":"false");
+ cur->file_id.constData(), tmp ? "true":"false");
} else {
CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "Unknown replica...");
}
if( tmp ) {
len = strlen( tmp->path );
if( len > 0 ) {
- h = c_jhash64((uint8_t *) tmp->path, len, 0);
+ h = c_jhash64((uint8_t *) tmp->path.constData(), len, 0);
/* First, check that the file is NOT in our tree (another file with the same name was added) */
node = c_rbtree_find(ctx->current == REMOTE_REPLICA ? ctx->remote.tree : ctx->local.tree, &h);
if (node) {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Origin found in our tree : %s", tmp->path);
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Origin found in our tree : %s", tmp->path.constData());
} else {
/* Find the temporar file in the other tree. */
node = c_rbtree_find(tree, &h);
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "PHash of temporary opposite (%s): %" PRIu64 " %s",
- tmp->path , h, node ? "found": "not found" );
+ tmp->path.constData() , h, node ? "found": "not found" );
if (node) {
other = (csync_file_stat_t*)node->data;
} else {
|| other->instruction == CSYNC_INSTRUCTION_UPDATE_METADATA
|| cur->type == CSYNC_FTW_TYPE_DIR) {
other->instruction = CSYNC_INSTRUCTION_RENAME;
- other->destpath = c_strdup( cur->path );
- if( !c_streq(cur->file_id, "") ) {
- csync_vio_set_file_id( other->file_id, cur->file_id );
+ other->rename_path = cur->path;
+ if( !cur->file_id.isEmpty() ) {
+ other->file_id = cur->file_id;
}
other->inode = cur->inode;
cur->instruction = CSYNC_INSTRUCTION_NONE;
} else if (other->instruction == CSYNC_INSTRUCTION_REMOVE) {
other->instruction = CSYNC_INSTRUCTION_RENAME;
- other->destpath = c_strdup( cur->path );
+ other->rename_path = cur->path;
- if( !c_streq(cur->file_id, "") ) {
- csync_vio_set_file_id( other->file_id, cur->file_id );
+ if( !cur->file_id.isEmpty() ) {
+ other->file_id = cur->file_id;
}
other->inode = cur->inode;
cur->instruction = CSYNC_INSTRUCTION_NONE;
cur->instruction = CSYNC_INSTRUCTION_NONE;
other->instruction = CSYNC_INSTRUCTION_SYNC;
}
- csync_file_stat_free(tmp);
}
break;
case CSYNC_INSTRUCTION_NEW:
// This operation is usually a no-op and will by default return false
if (csync_file_locked_or_open(ctx->local.uri, cur->path)) {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] IGNORING file %s/%s since it is locked / open", ctx->local.uri, cur->path);
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_DEBUG, "[Reconciler] IGNORING file %s/%s since it is locked / open", ctx->local.uri, cur->path.constData());
cur->instruction = CSYNC_INSTRUCTION_ERROR;
if (cur->error_status == CSYNC_STATUS_OK) // don't overwrite error
cur->error_status = CYSNC_STATUS_FILE_LOCKED_OR_OPEN;
"%-30s %s dir: %s",
csync_instruction_str(cur->instruction),
repo,
- cur->path);
+ cur->path.constData());
}
else
{
"%-30s %s file: %s",
csync_instruction_str(cur->instruction),
repo,
- cur->path);
+ cur->path.constData());
}
}
else
"%-30s %s dir: %s",
csync_instruction_str(cur->instruction),
repo,
- cur->path);
+ cur->path.constData());
}
else
{
"%-30s %s file: %s",
csync_instruction_str(cur->instruction),
repo,
- cur->path);
+ cur->path.constData());
}
}
std::map<std::string, std::string> folder_renamed_to; // map from->to
std::map<std::string, std::string> folder_renamed_from; // map to->from
-
- struct renameop {
- csync_file_stat_t *st;
- bool operator<(const renameop &other) const {
- return strlen(st->destpath) < strlen(other.st->destpath);
- }
- };
- std::vector<renameop> todo;
};
void csync_rename_destroy(CSYNC* ctx)
#define _GNU_SOURCE
#endif
+#include <assert.h>
#include <sqlite3.h>
#include <stdio.h>
#include <sys/types.h>
return rc;
}
-#define METADATA_QUERY \
- "phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, " \
- "filesize, ignoredChildrenRemote, " \
- "contentchecksumtype.name || ':' || contentChecksum " \
- "FROM metadata " \
+#define METADATA_QUERY \
+ "phash, path, inode, modtime, type, md5, fileid, remotePerm, " \
+ "filesize, ignoredChildrenRemote, " \
+ "contentchecksumtype.name || ':' || contentChecksum " \
+ "FROM metadata " \
"LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id"
// This funciton parses a line from the metadata table into the given csync_file_stat
// structure which it is also allocating.
// Note that this function calls laso sqlite3_step to actually get the info from db and
// returns the sqlite return type.
-static int _csync_file_stat_from_metadata_table( csync_file_stat_t **st, sqlite3_stmt *stmt )
+static int _csync_file_stat_from_metadata_table( std::unique_ptr<csync_file_stat_t> &st, sqlite3_stmt *stmt )
{
int rc = SQLITE_ERROR;
- int column_count;
- int len;
if( ! stmt ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Fatal: Statement is NULL.");
return SQLITE_ERROR;
}
- column_count = sqlite3_column_count(stmt);
+ // Callers should all use METADATA_QUERY for their column list.
+ assert(sqlite3_column_count(stmt) == 11);
SQLITE_BUSY_HANDLED( sqlite3_step(stmt) );
if( rc == SQLITE_ROW ) {
- if(column_count > 7) {
- const char *name;
-
- /* phash, pathlen, path, inode, uid, gid, mode, modtime */
- len = sqlite3_column_int(stmt, 1);
- *st = (csync_file_stat_t*)c_malloc(sizeof(csync_file_stat_t) + len + 1);
- /* clear the whole structure */
- ZERO_STRUCTP(*st);
-
- /* The query suceeded so use the phash we pass to the function. */
- (*st)->phash = sqlite3_column_int64(stmt, 0);
-
- (*st)->pathlen = sqlite3_column_int(stmt, 1);
- name = (const char*) sqlite3_column_text(stmt, 2);
- memcpy((*st)->path, (len ? name : ""), len + 1);
- (*st)->inode = sqlite3_column_int64(stmt,3);
- (*st)->mode = sqlite3_column_int(stmt, 6);
- (*st)->modtime = strtoul((char*)sqlite3_column_text(stmt, 7), NULL, 10);
-
- if(*st && column_count > 8 ) {
- (*st)->type = static_cast<enum csync_ftw_type_e>(sqlite3_column_int(stmt, 8));
- }
-
- if(column_count > 9 && sqlite3_column_text(stmt, 9)) {
- (*st)->etag = c_strdup( (char*) sqlite3_column_text(stmt, 9) );
- }
- if(column_count > 10 && sqlite3_column_text(stmt,10)) {
- csync_vio_set_file_id((*st)->file_id, (char*) sqlite3_column_text(stmt, 10));
- }
- if(column_count > 11 && sqlite3_column_text(stmt,11)) {
- strncpy((*st)->remotePerm,
- (char*) sqlite3_column_text(stmt, 11),
- REMOTE_PERM_BUF_SIZE);
- }
- if(column_count > 12 && sqlite3_column_int64(stmt,12)) {
- (*st)->size = sqlite3_column_int64(stmt, 12);
- }
- if(column_count > 13) {
- (*st)->has_ignored_files = sqlite3_column_int(stmt, 13);
- }
- if (column_count > 14 && sqlite3_column_text(stmt, 14)) {
- (*st)->checksumHeader = c_strdup((char *)sqlite3_column_text(stmt, 14));
- }
-
- }
+ st.reset(new csync_file_stat_t);
+
+ /* The query suceeded so use the phash we pass to the function. */
+ st->phash = sqlite3_column_int64(stmt, 0);
+ st->path = (char*)sqlite3_column_text(stmt, 1);
+ st->inode = sqlite3_column_int64(stmt, 2);
+ st->modtime = strtoul((char*)sqlite3_column_text(stmt, 3), NULL, 10);
+ st->type = static_cast<enum csync_ftw_type_e>(sqlite3_column_int(stmt, 4));
+ st->etag = (char*)sqlite3_column_text(stmt, 5);
+ st->file_id = (char*)sqlite3_column_text(stmt, 6);
+ st->remotePerm = (char*)sqlite3_column_text(stmt, 7);
+ st->size = sqlite3_column_int64(stmt, 8);
+ st->has_ignored_files = sqlite3_column_int(stmt, 9);
+ st->checksumHeader = (char *)sqlite3_column_text(stmt, 10);
} else {
if( rc != SQLITE_DONE ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Query results in %d", rc);
}
/* caller must free the memory */
-csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx,
+std::unique_ptr<csync_file_stat_t> csync_statedb_get_stat_by_hash(CSYNC *ctx,
uint64_t phash)
{
- csync_file_stat_t *st = NULL;
+ std::unique_ptr<csync_file_stat_t> st;
int rc;
if( !ctx || ctx->db_is_empty ) {
sqlite3_bind_int64(ctx->statedb.by_hash_stmt, 1, (long long signed int)phash);
- rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_hash_stmt);
+ rc = _csync_file_stat_from_metadata_table(st, ctx->statedb.by_hash_stmt);
ctx->statedb.lastReturnValue = rc;
if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata: %d!", rc);
return st;
}
-csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx,
+std::unique_ptr<csync_file_stat_t> csync_statedb_get_stat_by_file_id(CSYNC *ctx,
const char *file_id ) {
- csync_file_stat_t *st = NULL;
+ std::unique_ptr<csync_file_stat_t> st;
int rc = 0;
if (!file_id) {
/* bind the query value */
sqlite3_bind_text(ctx->statedb.by_fileid_stmt, 1, file_id, -1, SQLITE_STATIC);
- rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_fileid_stmt);
+ rc = _csync_file_stat_from_metadata_table(st, ctx->statedb.by_fileid_stmt);
ctx->statedb.lastReturnValue = rc;
if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata: %d!", rc);
}
/* caller must free the memory */
-csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx,
+std::unique_ptr<csync_file_stat_t> csync_statedb_get_stat_by_inode(CSYNC *ctx,
uint64_t inode)
{
- csync_file_stat_t *st = NULL;
+ std::unique_ptr<csync_file_stat_t> st;
int rc;
if (!inode) {
sqlite3_bind_int64(ctx->statedb.by_inode_stmt, 1, (long long signed int)inode);
- rc = _csync_file_stat_from_metadata_table(&st, ctx->statedb.by_inode_stmt);
+ rc = _csync_file_stat_from_metadata_table(st, ctx->statedb.by_inode_stmt);
ctx->statedb.lastReturnValue = rc;
if( !(rc == SQLITE_ROW || rc == SQLITE_DONE) ) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Could not get line from metadata by inode: %d!", rc);
ctx->statedb.lastReturnValue = rc;
do {
- csync_file_stat_t *st = NULL;
+ std::unique_ptr<csync_file_stat_t> st;
- rc = _csync_file_stat_from_metadata_table( &st, stmt);
+ rc = _csync_file_stat_from_metadata_table(st, stmt);
if( st ) {
/* When selective sync is used, the database may have subtrees with a parent
* whose etag (md5) is _invalid_. These are ignored and shall not appear in the
* _invalid_, but that is not a problem as the next discovery will retrieve
* their correct etags again and we don't run into this case.
*/
- if( c_streq(st->etag, "_invalid_") ) {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s selective sync excluded", st->path);
- char *skipbase = c_strdup(st->path);
- skipbase[st->pathlen] = '/';
- int skiplen = st->pathlen + 1;
+ if( st->etag == "_invalid_") {
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s selective sync excluded", st->path.constData());
+ QByteArray skipbase = st->path;
+ skipbase += '/';
/* Skip over all entries with the same base path. Note that this depends
* strongly on the ordering of the retrieved items. */
do {
- csync_file_stat_free(st);
- rc = _csync_file_stat_from_metadata_table( &st, stmt);
- if( st && strncmp(st->path, skipbase, skiplen) != 0 ) {
- break;
+ st.reset();
+ rc = _csync_file_stat_from_metadata_table(st, stmt);
+ if( st ) {
+ if( st->path == skipbase )
+ break;
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s selective sync excluded because the parent is", st->path.constData());
}
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s selective sync excluded because the parent is", st->path);
} while( rc == SQLITE_ROW );
/* End of data? */
* without a full remote discovery being triggered. */
CSYNC_EXCLUDE_TYPE excluded = csync_excluded_traversal(ctx->excludes, st->path, st->type);
if (excluded != CSYNC_NOT_EXCLUDED) {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", st->path, excluded);
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded (%d)", st->path.constData(), excluded);
if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE
|| excluded == CSYNC_FILE_SILENTLY_EXCLUDED) {
- csync_file_stat_free(st);
+ st.reset();
continue;
}
}
/* store into result list. */
- if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
- csync_file_stat_free(st);
+ if (c_rbtree_insert(ctx->remote.tree, (void *) st.release()) < 0) {
+ st.reset();
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
break;
}
OCSYNC_EXPORT int csync_statedb_close(CSYNC *ctx);
-OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
+OCSYNC_EXPORT std::unique_ptr<csync_file_stat_t> csync_statedb_get_stat_by_hash(CSYNC *ctx, uint64_t phash);
-OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
+OCSYNC_EXPORT std::unique_ptr<csync_file_stat_t> csync_statedb_get_stat_by_inode(CSYNC *ctx, uint64_t inode);
-OCSYNC_EXPORT csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
+OCSYNC_EXPORT std::unique_ptr<csync_file_stat_t> csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *file_id);
/**
* @brief Query all files metadata inside and below a path.
#include <time.h>
#include "csync_time.h"
-#include "vio/csync_vio.h"
#ifndef _WIN32
#include <unistd.h>
#include <time.h>
-#include "csync_private.h"
-
int csync_gettime(struct timespec *tp);
void csync_sleep(unsigned int msecs);
static int _csync_detect_update(CSYNC *ctx, const char *file,
const csync_vio_file_stat_t *fs, enum csync_ftw_type_e type) {
uint64_t h = 0;
- size_t len = 0;
- size_t size = 0;
const char *path = NULL;
- csync_file_stat_t *st = NULL;
- csync_file_stat_t *tmp = NULL;
+ std::unique_ptr<csync_file_stat_t> st;
+ std::unique_ptr<csync_file_stat_t> tmp;
CSYNC_EXCLUDE_TYPE excluded;
if ((file == NULL) || (fs == NULL)) {
path += strlen(ctx->local.uri) + 1;
}
- len = strlen(path);
-
if (type == CSYNC_FTW_TYPE_SKIP) {
excluded =CSYNC_FILE_EXCLUDE_STAT_FAILED;
} else {
if( h == 0 ) {
return -1;
}
- size = sizeof(csync_file_stat_t) + len + 1;
- st = static_cast<csync_file_stat_t *>(c_malloc(size));
+ st.reset(new csync_file_stat_t);
- /* Set instruction by default to none */
- st->instruction = CSYNC_INSTRUCTION_NONE;
- st->etag = NULL;
- st->child_modified = 0;
- st->has_ignored_files = 0;
if (type == CSYNC_FTW_TYPE_FILE ) {
if (fs->mtime == 0) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - mtime is zero!", path);
tmp = csync_statedb_get_stat_by_hash(ctx, h);
if(_last_db_return_error(ctx)) {
- csync_file_stat_free(st);
- csync_file_stat_free(tmp);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64
", size: %" PRId64 " <-> %" PRId64 ", perms: %s <-> %s, ignore: %d",
((int64_t) fs->mtime), ((int64_t) tmp->modtime),
- fs->etag, tmp->etag, (uint64_t) fs->inode, (uint64_t) tmp->inode,
- (uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm, tmp->has_ignored_files );
+ fs->etag, tmp->etag.constData(), (uint64_t) fs->inode, (uint64_t) tmp->inode,
+ (uint64_t) fs->size, (uint64_t) tmp->size, fs->remotePerm, tmp->remotePerm.constData(), tmp->has_ignored_files );
if (ctx->current == REMOTE_REPLICA && !c_streq(fs->etag, tmp->etag)) {
st->instruction = CSYNC_INSTRUCTION_EVAL;
// Preserve the EVAL flag later on if the type has changed.
- if (_csync_filetype_different(tmp, fs)) {
- st->child_modified = 1;
+ if (_csync_filetype_different(tmp.get(), fs)) {
+ st->child_modified = true;
}
goto out;
// Checksum comparison at this stage is only enabled for .eml files,
// check #4754 #4755
bool isEmlFile = csync_fnmatch("*.eml", file, FNM_CASEFOLD) == 0;
- if (isEmlFile && fs->size == tmp->size && tmp->checksumHeader) {
+ if (isEmlFile && fs->size == tmp->size && !tmp->checksumHeader.isEmpty()) {
if (ctx->callbacks.checksum_hook) {
st->checksumHeader = ctx->callbacks.checksum_hook(
file, tmp->checksumHeader,
ctx->callbacks.checksum_userdata);
}
bool checksumIdentical = false;
- if (st->checksumHeader) {
- checksumIdentical = strncmp(st->checksumHeader, tmp->checksumHeader, 1000) == 0;
+ if (!st->checksumHeader.isEmpty()) {
+ checksumIdentical = st->checksumHeader == tmp->checksumHeader;
}
if (checksumIdentical) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "NOTE: Checksums are identical, file did not actually change: %s", path);
}
// Preserve the EVAL flag later on if the type has changed.
- if (_csync_filetype_different(tmp, fs)) {
- st->child_modified = 1;
+ if (_csync_filetype_different(tmp.get(), fs)) {
+ st->child_modified = true;
}
st->instruction = CSYNC_INSTRUCTION_EVAL;
} else {
enum csync_vio_file_type_e tmp_vio_type = CSYNC_VIO_FILE_TYPE_UNKNOWN;
- /* tmp might point to malloc mem, so free it here before reusing tmp */
- csync_file_stat_free(tmp);
-
/* 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)) {
- csync_file_stat_free(st);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
// Verify the checksum where possible
- if (isRename && tmp->checksumHeader && ctx->callbacks.checksum_hook
+ if (isRename && !tmp->checksumHeader.isEmpty() && ctx->callbacks.checksum_hook
&& fs->type == CSYNC_VIO_FILE_TYPE_REGULAR) {
st->checksumHeader = ctx->callbacks.checksum_hook(
file, tmp->checksumHeader,
ctx->callbacks.checksum_userdata);
- if (st->checksumHeader) {
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", path, st->checksumHeader, tmp->checksumHeader);
- isRename = strncmp(st->checksumHeader, tmp->checksumHeader, 1000) == 0;
+ if (!st->checksumHeader.isEmpty()) {
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "checking checksum of potential rename %s %s <-> %s", path, st->checksumHeader.constData(), tmp->checksumHeader.constData());
+ isRename = st->checksumHeader == tmp->checksumHeader;
}
}
tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id);
if(_last_db_return_error(ctx)) {
- csync_file_stat_free(st);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
if(tmp ) { /* tmp existing at all */
- if ( _csync_filetype_different(tmp, fs)) {
+ if ( _csync_filetype_different(tmp.get(), fs)) {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "file types different is not!");
st->instruction = CSYNC_INSTRUCTION_NEW;
goto out;
}
- CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "remote rename detected based on fileid %s %s", tmp->path, file);
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "remote rename detected based on fileid %s %s", tmp->path.constData(), file);
st->instruction = CSYNC_INSTRUCTION_EVAL_RENAME;
if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY) {
csync_rename_record(ctx, tmp->path, path);
if (fs->type == CSYNC_VIO_FILE_TYPE_DIRECTORY && ctx->current == REMOTE_REPLICA && ctx->callbacks.checkSelectiveSyncNewFolderHook) {
if (ctx->callbacks.checkSelectiveSyncNewFolderHook(ctx->callbacks.update_callback_userdata, path, fs->remotePerm)) {
- csync_file_stat_free(st);
return 1;
}
}
}
} else {
CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "Unable to open statedb" );
- csync_file_stat_free(st);
ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL;
return -1;
}
&& st->instruction != CSYNC_INSTRUCTION_IGNORE
&& st->instruction != CSYNC_INSTRUCTION_UPDATE_METADATA
&& type != CSYNC_FTW_TYPE_DIR) {
- st->child_modified = 1;
+ st->child_modified = true;
}
- ctx->current_fs = st;
+ ctx->current_fs = st.get();
- csync_file_stat_free(tmp);
st->inode = fs->inode;
- st->mode = fs->mode;
st->size = fs->size;
st->modtime = fs->mtime;
st->type = type;
st->etag = NULL;
if( fs->etag ) {
- SAFE_FREE(st->etag);
- st->etag = c_strdup(fs->etag);
+ st->etag = fs->etag;
}
- csync_vio_set_file_id(st->file_id, fs->file_id);
+ st->file_id = fs->file_id;
if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADURL) {
- SAFE_FREE(st->directDownloadUrl);
- st->directDownloadUrl = c_strdup(fs->directDownloadUrl);
+ st->directDownloadUrl = fs->directDownloadUrl;
}
if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_DIRECTDOWNLOADCOOKIES) {
- SAFE_FREE(st->directDownloadCookies);
- st->directDownloadCookies = c_strdup(fs->directDownloadCookies);
+ st->directDownloadCookies = fs->directDownloadCookies;
}
if (fs->fields & CSYNC_VIO_FILE_STAT_FIELDS_PERM) {
- strncpy(st->remotePerm, fs->remotePerm, REMOTE_PERM_BUF_SIZE);
+ st->remotePerm = fs->remotePerm;
}
// For the remote: propagate the discovered checksum
if (fs->checksumHeader && ctx->current == REMOTE_REPLICA) {
- st->checksumHeader = c_strdup(fs->checksumHeader);
+ st->checksumHeader = fs->checksumHeader;
}
st->phash = h;
- st->pathlen = len;
- memcpy(st->path, (len ? path : ""), len + 1);
+ st->path = path;
+
+ CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "file: %s, instruction: %s <<=", st->path.constData(),
+ csync_instruction_str(st->instruction));
switch (ctx->current) {
case LOCAL_REPLICA:
- if (c_rbtree_insert(ctx->local.tree, (void *) st) < 0) {
- csync_file_stat_free(st);
+ if (c_rbtree_insert(ctx->local.tree, (void *) st.release()) < 0) {
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
return -1;
}
break;
case REMOTE_REPLICA:
- if (c_rbtree_insert(ctx->remote.tree, (void *) st) < 0) {
- csync_file_stat_free(st);
+ if (c_rbtree_insert(ctx->remote.tree, (void *) st.release()) < 0) {
ctx->status_code = CSYNC_STATUS_TREE_ERROR;
return -1;
}
default:
break;
}
- CSYNC_LOG(CSYNC_LOG_PRIORITY_INFO, "file: %s, instruction: %s <<=", st->path,
- csync_instruction_str(st->instruction));
return 0;
}
int flag) {
int rc = -1;
enum csync_ftw_type_e type = CSYNC_FTW_TYPE_SKIP;
- csync_file_stat_t *st = NULL;
+ std::unique_ptr<csync_file_stat_t> st;
uint64_t h;
if (ctx->abort) {
if( !st ) {
return 0;
}
- csync_file_stat_free(st);
- st = NULL;
+ st.reset();
type = CSYNC_FTW_TYPE_SKIP;
break;
{
}
-const char *CSyncChecksumHook::hook(const char *path, const char *otherChecksumHeader, void * /*this_obj*/)
+QByteArray CSyncChecksumHook::hook(const QByteArray &path, const QByteArray &otherChecksumHeader, void * /*this_obj*/)
{
QByteArray type = parseChecksumHeaderType(QByteArray(otherChecksumHeader));
if (type.isEmpty())
return NULL;
- QByteArray checksum = ComputeChecksum::computeNow(path, type);
+ QByteArray checksum = ComputeChecksum::computeNow(QString::fromUtf8(path), type);
if (checksum.isNull()) {
qCWarning(lcChecksums) << "Failed to compute checksum" << type << "for" << path;
return NULL;
}
- QByteArray checksumHeader = makeChecksumHeader(type, checksum);
- char *result = (char *)malloc(checksumHeader.size() + 1);
- memcpy(result, checksumHeader.constData(), checksumHeader.size());
- result[checksumHeader.size()] = 0;
- return result;
+ return makeChecksumHeader(type, checksum);
}
}
* to be set as userdata.
* The return value will be owned by csync.
*/
- static const char *hook(const char *path, const char *otherChecksumHeader, void *this_obj);
+ static QByteArray hook(const QByteArray &path, const QByteArray &otherChecksumHeader, void *this_obj);
};
}
* files are often read from database rather than being pulled from remote.
*/
if (remote) {
- item->_serverHasIgnoredFiles = (file->has_ignored_files > 0);
+ item->_serverHasIgnoredFiles = file->has_ignored_files;
}
// Sometimes the discovery computes checksums for local files
assert_int_equal(rc, 0);
for (i = 0; i < 100; i++) {
- st = (csync_file_stat_t*)c_malloc(sizeof(csync_file_stat_t) + 30 );
- snprintf(st->path, 29, "file_%d" , i );
+ st = new csync_file_stat_t;
+ st->path = QString("file_%1").arg(i).toUtf8();
st->phash = i;
rc = c_rbtree_insert(csync->local.tree, (void *) st);
int i, rc;
for (i = 0; i < 100; i++) {
- st = (csync_file_stat_t*)c_malloc(sizeof(csync_file_stat_t) + 30);
- snprintf(st->path, 29, "file_%d" , i );
+ st = new csync_file_stat_t;
+ st->path = QString("file_%1").arg(i).toUtf8();
st->phash = i;
rc = c_rbtree_insert(csync->local.tree, (void *) st);
static void check_csync_statedb_get_stat_by_hash_not_found(void **state)
{
CSYNC *csync = (CSYNC*)*state;
- csync_file_stat_t *tmp;
+ std::unique_ptr<csync_file_stat_t> tmp;
tmp = csync_statedb_get_stat_by_hash(csync, (uint64_t) 666);
- assert_null(tmp);
-
- free(tmp);
+ assert_null(tmp.get());
}
static void check_csync_statedb_get_stat_by_inode_not_found(void **state)
{
CSYNC *csync = (CSYNC*)*state;
- csync_file_stat_t *tmp;
+ std::unique_ptr<csync_file_stat_t> tmp;
tmp = csync_statedb_get_stat_by_inode(csync, (ino_t) 666);
- assert_null(tmp);
+ assert_null(tmp.get());
}
int torture_run_tests(void)
#include "csync_time.h"
#include "std/c_time.h"
+#include <unistd.h>
static void check_c_tspecdiff(void **state)
{
}
void testFullResult() {
- csync_file_stat_t *st = csync_statedb_get_stat_by_hash((CSYNC*)(&_ctx), 2081025720555645157 );
- QVERIFY(st);
+ std::unique_ptr<csync_file_stat_t> st = csync_statedb_get_stat_by_hash((CSYNC*)(&_ctx), 2081025720555645157 );
+ QVERIFY(st.get());
QCOMPARE( QString::number(st->phash), QString::number(2081025720555645157) );
- QCOMPARE( QString::number(st->pathlen), QString::number(13));
QCOMPARE( QString::fromUtf8(st->path), QLatin1String("test2/zu/zuzu") );
QCOMPARE( QString::number(st->inode), QString::number(1709554));
- QCOMPARE( QString::number(st->mode), QString::number(0));
QCOMPARE( QString::number(st->modtime), QString::number(1384415006));
QCOMPARE( QString::number(st->type), QString::number(2));
QCOMPARE( QString::fromUtf8(st->etag), QLatin1String("52847f2090665"));
}
void testByHash() {
- csync_file_stat_t *st = csync_statedb_get_stat_by_hash((CSYNC*)(&_ctx), -7147279406142960289);
- QVERIFY(st);
+ std::unique_ptr<csync_file_stat_t> st = csync_statedb_get_stat_by_hash((CSYNC*)(&_ctx), -7147279406142960289);
+ QVERIFY(st.get());
QCOMPARE(QString::fromUtf8(st->path), QLatin1String("documents/c1"));
- csync_file_stat_free(st);
st = csync_statedb_get_stat_by_hash((CSYNC*)(&_ctx), 5426481156826978940);
- QVERIFY(st);
+ QVERIFY(st.get());
QCOMPARE(QString::fromUtf8(st->path), QLatin1String("documents/c1/c2"));
- csync_file_stat_free(st);
}
void testByInode() {
- csync_file_stat_t *st = csync_statedb_get_stat_by_inode((CSYNC*)(&_ctx), 1709555);
- QVERIFY(st);
+ std::unique_ptr<csync_file_stat_t> st = csync_statedb_get_stat_by_inode((CSYNC*)(&_ctx), 1709555);
+ QVERIFY(st.get());
QCOMPARE(QString::fromUtf8(st->path), QLatin1String("test2/zu/zuzu/zuzuzu"));
- csync_file_stat_free(st);
st = csync_statedb_get_stat_by_inode((CSYNC*)(&_ctx), 1706571);
- QVERIFY(st);
+ QVERIFY(st.get());
QCOMPARE(QString::fromUtf8(st->path), QLatin1String("Shared/for_kf/a2"));
- csync_file_stat_free(st);
}
void testByFileId() {
- csync_file_stat_t *st = csync_statedb_get_stat_by_file_id((CSYNC*)(&_ctx), "00000556525d5af3d9625");
- QVERIFY(st);
+ std::unique_ptr<csync_file_stat_t> st = csync_statedb_get_stat_by_file_id((CSYNC*)(&_ctx), "00000556525d5af3d9625");
+ QVERIFY(st.get());
QCOMPARE(QString::fromUtf8(st->path), QLatin1String("test2/zu"));
- csync_file_stat_free(st);
st = csync_statedb_get_stat_by_file_id((CSYNC*)(&_ctx), "-0000001525d5af3d9625");
- QVERIFY(st);
+ QVERIFY(st.get());
QCOMPARE(QString::fromUtf8(st->path), QLatin1String("Shared"));
- csync_file_stat_free(st);
}
void cleanupTestCase() {