From d33b68ccc9cf9bbb0764fae10856fc3fa21af3dc Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Mon, 20 Oct 2014 19:27:02 +0200 Subject: [PATCH] CSync: Error out if DB error --- csync/src/csync_private.h | 2 ++ csync/src/csync_statedb.c | 13 +++++++++++++ csync/src/csync_update.c | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/csync/src/csync_private.h b/csync/src/csync_private.h index 07af5fba3..ecc4f772c 100644 --- a/csync/src/csync_private.h +++ b/csync/src/csync_private.h @@ -100,6 +100,8 @@ struct csync_s { sqlite3_stmt* by_hash_stmt; sqlite3_stmt* by_fileid_stmt; sqlite3_stmt* by_inode_stmt; + + int lastReturnValue; } statedb; struct { diff --git a/csync/src/csync_statedb.c b/csync/src/csync_statedb.c index e5928e700..0f69f1d16 100644 --- a/csync/src/csync_statedb.c +++ b/csync/src/csync_statedb.c @@ -209,6 +209,8 @@ int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb) { return -1; } + ctx->statedb.lastReturnValue = SQLITE_OK; + /* csync_statedb_check tries to open the statedb and creates it in case * its not there. */ @@ -361,6 +363,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, const char *hash_query = "SELECT * FROM metadata WHERE phash=?1"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, hash_query, strlen(hash_query), &ctx->statedb.by_hash_stmt, NULL)); + ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for hash query."); return NULL; @@ -374,6 +377,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_hash(CSYNC *ctx, 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); + 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); } @@ -400,6 +404,8 @@ void csync_statedb_finalize_statements(CSYNC *ctx) { sqlite3_finalize(ctx->statedb.by_inode_stmt); ctx->statedb.by_inode_stmt = NULL; } + + ctx->statedb.lastReturnValue = SQLITE_OK; } csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, @@ -422,6 +428,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, const char *query = "SELECT * FROM metadata WHERE fileid=?1"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, query, strlen(query), &ctx->statedb.by_fileid_stmt, NULL)); + ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for file id query."); return NULL; @@ -432,6 +439,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_file_id(CSYNC *ctx, 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); + 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); } @@ -460,6 +468,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, const char *inode_query = "SELECT * FROM metadata WHERE inode=?1"; SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, inode_query, strlen(inode_query), &ctx->statedb.by_inode_stmt, NULL)); + ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for inode query."); return NULL; @@ -473,6 +482,7 @@ csync_file_stat_t *csync_statedb_get_stat_by_inode(CSYNC *ctx, 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); + 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); } @@ -522,6 +532,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) { } SQLITE_BUSY_HANDLED(sqlite3_prepare_v2(ctx->statedb.db, BELOW_PATH_QUERY, -1, &stmt, NULL)); + ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_OK ) { CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "WRN: Unable to create stmt for below path query."); return -1; @@ -543,6 +554,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) { cnt = 0; + ctx->statedb.lastReturnValue = rc; do { csync_file_stat_t *st = NULL; @@ -558,6 +570,7 @@ int csync_statedb_get_below_path( CSYNC *ctx, const char *path ) { } } while( rc == SQLITE_ROW ); + ctx->statedb.lastReturnValue = rc; if( rc != SQLITE_DONE ) { ctx->status_code = CSYNC_STATUS_TREE_ERROR; } else { diff --git a/csync/src/csync_update.c b/csync/src/csync_update.c index 37067c2cb..a064e4f0b 100644 --- a/csync/src/csync_update.c +++ b/csync/src/csync_update.c @@ -100,6 +100,10 @@ static bool _csync_sameextension(const char *p1, const char *p2) { } #endif +static bool _last_db_return_error(CSYNC* ctx) { + return ctx->statedb.lastReturnValue != SQLITE_OK && ctx->statedb.lastReturnValue != SQLITE_DONE && ctx->statedb.lastReturnValue != SQLITE_ROW; +} + static int _csync_detect_update(CSYNC *ctx, const char *file, const csync_vio_file_stat_t *fs, const int type) { uint64_t h = 0; @@ -190,8 +194,15 @@ static int _csync_detect_update(CSYNC *ctx, const char *file, } if (fs->mtime == 0) { - tmp = csync_statedb_get_stat_by_hash(ctx, h); 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)) { + SAFE_FREE(st); + ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL; + return -1; + } + if (tmp == NULL) { CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "file: %s - not found in db, IGNORE!", path); st->instruction = CSYNC_INSTRUCTION_IGNORE; @@ -228,6 +239,12 @@ static int _csync_detect_update(CSYNC *ctx, const char *file, if (csync_get_statedb_exists(ctx)) { tmp = csync_statedb_get_stat_by_hash(ctx, h); + if(_last_db_return_error(ctx)) { + SAFE_FREE(st); + ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL; + return -1; + } + if(tmp && tmp->phash == h ) { /* there is an entry in the database */ /* we have an update! */ CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Database entry found, compare: %" PRId64 " <-> %" PRId64 ", etag: %s <-> %s, inode: %" PRId64 " <-> %" PRId64 ", size: %" PRId64 " <-> %" PRId64, @@ -289,6 +306,12 @@ static int _csync_detect_update(CSYNC *ctx, const char *file, tmp = csync_statedb_get_stat_by_inode(ctx, fs->inode); + if(_last_db_return_error(ctx)) { + SAFE_FREE(st); + ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL; + return -1; + } + /* translate the file type between the two stat types csync has. */ if( tmp && tmp->type == 0 ) { tmp_vio_type = CSYNC_VIO_FILE_TYPE_REGULAR; @@ -319,6 +342,12 @@ static int _csync_detect_update(CSYNC *ctx, const char *file, } else { /* Remote Replica Rename check */ tmp = csync_statedb_get_stat_by_file_id(ctx, fs->file_id); + + if(_last_db_return_error(ctx)) { + SAFE_FREE(st); + ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL; + return -1; + } if(tmp ) { /* tmp existing at all */ if ((tmp->type == CSYNC_FTW_TYPE_DIR && fs->type != CSYNC_VIO_FILE_TYPE_DIRECTORY) || (tmp->type == CSYNC_FTW_TYPE_FILE && fs->type != CSYNC_VIO_FILE_TYPE_REGULAR)) { @@ -652,6 +681,11 @@ int csync_ftw(CSYNC *ctx, const char *uri, csync_walker_fn fn, uint64_t h = c_jhash64((uint8_t *) path, len, 0); etag = csync_statedb_get_etag( ctx, h ); + if(_last_db_return_error(ctx)) { + ctx->status_code = CSYNC_STATUS_UNSUCCESSFUL; + goto error; + } + if( etag ) { SAFE_FREE(fs->etag); fs->etag = etag;