From e9f14108d09e93d652b0aa1fc4577eb41a2fbe68 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Thu, 30 Apr 2020 21:05:34 +0200 Subject: [PATCH] Timestamp verification for update --- inc/common/common.h | 2 ++ inc/lektor/common.h | 28 ++++++++++++++-------------- inc/lektor/database.h | 3 +++ src/common.c | 6 ++++++ src/database/open.c | 22 ++++++++++++++++++++++ src/net/downloader.c | 16 ++++++++++++---- 6 files changed, 59 insertions(+), 18 deletions(-) diff --git a/inc/common/common.h b/inc/common/common.h index 3dc3bdda..b56af85e 100644 --- a/inc/common/common.h +++ b/inc/common/common.h @@ -8,3 +8,5 @@ extern void __not_implemented(const char *func, char *file, int line); #define UNUSED(...) __unused((void *) __VA_ARGS__) void __unused(void *, ...); + +long min_long(long a, long b); diff --git a/inc/lektor/common.h b/inc/lektor/common.h index ec7da188..28155d19 100644 --- a/inc/lektor/common.h +++ b/inc/lektor/common.h @@ -61,38 +61,38 @@ enum mpd_idle_flag { /* Macros */ -#define SQLITE_PREPARE(db, stmt, SQL, goto_label) \ - if (sqlite3_prepare_v2(db, SQL, -1, &(stmt), 0) != SQLITE_OK) { \ - LOG_ERROR_SCT("DB", "Failed to prepare statement: %s", \ - sqlite3_errmsg(db)); \ - goto goto_label; \ +#define SQLITE_PREPARE(db, stmt, SQL, goto_label) \ + if (sqlite3_prepare_v2((sqlite3 *) db, SQL, -1, &(stmt), 0) != SQLITE_OK) { \ + LOG_ERROR_SCT("DB", "Failed to prepare statement: %s", \ + sqlite3_errmsg((sqlite3 *) db)); \ + goto goto_label; \ } -#define SQLITE_EXEC(db, SQL, goto_label) \ - if (sqlite3_exec(db, SQL, NULL, NULL, NULL) != SQLITE_OK) { \ - LOG_ERROR_SCT("DB", "Failed to exec statement: %s", \ - sqlite3_errmsg(db)); \ - goto goto_label; \ +#define SQLITE_EXEC(db, SQL, goto_label) \ + if (sqlite3_exec((sqlite3 *) db, SQL, NULL, NULL, NULL) != SQLITE_OK) { \ + LOG_ERROR_SCT("DB", "Failed to exec statement: %s", \ + sqlite3_errmsg((sqlite3 *) db)); \ + goto goto_label; \ } #define SQLITE_BIND_TEXT(db, stmt, pos, text, error) \ if (sqlite3_bind_text(stmt, pos, text, -1, 0) != SQLITE_OK) { \ LOG_ERROR_SCT("DB", "Failed to bind text %s at pos %d: %s", \ - text, pos, sqlite3_errmsg(db)); \ + text, pos, sqlite3_errmsg((sqlite3 *) db)); \ goto error; \ } #define SQLITE_BIND_INT(db, stmt, pos, integer, error) \ if (sqlite3_bind_int(stmt, pos, integer) != SQLITE_OK) { \ LOG_ERROR_SCT("DB", "Failed to bind int %d at pos %d: %s", \ - integer, pos, sqlite3_errmsg(db)); \ + integer, pos, sqlite3_errmsg((sqlite3 *) db)); \ goto error; \ } #define SQLITE_STEP(db, stmt, code, error) \ if (sqlite3_step(stmt) != code) { \ LOG_ERROR_SCT("DB", "Failed to step and get a row: %s", \ - sqlite3_errmsg(db)); \ + sqlite3_errmsg((sqlite3 *) db)); \ goto error; \ } @@ -101,7 +101,7 @@ enum mpd_idle_flag { #define SQLITE_STEP_OK(db, stmt, error) SQLITE_STEP(db, stmt, SQLITE_OK, error) #define SQLITE_DO_ROLLBACK(db) \ - sqlite3_exec(db, "ROLLBACK TRANSACTION;\n", NULL, NULL, NULL); + sqlite3_exec((sqlite3 *) db, "ROLLBACK TRANSACTION;\n", NULL, NULL, NULL); /* Random things */ diff --git a/inc/lektor/database.h b/inc/lektor/database.h index e46f067b..e0975dc7 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -22,6 +22,9 @@ struct lkt_queue_state { int length; }; +long database_get_timestamp(volatile sqlite3 *db); +void database_stamp(volatile sqlite3 *db); + /* Open correctly a database for lektor. */ bool database_new (sqlite3 **db); bool database_init (const char *dbpath); diff --git a/src/common.c b/src/common.c index b14f8269..8bc985b3 100644 --- a/src/common.c +++ b/src/common.c @@ -127,3 +127,9 @@ get_stdin_line(const char *prompt, char *buf, size_t len) buf[len - 1] = 0u; return is_utf8(buf); } + +long +min_long(long a, long b) +{ + return a < b ? a : b; +} diff --git a/src/database/open.c b/src/database/open.c index fcfbe69c..12c09489 100644 --- a/src/database/open.c +++ b/src/database/open.c @@ -191,3 +191,25 @@ error: LOG_ERROR_SCT("DB", "Failed to init the 'disk' database, path was '%s'", dbpath); return false; } + +long +database_get_timestamp(volatile sqlite3 *db) +{ + long ret = 0; + static const char *SQL = "SELECT last_update FROM misc WHERE id = 42;"; + sqlite3_stmt *stmt; + SQLITE_PREPARE(db, stmt, SQL, error); + SQLITE_STEP_ROW(db, stmt, error); + ret = sqlite3_column_int(stmt, 0); +error: + sqlite3_finalize(stmt); + return ret; +} + +void +database_stamp(volatile sqlite3 *db) +{ + SQLITE_EXEC(db, "UPDATE misc SET last_update = strftime('%s','now');", error); +error: + return; +} diff --git a/src/net/downloader.c b/src/net/downloader.c index aae9cb97..b4d8d328 100644 --- a/src/net/downloader.c +++ b/src/net/downloader.c @@ -383,7 +383,7 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, struct json_objec int32_t integer, err; struct kara *kara; char url[URL_MAX_LEN]; - long stamp, timestamp; + long filestamp, timestamp; RETURN_UNLESS(len > 0 && json_object_get_array(json), "Json invalid or array empty", NOTHING); LOG_INFO_SCT("REPO", "Starting to process json for repo %s", repo->name); @@ -409,13 +409,19 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, struct json_objec kara->filename[PATH_MAX - 1] = 0; LOG_INFO_SCT("REPO", "Crafted filename is '%s'", kara->filename); + /* Timestamp verification */ if (safe_json_get_long(kara_json, "unix_timestamp", ×tamp)) continue; - stamp = get_mtime(kara->filename); - if (stamp > timestamp) { - LOG_INFO_SCT("REPO", "Ignore kara '%ld', last timestamp was %ld, new is %ld", kara->id, stamp, timestamp); + filestamp = get_mtime(kara->filename); + if (database_get_timestamp(db) < filestamp) { + LOG_WARN_SCT("REPO", "Kara file %s is more recent than database timestamp, download it", kara->filename); + goto do_it; + } + if (filestamp > timestamp) { + LOG_INFO_SCT("REPO", "Ignore kara '%ld', last timestamp was %ld, new is %ld", kara->id, filestamp, timestamp); continue; } +do_it: err |= safe_json_get_string(kara_json, "song_name", kara->mdt.song_name, LEKTOR_TAG_MAX); err |= safe_json_get_string(kara_json, "source_name", kara->mdt.source_name, LEKTOR_TAG_MAX); @@ -446,6 +452,8 @@ __handle_got_json(volatile sqlite3 *db, struct lkt_repo *repo, struct json_objec continue; } + database_stamp(db); + LOG_INFO_SCT("REPO", "Added kara %ld from repo %s, filepath is %s", kara->id, repo->name, kara->filename); } -- GitLab