Exemplo n.º 1
0
int csync_statedb_load(CSYNC *ctx, const char *statedb, sqlite3 **pdb) {
    int rc = -1;
    c_strlist_t *result = NULL;
    sqlite3 *db = NULL;

    if( !ctx ) {
        return -1;
    }

    if (ctx->statedb.db) {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: DB already open");
        ctx->status_code = CSYNC_STATUS_PARAM_ERROR;
        return -1;
    }

    ctx->statedb.lastReturnValue = SQLITE_OK;

    /* Openthe database */
    if (sqlite_open(statedb, &db) != SQLITE_OK) {
        const char *errmsg= sqlite3_errmsg(ctx->statedb.db);
        CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: Failed to sqlite3 open statedb - bail out: %s.",
                  errmsg ? errmsg : "<no sqlite3 errormsg>");

        rc = -1;
        ctx->status_code = CSYNC_STATUS_STATEDB_LOAD_ERROR;
        goto out;
    }

    if (_csync_check_db_integrity(db) != 0) {
        const char *errmsg= sqlite3_errmsg(db);
        CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "ERR: sqlite3 integrity check failed - bail out: %s.",
                  errmsg ? errmsg : "<no sqlite3 errormsg>");
        rc = -1;
        ctx->status_code = CSYNC_STATUS_STATEDB_CORRUPTED;
        goto out;
    }

    if (_csync_statedb_is_empty(db)) {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "statedb contents doesn't exist");
        csync_set_statedb_exists(ctx, 0);
    } else {
        csync_set_statedb_exists(ctx, 1);
    }

    /* Print out the version */
    //
    result = csync_statedb_query(db, "SELECT sqlite_version();");
    if (result && result->count >= 1) {
        CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "sqlite3 version \"%s\"", *result->vector);
    }
    c_strlist_destroy(result);

    /* optimization for speeding up SQLite */
    result = csync_statedb_query(db, "PRAGMA synchronous = NORMAL;");
    c_strlist_destroy(result);
    result = csync_statedb_query(db, "PRAGMA case_sensitive_like = ON;");
    c_strlist_destroy(result);

    /* set a busy handler with 5 seconds timeout */
    sqlite3_busy_timeout(db, 5000);

#ifndef NDEBUG
    sqlite3_profile(db, sqlite_profile, 0 );
#endif
    *pdb = db;

    CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "Success");

    return 0;
out:
    sqlite3_close(db);
    return rc;
}
Exemplo n.º 2
0
static int _csync_statedb_check(const char *statedb) {
  int fd = -1, rc;
  ssize_t r;
  char buf[BUF_SIZE] = {0};
  sqlite3 *db = NULL;
  csync_stat_t sb;

  mbchar_t *wstatedb = c_utf8_to_locale(statedb);

  if (wstatedb == NULL) {
    return -1;
  }

  /* check db version */
#ifdef _WIN32
    _fmode = _O_BINARY;
#endif

    fd = _topen(wstatedb, O_RDONLY);

    if (fd >= 0) {
        /* Check size. Size of zero is a valid database actually. */
        rc = _tfstat(fd, &sb);

        if (rc == 0) {
            if (sb.st_size == 0) {
                CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Database size is zero byte!");
                close(fd);
            } else {
                r = read(fd, (void *) buf, sizeof(buf) - 1);
                close(fd);
                if (r >= 0) {
                    buf[BUF_SIZE - 1] = '\0';
                    if (c_streq(buf, "SQLite format 3")) {
                        if (sqlite3_open(statedb, &db ) == SQLITE_OK) {
                            rc = _csync_check_db_integrity(db);
                            if( sqlite3_close(db) != 0 ) {
                                CSYNC_LOG(CSYNC_LOG_PRIORITY_NOTICE, "WARN: sqlite3_close error!");
                            }

                            if( rc >= 0 ) {
                                /* everything is fine */
                                c_free_locale_string(wstatedb);
                                return 0;
                            }
                            CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "Integrity check failed!");
                        } else {
                            /* resources need to be freed even when open failed */
                            sqlite3_close(db);
                            CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "database corrupted, removing!");
                        }
                    } else {
                        CSYNC_LOG(CSYNC_LOG_PRIORITY_WARN, "sqlite version mismatch");
                    }
                }
            }
        }
        /* if it comes here, the database is broken and should be recreated. */
        _tunlink(wstatedb);
    }

  c_free_locale_string(wstatedb);

  /* create database */
  rc = sqlite3_open(statedb, &db);
  if (rc == SQLITE_OK) {
    sqlite3_close(db);
    _csync_win32_hide_file(statedb);
    return 1;
  }
  sqlite3_close(db);
   CSYNC_LOG(CSYNC_LOG_PRIORITY_ERROR, "sqlite3_open failed: %s %s", sqlite3_errmsg(db), statedb);
   return -1;
}