From d354abf57454771291d7fd4cba4d288a28b46625 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 2 Dec 2018 11:27:31 +0100 Subject: Cleaned the DB code a little bit. --- src/analysis/db/cdb.c | 145 +++++++++++++++++++++++++------------------ src/analysis/db/cdb.h | 2 +- src/analysis/db/collection.c | 33 ++++++---- src/analysis/db/collection.h | 4 +- src/analysis/db/server.c | 4 +- src/core/logs.h | 2 +- 6 files changed, 111 insertions(+), 79 deletions(-) diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c index fd1f5cf..829be19 100644 --- a/src/analysis/db/cdb.c +++ b/src/analysis/db/cdb.c @@ -38,6 +38,7 @@ #include +#include #include @@ -49,6 +50,7 @@ #include "../../common/pathname.h" #include "../../common/xml.h" #include "../../core/collections.h" +#include "../../core/logs.h" #include "../../core/params.h" @@ -150,6 +152,8 @@ static void on_collection_changed(GDbCollection *, DBAction, GDbItem *, GCdbArch /* Assure le traitement des requêtes de clients. */ static void *g_cdb_archive_process(GCdbArchive *); +/* Dissocie un utilisateur de l'archive. */ +static void g_cdb_archive_remove_client(GCdbArchive *, size_t); @@ -779,24 +783,17 @@ static void on_collection_changed(GDbCollection *collec, DBAction action, GDbIte g_mutex_lock(&archive->clients_access); for (i = 0; i < archive->count && status; i++) + { status = ssl_send_packed_buffer(&pbuf, archive->clients[i].ssl_fd); - g_mutex_unlock(&archive->clients_access); - - exit_packed_buffer(&pbuf); - - if (!status) - goto occ_error; - - - printf("CHANGED for %d clients !!\n", (int)archive->count); - + if (!status) + LOG_ERROR(LMT_ERROR, _("Failed to send some DB update")); + } - occ_error: + g_mutex_unlock(&archive->clients_access); - /* TODO : close() */ - ; + exit_packed_buffer(&pbuf); } @@ -826,6 +823,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive) DBError error; /* Bilan d'une opération */ packed_buffer out_pbuf; /* Tampon d'émission */ GDbCollection *collec; /* Collection visée au final */ + char *msg; /* Erreur à faire remonter */ void interrupt_poll_with_sigusr1(int sig) { }; @@ -845,7 +843,7 @@ static void *g_cdb_archive_process(GCdbArchive *archive) g_mutex_lock(&archive->clients_access); nfds = archive->count; - fds = (struct pollfd *)realloc(fds, nfds * sizeof(struct pollfd)); + fds = realloc(fds, nfds * sizeof(struct pollfd)); for (i = 0; i < nfds; i++) { @@ -940,7 +938,9 @@ static void *g_cdb_archive_process(GCdbArchive *archive) break; default: - printf("bad command :: 0x%08x\n", command); + asprintf(&msg, _("Bad protocol command: 0x%08x"), command); + LOG_ERROR(LMT_ERROR, msg); + free(msg); goto gcap_bad_exchange; break; @@ -956,16 +956,13 @@ static void *g_cdb_archive_process(GCdbArchive *archive) gcap_bad_exchange: - printf("Bad exchange...\n"); + LOG_ERROR(LMT_ERROR, _("Bad exchange")); exit_packed_buffer(&in_pbuf); gcap_closed_exchange: - /* TODO : close conn */ - - ; - + g_cdb_archive_remove_client(archive, i); } @@ -987,13 +984,11 @@ static void *g_cdb_archive_process(GCdbArchive *archive) if (fds != NULL) free(fds); - return NULL; } - /****************************************************************************** * * * Paramètres : archive = archive à connecter avec un utilisateur. * @@ -1002,85 +997,111 @@ static void *g_cdb_archive_process(GCdbArchive *archive) * * * Description : Associe un nouvel utilisateur à l'archive. * * * -* Retour : Indication d'une éventuelle erreur lors de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -DBError g_cdb_archive_add_client(GCdbArchive *archive, SSL *fd, const rle_string *user) +void g_cdb_archive_add_client(GCdbArchive *archive, SSL *fd, const rle_string *user) { - + packed_buffer out_pbuf; /* Tampon d'émission */ + bool status; /* Bilan d'un envoi de retour */ GList *iter; /* Boucle de parcours */ GDbCollection *collec; /* Collection visée manipulée */ volatile pthread_t *process_id; /* Identifiant de la procédure */ - packed_buffer out_pbuf; /* Tampon d'émission */ - bool status; /* Bilan d'un envoi de retour */ - + /* Envoi des mises à jour au nouveau client... */ + init_packed_buffer(&out_pbuf); + status = true; + for (iter = g_list_first(archive->collections); + iter != NULL && status; + iter = g_list_next(iter)) + { + collec = G_DB_COLLECTION(iter->data); - g_mutex_lock(&archive->clients_access); + status = g_db_collection_pack_all_updates(collec, &out_pbuf); - /* Ajout dans la liste officielle */ + } - archive->clients = (cdb_client *)realloc(archive->clients, ++archive->count * sizeof(cdb_client)); + if (status && get_packed_buffer_payload_length(&out_pbuf) > 0) + status = ssl_send_packed_buffer(&out_pbuf, fd); - archive->clients[archive->count - 1].ssl_fd = fd; - dup_into_rle_string(&archive->clients[archive->count - 1].user, get_rle_string(user)); + exit_packed_buffer(&out_pbuf); - /* Démarrage ou redémarrage du processus d'écoute */ + if (!status) + LOG_ERROR(LMT_ERROR, _("Failed to add a client")); - if (archive->process == NULL) + else { - archive->process = g_thread_new("cdb_process", (GThreadFunc)g_cdb_archive_process, archive); + /* Ajout dans la liste officielle */ - /* On attend que le processus parallèle soit prêt */ + g_mutex_lock(&archive->clients_access); - process_id = &archive->process_id; + archive->clients = realloc(archive->clients, ++archive->count * sizeof(cdb_client)); - g_mutex_lock(&archive->id_access); - while (process_id == 0) - g_cond_wait(&archive->id_cond, &archive->id_access); - g_mutex_unlock(&archive->id_access); + archive->clients[archive->count - 1].ssl_fd = fd; + dup_into_rle_string(&archive->clients[archive->count - 1].user, get_rle_string(user)); - } - else - pthread_kill(archive->process_id, SIGUSR1); + /* Démarrage ou redémarrage du processus d'écoute */ - g_mutex_unlock(&archive->clients_access); + if (archive->process == NULL) + { + archive->process = g_thread_new("cdb_process", (GThreadFunc)g_cdb_archive_process, archive); - /* Envoi des mises à jour au nouveau client... */ + /* On attend que le processus parallèle soit prêt */ - init_packed_buffer(&out_pbuf); + process_id = &archive->process_id; - status = true; + g_mutex_lock(&archive->id_access); + while (process_id == 0) + g_cond_wait(&archive->id_cond, &archive->id_access); + g_mutex_unlock(&archive->id_access); + } + else + pthread_kill(archive->process_id, SIGUSR1); - /* TODO : lock ? */ + g_mutex_unlock(&archive->clients_access); - for (iter = g_list_first(archive->collections); - iter != NULL && status; - iter = g_list_next(iter)) - { - collec = G_DB_COLLECTION(iter->data); + } - status = g_db_collection_pack_all_updates(collec, &out_pbuf); +} - } - if (status && get_packed_buffer_payload_length(&out_pbuf) > 0) - status = ssl_send_packed_buffer(&out_pbuf, fd); +/****************************************************************************** +* * +* Paramètres : archive = archive à connecter avec un utilisateur. * +* index = indice de l'utilisateur concerné. * +* * +* Description : Dissocie un utilisateur de l'archive. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ - exit_packed_buffer(&out_pbuf); +static void g_cdb_archive_remove_client(GCdbArchive *archive, size_t index) +{ + cdb_client *client; /* Client à traiter */ + client = &archive->clients[index]; + g_mutex_lock(&archive->clients_access); - return DBE_NONE; //// + SSL_free(client->ssl_fd); + exit_rle_string(&client->user); -} + if ((index + 1) < archive->count) + memmove(&archive->clients[index], &archive->clients[index + 1], + (archive->count - index - 1) * sizeof(cdb_client)); + archive->clients = realloc(archive->clients, --archive->count * sizeof(cdb_client)); + g_mutex_unlock(&archive->clients_access); +} diff --git a/src/analysis/db/cdb.h b/src/analysis/db/cdb.h index 49a18a5..601b10f 100644 --- a/src/analysis/db/cdb.h +++ b/src/analysis/db/cdb.h @@ -67,7 +67,7 @@ int g_cdb_archive_compare_hash(const GCdbArchive *, const rle_string *); /* Associe un nouvel utilisateur à l'archive. */ -DBError g_cdb_archive_add_client(GCdbArchive *, SSL *, const rle_string *); +void g_cdb_archive_add_client(GCdbArchive *, SSL *, const rle_string *); diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index adf607d..a99c2de 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -310,12 +310,15 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3 { if (collec->binary != NULL && g_db_item_is_active(item)) result = g_db_item_apply(item, collec->binary); - if (db != NULL) - result &= g_db_collection_store_item(collec, item, db); - } - if (!result) - /* TODO : retirer l'élément */; + if (result && db != NULL) + result = g_db_collection_store_item(collec, item, db); + + /* En cas d'erreur, il faut retirer l'élément */ + if (!result) + _g_db_collection_remove_item(collec, item, true, false); + + } break; @@ -331,7 +334,7 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3 { /* Côté client */ if (db == NULL) - result = _g_db_collection_remove_item(collec, item, false); + result = _g_db_collection_remove_item(collec, item, false, true); /* Côté serveur */ else @@ -613,6 +616,7 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock) * Paramètres : collec = ensemble d'éléments à considérer. * * item = élément de collection à manipuler. * * lock = indique si le verrou d'écriture doit être posé. * +* signal = émet un événement pour signaler le retrait. * * * * Description : Procède au retrait d'un nouvel élément dans la collection. * * * @@ -622,7 +626,7 @@ bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock) * * ******************************************************************************/ -bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool lock) +bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool lock, bool signal) { bool result; /* Bilan à faire remonter */ GList *found; /* Test de présence existante */ @@ -633,7 +637,7 @@ bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool loc if (lock) g_db_collection_wlock(collec); - found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare_with_timestamp); + found = g_list_find_custom(collec->sorted, item, (GCompareFunc)g_db_item_compare_with_timestamp); result = (found != NULL); @@ -641,11 +645,18 @@ bool _g_db_collection_remove_item(GDbCollection *collec, GDbItem *item, bool loc { internal = G_DB_ITEM(found->data); + collec->sorted = g_list_delete_link(collec->sorted, found); + + found = g_list_find(collec->items, item); + assert(found != NULL); + collec->items = g_list_delete_link(collec->items, found); - g_signal_emit_by_name(collec, "content-changed", DBA_REM_ITEM, internal); + if (signal) + g_signal_emit_by_name(collec, "content-changed", DBA_REM_ITEM, internal); g_object_unref(G_OBJECT(internal)); + g_object_unref(G_OBJECT(internal)); } @@ -1036,7 +1047,7 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db) break; case SQLITE_FLOAT: - assert(0); /* TODO */ + assert(0); break; case SQLITE_TEXT: @@ -1044,7 +1055,7 @@ bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db) break; case SQLITE_BLOB: - assert(0); /* TODO */ + assert(0); break; case SQLITE_NULL: diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h index 5fbf385..5292e89 100644 --- a/src/analysis/db/collection.h +++ b/src/analysis/db/collection.h @@ -104,7 +104,7 @@ bool g_db_collection_has_item(GDbCollection *, GDbItem *); bool _g_db_collection_add_item(GDbCollection *, GDbItem *, bool); /* Procède au retrait d'un nouvel élément dans la collection. */ -bool _g_db_collection_remove_item(GDbCollection *, GDbItem *, bool); +bool _g_db_collection_remove_item(GDbCollection *, GDbItem *, bool, bool); /* Détermine l'horodatage le plus jeune pour une désactivation. */ timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *, bool); @@ -113,7 +113,7 @@ timestamp_t _g_db_collection_compute_inactivity_timestamp(GDbCollection *, bool) bool _g_db_collection_update_item_activity(GDbCollection *, GDbItem *, timestamp_t *, bool); #define g_db_collection_add_item(c, i) _g_db_collection_add_item(c, i, true) -#define g_db_collection_remove_item(c, i) _g_db_collection_remove_item(c, i, true) +#define g_db_collection_remove_item(c, i) _g_db_collection_remove_item(c, i, true, true) #define g_db_collection_compute_inactivity_timestamp(c) _g_db_collection_compute_inactivity_timestamp(c, true) #define g_db_collection_update_item_activity(c, i, t) _g_db_collection_update_item_activity(c, i, t, true) diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c index a996360..5f6660f 100644 --- a/src/analysis/db/server.c +++ b/src/analysis/db/server.c @@ -513,7 +513,7 @@ static bool g_db_server_register_user(GDbServer *server, const char *author, cha server->users = realloc(server->users, ++server->users_count * sizeof(registered_user)); - dup_into_rle_string(&server->users[server->users_count - 1].author, author); /* FIXME : src ? */ + dup_into_rle_string(&server->users[server->users_count - 1].author, author); server->users[server->users_count - 1].key_file = kfile; return true; @@ -839,7 +839,7 @@ static void *g_db_server_listener(GDbServer *server) if (iter == NULL) server->archives = g_list_append(server->archives, archive); - error = g_cdb_archive_add_client(archive, tls_fd, &user); + g_cdb_archive_add_client(archive, tls_fd, &user); exit_packed_buffer(&out_pbuf); diff --git a/src/core/logs.h b/src/core/logs.h index 27dd039..afdcfa2 100644 --- a/src/core/logs.h +++ b/src/core/logs.h @@ -75,7 +75,7 @@ void log_variadic_message(LogMessageType, const char *, ...); #define LOG_ERROR(tp, msg) \ - log_variadic_message(tp, "[%s:%u] %s", __FUNCTION__, __LINE__, msg); + log_variadic_message(tp, "[%s:%u] %s", __FUNCTION__, __LINE__, msg) #define LOG_ERROR_N(func) \ do \ -- cgit v0.11.2-87-g4458