diff options
Diffstat (limited to 'src/analysis')
-rw-r--r-- | src/analysis/binary.c | 67 | ||||
-rw-r--r-- | src/analysis/binary.h | 4 | ||||
-rwxr-xr-x | src/analysis/db/Makefile.am | 1 | ||||
-rw-r--r-- | src/analysis/db/cdb.c | 44 | ||||
-rw-r--r-- | src/analysis/db/collection-int.h | 78 | ||||
-rw-r--r-- | src/analysis/db/collection.c | 272 | ||||
-rw-r--r-- | src/analysis/db/collection.h | 28 | ||||
-rw-r--r-- | src/analysis/db/items/bookmark.c | 377 | ||||
-rw-r--r-- | src/analysis/db/items/bookmark.h | 27 | ||||
-rw-r--r-- | src/analysis/db/server.c | 11 |
10 files changed, 772 insertions, 137 deletions
diff --git a/src/analysis/binary.c b/src/analysis/binary.c index 55b984a..96e774c 100644 --- a/src/analysis/binary.c +++ b/src/analysis/binary.c @@ -232,7 +232,7 @@ static void g_loaded_binary_finalize(GLoadedBinary *binary) * Remarques : - * * * ******************************************************************************/ -#include "db/items/bookmark.h" + GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const char *path) { GLoadedBinary *result; /* Adresse à retourner */ @@ -303,61 +303,6 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch status = g_db_client_start(result->local, host, port, author); - - - - - /* --------- %< --------- %< --------- %< --------- %< --------- */ - - do - { - vmpa2t addr; - GDbBookmark *bm; - bool status; - - - init_vmpa(&addr, 0xaeb4, VMPA_NO_VIRTUAL); - - bm = g_db_bookmark_new(&addr, "Premier commentaire"); - - - - status = g_loaded_binary_add_to_collection(result, DBF_BOOKMARKS, G_DB_ITEM(bm)); - - if (status) - printf("send OK\n"); - else - printf("send nok\n"); - - - g_db_client_save(result->local); - - - - /* - safe_send(client->fd, (uint32_t []) { htobe32(DBC_COLLECTION) }, sizeof(uint32_t), MSG_MORE); - safe_send(client->fd, (uint32_t []) { htobe32(DBF_BOOKMARKS) }, sizeof(uint32_t), MSG_MORE); - safe_send(client->fd, (uint32_t []) { htobe32(DBA_ADD_ITEM) }, sizeof(uint32_t), MSG_MORE); - - if (g_db_item_send(G_DB_ITEM(bm), client->fd, 0)) - printf("send OK\n"); - else - printf("send nok\n"); - - */ - - - } - while (0); - - /* --------- %< --------- %< --------- %< --------- %< --------- */ - - - - - - - printf("DB status :: %d\n", status); return result; @@ -394,6 +339,11 @@ bool g_loaded_binary_save(const GLoadedBinary *binary, xmlDocPtr xdoc, xmlXPathC result = g_loaded_binary_save_storage(binary, xdoc, context, path); + + //// + g_db_client_save(binary->local); + + return result; } @@ -797,6 +747,7 @@ GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *binary, DBFeatures * Paramètres : binary = élément binaire à consulter. * * feature = fonctionnalité visée par la requête. * * item = élémnent à pousser vers un serveur de collection. * +* lock = indique si le verrou d'écriture doit être posé. * * * * Description : Demande l'intégration d'une modification dans une collection.* * * @@ -806,7 +757,7 @@ GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *binary, DBFeatures * * ******************************************************************************/ -bool g_loaded_binary_add_to_collection(GLoadedBinary *binary, DBFeatures feature, GDbItem *item) +bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, DBFeatures feature, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ GDbCollection *collec; /* Collection visée au final */ @@ -819,7 +770,7 @@ bool g_loaded_binary_add_to_collection(GLoadedBinary *binary, DBFeatures feature /* S'il n'y a pas besoin de sauvegarde... */ if (g_db_item_is_volatile(item)) - g_db_collection_add_item(collec, item); + _g_db_collection_add_item(collec, item, lock); /* Sinon on envoie par le réseau ! */ else diff --git a/src/analysis/binary.h b/src/analysis/binary.h index 625ff4a..26367c4 100644 --- a/src/analysis/binary.h +++ b/src/analysis/binary.h @@ -119,8 +119,10 @@ void g_loaded_binary_set_storage(GLoadedBinary *, DBFeatures, DBStorage); GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *, DBFeatures); /* Demande l'intégration d'une modification dans une collection. */ -bool g_loaded_binary_add_to_collection(GLoadedBinary *, DBFeatures, GDbItem *); +bool _g_loaded_binary_add_to_collection(GLoadedBinary *, DBFeatures, GDbItem *, bool); +#define g_loaded_binary_add_to_collection(b, f, i) \ + _g_loaded_binary_add_to_collection(b, f, i, true); diff --git a/src/analysis/db/Makefile.am b/src/analysis/db/Makefile.am index 6852821..2e8e0f1 100755 --- a/src/analysis/db/Makefile.am +++ b/src/analysis/db/Makefile.am @@ -4,6 +4,7 @@ noinst_LTLIBRARIES = libanalysisdb.la libanalysisdb_la_SOURCES = \ cdb.h cdb.c \ client.h client.c \ + collection-int.h \ collection.h collection.c \ core.h core.c \ item-int.h \ diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c index 24da20e..014a6d8 100644 --- a/src/analysis/db/cdb.c +++ b/src/analysis/db/cdb.c @@ -328,7 +328,7 @@ GCdbArchive *g_cdb_archive_new(const char *owner, const rle_string *hash, const /* Ouverture de l'archive */ - if (!g_cdb_archive_read(result) && 0) + if (!g_cdb_archive_read(result)) goto gcan_error; /* Chargement des éléments sauvegardés */ @@ -712,6 +712,7 @@ static bool g_cdb_archive_create_db(const GCdbArchive *archive, const core_db_in static bool g_cdb_archive_load_collections(GCdbArchive *archive) { GList *iter; /* Boucle de parcours */ + GDbCollection *collec; /* Collection visée manipulée */ archive->collections = create_collections_list(); @@ -719,7 +720,12 @@ static bool g_cdb_archive_load_collections(GCdbArchive *archive) iter != NULL; iter = g_list_next(iter)) { - g_signal_connect(iter->data, "content-changed", G_CALLBACK(on_collection_changed), archive); + collec = G_DB_COLLECTION(iter->data); + g_signal_connect(collec, "content-changed", G_CALLBACK(on_collection_changed), archive); + + if (!g_db_collection_load_all_items(collec, archive->db)) + return false; + } return true; @@ -762,7 +768,7 @@ static void on_collection_changed(GDbCollection *collec, DBAction action, GDbIte g_mutex_unlock(&archive->clients_access); - printf("CHANGED !!\n"); + printf("CHANGED for %d clients !!\n", (int)archive->count); @@ -947,6 +953,8 @@ static void *g_cdb_archive_process(GCdbArchive *archive) DBError g_cdb_archive_add_client(GCdbArchive *archive, int fd, const rle_string *user) { + GList *iter; /* Boucle de parcours */ + GDbCollection *collec; /* Collection visée manipulée */ volatile pthread_t *process_id; /* Identifiant de la procédure */ @@ -964,6 +972,28 @@ DBError g_cdb_archive_add_client(GCdbArchive *archive, int fd, const rle_string archive->clients[archive->count - 1].fd = fd; dup_rle_string(&archive->clients[archive->count - 1].user, user); + + + /* Envoi des mises à jour au nouveau client... */ + + + for (iter = g_list_first(archive->collections); + iter != NULL; + iter = g_list_next(iter)) + { + collec = G_DB_COLLECTION(iter->data); + + if (!g_db_collection_send_all_updates(collec, fd)) + /* TODO */; + + + + + + } + + + /* Démarrage ou redémarrage du processus d'écoute */ if (archive->process == NULL) @@ -979,14 +1009,8 @@ DBError g_cdb_archive_add_client(GCdbArchive *archive, int fd, const rle_string g_mutex_unlock(&archive->clients_access); - /* Envoi des mises à jour au nouveau client... */ - - - /* TODO */ - - - return DBE_NONE; + return DBE_NONE; //// } diff --git a/src/analysis/db/collection-int.h b/src/analysis/db/collection-int.h new file mode 100644 index 0000000..6ca9ab4 --- /dev/null +++ b/src/analysis/db/collection-int.h @@ -0,0 +1,78 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * collection-int.h - prototypes et définitions internes pour les collections d'éléments + * + * Copyright (C) 2015 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * OpenIDA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * OpenIDA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _ANALYSIS_DB_COLLECTION_INT_H +#define _ANALYSIS_DB_COLLECTION_INT_H + + +#include "collection.h" + + +#include <stdarg.h> + + + +/* Décrit les colonnes utiles à un chargement de données. */ +typedef bool (* collec_setup_load_fc) (GDbCollection *, bound_value **, size_t *); + +/* Charge les valeurs utiles pour une localisation. */ +typedef bool (* collec_load_item) (GDbCollection *, const bound_value *, size_t); + +/* Détermine si un élément est déjà présent ou non. */ +typedef GDbItem * (* collec_has_key_fc) (GDbCollection *, va_list *); + + + +/* Collection générique d'éléments (instance) */ +struct _GDbCollection +{ + GObject parent; /* A laisser en premier */ + + uint32_t featuring; /* Fonctionnalité représentée */ + GType type; /* Identifiant GLib équivalent */ + const char *name; /* Nom en base de données */ + + GList *items; /* Eléments rassemblés */ + GList *sorted; /* Eléments triés */ + GRWLock params_access; /* Verrou de protection */ + +}; + +/* Collection générique d'éléments (classe) */ +struct _GDbCollectionClass +{ + GObjectClass parent; /* A laisser en premier */ + + collec_setup_load_fc setup_load; /* Prépare le chargement */ + collec_load_item load_item; /* Charge un élément */ + collec_has_key_fc has_key; /* Recherche de présence */ + + /* Signaux */ + + void (* content_changed) (GDbCollection *, DBAction, GDbItem *); + +}; + + + +#endif /* _ANALYSIS_DB_COLLECTION_INT_H */ diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c index 5c25720..84acc58 100644 --- a/src/analysis/db/collection.c +++ b/src/analysis/db/collection.c @@ -24,41 +24,19 @@ #include "collection.h" +#include <assert.h> +#include <malloc.h> #include <stdio.h> #include <string.h> +#include "collection-int.h" #include "../../common/extstr.h" #include "../../common/io.h" #include "../../glibext/chrysamarshal.h" -/* Collection générique d'éléments (instance) */ -struct _GDbCollection -{ - GObject parent; /* A laisser en premier */ - - uint32_t featuring; /* Fonctionnalité représentée */ - GType type; /* Identifiant GLib équivalent */ - const char *name; /* Nom en base de données */ - - GList *items; /* Eléments rassemblés */ - GList *sorted; /* Eléments triés */ - GRWLock params_access; /* Verrou de protection */ - -}; - -/* Collection générique d'éléments (classe) */ -struct _GDbCollectionClass -{ - GObjectClass parent; /* A laisser en premier */ - - /* Signaux */ - - void (* content_changed) (GDbCollection *, DBAction, GDbItem *); - -}; @@ -80,6 +58,9 @@ static void g_db_collection_finalize(GDbCollection *); /* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ +/* Décrit les colonnes utiles à un chargement de données. */ +static bool g_db_collection_setup_load(GDbCollection *, bound_value **, size_t *); + /* Enregistre un élément de collection dans une base de données. */ static bool g_db_collection_store_item(const GDbCollection *, const GDbItem *, sqlite3 *); @@ -345,8 +326,37 @@ bool g_db_collection_send(GDbCollection *collec, int fd, DBAction action, GDbIte } +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à considérer. * +* fd = flux ouvert en écriture pour l'émission de données. * +* * +* Description : Envoie pour mise à jour tous les éléments courants. * +* * +* Retour : Bilan de l'exécution de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ +bool g_db_collection_send_all_updates(GDbCollection *collec, int fd) +{ + bool result; /* Bilan à renvoyer */ + GList *iter; /* Boucle de parcours */ + + result = true; + + for (iter = g_list_first(collec->items); + iter != NULL && result; + iter = g_list_next(iter)) + { + result = g_db_collection_send(collec, fd, DBA_ADD_ITEM, G_DB_ITEM(iter->data)); + + } + + return result; +} @@ -408,17 +418,76 @@ GList *g_db_collection_list_items(const GDbCollection *collec) } +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à consulter. * +* ... = clef identifiant de manière unique un élément. * +* * +* Description : Détermine si un élément est déjà présent ou non. * +* * +* Retour : Elément trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GDbItem *g_db_collection_has_key(GDbCollection *collec, ...) +{ + GDbItem *result; /* Bilan à retourner */ + va_list ap; /* Liste d'arguments en plus */ + + va_start(ap, collec); + + result = G_DB_COLLECTION_GET_CLASS(collec)->has_key(collec, &ap); + + va_end(ap); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à consulter. * +* item = élément complet dont un double est à rechercher. * +* * +* Description : Détermine si un élément est déjà présent ou non. * +* * +* Retour : true si un élément similaire est présent dans la collection. * +* * +* Remarques : - * +* * +******************************************************************************/ +bool g_db_collection_has_item(GDbCollection *collec, GDbItem *item) +{ + bool result; /* Bilan à retourner */ + GList *found; /* Test de présence existante */ + + /** + * Un verrou doit être posé ! + * Il n'y a pas d'assert() possible pour le vérifier... + */ + + printf(" --- has\n"); + + found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare); + printf(" --- has: %p\n", found); + result = (found != NULL); + return result; +} /****************************************************************************** * * * 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é. * * * * Description : Procède à l'ajout d'un nouvel élément dans la collection. * * * @@ -428,12 +497,13 @@ GList *g_db_collection_list_items(const GDbCollection *collec) * * ******************************************************************************/ -bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item) +bool _g_db_collection_add_item(GDbCollection *collec, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ GList *found; /* Test de présence existante */ - g_db_collection_wlock(collec); + if (lock) + g_db_collection_wlock(collec); found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare); @@ -451,14 +521,15 @@ bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item) g_signal_emit_by_name(collec, "content-changed", DBA_ADD_ITEM, item); - printf(" ==== CONTENT CHANGED !!!\n"); + printf(" ==== CONTENT CHANGED (-> %u) !!!\n", g_list_length(collec->items)); result = true; } - g_db_collection_wunlock(collec); + if (lock) + g_db_collection_wunlock(collec); return result; @@ -469,6 +540,7 @@ bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item) * * * Paramètres : collec = ensemble d'éléments à considérer. * * item = élément de collection à copier. * +* lock = indique si le verrou d'écriture doit être posé. * * * * Description : Procède à la modification d'un élément dans la collection. * * * @@ -478,7 +550,7 @@ bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item) * * ******************************************************************************/ -bool g_db_collection_modify_item(GDbCollection *collec, GDbItem *item) +bool _g_db_collection_modify_item(GDbCollection *collec, GDbItem *item, bool lock) { bool result; /* Bilan à faire remonter */ GList *found; /* Test de présence existante */ @@ -499,15 +571,151 @@ bool g_db_collection_modify_item(GDbCollection *collec, GDbItem *item) - /* ---------------------------------------------------------------------------------- */ -/* CREATION DE L'ABSTRACTION POUR COLLECTIONS */ /* MANIPULATIONS AVEC UNE BASE DE DONNEES */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * +* Paramètres : collec = ensemble d'éléments à consulter. * +* values = tableau d'éléments à compléter. [OUT] * +* count = nombre de descriptions renseignées. [OUT] * +* * +* Description : Décrit les colonnes utiles à un chargement de données. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_db_collection_setup_load(GDbCollection *collec, bound_value **values, size_t *count) +{ + *values = NULL; + *count = 0; + + return G_DB_COLLECTION_GET_CLASS(collec)->setup_load(collec, values, count); + +} + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à peupler. * +* db = base de données repondant aux requêtes. * +* * +* Description : Charge un ensemble d'éléments à partir d'une base de données.* +* * +* Retour : Bilan de l'exécution de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_db_collection_load_all_items(GDbCollection *collec, sqlite3 *db) +{ + bool result; /* Conclusion à faire remonter */ + bound_value *values; /* Champs de table à inclure */ + size_t count; /* Nombre de ces champs */ + char *sql; /* Requête SQL à construire */ + size_t i; /* Boucle de parcours */ + sqlite3_stmt *stmt; /* Déclaration mise en place */ + int ret; /* Bilan d'un appel à SQLite */ + + if (!g_db_collection_setup_load(collec, &values, &count)) + return false; + + result = false; + + /* Préparation de la requête */ + + sql = strdup("SELECT "); + + for (i = 0; i < count; i++) + { + if (i > 0) sql = stradd(sql, ", "); + + sql = stradd(sql, values[i].name); + + } + + sql = stradd(sql, " FROM "); + sql = stradd(sql, collec->name); + sql = stradd(sql, ";"); + + ret = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL); + if (ret != SQLITE_OK) + { + fprintf(stderr, "Can't prepare SELECT statment '%s' (ret=%d): %s\n", sql, ret, sqlite3_errmsg(db)); + goto gdclai_exit; + } + + /* Chargement des valeurs existantes */ + + result = true; + + for (ret = sqlite3_step(stmt); ret == SQLITE_ROW && result; ret = sqlite3_step(stmt)) + { + /* Conversion des valeurs */ + + for (i = 0; i < count; i++) + { + values[i].type = sqlite3_column_type(stmt, i); + + switch (values[i].type) + { + case SQLITE_INTEGER: + values[i].type = SQLITE_INT64; + values[i].integer64 = sqlite3_column_int64(stmt, i); + break; + + case SQLITE_FLOAT: + assert(0); /* TODO */ + break; + + case SQLITE_TEXT: + values[i].cstring = (const char *)sqlite3_column_text(stmt, i); + break; + + case SQLITE_BLOB: + assert(0); /* TODO */ + break; + + case SQLITE_NULL: + break; + + default: + assert(0); + break; + + } + + } + + /* Chargement d'un nouvel élément */ + + result = G_DB_COLLECTION_GET_CLASS(collec)->load_item(collec, values, count); + + } + + /* Sortie propre */ + + sqlite3_finalize(stmt); + + gdclai_exit: + + free(sql); + + printf("LOAD ? %d\n", result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : collec = ensemble d'éléments à considérer. * * item = élément de collection à enregistrer. * * db = base de données à mettre à jour. * diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h index b400820..268c2be 100644 --- a/src/analysis/db/collection.h +++ b/src/analysis/db/collection.h @@ -39,10 +39,14 @@ #define G_TYPE_DB_COLLECTION g_db_collection_get_type() #define G_DB_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_collection_get_type(), GDbCollection)) #define G_IS_DB_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_collection_get_type())) -#define G_DB_COLLECTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), g_db_collection_get_type(), GDbCollectionIface)) +#define G_DB_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_COLLECTION, GDbCollectionClass)) +#define G_IS_DB_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_COLLECTION)) #define G_DB_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_COLLECTION, GDbCollectionClass)) + + + /* Collection générique d'éléments (instance) */ typedef struct _GDbCollection GDbCollection; @@ -70,7 +74,8 @@ bool g_db_collection_recv(GDbCollection *, int, sqlite3 *); /* Envoie pour traitement une requête réseau pour collection. */ bool g_db_collection_send(GDbCollection *, int, DBAction, GDbItem *); - +/* Envoie pour mise à jour tous les éléments courants. */ +bool g_db_collection_send_all_updates(GDbCollection *, int); @@ -89,15 +94,28 @@ void g_db_collection_lock_unlock(GDbCollection *, bool, bool); /* Renvoie la liste des éléments rassemblés. */ GList *g_db_collection_list_items(const GDbCollection *); +/* Détermine si un élément est déjà présent ou non. */ +GDbItem *g_db_collection_has_key(GDbCollection *, ...); - +/* Détermine si un élément est déjà présent ou non. */ +bool g_db_collection_has_item(GDbCollection *, GDbItem *); /* Procède à l'ajout d'un nouvel élément dans la collection. */ -bool g_db_collection_add_item(GDbCollection *, GDbItem *); +bool _g_db_collection_add_item(GDbCollection *, GDbItem *, bool); /* Procède à la modification d'un élément dans la collection. */ -bool g_db_collection_modify_item(GDbCollection *, GDbItem *); +bool _g_db_collection_modify_item(GDbCollection *, GDbItem *, bool); + +#define g_db_collection_add_item(c, i) _g_db_collection_add_item(c, i, true) +#define g_db_collection_modify_item(c, i) _g_db_collection_modify_item(c, i, true) + + + +/* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ + +/* Charge un ensemble d'éléments à partir d'une base de données. */ +bool g_db_collection_load_all_items(GDbCollection *, sqlite3 *); diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c index 6ff386c..a8182ce 100644 --- a/src/analysis/db/items/bookmark.c +++ b/src/analysis/db/items/bookmark.c @@ -28,11 +28,18 @@ #include <sys/socket.h> +#include "../collection-int.h" #include "../item-int.h" #include "../misc/rlestr.h" + + + +/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */ + + /* Signet à l'intérieur d'une zone de texte (instance) */ struct _GDbBookmark { @@ -81,48 +88,54 @@ static bool g_db_bookmark_prepare_db_statement(const GDbBookmark *, bool, bound_ -/****************************************************************************** -* * -* Paramètres : db = accès à la base de données. * -* * -* Description : Crée la table des signets dans une base de données. * -* * -* Retour : Bilan de l'opération. * -* * -* Remarques : - * -* * -******************************************************************************/ -bool create_bookmark_db_table(sqlite3 *db) + +/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */ + + + + +/* Collection dédiée aux signets (instance) */ +struct _GBookmarkCollection { - char *sql; /* Requête à exécuter */ - int ret; /* Bilan de la création */ - char *msg; /* Message d'erreur */ + GDbCollection parent; /* A laisser en premier */ - sql = "CREATE TABLE Bookmarks (" \ - SQLITE_DB_ITEM_CREATE \ - SQLITE_VMPA_CREATE \ - "comment TEXT" \ - ");"; +}; - ret = sqlite3_exec(db, sql, NULL, NULL, &msg); - if (ret != SQLITE_OK) - { - fprintf(stderr, "sqlite3_exec(): %s\n", msg); - sqlite3_free(msg); - } +/* Collection dédiée aux signets (classe) */ +struct _GBookmarkCollectionClass +{ + GDbCollectionClass parent; /* A laisser en premier */ - return (ret == SQLITE_OK); +}; -} +/* Initialise la classe des signets dans une zone de texte. */ +static void g_bookmark_collection_class_init(GBookmarkCollectionClass *); +/* Initialise un signet dans une zone de texte. */ +static void g_bookmark_collection_init(GBookmarkCollection *); +/* Supprime toutes les références externes. */ +static void g_bookmark_collection_dispose(GBookmarkCollection *); + +/* Procède à la libération totale de la mémoire. */ +static void g_bookmark_collection_finalize(GBookmarkCollection *); + +/* Décrit les colonnes utiles à un chargement de données. */ +static bool g_bookmark_collection_setup_load(GBookmarkCollection *, bound_value **, size_t *); +/* Charge les valeurs utiles pour une localisation. */ +static bool g_bookmark_collection_load_item(GBookmarkCollection *, const bound_value *, size_t); +/* Détermine si un élément est déjà présent ou non. */ +static GDbItem *g_bookmark_collection_has_key(GBookmarkCollection *, va_list *); +/* ---------------------------------------------------------------------------------- */ +/* ELABORATION D'UN ELEMENT DE COLLECTION */ +/* ---------------------------------------------------------------------------------- */ /* Indique le type défini pour un signet à l'intérieur d'une zone de texte. */ @@ -269,12 +282,12 @@ static gint g_db_bookmark_cmp(GDbBookmark *a, GDbBookmark *b) { gint result; /* Bilan de la comparaison */ - result = cmp_vmpa_by_phy(&a->addr, &b->addr); + result = cmp_vmpa(&a->addr, &b->addr); if (result == 0) result = cmp_rle_string(&a->comment, &b->comment); - return 0; + return result; } @@ -451,3 +464,307 @@ void g_db_bookmark_set_comment(GDbBookmark *bookmark, const char *comment) set_rle_string(&bookmark->comment, comment); } + + + +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION DE LA COLLECTION ASSOCIEE */ +/* ---------------------------------------------------------------------------------- */ + + +/* Indique le type défini pour une collection de signets. */ +G_DEFINE_TYPE(GBookmarkCollection, g_bookmark_collection, G_TYPE_DB_COLLECTION); + + +/****************************************************************************** +* * +* Paramètres : klass = classe à initialiser. * +* * +* Description : Initialise la classe des signets dans une zone de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmark_collection_class_init(GBookmarkCollectionClass *klass) +{ + GObjectClass *object; /* Autre version de la classe */ + GDbCollectionClass *collec; /* Encore une autre vision... */ + + object = G_OBJECT_CLASS(klass); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_bookmark_collection_dispose; + object->finalize = (GObjectFinalizeFunc)g_bookmark_collection_finalize; + + collec = G_DB_COLLECTION_CLASS(klass); + + collec->setup_load = (collec_setup_load_fc)g_bookmark_collection_setup_load; + collec-> load_item = (collec_load_item)g_bookmark_collection_load_item; + collec->has_key = (collec_has_key_fc)g_bookmark_collection_has_key; + +} + + +/****************************************************************************** +* * +* Paramètres : collec = instance à initialiser. * +* * +* Description : Initialise un signet dans une zone de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmark_collection_init(GBookmarkCollection *collec) +{ + + + G_DB_COLLECTION(collec)->featuring = 0; + G_DB_COLLECTION(collec)->type = G_TYPE_DB_BOOKMARK; + G_DB_COLLECTION(collec)->name = "Bookmarks"; + + + +} + + +/****************************************************************************** +* * +* Paramètres : collec = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmark_collection_dispose(GBookmarkCollection *collec) +{ + G_OBJECT_CLASS(g_bookmark_collection_parent_class)->dispose(G_OBJECT(collec)); + +} + + +/****************************************************************************** +* * +* Paramètres : bookmark = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_bookmark_collection_finalize(GBookmarkCollection *collec) +{ + G_OBJECT_CLASS(g_bookmark_collection_parent_class)->finalize(G_OBJECT(collec)); + +} + + +/****************************************************************************** +* * +* Paramètres : - * +* * +* Description : Crée une collection dédiée aux signets. * +* * +* Retour : Collection mise en place. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBookmarkCollection *g_bookmark_collection_new(void) +{ + GBookmarkCollection *result; /* Instance à retourner */ + + result = g_object_new(G_TYPE_BM_COLLECTION, NULL); + + return result; + +} + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : db = accès à la base de données. * +* * +* Description : Crée la table des signets dans une base de données. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool create_bookmark_db_table(sqlite3 *db) +{ + char *sql; /* Requête à exécuter */ + int ret; /* Bilan de la création */ + char *msg; /* Message d'erreur */ + + sql = "CREATE TABLE Bookmarks (" \ + SQLITE_DB_ITEM_CREATE \ + SQLITE_VMPA_CREATE \ + "comment TEXT" \ + ");"; + + ret = sqlite3_exec(db, sql, NULL, NULL, &msg); + if (ret != SQLITE_OK) + { + fprintf(stderr, "sqlite3_exec(): %s\n", msg); + sqlite3_free(msg); + } + + return (ret == SQLITE_OK); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à consulter. * +* values = tableau d'éléments à compléter. [OUT] * +* count = nombre de descriptions renseignées. [OUT] * +* * +* Description : Décrit les colonnes utiles à un chargement de données. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_bookmark_collection_setup_load(GBookmarkCollection *collec, bound_value **values, size_t *count) +{ + // TODO : classe supérieure + + if (!setup_load_for_vmpa(NULL, values, count)) + return false; + + *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); + + (*values)[*count - 1].name = "comment"; + + return true; + + +} + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à compléter. * +* values = tableau d'éléments à consulter. * +* count = nombre de descriptions renseignées. * +* * +* Description : Charge les valeurs utiles pour une localisation. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static bool g_bookmark_collection_load_item(GBookmarkCollection *collec, const bound_value *values, size_t count) +{ + vmpa2t addr; /* Localisation d'un signet */ + const char *comment; /* Eventuel commentaire associé*/ + const bound_value *value; /* Valeur à intégrer */ + GDbBookmark *new; /* Nouvel élément à intégrer */ + + if (!load_vmpa(&addr, values, count)) + return false; + + value = find_bound_value(values, count, "comment"); + if (value == NULL) return false; + + switch (value->type) + { + case SQLITE_TEXT: + comment = value->cstring; + break; + + case SQLITE_NULL: + comment = NULL; + break; + + default: + return false; + break; + + } + + new = g_db_bookmark_new(&addr, comment); + + printf(" LOAD new bm :: %p\n", new); + + return g_db_collection_add_item(G_DB_COLLECTION(collec), G_DB_ITEM(new)); + +} + + +/****************************************************************************** +* * +* Paramètres : collec = ensemble d'éléments à consulter. * +* ap = clef identifiant de manière unique un élément. * +* * +* Description : Détermine si un élément est déjà présent ou non. * +* * +* Retour : Elément trouvé ou NULL si aucun. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GDbItem *g_bookmark_collection_has_key(GBookmarkCollection *collec, va_list *ap) +{ + GDbItem *result; /* Bilan à retourner */ + vmpa2t *ref; /* Adresse de référence */ + GList *items; /* Eléments déjà en place */ + GList *iter; /* Boucle de parcours */ + GDbBookmark *bm; /* Signet à consulter */ + + result = NULL; + + ref = va_arg(ap, vmpa2t *); + + items = g_db_collection_list_items(G_DB_COLLECTION(collec)); + + for (iter = g_list_first(items); iter != NULL && result == NULL; iter = g_list_next(iter)) + { + bm = G_DB_BOOKMARK(iter->data); + + if (cmp_vmpa(&bm->addr, ref) != 0) + + /** + * Un verrou est sensé être posé, donc il n'y a pas besoin + * de toucher au décompte des références car l'élément trouvé + * ne peut pas être supprimé. + */ + result = G_DB_ITEM(bm); + + } + + return result; + +} diff --git a/src/analysis/db/items/bookmark.h b/src/analysis/db/items/bookmark.h index cd5e202..de12b1b 100644 --- a/src/analysis/db/items/bookmark.h +++ b/src/analysis/db/items/bookmark.h @@ -42,6 +42,7 @@ bool create_bookmark_db_table(sqlite3 *); +/* --------------------- ELABORATION D'UN ELEMENT DE COLLECTION --------------------- */ #define G_TYPE_DB_BOOKMARK g_db_bookmark_get_type() @@ -76,4 +77,30 @@ void g_db_bookmark_set_comment(GDbBookmark *, const char *); +/* ---------------------- DEFINITION DE LA COLLECTION ASSOCIEE ---------------------- */ + + +#define G_TYPE_BM_COLLECTION g_bookmark_collection_get_type() +#define G_BM_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_bookmark_collection_get_type(), GBookmarkCollection)) +#define G_IS_BM_COLLECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_bookmark_collection_get_type())) +#define G_BM_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BM_COLLECTION, GBookmarkCollectionClass)) +#define G_IS_BM_COLLECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BM_COLLECTION)) +#define G_BM_COLLECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BM_COLLECTION, GBookmarkCollectionClass)) + + +/* Collection dédiée aux signets (instance) */ +typedef struct _GBookmarkCollection GBookmarkCollection; + +/* Collection dédiée aux signets (classe) */ +typedef struct _GBookmarkCollectionClass GBookmarkCollectionClass; + + +/* Indique le type défini pour une collection de signets. */ +GType g_bookmark_collection_get_type(void); + +/* Crée une collection dédiée aux signets. */ +GBookmarkCollection *g_bookmark_collection_new(void); + + + #endif /* _ANALYSIS_DB_ITEMS_BOOKMARK_H */ diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c index 42688c8..04b0dc4 100644 --- a/src/analysis/db/server.c +++ b/src/analysis/db/server.c @@ -365,8 +365,10 @@ static void *g_db_server_listener(GDbServer *server) } + /* if (archive != NULL) error = g_cdb_archive_add_client(archive, fd, &user); + */ /** * Le serveur doit répondre pour un message type : @@ -382,7 +384,14 @@ static void *g_db_server_listener(GDbServer *server) if (!safe_send(fd, (uint32_t []) { htobe32(error) }, sizeof(uint32_t), 0)) goto gdsl_error; - if (error == DBE_NONE) continue; + //if (error == DBE_NONE) continue; + + + if (archive != NULL) + error = g_cdb_archive_add_client(archive, fd, &user); + + + gdsl_error: |