summaryrefslogtreecommitdiff
path: root/src/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'src/analysis')
-rw-r--r--src/analysis/binary.c67
-rw-r--r--src/analysis/binary.h4
-rwxr-xr-xsrc/analysis/db/Makefile.am1
-rw-r--r--src/analysis/db/cdb.c44
-rw-r--r--src/analysis/db/collection-int.h78
-rw-r--r--src/analysis/db/collection.c272
-rw-r--r--src/analysis/db/collection.h28
-rw-r--r--src/analysis/db/items/bookmark.c377
-rw-r--r--src/analysis/db/items/bookmark.h27
-rw-r--r--src/analysis/db/server.c11
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: