From a0a7b6c1e05c78ae433f353d15e3366107b67d03 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 18 Aug 2014 21:55:24 +0000
Subject: Inserted storages and collections into loaded binaries (first steps).

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@389 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                                      |  111 +++
 configure.ac                                   |    6 +-
 plugins/pychrysa/analysis/Makefile.am          |    2 +-
 plugins/pychrysa/analysis/binaries/file.c      |    2 +-
 plugins/pychrysa/analysis/db/Makefile.am       |   17 +
 plugins/pychrysa/analysis/db/collection.c      |  117 +++
 plugins/pychrysa/analysis/db/collection.h      |   42 +
 plugins/pychrysa/analysis/db/item.c            |  189 ++++
 plugins/pychrysa/analysis/db/item.h            |   42 +
 plugins/pychrysa/analysis/db/items/Makefile.am |   14 +
 plugins/pychrysa/analysis/db/items/comment.c   |  233 +++++
 plugins/pychrysa/analysis/db/items/comment.h   |   42 +
 plugins/pychrysa/analysis/db/items/module.c    |   91 ++
 plugins/pychrysa/analysis/db/items/module.h    |   39 +
 plugins/pychrysa/analysis/db/module.c          |   93 ++
 plugins/pychrysa/analysis/db/module.h          |   39 +
 plugins/pychrysa/arch/vmpa.c                   |   27 +-
 plugins/pychrysa/arch/vmpa.h                   |    6 +
 src/analysis/binary-int.h                      |    2 +
 src/analysis/binary.c                          |  194 +++-
 src/analysis/binary.h                          |   33 +-
 src/analysis/db/Makefile.am                    |   10 +-
 src/analysis/db/bookmark.c                     |   69 --
 src/analysis/db/bookmark.h                     |   41 -
 src/analysis/db/cdb.c                          |  427 ++++++++-
 src/analysis/db/cdb.h                          |   19 +-
 src/analysis/db/client.c                       |  272 +++++-
 src/analysis/db/client.h                       |   13 +-
 src/analysis/db/collection.c                   |  491 ++++++++++
 src/analysis/db/collection.h                   |   81 ++
 src/analysis/db/core.c                         |    6 +-
 src/analysis/db/item-int.h                     |   68 ++
 src/analysis/db/item.c                         |  356 +++++++
 src/analysis/db/item.h                         |   68 ++
 src/analysis/db/items/Makefile.am              |   17 +
 src/analysis/db/items/bookmark.c               |  416 +++++++++
 src/analysis/db/items/bookmark.h               |   79 ++
 src/analysis/db/items/comment.c                |  398 ++++++++
 src/analysis/db/items/comment.h                |   77 ++
 src/analysis/db/misc/Makefile.am               |   16 +
 src/analysis/db/misc/rlestr.c                  |  345 +++++++
 src/analysis/db/misc/rlestr.h                  |   83 ++
 src/analysis/db/protocol.h                     |  101 +-
 src/analysis/db/server.c                       |  262 ++++--
 src/arch/vmpa.h                                |    1 +
 src/common/io.c                                |  102 ++
 src/common/io.h                                |   11 +-
 src/core/Makefile.am                           |    1 +
 src/core/collections.c                         |  175 ++++
 src/core/collections.h                         |   54 ++
 src/core/core.c                                |    5 +
 src/core/params.c                              |   90 ++
 src/core/params.h                              |    6 +
 src/gui/panels/Makefile.am                     |    1 +
 src/gui/panels/bookmarks.c                     | 1179 ++++++++++++++++++++++++
 src/gui/panels/bookmarks.h                     |   65 ++
 src/gui/panels/panel.c                         |    4 +
 src/gui/panels/regedit.c                       |    2 +-
 58 files changed, 6446 insertions(+), 306 deletions(-)
 create mode 100644 plugins/pychrysa/analysis/db/Makefile.am
 create mode 100644 plugins/pychrysa/analysis/db/collection.c
 create mode 100644 plugins/pychrysa/analysis/db/collection.h
 create mode 100644 plugins/pychrysa/analysis/db/item.c
 create mode 100644 plugins/pychrysa/analysis/db/item.h
 create mode 100644 plugins/pychrysa/analysis/db/items/Makefile.am
 create mode 100644 plugins/pychrysa/analysis/db/items/comment.c
 create mode 100644 plugins/pychrysa/analysis/db/items/comment.h
 create mode 100644 plugins/pychrysa/analysis/db/items/module.c
 create mode 100644 plugins/pychrysa/analysis/db/items/module.h
 create mode 100644 plugins/pychrysa/analysis/db/module.c
 create mode 100644 plugins/pychrysa/analysis/db/module.h
 delete mode 100644 src/analysis/db/bookmark.c
 delete mode 100644 src/analysis/db/bookmark.h
 create mode 100644 src/analysis/db/item-int.h
 create mode 100644 src/analysis/db/item.c
 create mode 100644 src/analysis/db/item.h
 create mode 100644 src/analysis/db/items/Makefile.am
 create mode 100644 src/analysis/db/items/bookmark.c
 create mode 100644 src/analysis/db/items/bookmark.h
 create mode 100644 src/analysis/db/items/comment.c
 create mode 100644 src/analysis/db/items/comment.h
 create mode 100755 src/analysis/db/misc/Makefile.am
 create mode 100644 src/analysis/db/misc/rlestr.c
 create mode 100644 src/analysis/db/misc/rlestr.h
 create mode 100644 src/core/collections.c
 create mode 100644 src/core/collections.h
 create mode 100644 src/gui/panels/bookmarks.c
 create mode 100644 src/gui/panels/bookmarks.h

diff --git a/ChangeLog b/ChangeLog
index 8925f32..035b021 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,114 @@
+14-08-18  Cyrille Bagard <nocbos@gmail.com>
+
+	* configure.ac:
+	Extend the 'marshal' command. Add the new Makefiles from the
+	'plugins/pychrysa/analysis/db', 'plugins/pychrysa/analysis/db/items',
+	'src/analysis/db/items' and 'src/analysis/db/misc' directories.
+
+	* plugins/pychrysa/analysis/binaries/file.c:
+	Typo.
+
+	* plugins/pychrysa/analysis/db/collection.c:
+	* plugins/pychrysa/analysis/db/collection.h:
+	* plugins/pychrysa/analysis/db/item.c:
+	* plugins/pychrysa/analysis/db/item.h:
+	* plugins/pychrysa/analysis/db/items/comment.c:
+	* plugins/pychrysa/analysis/db/items/comment.h:
+	* plugins/pychrysa/analysis/db/items/Makefile.am:
+	* plugins/pychrysa/analysis/db/items/module.c:
+	* plugins/pychrysa/analysis/db/items/module.h:
+	* plugins/pychrysa/analysis/db/Makefile.am:
+	* plugins/pychrysa/analysis/db/module.c:
+	* plugins/pychrysa/analysis/db/module.h:
+	New entries: create new Python wrappers for items and collections.
+
+	* plugins/pychrysa/analysis/Makefile.am:
+	Add 'db' to SUBDIRS.
+
+	* plugins/pychrysa/arch/vmpa.c:
+	* plugins/pychrysa/arch/vmpa.h:
+	Give an access to the internal vmpa_t C definition.
+
+	* src/analysis/binary.c:
+	* src/analysis/binary.h:
+	* src/analysis/binary-int.h:
+	Insert storages and collections into loaded binaries (first steps).
+
+	* src/analysis/db/bookmark.c:
+	* src/analysis/db/bookmark.h:
+	Moved files. See 'items/bookmark.[ch]'.
+
+	* src/analysis/db/cdb.c:
+	* src/analysis/db/cdb.h:
+	* src/analysis/db/client.c:
+	* src/analysis/db/client.h:
+	Improve the archive and client definitions.
+
+	* src/analysis/db/collection.c:
+	* src/analysis/db/collection.h:
+	New entries: define generic collections.
+
+	* src/analysis/db/core.c:
+	Disable some code.
+
+	* src/analysis/db/item.c:
+	* src/analysis/db/item.h:
+	* src/analysis/db/item-int.h:
+	New entries: define generic items for collections.
+
+	* src/analysis/db/items/bookmark.c:
+	* src/analysis/db/items/bookmark.h:
+	* src/analysis/db/items/comment.c:
+	* src/analysis/db/items/comment.h:
+	* src/analysis/db/items/Makefile.am:
+	New entries: define the first definitions of real collected items.
+
+	* src/analysis/db/Makefile.am:
+	Remove the 'bookmark.[ch]' files from libanalysisdb_la_SOURCES and add 'item-int.h',
+	'item.[ch]' in place of them.
+
+	* src/analysis/db/misc/Makefile.am:
+	* src/analysis/db/misc/rlestr.c:
+	* src/analysis/db/misc/rlestr.h:
+	New entries: handle strings within network communications.
+
+	* src/analysis/db/protocol.h:
+	* src/analysis/db/server.c:
+	Improve the storage protocol and the server.
+
+	* src/arch/vmpa.h:
+	Fix a bug by adding a missing header.
+
+	* src/common/io.c:
+	* src/common/io.h:
+	Update code of inputs and outputs.
+
+	* src/core/collections.c:
+	* src/core/collections.h:
+	New entries: register collections for binaries storage.
+
+	* src/core/core.c:
+	Update code.
+
+	* src/core/Makefile.am:
+
+	* src/core/params.c:
+	* src/core/params.h:
+	Define more extra parameters for the main configuration.
+
+	* src/gui/panels/bookmarks.c:
+	* src/gui/panels/bookmarks.h:
+	New entries: create a new dialog for bookmarks. This part needs to be finished.
+
+	* src/gui/panels/Makefile.am:
+	Add the 'bookmark.[ch]' files to libguipanels_la_SOURCES.
+
+	* src/gui/panels/panel.c:
+	Update code.
+
+	* src/gui/panels/regedit.c:
+	Typo.
+
 14-08-16  Cyrille Bagard <nocbos@gmail.com>
 
 	* plugins/pychrysa/arch/vmpa.c:
diff --git a/configure.ac b/configure.ac
index 846cc82..9349f23 100644
--- a/configure.ac
+++ b/configure.ac
@@ -264,7 +264,7 @@ AC_SUBST(LIBGRAPH_LIBS)
 
 AC_CONFIG_FILES([stamp-h po/Makefile.in], [echo timestamp > stamp-h])
 
-AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT\nVOID:OBJECT,OBJECT" > src/glibext/chrysamarshal.list])
+AC_CONFIG_COMMANDS([marshal], [echo -e "VOID:UINT64\nVOID:UINT64,UINT64\nVOID:INT,UINT64,INT\nVOID:OBJECT\nVOID:OBJECT,OBJECT\nVOID:ENUM,OBJECT" > src/glibext/chrysamarshal.list])
 
 AC_CONFIG_FILES([Makefile
                  pixmaps/Makefile
@@ -275,6 +275,8 @@ AC_CONFIG_FILES([Makefile
                  plugins/pychrysa/analysis/Makefile
                  plugins/pychrysa/analysis/binaries/Makefile
                  plugins/pychrysa/analysis/blocks/Makefile
+                 plugins/pychrysa/analysis/db/Makefile
+                 plugins/pychrysa/analysis/db/items/Makefile
                  plugins/pychrysa/arch/Makefile
                  plugins/pychrysa/core/Makefile
                  plugins/pychrysa/debug/Makefile
@@ -296,6 +298,8 @@ AC_CONFIG_FILES([Makefile
                  src/analysis/binaries/Makefile
                  src/analysis/blocks/Makefile
                  src/analysis/db/Makefile
+                 src/analysis/db/items/Makefile
+                 src/analysis/db/misc/Makefile
                  src/analysis/decomp/Makefile
                  src/analysis/disass/Makefile
                  src/analysis/types/Makefile
diff --git a/plugins/pychrysa/analysis/Makefile.am b/plugins/pychrysa/analysis/Makefile.am
index 9b9ac18..7e18757 100644
--- a/plugins/pychrysa/analysis/Makefile.am
+++ b/plugins/pychrysa/analysis/Makefile.am
@@ -27,4 +27,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJE
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = binaries blocks
+SUBDIRS = binaries blocks db
diff --git a/plugins/pychrysa/analysis/binaries/file.c b/plugins/pychrysa/analysis/binaries/file.c
index 6bf553b..af285d9 100644
--- a/plugins/pychrysa/analysis/binaries/file.c
+++ b/plugins/pychrysa/analysis/binaries/file.c
@@ -79,7 +79,7 @@ static PyObject *py_binary_file_new(PyTypeObject *type, PyObject *args, PyObject
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : self    = NULL car méthode statique.                         *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
 *                closure = non utilisé ici.                                   *
 *                                                                             *
 *  Description : Fournit le chemin d'accès au binaire représenté.             *
diff --git a/plugins/pychrysa/analysis/db/Makefile.am b/plugins/pychrysa/analysis/db/Makefile.am
new file mode 100644
index 0000000..e33130f
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisdb.la
+
+libpychrysaanalysisdb_la_SOURCES =		\
+	collection.h collection.c			\
+	item.h item.c						\
+	module.h module.c
+
+libpychrysaanalysisdb_la_LDFLAGS = 
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+	-I../../../../src
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = items
diff --git a/plugins/pychrysa/analysis/db/collection.c b/plugins/pychrysa/analysis/db/collection.c
new file mode 100644
index 0000000..87d46e5
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/collection.c
@@ -0,0 +1,117 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * collection.c - équivalent Python du fichier "analysis/db/collection.c"
+ *
+ * Copyright (C) 2012 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "collection.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/db/collection.h>
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_db_collection_type(void)
+{
+    static PyMethodDef py_db_collection_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_db_collection_getseters[] = {
+
+        { NULL }
+
+    };
+
+    static PyTypeObject py_db_collection_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.db.DbCollection",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide collection for DataBase collection",
+
+        .tp_methods     = py_db_collection_methods,
+        .tp_getset      = py_db_collection_getseters,
+
+    };
+
+    return &py_db_collection_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....db.DbCollection'.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_db_collection(PyObject *module)
+{
+    PyTypeObject *py_db_collection_type;    /* Type Python 'DbCollection'  */
+    int ret;                                /* Bilan d'un appel            */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_db_collection_type = get_python_db_collection_type();
+
+    py_db_collection_type->tp_base = &PyGObject_Type;
+    py_db_collection_type->tp_basicsize = py_db_collection_type->tp_base->tp_basicsize;
+
+    if (PyType_Ready(py_db_collection_type) != 0)
+        return false;
+
+    Py_INCREF(py_db_collection_type);
+    ret = PyModule_AddObject(module, "DbCollection", (PyObject *)py_db_collection_type);
+    if (ret != 0) return false;
+
+    dict = PyModule_GetDict(module);
+    pygobject_register_class(dict, "DbCollection", G_TYPE_DB_COLLECTION, py_db_collection_type,
+                             Py_BuildValue("(O)", py_db_collection_type->tp_base));
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/analysis/db/collection.h b/plugins/pychrysa/analysis/db/collection.h
new file mode 100644
index 0000000..cb9a88a
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/collection.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * collection.h - prototypes pour l'équivalent Python du fichier "analysis/db/collection.h"
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_ANALYSIS_DB_COLLECTION_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_DB_COLLECTION_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_db_collection_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.db.DbCollection'. */
+bool register_python_db_collection(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_ANALYSIS_DB_COLLECTIONS_H */
diff --git a/plugins/pychrysa/analysis/db/item.c b/plugins/pychrysa/analysis/db/item.c
new file mode 100644
index 0000000..4f536b4
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/item.c
@@ -0,0 +1,189 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * item.c - équivalent Python du fichier "analysis/db/item.c"
+ *
+ * Copyright (C) 2012 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "item.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/db/item.h>
+
+
+
+/* Indique si l'élément contient des données à oublier ou non. */
+static PyObject *py_db_item_get_volatile(PyObject *, void *);
+
+/* Définit si l'élément contient des données à oublier ou non. */
+static int py_db_item_set_volatile(PyObject *, PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Indique si l'élément contient des données à oublier ou non.  *
+*                                                                             *
+*  Retour      : Etat de la sauegarde de l'élément consulté.                  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_item_get_volatile(PyObject *self, void *closure)
+{
+    PyObject *result;                       /* Valeur à retourner          */
+    GDbItem *item;                          /* Elément à consulter         */
+
+    item = G_DB_ITEM(pygobject_get(self));
+
+    result = (g_db_item_is_volatile(item) ? Py_True : Py_False);
+    Py_INCREF(result);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                value   = valeur fournie à intégrer ou prendre en compte.    *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Définit si l'élément contient des données à oublier ou non.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération pour Python.                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_db_item_set_volatile(PyObject *self, PyObject *value, void *closure)
+{
+    GDbItem *item;                          /* Elément à modifier          */
+
+    if (!PyBool_Check(value))
+    {
+        PyErr_SetString(PyExc_TypeError, _("The attribute value must be a boolean."));
+        return -1;
+    }
+
+    item = G_DB_ITEM(pygobject_get(self));
+    g_db_item_set_volatile(item, (bool)(value == Py_True));
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_db_item_type(void)
+{
+    static PyMethodDef py_db_item_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_db_item_getseters[] = {
+
+        {
+            "volatile", py_db_item_get_volatile, py_db_item_set_volatile,
+            "Define if a Database item can be forgotten.", NULL
+        },
+        { NULL }
+
+    };
+
+    static PyTypeObject py_db_item_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.db.DbItem",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+
+        .tp_doc         = "PyChrysalide item for DataBase collection",
+
+        .tp_methods     = py_db_item_methods,
+        .tp_getset      = py_db_item_getseters,
+
+    };
+
+    return &py_db_item_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....db.items.DbItem'.   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_db_item(PyObject *module)
+{
+    PyTypeObject *py_db_item_type;          /* Type Python 'DbItem'        */
+    int ret;                                /* Bilan d'un appel            */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_db_item_type = get_python_db_item_type();
+
+    py_db_item_type->tp_base = &PyGObject_Type;
+    py_db_item_type->tp_basicsize = py_db_item_type->tp_base->tp_basicsize;
+
+    if (PyType_Ready(py_db_item_type) != 0)
+        return false;
+
+    Py_INCREF(py_db_item_type);
+    ret = PyModule_AddObject(module, "DbItem", (PyObject *)py_db_item_type);
+    if (ret != 0) return false;
+
+    dict = PyModule_GetDict(module);
+    pygobject_register_class(dict, "DbItem", G_TYPE_DB_ITEM, py_db_item_type,
+                             Py_BuildValue("(O)", py_db_item_type->tp_base));
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/analysis/db/item.h b/plugins/pychrysa/analysis/db/item.h
new file mode 100644
index 0000000..eff0d04
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/item.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * item.h - prototypes pour l'équivalent Python du fichier "analysis/db/item.h"
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEM_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEM_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_db_item_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.db.DbItem'. */
+bool register_python_db_item(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEM_H */
diff --git a/plugins/pychrysa/analysis/db/items/Makefile.am b/plugins/pychrysa/analysis/db/items/Makefile.am
new file mode 100644
index 0000000..b08a558
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/items/Makefile.am
@@ -0,0 +1,14 @@
+
+noinst_LTLIBRARIES = libpychrysaanalysisdbitems.la
+
+libpychrysaanalysisdbitems_la_SOURCES =	\
+	comment.h comment.c					\
+	module.h module.c
+
+libpychrysaanalysisdbitems_la_LDFLAGS = 
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBPYTHON_CFLAGS) $(LIBPYGOBJECT_CFLAGS) \
+	-I../../../../../src
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
diff --git a/plugins/pychrysa/analysis/db/items/comment.c b/plugins/pychrysa/analysis/db/items/comment.c
new file mode 100644
index 0000000..1bb2863
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/items/comment.c
@@ -0,0 +1,233 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * comment.c - équivalent Python du fichier "analysis/db/items/comment.c"
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "comment.h"
+
+
+#include <pygobject.h>
+
+
+#include <i18n.h>
+#include <analysis/db/items/comment.h>
+
+
+#include "../item.h"
+#include "../../../arch/vmpa.h"
+
+
+
+/* Crée un nouvel objet Python de type 'DbComment'. */
+static PyObject *py_db_comment_new(PyTypeObject *, PyObject *, PyObject *);
+
+/* Fournit le commentaire associé à un commentaire. */
+static PyObject *py_db_comment_get_text(PyObject *, void *);
+
+/* Définit le commentaire associé à un commentaire. */
+static int py_db_comment_set_text(PyObject *, PyObject *, void *);
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : type = type de l'objet à instancier.                         *
+*                args = arguments fournis à l'appel.                          *
+*                kwds = arguments de type key=val fournis.                    *
+*                                                                             *
+*  Description : Crée un nouvel objet Python de type 'DbComment'.             *
+*                                                                             *
+*  Retour      : Instance Python mise en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_comment_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+    PyObject *result;                       /* Instance à retourner        */
+    PyObject *py_vmpa;                      /* Localisation version Python */
+    char *text;                             /* Texte à associer            */
+    int is_volatile;                        /* Conservation en mémoire     */
+    int ret;                                /* Bilan de lecture des args.  */
+    vmpa2t *addr;                           /* Localisation version C      */
+    GDbComment *comment;                    /* Version GLib du commentaire */
+
+    ret = PyArg_ParseTuple(args, "Osp", &py_vmpa, &text, &is_volatile);
+    if (!ret) Py_RETURN_NONE;
+
+    addr = get_internal_vmpa(py_vmpa);
+    if (py_vmpa == NULL) Py_RETURN_NONE;
+
+    comment = g_db_comment_new(addr, text, is_volatile);
+
+    result = pygobject_new(G_OBJECT(comment));
+    g_object_unref(comment);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Fournit le commentaire associé à un commentaire.             *
+*                                                                             *
+*  Retour      : Texte manipulable en Python.                                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static PyObject *py_db_comment_get_text(PyObject *self, void *closure)
+{
+    GDbComment *comment;                    /* Commentaire à consulter     */
+    const char *content;                    /* Contenu textuel associé     */
+
+    comment = G_DB_COMMENT(pygobject_get(self));
+    content = g_db_comment_get_text(comment);
+
+    return PyUnicode_FromString(content);
+
+}
+
+
+/*********************d*********************************************************
+*                                                                             *
+*  Paramètres  : self    = objet Python concerné par l'appel.                 *
+*                value   = valeur fournie à intégrer ou prendre en compte.    *
+*                closure = non utilisé ici.                                   *
+*                                                                             *
+*  Description : Définit le commentaire associé à un commentaire.             *
+*                                                                             *
+*  Retour      : Bilan de l'opération pour Python.                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static int py_db_comment_set_text(PyObject *self, PyObject *value, void *closure)
+{
+    GDbComment *comment;                    /* Commentaire à consulter     */
+
+    if (!PyUnicode_Check(value))
+    {
+        PyErr_SetString(PyExc_TypeError, _("The attribute value must be a string."));
+        return -1;
+    }
+
+    comment = G_DB_COMMENT(pygobject_get(self));
+    g_db_comment_set_text(comment, PyUnicode_DATA(value));
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Fournit un accès à une définition de type à diffuser.        *
+*                                                                             *
+*  Retour      : Définition d'objet pour Python.                              *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+PyTypeObject *get_python_db_comment_type(void)
+{
+    static PyMethodDef py_db_comment_methods[] = {
+        { NULL }
+    };
+
+    static PyGetSetDef py_db_comment_getseters[] = {
+        {
+            "text", py_db_comment_get_text, py_db_comment_set_text,
+            "Give access to the content of a given comment.", NULL
+        },
+        { NULL }
+    };
+
+    static PyTypeObject py_db_comment_type = {
+
+        PyVarObject_HEAD_INIT(NULL, 0)
+
+        .tp_name        = "pychrysalide.analysis.db.items.DbComment",
+        .tp_basicsize   = sizeof(PyGObject),
+
+        .tp_flags       = Py_TPFLAGS_DEFAULT,
+
+        .tp_doc         = "PyChrysalide comment for edited binary",
+
+        .tp_methods     = py_db_comment_methods,
+        .tp_getset      = py_db_comment_getseters,
+        .tp_new         = (newfunc)py_db_comment_new
+
+    };
+
+    return &py_db_comment_type;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Prend en charge l'objet 'pychrysalide....db.items.DbComment'.*
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool register_python_db_comment(PyObject *module)
+{
+    PyTypeObject *py_db_comment_type;      /* Type Python 'DbComment'      */
+    int ret;                                /* Bilan d'un appel            */
+    PyObject *dict;                         /* Dictionnaire du module      */
+
+    py_db_comment_type = get_python_db_comment_type();
+
+    py_db_comment_type->tp_base = get_python_db_item_type();
+    py_db_comment_type->tp_basicsize = py_db_comment_type->tp_base->tp_basicsize;
+
+    if (PyType_Ready(py_db_comment_type) != 0)
+        return false;
+
+    Py_INCREF(py_db_comment_type);
+    ret = PyModule_AddObject(module, "DbComment", (PyObject *)py_db_comment_type);
+    if (ret != 0) return false;
+
+    dict = PyModule_GetDict(module);
+    pygobject_register_class(dict, "DbComment", G_TYPE_DB_COMMENT, py_db_comment_type,
+                             Py_BuildValue("(O)", py_db_comment_type->tp_base));
+
+    return true;
+
+}
diff --git a/plugins/pychrysa/analysis/db/items/comment.h b/plugins/pychrysa/analysis/db/items/comment.h
new file mode 100644
index 0000000..db02dca
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/items/comment.h
@@ -0,0 +1,42 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * comment.h - prototypes pour l'équivalent Python du fichier "analysis/db/items/comment.h"
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEMS_COMMENT_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEMS_COMMENT_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Fournit un accès à une définition de type à diffuser. */
+PyTypeObject *get_python_db_comment_type(void);
+
+/* Prend en charge l'objet 'pychrysalide.analysis.db.items.DbComment'. */
+bool register_python_db_comment(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEMS_COMMENT_H */
diff --git a/plugins/pychrysa/analysis/db/items/module.c b/plugins/pychrysa/analysis/db/items/module.c
new file mode 100644
index 0000000..3c634e3
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/items/module.c
@@ -0,0 +1,91 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire items en tant que module
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "module.h"
+
+
+#include "comment.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Ajoute le module 'items' au module Python.                   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_analysis_db_items_module_to_python_module(PyObject *super)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Sous-module mis en place    */
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyModuleDef py_chrysalide_items_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.analysis.db.items",
+        .m_doc = "Python module for Chrysalide.analysis.db.items",
+
+        .m_size = -1,
+
+    };
+
+    result = false;
+
+    module = PyModule_Create(&py_chrysalide_items_module);
+    if (module == NULL) return false;
+
+    ret = PyState_AddModule(super, &py_chrysalide_items_module);
+    if (ret != 0) goto aadimtpm_exit;
+
+    ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.db.items");
+    if (ret != 0) goto aadimtpm_exit;
+
+    Py_INCREF(module);
+    ret = PyModule_AddObject(super, "items", module);
+    if (ret != 0) goto aadimtpm_exit;
+
+    result = true;
+
+    result &= register_python_db_comment(module);
+
+ aadimtpm_exit:
+
+    if (!result)
+    {
+        printf("something went wrong in %s...\n", __FUNCTION__);
+        /* ... */
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysa/analysis/db/items/module.h b/plugins/pychrysa/analysis/db/items/module.h
new file mode 100644
index 0000000..d780d30
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/items/module.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire items en tant que module
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEMS_MODULE_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEMS_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'items' au module Python. */
+bool add_analysis_db_items_module_to_python_module(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_ANALYSIS_DB_ITEMS_MODULE_H */
diff --git a/plugins/pychrysa/analysis/db/module.c b/plugins/pychrysa/analysis/db/module.c
new file mode 100644
index 0000000..8c527a9
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/module.c
@@ -0,0 +1,93 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.c - intégration du répertoire db en tant que module
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "module.h"
+
+
+#include "collection.h"
+#include "item.h"
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : module = module dont la définition est à compléter.          *
+*                                                                             *
+*  Description : Ajoute le module 'db' au module Python.                      *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool add_analysis_db_module_to_python_module(PyObject *super)
+{
+    bool result;                            /* Bilan à retourner           */
+    PyObject *module;                       /* Sous-module mis en place    */
+    int ret;                                /* Bilan d'un appel            */
+
+    static PyModuleDef py_chrysalide_db_module = {
+
+        .m_base = PyModuleDef_HEAD_INIT,
+
+        .m_name = "pychrysalide.analysis.db",
+        .m_doc = "Python module for Chrysalide.analysis.db",
+
+        .m_size = -1,
+
+    };
+
+    result = false;
+
+    module = PyModule_Create(&py_chrysalide_db_module);
+    if (module == NULL) return false;
+
+    ret = PyState_AddModule(super, &py_chrysalide_db_module);
+    if (ret != 0) goto aadmtpm_exit;
+
+    ret = _PyImport_FixupBuiltin(module, "pychrysalide.analysis.db");
+    if (ret != 0) goto aadmtpm_exit;
+
+    Py_INCREF(module);
+    ret = PyModule_AddObject(super, "db", module);
+    if (ret != 0) goto aadmtpm_exit;
+
+    result = true;
+
+    result &= register_python_db_collection(module);
+    result &= register_python_db_item(module);
+
+ aadmtpm_exit:
+
+    if (!result)
+    {
+        printf("something went wrong in %s...\n", __FUNCTION__);
+        /* ... */
+
+    }
+
+    return result;
+
+}
diff --git a/plugins/pychrysa/analysis/db/module.h b/plugins/pychrysa/analysis/db/module.h
new file mode 100644
index 0000000..d85c092
--- /dev/null
+++ b/plugins/pychrysa/analysis/db/module.h
@@ -0,0 +1,39 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * module.h - prototypes pour l'intégration du répertoire db en tant que module
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _PLUGINS_PYCHRYSA_ANALYSIS_DB_MODULE_H
+#define _PLUGINS_PYCHRYSA_ANALYSIS_DB_MODULE_H
+
+
+#include <Python.h>
+#include <stdbool.h>
+
+
+
+/* Ajoute le module 'db' au module Python. */
+bool add_analysis_db_module_to_python_module(PyObject *);
+
+
+
+#endif  /* _PLUGINS_PYCHRYSA_ANALYSIS_DB_MODULE_H */
diff --git a/plugins/pychrysa/arch/vmpa.c b/plugins/pychrysa/arch/vmpa.c
index f9a9db7..43131b5 100644
--- a/plugins/pychrysa/arch/vmpa.c
+++ b/plugins/pychrysa/arch/vmpa.c
@@ -28,7 +28,6 @@
 #include <string.h>
 
 
-#include <src/arch/vmpa.h>
 
 
 
@@ -544,8 +543,6 @@ PyTypeObject *get_python_vmpa_type(void)
 }
 
 
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : module = module dont la définition est à compléter.          *
@@ -574,3 +571,27 @@ bool register_python_vmpa(PyObject *module)
     return (ret == 0);
 
 }
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : obj = objet Python à traiter.                                *
+*                                                                             *
+*  Description : Donne accès au coeur d'un objet 'pychrysalide.arch.vmpa'.    *
+*                                                                             *
+*  Retour      : Localistion réelle ou NULL en cas de mauvaise conversion.    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+vmpa2t *get_internal_vmpa(PyObject *obj)
+{
+    int ret;                                /* Bilan d'analyse             */
+
+    ret = PyObject_IsInstance(obj, (PyObject *)get_python_vmpa_type());
+    if (!ret) return NULL;
+
+    return &((py_vmpa_t *)obj)->addr;
+
+}
diff --git a/plugins/pychrysa/arch/vmpa.h b/plugins/pychrysa/arch/vmpa.h
index 6ee00b2..8635b51 100644
--- a/plugins/pychrysa/arch/vmpa.h
+++ b/plugins/pychrysa/arch/vmpa.h
@@ -30,6 +30,9 @@
 #include <stdbool.h>
 
 
+#include <src/arch/vmpa.h>
+
+
 
 /* Fournit un accès à une définition de type à diffuser. */
 PyTypeObject *get_python_vmpa_type(void);
@@ -37,6 +40,9 @@ PyTypeObject *get_python_vmpa_type(void);
 /* Prend en charge l'objet 'pychrysalide.arch.vmpa'. */
 bool register_python_vmpa(PyObject *);
 
+/* Donne accès au coeur d'un objet 'pychrysalide.arch.vmpa'. */
+vmpa2t *get_internal_vmpa(PyObject *);
+
 
 
 #endif  /* _PLUGINS_PYCHRYSALIDE_ARCH_VMPA_H */
diff --git a/src/analysis/binary-int.h b/src/analysis/binary-int.h
index 6361a0c..28d4594 100644
--- a/src/analysis/binary-int.h
+++ b/src/analysis/binary-int.h
@@ -53,7 +53,9 @@ struct _GLoadedBinary
 
     GDbClient *local;                       /* Enregistrements locaux      */
     GDbClient *remote;                      /* Enregistrements distants    */
+
     DBStorage storages[DBF_COUNT];          /* Lieux d'enregistrement      */
+    GList *collections;                     /* Ensemble de modifications   */
 
     save_binary_fc save;                    /* Sauvegarde au format XML    */
     get_binary_name_fc get_name;            /* Obtention d'une description */
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index 83e81d8..5577bb8 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -40,6 +40,7 @@
 #include "disass/disassembler.h"
 #include "../common/extstr.h"
 #include "../common/cpp.h"
+#include "../core/params.h"
 
 
 
@@ -222,11 +223,20 @@ 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         */
     char *type;                             /* Type de binaire à charger   */
+
+
+
+    char *host;                             /* Nom du serveur à contacter  */
+    int port;                               /* Numéro du port associé      */
+    char *author;                           /* Identification à diffuser   */
+
+
+
     bool status;                            /* Etat de la connexion à la BD*/
 
     result = NULL;
@@ -241,16 +251,101 @@ GLoadedBinary *g_loaded_binary_new_from_xml(xmlXPathContextPtr context, const ch
     if (result == NULL)
         return NULL;
 
+    /* --------- %< --------- TODO : à bouger pur + de générique --------- %< --------- */
+
+
+    result->collections = create_collections_list();
+
+
     if (!g_loaded_binary_load_storage(result, context, path))
         goto glbnfx_error;
 
+
+    /* --------- %< --------- TODO : à bouger pur + de générique --------- %< --------- */
+
+
+
     /*
     if (!g_loaded_binary_load_parts_from_xml(result, context, path))
         goto glbnfx_error;
     */
 
-    result->local = g_db_client_new("localhost", 1337);
-    status = g_db_client_start(result->local);
+
+    printf("data :: %p  length :: %d\n", result->bin_data, result->bin_length);
+
+
+
+    /* Détermination de l'identifiant */
+
+    result->checksum = g_checksum_new(G_CHECKSUM_SHA256);
+    g_checksum_update(result->checksum, result->bin_data, result->bin_length);
+
+
+    result->local = g_db_client_new(g_loaded_binary_get_cheksum(result), result->collections);
+
+
+    if (!g_generic_config_get_value(get_main_configuration(), MPK_LOCAL_HOST, &host))
+        /* ... */;
+
+    if (!g_generic_config_get_value(get_main_configuration(), MPK_LOCAL_PORT, &port))
+        /* ... */;
+
+    if (!g_generic_config_get_value(get_main_configuration(), MPK_AUTHOR_NAME, &author))
+        /* ... */;
+
+
+    status = g_db_client_start(result->local, host, port, author);
+
+
+
+
+
+    /* --------- %< --------- %< --------- %< --------- %< --------- */
+
+    do
+    {
+        vmpa2t addr;
+        GDbBookmark *bm;
+        bool status;
+
+
+        init_vmpa(&addr, 123, 0x200);
+
+        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");
+
+
+        /*
+        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);
 
@@ -872,6 +967,97 @@ void g_loaded_binary_set_storage(GLoadedBinary *binary, DBFeatures feature, DBSt
 
 
 
+/* ---------------------------------------------------------------------------------- */
+/*                            MANIPULATION DES COLLECTIONS                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary  = élément binaire à consulter.                       *
+*                feature = fonctionnalité assurée par la collection visée.    *
+*                                                                             *
+*  Description : Trouve une collection assurant une fonctionnalité donnée.    *
+*                                                                             *
+*  Retour      : Collection trouvée ou NULL.                                  *
+*                                                                             *
+*  Remarques   : Le résultat est à déréfrencer après usage.                   *
+*                                                                             *
+******************************************************************************/
+
+GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *binary, DBFeatures feature)
+{
+    GDbCollection *result;                  /* Collection à retourner      */
+
+    /* TODO : lock */
+
+    result = find_collection_in_list(binary->collections, feature);
+
+    if (result != NULL)
+        g_object_ref(G_OBJECT(result));
+
+    /* TODO : unlock */
+
+    return result;
+
+}
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary  = élément binaire à consulter.                       *
+*                feature = fonctionnalité visée par la requête.               *
+*                item    = élémnent à pousser vers un serveur de collection.  *
+*                                                                             *
+*  Description : Demande l'intégration d'une modification dans une collection.*
+*                                                                             *
+*  Retour      : Bilan partiel de l'opération demandée.                       *
+*                                                                             *
+*  Remarques   : L'appelant perd la propriété de l'élément à ajouté.          *
+*                                                                             *
+******************************************************************************/
+
+bool g_loaded_binary_add_to_collection(GLoadedBinary *binary, DBFeatures feature, GDbItem *item)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    GDbCollection *collec;                  /* Collection visée au final   */
+    DBStorage storage;                      /* Forme d'enregistrement      */
+    GDbClient *client;                      /* Liaison à utiliser          */
+    int fd;                                 /* Identifiant du canal de com.*/
+
+    collec = g_loaded_binary_find_collection(binary, feature);
+    if (collec == NULL) return false;
+
+    /* S'il n'y a pas besoin de sauvegarde... */
+    if (g_db_item_is_volatile(item))
+        g_db_collection_add_item(collec, item);
+
+    /* Sinon on envoie par le réseau ! */
+    else
+    {
+        storage = g_loaded_binary_get_storage(binary, feature);
+
+
+        /* TODO : sélection du bon client... */
+        client = binary->local;
+
+
+        fd = g_db_client_get_fd(client);
+
+        result = g_db_collection_send(collec, fd, DBA_ADD_ITEM, item);
+
+        g_db_client_put_fd(client);
+
+    }
+
+    g_object_unref(G_OBJECT(collec));
+    g_object_unref(G_OBJECT(item));
+
+    return result;
+
+}
+
 
 
 
@@ -946,8 +1132,10 @@ void g_loaded_binary_analyse(GLoadedBinary *binary)
 
     /* Détermination de l'identifiant */
 
+    /* déplacé
     binary->checksum = g_checksum_new(G_CHECKSUM_SHA256);
     g_checksum_update(binary->checksum, binary->bin_data, binary->bin_length);
+    */
 
     /* Contacts avec les serveurs */
 
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index dbadd64..2a7e7d9 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -28,7 +28,8 @@
 #include <glib-object.h>
 #include <stdbool.h>
 
-
+#include "db/collection.h"
+#include "db/item.h"
 #include "db/protocol.h"
 #include "../arch/processor.h"
 #include "../common/xml.h"
@@ -108,10 +109,40 @@ void g_loaded_binary_set_storage(GLoadedBinary *, DBFeatures, DBStorage);
 
 
 
+/* ------------------------- INFORMATIONS D'ENREGISTREMENTS ------------------------- */
+/* -------------------------- MANIPULATION DES COLLECTIONS -------------------------- */
+
+
+
+
+/* Trouve une collection assurant une fonctionnalité donnée. */
+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 *);
+
+
+
+
+
+#define g_loaded_binary_remove_from_collection(b, f, i)
+
+
+/**
+ * TODO :
+ *
+ * - connect_signal
+ * - add_obj
+ *
+ */
+
+
+
 
 
 
 /* Définit les parties de binaire à analyser. */
+
 void g_loaded_binary_set_parts(GLoadedBinary *, BinaryPartModel, GBinPart **, size_t);
 
 /* Fournit les parties de binaire analysées. */
diff --git a/src/analysis/db/Makefile.am b/src/analysis/db/Makefile.am
index ef98a24..6852821 100755
--- a/src/analysis/db/Makefile.am
+++ b/src/analysis/db/Makefile.am
@@ -2,15 +2,19 @@
 noinst_LTLIBRARIES  = libanalysisdb.la
 
 libanalysisdb_la_SOURCES =				\
-	bookmark.h bookmark.c				\
 	cdb.h cdb.c							\
 	client.h client.c					\
 	collection.h collection.c			\
 	core.h core.c						\
+	item-int.h							\
+	item.h item.c						\
 	protocol.h							\
 	server.h server.c
 
-libanalysisdb_la_LIBADD =	
+libanalysisdb_la_LIBADD =				\
+	items/libanalysisdbitems.la			\
+	misc/libanalysisdbmisc.la
+
 
 libanalysisdb_la_LDFLAGS = 
 
@@ -19,4 +23,4 @@ AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE
 
 AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
 
-SUBDIRS = 
+SUBDIRS = items misc
diff --git a/src/analysis/db/bookmark.c b/src/analysis/db/bookmark.c
deleted file mode 100644
index 9a46a0d..0000000
--- a/src/analysis/db/bookmark.c
+++ /dev/null
@@ -1,69 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * bookmark.h - prototypes pour la gestion des signets au sein d'un binaire
- *
- * Copyright (C) 2014 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/>.
- */
-
-
-#include "bookmark.h"
-
-
-#include <malloc.h>
-
-
-
-
-
-
-/******************************************************************************
-*                                                                             *
-*  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 ("            \
-             "id INT PRIMARY KEY NOT NULL, "    \
-             "user TEXT NOT NULL, "             \
-             "created INT NOT NULL, "           \
-             "address INT NOT NULL, "           \
-             "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);
-
-}
diff --git a/src/analysis/db/bookmark.h b/src/analysis/db/bookmark.h
deleted file mode 100644
index 5308e92..0000000
--- a/src/analysis/db/bookmark.h
+++ /dev/null
@@ -1,41 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * bookmark.h - prototypes pour la gestion des signets au sein d'un binaire
- *
- * Copyright (C) 2014 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_BOOKMARK_H
-#define _ANALYSIS_DB_BOOKMARK_H
-
-
-
-#include <sqlite3.h>
-#include <stdbool.h>
-
-
-
-/* Crée la table des signets dans une base de données. */
-bool create_bookmark_db_table(sqlite3 *);
-
-
-
-
-
-#endif  /* _ANALYSIS_DB_BOOKMARK_H */
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index 7e530ac..563aa40 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -28,7 +28,11 @@
 #include <archive_entry.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <limits.h>
 #include <malloc.h>
+#include <poll.h>
+#include <pthread.h>
+#include <signal.h>
 #include <stdio.h>
 #include <sqlite3.h>
 #include <string.h>
@@ -39,8 +43,9 @@
 #include <config.h>
 
 
-#include "bookmark.h"
+#include "collection.h"
 #include "protocol.h"
+#include "items/bookmark.h"
 #include "../../common/cpp.h"
 #include "../../common/extstr.h"
 #include "../../common/io.h"
@@ -53,13 +58,26 @@
 #define ARCHIVE_RBUF_SIZE 2048
 
 
+
+
+
+/* Informations relatives à un client */
+typedef struct _cdb_client
+{
+    int fd;                                 /* Canal de communication      */
+    rle_string user;                        /* Utilisateur à l'autre bout  */
+
+    uint64_t last_time;                     /* Date de dernier envoi       */
+
+} cdb_client;
+
+
 /* Description d'une archive d'éléments utilisateur (instance) */
 struct _GCdbArchive
 {
     GObject parent;                         /* A laisser en premier        */
 
-    char hash[65];                          /* Empreinte SHA256            */
-
+    rle_string hash;                        /* Empreinte cryptographique   */
 
     char *filename;                         /* Chemin d'accès à l'archive  */
 
@@ -71,6 +89,15 @@ struct _GCdbArchive
 
     sqlite3 *db;                            /* Base de données à manipuler */
 
+    GList *collections;                     /* Ensemble de modifications   */
+
+    cdb_client *clients;                    /* Connexions en place         */
+    size_t count;                           /* Quantité de clients         */
+    GMutex clients_access;                  /* Verrou pour l'accès         */
+
+    GThread *process;                       /* Procédure de traitement     */
+    pthread_t process_id;                   /* Identifiant de la procédure */
+
 };
 
 /* Description d'une archive d'éléments utilisateur (classe) */
@@ -101,7 +128,8 @@ static bool g_cdb_archive_read(GCdbArchive *);
 
 
 /* Crée la description XML correspondant à l'archive. */
-static bool g_cdb_archive_create_xml_desc(GCdbArchive *, const core_db_info *);
+static bool g_cdb_archive_create_xml_desc(GCdbArchive *, const rle_string *);
+
 
 
 
@@ -112,6 +140,22 @@ static bool g_cdb_archive_create_db(const GCdbArchive *, const core_db_info *);
 
 
 
+/////////////////////////:
+
+
+/* Crée et remplit les collections à partir de leurs bases. */
+static bool g_cdb_archive_load_collections(GCdbArchive *);
+
+/* Réagit à une modification au sein d'une collection donnée. */
+static void on_collection_changed(GDbCollection *, DBAction, GDbItem *, GCdbArchive *);
+
+/* Assure le traitement des requêtes de clients. */
+static void *g_cdb_archive_process(GCdbArchive *);
+
+
+
+
+
 
 /* Indique le type défini pour une une archive d'éléments utilisateur. */
 G_DEFINE_TYPE(GCdbArchive, g_cdb_archive, G_TYPE_OBJECT);
@@ -155,6 +199,7 @@ static void g_cdb_archive_class_init(GCdbArchiveClass *klass)
 
 static void g_cdb_archive_init(GCdbArchive *archive)
 {
+    g_mutex_init(&archive->clients_access);
 
 }
 
@@ -203,19 +248,21 @@ static void g_cdb_archive_finalize(GCdbArchive *archive)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : local  = indique si l'enregistrement est local ou non.       *
-*                client = flux ouvert en lecture pour les informations utiles.*
-*                info   = informations de base associées à la requête.        *
+*  Paramètres  : owner = description humaine du serveur d'accueil.            *
+*                hash  = empreinte du binaire à représenter.                  *
+*                user  = désignation d'un éventuel nouveau créateur.          *
+*                error = indication éventuelle en cas d'échec. [OUT]          *
 *                                                                             *
 *  Description : Définit ou ouvre une archive d'éléments utilisateur.         *
 *                                                                             *
 *  Retour      : Structure mise en plae ou NULL en cas d'échec.               *
 *                                                                             *
-*  Remarques   : -                                                            *
+*  Remarques   : Les chaînes sont assurées d'être non vides ; la procédure    *
+*                assume un transfert de propriété.                            *
 *                                                                             *
 ******************************************************************************/
 
-GCdbArchive *g_cdb_archive_new(bool local, GDbClient *client, const core_db_info *info)
+GCdbArchive *g_cdb_archive_new(const char *owner, const rle_string *hash, const rle_string *user, DBError *error)
 {
     GCdbArchive *result;                    /* Adresse à retourner         */
     char *suffix;                           /* Fin du nom de fichier       */
@@ -224,19 +271,14 @@ GCdbArchive *g_cdb_archive_new(bool local, GDbClient *client, const core_db_info
 
     result = g_object_new(G_TYPE_CDB_ARCHIVE, NULL);
 
-
-
-    strcpy(result->hash, info->hash);
-
-
-
+    dup_rle_string(&result->hash, hash);
 
     /* Chemin de l'archive */
 
     suffix = strdup("chrysalide" G_DIR_SEPARATOR_S);
-    suffix = stradd(suffix, local ? "local" : "server");
+    suffix = stradd(suffix, owner);
     suffix = stradd(suffix, G_DIR_SEPARATOR_S);
-    suffix = stradd(suffix, result->hash);
+    suffix = stradd(suffix, hash->data);
     suffix = stradd(suffix, ".tar.xz");
 
     result->filename = get_xdg_config_dir(suffix);
@@ -253,7 +295,7 @@ GCdbArchive *g_cdb_archive_new(bool local, GDbClient *client, const core_db_info
     if (result->xml_desc[strlen(result->xml_desc) - 1] != G_DIR_SEPARATOR)
         result->xml_desc = stradd(result->xml_desc, G_DIR_SEPARATOR_S);
 
-    result->xml_desc = stradd(result->xml_desc, result->hash);
+    result->xml_desc = stradd(result->xml_desc, result->hash.data);
     result->xml_desc = stradd(result->xml_desc, "_desc.xml");
 
     result->sql_db = strdup(g_get_tmp_dir());
@@ -261,7 +303,7 @@ GCdbArchive *g_cdb_archive_new(bool local, GDbClient *client, const core_db_info
     if (result->sql_db[strlen(result->sql_db) - 1] != G_DIR_SEPARATOR)
         result->sql_db = stradd(result->sql_db, G_DIR_SEPARATOR_S);
 
-    result->sql_db = stradd(result->sql_db, result->hash);
+    result->sql_db = stradd(result->sql_db, result->hash.data);
     result->sql_db = stradd(result->sql_db, "_db.sql");
 
     /* Création de l'archive si elle n'existe pas */
@@ -273,8 +315,8 @@ GCdbArchive *g_cdb_archive_new(bool local, GDbClient *client, const core_db_info
         /* Le soucis ne vient pas de l'absence du fichier... */
         if (errno != ENOENT) goto gcan_error;
 
-        g_cdb_archive_create_xml_desc(result, info);
-        g_cdb_archive_create_db(result, info);
+        g_cdb_archive_create_xml_desc(result, user);
+        g_cdb_archive_create_db(result, NULL);
 
         if (!g_cdb_archive_write(result))
             goto gcan_error;
@@ -288,6 +330,11 @@ GCdbArchive *g_cdb_archive_new(bool local, GDbClient *client, const core_db_info
     if (!g_cdb_archive_read(result) && 0)
         goto gcan_error;
 
+    /* Chargement des éléments sauvegardés */
+
+    if (!g_cdb_archive_load_collections(result))
+        goto gcan_error;
+
     return result;
 
  gcan_error:
@@ -301,7 +348,7 @@ GCdbArchive *g_cdb_archive_new(bool local, GDbClient *client, const core_db_info
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : archive = information quant à l'archive à interpréter.       *
+*  Paramètres  : archive = informations quant à l'archive à interpréter.      *
 *                                                                             *
 *  Description : Ouvre une archive avec tous les éléments à conserver.        *
 *                                                                             *
@@ -416,7 +463,7 @@ static bool g_cdb_archive_read(GCdbArchive *archive)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : archive = information quant à l'archive à créer.             *
+*  Paramètres  : archive = informations quant à l'archive à créer.            *
 *                                                                             *
 *  Description : Enregistre une archive avec tous les éléments à conserver.   *
 *                                                                             *
@@ -497,9 +544,24 @@ bool g_cdb_archive_write(const GCdbArchive *archive)
 }
 
 
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : archive = informations quant à l'archive à consulter.        *
+*                hash    = empreinte extérieure à comparer.                   *
+*                                                                             *
+*  Description : Détermine si une empreinte correspond à celle d'une archive. *
+*                                                                             *
+*  Retour      : Résultat de la comparaison : -1, 0 ou 1.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
+int g_cdb_archive_compare_hash(const GCdbArchive *archive, const rle_string *hash)
+{
+    return cmp_rle_string(&archive->hash, hash);
 
-
+}
 
 
 
@@ -514,7 +576,7 @@ bool g_cdb_archive_write(const GCdbArchive *archive)
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : archive = archive à constituer.                              *
-*                info    = informations de base associées à la requête.       *
+*                user    = désignation d'un éventuel nouveau créateur.        *
 *                                                                             *
 *  Description : Crée la description XML correspondant à l'archive.           *
 *                                                                             *
@@ -524,7 +586,7 @@ bool g_cdb_archive_write(const GCdbArchive *archive)
 *                                                                             *
 ******************************************************************************/
 
-static bool g_cdb_archive_create_xml_desc(GCdbArchive *archive, const core_db_info *info)
+static bool g_cdb_archive_create_xml_desc(GCdbArchive *archive, const rle_string *user)
 {
     bool result;                            /* Bilan à retourner           */
     char tmp[sizeof(STR(ULLONG_MAX))];      /* Stockage temporaire        */
@@ -536,12 +598,15 @@ static bool g_cdb_archive_create_xml_desc(GCdbArchive *archive, const core_db_in
                                   "/ChrysalideBinary/Version", PACKAGE_VERSION);
 
     result &= add_content_to_node(archive->xdoc, archive->context,
-                                  "/ChrysalideBinary/Hash", archive->hash);
+                                  "/ChrysalideBinary/Protocol", XSTR(CDB_PROTOCOL_VERSION));
 
     result &= add_content_to_node(archive->xdoc, archive->context,
-                                  "/ChrysalideBinary/Creation/Author", "**me**");
+                                  "/ChrysalideBinary/Hash", archive->hash.data);
 
-    snprintf(tmp, sizeof(tmp), "%" PRIu64, (uint64_t)10ull);
+    result &= add_content_to_node(archive->xdoc, archive->context,
+                                  "/ChrysalideBinary/Creation/Author", user->data);
+
+    snprintf(tmp, sizeof(tmp), "%" PRIu64, (uint64_t)time(NULL));
 
     result &= add_content_to_node(archive->xdoc, archive->context,
                                   "/ChrysalideBinary/Creation/Date", tmp);
@@ -600,3 +665,307 @@ static bool g_cdb_archive_create_db(const GCdbArchive *archive, const core_db_in
     return result;
 
 }
+
+
+
+
+
+
+
+
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           ACCES A LA BASE DE DONNEES SQL                           */
+/*                           ACCES A LA BASE DE DONNEES SQL                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : archive = archive dont les collections sont à initialiser.   *
+*                                                                             *
+*  Description : Crée et remplit les collections à partir de leurs bases.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_cdb_archive_load_collections(GCdbArchive *archive)
+{
+    GList *iter;                            /* Boucle de parcours          */
+
+    archive->collections = create_collections_list();
+
+    for (iter = g_list_first(archive->collections);
+         iter != NULL;
+         iter = g_list_next(iter))
+    {
+        g_signal_connect(iter->data, "content-changed", G_CALLBACK(on_collection_changed), archive);
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec  = collection dont le contenu a évolué.               *
+*                action  = type d'évolution rencontrée.                       *
+*                item    = élément ajouté, modifié ou supprimé.               *
+*                archive = centralisation de tous les savoirs.                *
+*                                                                             *
+*  Description : Réagit à une modification au sein d'une collection donnée.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void on_collection_changed(GDbCollection *collec, DBAction action, GDbItem *item, GCdbArchive *archive)
+{
+    size_t i;                               /* Boucle de parcours          */
+    bool status;                            /* Bilan d'un envoi de retour  */
+
+    g_mutex_lock(&archive->clients_access);
+
+    for (i = 0; i < archive->count; i++)
+    {
+        status = g_db_collection_send(collec, archive->clients[i].fd, action, item);
+
+        if (!status)
+        {
+            /* TODO : close() */
+        }
+
+    }
+
+    g_mutex_unlock(&archive->clients_access);
+
+    printf("CHANGED !!\n");
+
+
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : archive = centralisation de tous les savoirs.                *
+*                                                                             *
+*  Description : Assure le traitement des requêtes de clients.                *
+*                                                                             *
+*  Retour      : NULL.                                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void *g_cdb_archive_process(GCdbArchive *archive)
+{
+    struct pollfd *fds;                     /* Surveillance des flux       */
+    nfds_t nfds;                            /* Quantité de ces flux        */
+    nfds_t i;                               /* Boucle de parcours          */
+    int ret;                                /* Bilan d'un appel            */
+    uint32_t val32;                         /* Valeur sur 32 bits          */
+    bool status;                            /* Bilan de lecture initiale   */
+    uint32_t command;                       /* Commande de la requête      */
+    GDbCollection *collec;                  /* Collection visée au final   */
+
+    void interrupt_poll_with_sigusr1(int sig) { };
+
+    signal(SIGUSR1, interrupt_poll_with_sigusr1);
+
+    archive->process_id = pthread_self();
+
+    fds = NULL;
+
+    while (1)
+    {
+        /* Reconstitution d'une liste à jour */
+
+        g_mutex_lock(&archive->clients_access);
+
+        nfds = archive->count;
+        fds = (struct pollfd *)realloc(fds, nfds * sizeof(struct pollfd));
+
+        for (i = 0; i < nfds; i++)
+        {
+            fds[i].fd = archive->clients[i].fd;
+            fds[i].events = POLLIN | POLLPRI;
+        }
+
+        if (nfds == 0)
+            goto gcap_no_more_clients;
+
+        g_mutex_unlock(&archive->clients_access);
+
+        /* Lancement d'une phase de surveillance */
+
+        printf("(%p) POLL %d\n", archive, nfds);
+
+        ret = poll(fds, nfds, -1);
+        if (ret == -1)
+        {
+            if (errno == EINTR) continue;
+
+            perror("poll");
+            break;
+
+        }
+
+        /* Traitement des requêtes reçues */
+
+        for (i = 0; i < nfds; i++)
+        {
+            /* Le canal est fermé, une sortie doit être demandée... */
+            if (fds[i].revents & POLLNVAL)
+                goto gcap_bad_exchange;
+
+            /* Données présentes en entrée */
+            if (fds[i].revents & (POLLIN | POLLPRI))
+            {
+                status = safe_recv(fds[i].fd, &val32, sizeof(uint32_t), 0);
+                if (!status) goto gcap_bad_exchange;
+
+                command = be32toh(val32);
+
+                switch (command)
+                {
+                    case DBC_COLLECTION:
+
+                        status = safe_recv(fds[i].fd, &val32, sizeof(uint32_t), 0);
+                        if (!status) goto gcap_bad_exchange;
+
+                        collec = find_collection_in_list(archive->collections, be32toh(val32));
+                        if (collec == NULL) goto gcap_bad_exchange;
+
+                        status = g_db_collection_recv(collec, fds[i].fd);
+                        if (!status) goto gcap_bad_exchange;
+
+                        printf("## CDB ## Got something for collection %p...\n", collec);
+
+                        //GDbCollection *find_collection_in_list(GList *, uint32_t);
+
+                        //static GGenConfig *find_collection_in_list(GList *list, uint32_t id)
+
+                        break;
+
+                    default:
+                        printf("bad command :: 0x%08x\n", command);
+                        goto gcap_bad_exchange;
+                        break;
+
+                }
+
+                continue;
+
+ gcap_bad_exchange:
+
+                printf("Bad exchange...\n");
+
+                /* TODO : close conn */
+
+                ;
+
+
+            }
+
+        }
+
+    }
+
+    /* On disparaît des écrans... */
+
+    g_mutex_lock(&archive->clients_access);
+
+ gcap_no_more_clients:
+
+    archive->process = NULL;
+    archive->process_id = 0;
+
+    g_mutex_unlock(&archive->clients_access);
+
+    if (fds != NULL)
+        free(fds);
+
+
+    return NULL;
+
+}
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : archive = archive à connecter avec un utilisateur.           *
+*                fd      = canal de communication réseau ouvert.              *
+*                user    = désignation de l'utilisateur associé.              *
+*                                                                             *
+*  Description : Associe un nouvel utilisateur à l'archive.                   *
+*                                                                             *
+*  Retour      : Indication d'une éventuelle erreur lors de l'opération.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+DBError g_cdb_archive_add_client(GCdbArchive *archive, int fd, const rle_string *user)
+{
+
+    volatile pthread_t *process_id;         /* Identifiant de la procédure */
+
+
+
+
+    printf("Add '%s' for archive...\n", user->data);
+
+
+    g_mutex_lock(&archive->clients_access);
+
+    /* Ajout dans la liste officielle */
+
+    archive->clients = (cdb_client *)realloc(archive->clients, ++archive->count * sizeof(cdb_client));
+
+    archive->clients[archive->count - 1].fd = fd;
+    dup_rle_string(&archive->clients[archive->count - 1].user, user);
+
+    /* Démarrage ou redémarrage du processus d'écoute */
+
+    if (archive->process == NULL)
+    {
+        archive->process = g_thread_new("cdb_process", (GThreadFunc)g_cdb_archive_process, archive);
+
+        /* On attend que le processus parallèle soit prêt */
+        for (process_id = &archive->process_id; *process_id == 0; );
+
+    }
+    else
+        pthread_kill(archive->process_id, SIGUSR1);
+
+    g_mutex_unlock(&archive->clients_access);
+
+    /* Envoi des mises à jour au nouveau client... */
+
+
+    /* TODO */
+
+
+
+    return DBE_NONE;
+
+}
+
+
+
diff --git a/src/analysis/db/cdb.h b/src/analysis/db/cdb.h
index a093039..17327f5 100644
--- a/src/analysis/db/cdb.h
+++ b/src/analysis/db/cdb.h
@@ -29,8 +29,13 @@
 #include <stdbool.h>
 
 
+#include "protocol.h"
+#include "misc/rlestr.h"
+
+//////
 #include "client.h"
 #include "core.h"
+//////////
 
 
 
@@ -52,11 +57,23 @@ typedef struct _GCdbArchiveClass GCdbArchiveClass;
 GType g_cdb_archive_get_type(void);
 
 /* Prépare un client pour une connexion à une BD. */
-GCdbArchive *g_cdb_archive_new(bool, GDbClient *, const core_db_info *);
+GCdbArchive *g_cdb_archive_new(const char *, const rle_string *, const rle_string *, DBError *);
 
 /* Enregistre une archive avec tous les éléments à conserver. */
 bool g_cdb_archive_write(const GCdbArchive *);
 
+/* Détermine si une empreinte correspond à celle d'une archive. */
+int g_cdb_archive_compare_hash(const GCdbArchive *, const rle_string *);
+
+
+
+
+
+/* Associe un nouvel utilisateur à l'archive. */
+DBError g_cdb_archive_add_client(GCdbArchive *, int, const rle_string *);
+
+
+
 
 
 #endif  /* _ANALYSIS_DB_CDB_H */
diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c
index 946f202..4b807ae 100644
--- a/src/analysis/db/client.c
+++ b/src/analysis/db/client.c
@@ -33,6 +33,9 @@
 
 
 #include "protocol.h"
+#include "misc/rlestr.h"
+#include "../../common/io.h"
+#include "../../gui/panels/log.h"
 
 
 
@@ -41,9 +44,12 @@ struct _GDbClient
 {
     GObject parent;                         /* A laisser en premier        */
 
-    int fd;
-    struct sockaddr_in addr;                /* Adresse d'écoute            */
+    rle_string hash;                        /* Empreinte du binaire lié    */
+    GList *collections;                     /* Collections d'un binaire    */
 
+    int fd;                                 /* Canal de communication      */
+
+    GMutex sending_lock;                    /* Concurrence des envois      */
     GThread *update;                        /* Procédure de traitement     */
 
 };
@@ -118,7 +124,7 @@ static void g_db_client_init(GDbClient *client)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : binary = instance d'objet GLib à traiter.                    *
+*  Paramètres  : client = instance d'objet GLib à traiter.                    *
 *                                                                             *
 *  Description : Procède à la libération totale de la mémoire.                *
 *                                                                             *
@@ -128,19 +134,19 @@ static void g_db_client_init(GDbClient *client)
 *                                                                             *
 ******************************************************************************/
 
-static void g_db_client_finalize(GDbClient *binary)
+static void g_db_client_finalize(GDbClient *client)
 {
-    //free(binary->filename);
+    unset_rle_string(&client->hash);
 
-    G_OBJECT_CLASS(g_db_client_parent_class)->finalize(G_OBJECT(binary));
+    G_OBJECT_CLASS(g_db_client_parent_class)->finalize(G_OBJECT(client));
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : host = hôte à représenter pour le service.                   *
-*                port = port de connexion pour les clients.                   *
+*  Paramètres  : hash        = empreinte d'un binaire en cours d'analyse.     *
+*                collections = ensemble de collections existantes.            *
 *                                                                             *
 *  Description : Prépare un client pour une connexion à une BD.               *
 *                                                                             *
@@ -150,28 +156,155 @@ static void g_db_client_finalize(GDbClient *binary)
 *                                                                             *
 ******************************************************************************/
 
-GDbClient *g_db_client_new(const char *host, short port)
+GDbClient *g_db_client_new(const char *hash, GDbCollection *collections)
 {
     GDbClient *result;                      /* Adresse à retourner         */
-    struct hostent *hp;                     /* Informations sur l'hôte     */
 
     result = g_object_new(G_TYPE_DB_CLIENT, NULL);
 
+    set_rle_string(&result->hash, hash);
+    result->collections = collections;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : client   = client pour les accès distants à manipuler.       *
+*                host     = hôte à représenter pour le service.               *
+*                port     = port de connexion pour les clients.               *
+*                username = utilisateur effectuant les évolutions.            *
+*                                                                             *
+*  Description : Démarre la connexion à la base de données.                   *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_client_start(GDbClient *client, const char *host, unsigned short port, const char *username)
+{
+    struct hostent *hp;                     /* Informations sur l'hôte     */
+    struct sockaddr_in addr;                /* Adresse de transmission     */
+    int ret;                                /* Bilan d'un appel            */
+    rle_string user;                        /* Nom d'utilisateur associé   */
+    uint32_t data;                          /* Mot de données lues         */
+    DBError error;                          /* Validation de la connexion  */
+
+    /* Identification du serveur à contacter */
+
     hp = gethostbyname(host);
-    if (hp == NULL) goto gdsn_error;
+    if (hp == NULL) return false;
 
-    result->addr.sin_family = hp->h_addrtype;
-    memcpy(&result->addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
+    addr.sin_family = hp->h_addrtype;
+    memcpy(&addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
 
-    result->addr.sin_port = htons(port);
+    addr.sin_port = htons(port);
 
-    return result;
+    /* Création d'un canal de communication */
+
+    client->fd = socket(AF_INET, SOCK_STREAM, 0);
+    if (client->fd == -1)
+    {
+        perror("socket");
+        return false;
+    }
+
+    ret = connect(client->fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
+    if (ret == -1)
+    {
+        perror("connect");
+        goto gdcs_no_listening;
+    }
 
- gdsn_error:
+    /* Préparation du nom d'utilisateur à diffuser */
 
-    g_object_unref(G_OBJECT(result));
+    init_rle_string(&user, username);
 
-    return NULL;
+    /**
+     * On réalise l'envoi initial ; le premier paquet doit contenir :
+     *    - la commande 'DBC_HELO'.
+     *    - le numéro de version du client.
+     *    - l'empreinte du binaire analysé.
+     *    - l'identifiant de l'utilisateur effectuant des modifications.
+     *
+     * Tout ceci est à synchroniser avec la fonction g_db_server_listener().
+     */
+
+    if (!safe_send(client->fd, (uint32_t []) { htobe32(DBC_HELO) }, sizeof(uint32_t), MSG_MORE))
+        goto gdcs_error;
+
+    if (!safe_send(client->fd, (uint32_t []) { htobe32(CDB_PROTOCOL_VERSION) }, sizeof(uint32_t), MSG_MORE))
+        goto gdcs_error;
+
+    if (!send_rle_string(&client->hash, client->fd, MSG_MORE))
+        goto gdcs_error;
+
+    if (!send_rle_string(&user, client->fd, 0))
+        goto gdcs_error;
+
+    /**
+     * Le serveur doit répondre pour un message type :
+     *    - la commande 'DBC_WELCOME'.
+     *    - un identifiant d'erreur ('DBE_NONE' ou 'DBE_WRONG_VERSION').
+     */
+
+    if (!safe_recv(client->fd, &data, sizeof(uint32_t), 0))
+        goto gdcs_error;
+
+    if (be32toh(data) != DBC_WELCOME)
+    {
+        log_variadic_message(LMT_ERROR, _("The server '%s:%hu' did not welcome us!"), host, port);
+        goto gdcs_error;
+    }
+
+    if (!safe_recv(client->fd, &data, sizeof(uint32_t), 0))
+        goto gdcs_error;
+
+    error = be32toh(data);
+
+    switch (error)
+    {
+        case DBE_NONE:
+            log_variadic_message(LMT_INFO, _("Connected to the server '%s:%hu'!"), host, port);
+            break;
+
+        case DBE_WRONG_VERSION:
+            log_variadic_message(LMT_ERROR, _("The server '%s:%hu' does not use our protocol version (0x%08x)..."),
+                                 host, port, CDB_PROTOCOL_VERSION);
+            goto gdcs_error;
+            break;
+
+        default:
+            log_variadic_message(LMT_ERROR, _("The server '%s:%hu' uses an unknown protocol..."), host, port);
+            goto gdcs_error;
+            break;
+
+    }
+
+    client->update = g_thread_try_new("cdb_client", (GThreadFunc)g_db_client_update, client, NULL);
+    if (client->update == NULL)
+    {
+        log_variadic_message(LMT_ERROR, _("Failed to start a listening thread for the server '%s:%hu'!"),
+                             host, port);
+        goto gdcs_error;
+    }
+
+    return true;
+
+ gdcs_error:
+
+    unset_rle_string(&user);
+
+ gdcs_no_listening:
+
+    close(client->fd);
+    client->fd = -1;
+
+    return false;
 
 }
 
@@ -192,6 +325,10 @@ static void *g_db_client_update(GDbClient *client)
 {
     struct pollfd fds;                      /* Surveillance des flux       */
     int ret;                                /* Bilan d'un appel            */
+    uint32_t val32;                         /* Valeur sur 32 bits          */
+    bool status;                            /* Bilan d'une opération       */
+    uint32_t command;                       /* Commande de la requête      */
+    GDbCollection *collec;                  /* Collection visée au final   */
 
     fds.fd = client->fd;
     fds.events = POLLIN | POLLPRI;
@@ -209,16 +346,50 @@ static void *g_db_client_update(GDbClient *client)
 
         if (fds.revents & (POLLIN | POLLPRI))
         {
+            status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0);
+            if (!status) goto gdcu_bad_exchange;
+
+            command = be32toh(val32);
+
+            switch (command)
+            {
+                case DBC_COLLECTION:
+
+                    status = safe_recv(fds.fd, &val32, sizeof(uint32_t), 0);
+                    if (!status) goto gdcu_bad_exchange;
+
+                    collec = find_collection_in_list(client->collections, be32toh(val32));
+                    if (collec == NULL) goto gdcu_bad_exchange;
+
+                    status = g_db_collection_recv(collec, fds.fd);
+                    if (!status) goto gdcu_bad_exchange;
+
+
+
+
+                    printf("## CLIENT ## Got Something to read...\n");
+
+                    break;
+
+            }
+
+            continue;
+
+ gdcu_bad_exchange:
+
+                printf("Bad reception...\n");
+
+                /* TODO : close conn */
+
+                ;
 
-            /* TODO */
-            pause();
 
 
         }
 
     }
 
-    g_db_client_stop(client);
+    //g_db_client_stop(client);
 
     return NULL;
 
@@ -229,39 +400,44 @@ static void *g_db_client_update(GDbClient *client)
 *                                                                             *
 *  Paramètres  : client = client pour les accès distants à manipuler.         *
 *                                                                             *
-*  Description : Démarre la connexion à la base de données.                   *
+*  Description : Arrête la connexion à la base de données.                    *
 *                                                                             *
-*  Retour      : Bilan de l'opération.                                        *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-bool g_db_client_start(GDbClient *client)
+void g_db_client_stop(GDbClient *client)
 {
-    int ret;                                /* Bilan d'un appel            */
+    if (client->fd != -1)
+        return;
 
-    client->fd = socket(AF_INET, SOCK_STREAM, 0);
-    if (client->fd == -1)
-    {
-        perror("socket");
-        return false;
-    }
+    close(client->fd);
+    client->fd = -1;
 
-    ret = connect(client->fd, (struct sockaddr *)&client->addr, sizeof(struct sockaddr_in));
-    if (ret == -1)
-    {
-        perror("connect");
-        close(client->fd);
-        client->fd = -1;
-        return false;
-    }
+    g_thread_join(client->update);
 
-    //client->update = g_thread_new("cdb_listener", (GThreadFunc)g_db_client_update, client);
+}
 
-    send(client->fd, "A", 1, 0);
 
-    return true;
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : client = client pour les accès distants à manipuler.         *
+*                                                                             *
+*  Description : Identifie le canal de communication pour envois au serveur.  *
+*                                                                             *
+*  Retour      : Descripteur de flux normalement ouvert.                      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int g_db_client_get_fd(GDbClient *client)
+{
+    g_mutex_lock(&client->sending_lock);
+
+    return client->fd;
 
 }
 
@@ -270,7 +446,7 @@ bool g_db_client_start(GDbClient *client)
 *                                                                             *
 *  Paramètres  : client = client pour les accès distants à manipuler.         *
 *                                                                             *
-*  Description : Arrête la connexion à la base de données.                    *
+*  Description : Marque le canal de communication comme disponible.           *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -278,14 +454,8 @@ bool g_db_client_start(GDbClient *client)
 *                                                                             *
 ******************************************************************************/
 
-void g_db_client_stop(GDbClient *client)
+void g_db_client_put_fd(GDbClient *client)
 {
-    if (client->fd != -1)
-        return;
-
-    close(client->fd);
-    client->fd = -1;
-
-    g_thread_join(client->update);
+    g_mutex_unlock(&client->sending_lock);
 
 }
diff --git a/src/analysis/db/client.h b/src/analysis/db/client.h
index e57a5b6..a1a9f8e 100644
--- a/src/analysis/db/client.h
+++ b/src/analysis/db/client.h
@@ -29,6 +29,9 @@
 #include <stdbool.h>
 
 
+#include "collection.h"
+
+
 
 #define G_TYPE_DB_CLIENT               g_db_client_get_type()
 #define G_DB_CLIENT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_client_get_type(), GDbClient))
@@ -48,14 +51,20 @@ typedef struct _GDbClientClass GDbClientClass;
 GType g_db_client_get_type(void);
 
 /* Prépare un client pour une connexion à une BD. */
-GDbClient *g_db_client_new(const char *, short);
+GDbClient *g_db_client_new(const char *, GDbCollection *);
 
 /* Démarre la connexion à la base de données. */
-bool g_db_client_start(GDbClient *);
+bool g_db_client_start(GDbClient *, const char *, unsigned short, const char *);
 
 /* Arrête la connexion à la base de données. */
 void g_db_client_stop(GDbClient *);
 
+/* Identifie le canal de communication pour envois au serveur. */
+int g_db_client_get_fd(GDbClient *);
+
+/* Marque le canal de communication comme disponible. */
+void g_db_client_put_fd(GDbClient *);
+
 
 
 #endif  /* _ANALYSIS_DB_CLIENT_H */
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index 9ddba48..20b1ff3 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -24,3 +24,494 @@
 #include "collection.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 */
+
+    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 *);
+
+};
+
+
+
+
+/* Initialise la classe des collections génériques d'éléments. */
+static void g_db_collection_class_init(GDbCollectionClass *);
+
+/* Initialise une collection générique d'éléments. */
+static void g_db_collection_init(GDbCollection *);
+
+/* Supprime toutes les références externes. */
+static void g_db_collection_dispose(GDbCollection *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_db_collection_finalize(GDbCollection *);
+
+
+
+
+/* Indique le type défini pour une collection générique d'éléments. */
+G_DEFINE_TYPE(GDbCollection, g_db_collection, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des collections génériques d'éléments.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_collection_class_init(GDbCollectionClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_db_collection_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_db_collection_finalize;
+
+    g_signal_new("content-changed",
+                 G_TYPE_DB_COLLECTION,
+                 G_SIGNAL_RUN_LAST,
+                 G_STRUCT_OFFSET(GDbCollectionClass, content_changed),
+                 NULL, NULL,
+                 g_cclosure_user_marshal_VOID__ENUM_OBJECT,
+                 G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_OBJECT);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = instance à initialiser.                             *
+*                                                                             *
+*  Description : Initialise une collection générique d'éléments.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_collection_init(GDbCollection *collec)
+{
+    g_rw_lock_init(&collec->params_access);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_collection_dispose(GDbCollection *collec)
+{
+    G_OBJECT_CLASS(g_db_collection_parent_class)->dispose(G_OBJECT(collec));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = instance d'objet GLib à traiter.                    *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_collection_finalize(GDbCollection *collec)
+{
+    g_rw_lock_clear(&collec->params_access);
+
+    G_OBJECT_CLASS(g_db_collection_parent_class)->finalize(G_OBJECT(collec));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : id   = identifiant réseau des éléments à traiter.            *
+*                type = type GLib des éléments à intégrer dans la collection. *
+*                                                                             *
+*  Description : Prépare la mise en place d'une nouvelle collection.          *
+*                                                                             *
+*  Retour      : Adresse de l'instance ou NULL en cas d'échec.                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GDbCollection *g_db_collection_new(uint32_t id, GType type)
+{
+    GDbCollection *result;                  /* Adresse à retourner         */
+
+    result = g_object_new(G_TYPE_DB_COLLECTION, NULL);
+
+    result->featuring = id;
+    result->type = type;
+
+    return result;
+
+}
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = collection générique d'éléments à consulter.        *
+*                                                                             *
+*  Description : Décrit le type des éléments rassemblées dans une collection. *
+*                                                                             *
+*  Retour      : Identifiant interne des éléments collectionés.               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint32_t g_db_collection_get_feature(const GDbCollection *collec)
+{
+    return collec->featuring;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = ensemble d'éléments à considérer.                   *
+*                fd     = flux ouvert en lecture pour la réception de données.*
+*                                                                             *
+*  Description : Réceptionne et traite une requête réseau pour collection.    *
+*                                                                             *
+*  Retour      : Bilan de l'exécution de l'opération.                         *
+*                                                                             *
+*  Remarques   : Cette fonction est uniquement destinée aux appels depuis     *
+*                la fonction g_cdb_archive_process() ; une partie des         *
+*                informations ont déjà été tirées des échanges protocolaires. *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_collection_recv(GDbCollection *collec, int fd)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    uint32_t val32;                         /* Valeur sur 32 bits          */
+    bool status;                            /* Bilan de lecture initiale   */
+    DBAction action;                        /* Commande de la requête      */
+    GDbItem *item;                          /* Définition d'élément visé   */
+
+    status = safe_recv(fd, &val32, sizeof(uint32_t), 0);
+    if (!status) return false;
+
+    action = be32toh(val32);
+    if (action < 0 || action >= DBA_COUNT) return false;
+
+    item = g_object_new(collec->type, NULL);
+
+    status = g_db_item_recv(item, fd, 0);
+    if (!status) return false;
+
+    result = false;
+
+    switch (action)
+    {
+        case DBA_ADD_ITEM:
+            result = g_db_collection_add_item(collec, item);
+            break;
+
+        case DBA_REM_ITEM:
+            break;
+
+        case DBA_MOD_ITEM:
+            result = g_db_collection_modify_item(collec, item);
+            break;
+
+        default:
+            /* Pour GCC : DBA_COUNT */
+            break;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = ensemble d'éléments à considérer.                   *
+*                fd     = flux ouvert en écriture pour l'émission de données. *
+*                action = avenir de l'élément fourni.                         *
+*                item   = élément de collection à sérialiser.                 *
+*                                                                             *
+*  Description : Envoie pour traitement une requête réseau pour collection.   *
+*                                                                             *
+*  Retour      : Bilan de l'exécution de l'opération.                         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_collection_send(GDbCollection *collec, int fd, DBAction action, GDbItem *item)
+{
+    bool status;                            /* Bilan de lecture initiale   */
+
+    status = safe_send(fd, (uint32_t []) { htobe32(DBC_COLLECTION) }, sizeof(uint32_t), MSG_MORE);
+    if (!status) return false;
+
+    status = safe_send(fd, (uint32_t []) { htobe32(collec->featuring) }, sizeof(uint32_t), MSG_MORE);
+    if (!status) return false;
+
+    status = safe_send(fd, (uint32_t []) { htobe32(action) }, sizeof(uint32_t), MSG_MORE);
+    if (!status) return false;
+
+    status = g_db_item_send(item, fd, 0);
+    if (!status) return false;
+
+    return true;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = collection à mettre à jour.                         *
+*                write  = précise le type d'accès prévu (lecture/écriture).   *
+*                lock   = indique le sens du verrouillage à mener.            *
+*                                                                             *
+*  Description : Met à disposition un encadrement des accès aux éléments.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_db_collection_lock_unlock(GDbCollection *collec, bool write, bool lock)
+{
+    if (write)
+    {
+        if (lock) g_rw_lock_writer_lock(&collec->params_access);
+        else g_rw_lock_writer_unlock(&collec->params_access);
+    }
+    else
+    {
+        if (lock) g_rw_lock_reader_lock(&collec->params_access);
+        else g_rw_lock_reader_unlock(&collec->params_access);
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = ensemble d'éléments à consulter.                    *
+*                                                                             *
+*  Description : Renvoie la liste des éléments rassemblés.                    *
+*                                                                             *
+*  Retour      : Liste d'éléments à parcourir.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GList *g_db_collection_list_items(const GDbCollection *collec)
+{
+    /**
+     * Un verrou doit être posé !
+     * Il n'y a pas d'assert() possible pour le vérifier...
+     */
+
+    return collec->items;
+
+}
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = ensemble d'éléments à considérer.                   *
+*                item   = élément de collection à manipuler.                  *
+*                                                                             *
+*  Description : Procède à l'ajout d'un nouvel élément dans la collection.    *
+*                                                                             *
+*  Retour      : Bilan de l'exécution de l'opération.                         *
+*                                                                             *
+*  Remarques   : L'appelant reste le propriétaire de l'object transféré.      *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_collection_add_item(GDbCollection *collec, GDbItem *item)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    GList *found;                           /* Test de présence existante  */
+
+    g_db_collection_wlock(collec);
+
+    found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare);
+
+    if (found != NULL)
+        result = g_db_collection_modify_item(collec, item);
+
+    else
+    {
+        g_object_ref(G_OBJECT(item));
+        collec->items = g_list_append(collec->items, item);
+
+        g_object_ref(G_OBJECT(item));
+        collec->sorted = g_list_insert_sorted(collec->sorted, item, (GCompareFunc)g_db_item_compare);
+
+        g_signal_emit_by_name(collec, "content-changed", DBA_ADD_ITEM, item);
+
+        result = true;
+
+    }
+
+    g_db_collection_wunlock(collec);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : collec = ensemble d'éléments à considérer.                   *
+*                item   = élément de collection à copier.                     *
+*                                                                             *
+*  Description : Procède à la modification d'un élément dans la collection.   *
+*                                                                             *
+*  Retour      : Bilan de l'exécution de l'opération.                         *
+*                                                                             *
+*  Remarques   : L'appelant reste le propriétaire de l'object transféré.      *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_collection_modify_item(GDbCollection *collec, GDbItem *item)
+{
+    bool result;                            /* Bilan à faire remonter      */
+    GList *found;                           /* Test de présence existante  */
+
+    found = g_list_find_custom(collec->items, item, (GCompareFunc)g_db_item_compare);
+
+
+
+    result = true;
+
+
+
+
+
+    return result;
+
+}
+
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                     CREATION DE L'ABSTRACTION POUR COLLECTIONS                     */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : list = ensemble de collectons à parcourir.                   *
+*                id   = identifiant interne du type d'éléments groupés.       *
+*                                                                             *
+*  Description : Recherche une collection correspondant à un type donné.      *
+*                                                                             *
+*  Retour      : Collection trouvée ou NULL en cas d'échec.                   *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GDbCollection *find_collection_in_list(GList *list, uint32_t id)
+{
+    GDbCollection *result;                  /* Collection trouvée renvoyée */
+    GList *iter;                            /* Boucle de parcours          */
+
+    result = NULL;
+
+    for (iter = g_list_first(list);
+         iter != NULL;
+         iter = g_list_next(iter))
+    {
+        result = G_DB_COLLECTION(iter->data);
+
+        if (g_db_collection_get_feature(result) == id)
+            break;
+
+    }
+
+    return (iter != NULL ? result : NULL);
+
+}
diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h
index 715cdc9..75ee7df 100644
--- a/src/analysis/db/collection.h
+++ b/src/analysis/db/collection.h
@@ -25,6 +25,87 @@
 #define _ANALYSIS_DB_COLLECTION_H
 
 
+#include <glib-object.h>
+#include <stdint.h>
+
+
+#include "item.h"
+#include "protocol.h"
+
+
+
+#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_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;
+
+/* Collection générique d'éléments (classe) */
+typedef struct _GDbCollectionClass GDbCollectionClass;
+
+
+/* Indique le type défini pour une collection générique d'éléments. */
+GType g_db_collection_get_type(void);
+
+/* Prépare la mise en place d'une nouvelle collection. */
+GDbCollection *g_db_collection_new(uint32_t, GType);
+
+
+
+/* Décrit le type des éléments rassemblées dans une collection. */
+uint32_t g_db_collection_get_feature(const GDbCollection *);
+
+
+
+
+/* Réceptionne et traite une requête réseau pour collection. */
+bool g_db_collection_recv(GDbCollection *, int);
+
+/* Envoie pour traitement une requête réseau pour collection. */
+bool g_db_collection_send(GDbCollection *, int, DBAction, GDbItem *);
+
+
+
+
+
+
+/* Met à disposition un encadrement des accès aux éléments. */
+void g_db_collection_lock_unlock(GDbCollection *, bool, bool);
+
+
+#define g_db_collection_wlock(col) g_db_collection_lock_unlock(col, true, true);
+#define g_db_collection_wunlock(col) g_db_collection_lock_unlock(col, true, false);
+
+#define g_db_collection_rlock(col) g_db_collection_lock_unlock(col, false, true);
+#define g_db_collection_runlock(col) g_db_collection_lock_unlock(col, false, false);
+
+
+/* Renvoie la liste des éléments rassemblés. */
+GList *g_db_collection_list_items(const GDbCollection *);
+
+
+
+
+/* Procède à l'ajout d'un nouvel élément dans la collection. */
+bool g_db_collection_add_item(GDbCollection *, GDbItem *);
+
+/* Procède à la modification d'un élément dans la collection. */
+bool g_db_collection_modify_item(GDbCollection *, GDbItem *);
+
+
+
+
+
+/* ------------------- CREATION DE L'ABSTRACTION POUR COLLECTIONS ------------------- */
+
+
+/* Recherche une collection correspondant à un type donné. */
+GDbCollection *find_collection_in_list(GList *, uint32_t);
+
 
 
 #endif  /* _ANALYSIS_DB_COLLECTION_H */
diff --git a/src/analysis/db/core.c b/src/analysis/db/core.c
index 0bc5f50..81ea117 100644
--- a/src/analysis/db/core.c
+++ b/src/analysis/db/core.c
@@ -142,6 +142,7 @@ void init_core_db_info(core_db_info *info, uint64_t type, const char *user)
 
 bool load_core_db_info(core_db_info *info, uint64_t type, int fd)
 {
+#if 0
     ssize_t got;                            /* Quantité de données reçues  */
     uint64_t val64;                         /* Valeur sur 64 bits          */
 
@@ -163,7 +164,7 @@ bool load_core_db_info(core_db_info *info, uint64_t type, int fd)
     info->modified = be64toh(val64);
 
     info->saved = info->modified;
-
+#endif
     return true;
 
 }
@@ -184,6 +185,7 @@ bool load_core_db_info(core_db_info *info, uint64_t type, int fd)
 
 bool store_core_db_info(core_db_info *info, int fd)
 {
+#if 0
     ssize_t got;                            /* Quantité de données reçues  */
 
     got = safe_send(fd, (uint64_t []) { htobe64(info->type) }, sizeof(uint64_t), MSG_WAITALL);
@@ -199,7 +201,7 @@ bool store_core_db_info(core_db_info *info, int fd)
     if (got != sizeof(uint64_t)) return false;
 
     info->saved = time(NULL);
-
+#endif
     return true;
 
 }
diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h
new file mode 100644
index 0000000..b6d8f9c
--- /dev/null
+++ b/src/analysis/db/item-int.h
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * item-int.h - prototypes et définitions internes pour les bases d'éléments de collection
+ *
+ * Copyright (C) 2014 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_ITEM_INT_H
+#define _ANALYSIS_DB_ITEM_INT_H
+
+
+#include "item.h"
+
+
+#include <stdint.h>
+
+
+
+/* Importe la définition d'une base d'éléments pour collection. */
+typedef bool (* recv_db_item_fc) (GDbItem *, int, int);
+
+/* Exporte la définition d'une base d'éléments pour collection. */
+typedef bool (* send_db_item_fc) (const GDbItem *, int, int);
+
+
+/* Base d'un élément pour collection générique (instance) */
+struct _GDbItem
+{
+    GObject parent;                         /* A laisser en premier        */
+
+    uint64_t created;                       /* Date de création            */
+    uint64_t modified;                      /* Date de modification        */
+
+    bool is_volatile;                       /* Pas besoin de sauvegarde ?  */
+
+};
+
+/* Base d'un élément pour collection générique (classe) */
+struct _GDbItemClass
+{
+    GObjectClass parent;                    /* A laisser en premier        */
+
+    GCompareFunc cmp;                       /* Comparaison entre éléments  */
+
+    recv_db_item_fc recv;                   /* Réception depuis le réseau  */
+    send_db_item_fc send;                   /* Emission depuis le réseau   */
+
+};
+
+
+
+#endif  /* _ANALYSIS_DB_ITEM_INT_H */
diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c
new file mode 100644
index 0000000..e2fd7f3
--- /dev/null
+++ b/src/analysis/db/item.c
@@ -0,0 +1,356 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * item.c - gestion d'éléments destinés à une collection générique
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+
+#include "item.h"
+
+
+#include "item-int.h"
+#include "../../common/io.h"
+
+
+
+/* Initialise la classe des bases d'éléments pour collection. */
+static void g_db_item_class_init(GDbItemClass *);
+
+/* Initialise une base d'élément pour collection générique. */
+static void g_db_item_init(GDbItem *);
+
+/* Supprime toutes les références externes. */
+static void g_db_item_dispose(GDbItem *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_db_item_finalize(GDbItem *);
+
+/* Effectue la comparaison entre deux éléments de collection. */
+static gint g_db_item_cmp(GDbItem *, GDbItem *);
+
+/* Importe la définition d'une base d'éléments pour collection. */
+static bool g_db_item_recv_from_fd(GDbItem *, int, int);
+
+/* Exporte la définition d'une base d'éléments pour collection. */
+static bool g_db_item_send_to_fd(const GDbItem *, int, int);
+
+
+
+
+/* Indique le type défini pour une base d'élément de collection générique. */
+G_DEFINE_TYPE(GDbItem, g_db_item, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des bases d'éléments pour collection.   *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_item_class_init(GDbItemClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_db_item_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_db_item_finalize;
+
+    klass->cmp = (GCompareFunc)g_db_item_cmp;
+
+    klass->recv = (recv_db_item_fc)g_db_item_recv_from_fd;
+    klass->send = (send_db_item_fc)g_db_item_send_to_fd;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance à initialiser.                               *
+*                                                                             *
+*  Description : Initialise une base d'élément pour collection générique.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_item_init(GDbItem *item)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_item_dispose(GDbItem *item)
+{
+    G_OBJECT_CLASS(g_db_item_parent_class)->dispose(G_OBJECT(item));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = instance d'objet GLib à traiter.                      *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_item_finalize(GDbItem *item)
+{
+    G_OBJECT_CLASS(g_db_item_parent_class)->finalize(G_OBJECT(item));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier élément à analyser.                              *
+*                b = second élément à analyser.                               *
+*                                                                             *
+*  Description : Effectue la comparaison entre deux éléments de collection.   *
+*                                                                             *
+*  Retour      : Bilan de la comparaison : -1, 0 ou 1.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gint g_db_item_cmp(GDbItem *a, GDbItem *b)
+{
+    gint result;                            /* Bilan à retourner           */
+
+    /**
+     * A n'utiliser qu'en dernier recours, pour départager deux
+     * éléments par un serveur NTP...
+     */
+
+    if (a->modified > b->modified)
+        result = 1;
+
+    else if (a->modified < b->modified)
+        result = -1;
+
+    else
+    {
+        if (a->created > b->created)
+            result = 1;
+
+        else if (a->created < b->created)
+            result = -1;
+
+        else
+            result = 0;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier élément à analyser.                              *
+*                b = second élément à analyser.                               *
+*                                                                             *
+*  Description : Effectue la comparaison entre deux éléments de collection.   *
+*                                                                             *
+*  Retour      : Bilan de la comparaison : -1, 0 ou 1.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+gint g_db_item_compare(GDbItem *a, GDbItem *b)
+{
+    return G_DB_ITEM_GET_CLASS(a)->cmp(a, b);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = base d'éléments à charger. [OUT]                     *
+*                fd    = flux ouvert en lecture pour l'importation.           *
+*                flags = éventuelles options d'envoi supplémentaires.         *
+*                                                                             *
+*  Description : Importe la définition d'une base d'éléments pour collection. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_db_item_recv_from_fd(GDbItem *item, int fd, int flags)
+{
+    uint64_t val64;                         /* Valeur sur 64 bits          */
+    bool status;                            /* Bilan d'une réception       */
+
+    status = safe_recv(fd, &val64, sizeof(uint64_t), flags);
+    if (!status) return false;
+
+    item->created = be64toh(val64);
+
+    status = safe_recv(fd, &val64, sizeof(uint64_t), flags);
+    if (!status) return false;
+
+    item->modified = be64toh(val64);
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = base d'éléments à charger. [OUT]                     *
+*                fd    = flux ouvert en lecture pour l'importation.           *
+*                flags = éventuelles options d'envoi supplémentaires.         *
+*                                                                             *
+*  Description : Importe la définition d'une base d'éléments pour collection. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_item_recv(GDbItem *item, int fd, int flags)
+{
+    return G_DB_ITEM_GET_CLASS(item)->recv(item, fd, flags);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = informations à sauvegarer.                           *
+*                fd    = flux ouvert en écriture pour l'exportation.          *
+*                flags = éventuelles options d'envoi supplémentaires.         *
+*                                                                             *
+*  Description : Exporte la définition d'une base d'éléments pour collection. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_db_item_send_to_fd(const GDbItem *item, int fd, int flags)
+{
+    bool status;                            /* Bilan d'une émission        */
+
+
+    printf("<sending> FROM %s...\n", __FUNCTION__);
+
+
+    status = safe_send(fd, (uint64_t []) { htobe64(item->created) }, sizeof(uint64_t), MSG_MORE | flags);
+    if (!status) return false;
+
+    status = safe_send(fd, (uint64_t []) { htobe64(item->modified) }, sizeof(uint64_t), flags);
+    if (!status) return false;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item  = informations à sauvegarer.                           *
+*                fd    = flux ouvert en écriture pour l'exportation.          *
+*                flags = éventuelles options d'envoi supplémentaires.         *
+*                                                                             *
+*  Description : Exporte la définition d'une base d'éléments pour collection. *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_item_send(const GDbItem *item, int fd, int flags)
+{
+    return G_DB_ITEM_GET_CLASS(item)->send(item, fd, flags);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item        = base d'éléments à modifier.                    *
+*                is_volatile = état du besoin en sauvegarde.                  *
+*                                                                             *
+*  Description : Définit si l'élément contient des données à oublier ou non.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_db_item_set_volatile(GDbItem *item, bool is_volatile)
+{
+    item->is_volatile = is_volatile;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : item = base d'éléments à consulter.                          *
+*                                                                             *
+*  Description : Indique si l'élément contient des données à oublier ou non.  *
+*                                                                             *
+*  Retour      : Etat du besoin en sauvegarde.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_db_item_is_volatile(const GDbItem *item)
+{
+    return item->is_volatile;
+
+}
diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h
new file mode 100644
index 0000000..3938610
--- /dev/null
+++ b/src/analysis/db/item.h
@@ -0,0 +1,68 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * item.h - prototypes pour la gestion d'éléments destinés à une collection générique
+ *
+ * Copyright (C) 2014 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_ITEM_H
+#define _ANALYSIS_DB_ITEM_H
+
+
+#include <glib-object.h>
+#include <stdbool.h>
+
+
+
+#define G_TYPE_DB_ITEM               g_db_item_get_type()
+#define G_DB_ITEM(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_item_get_type(), GDbItem))
+#define G_IS_DB_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_item_get_type()))
+#define G_DB_ITEM_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_ITEM, GDbItemClass))
+#define G_IS_DB_ITEM_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_ITEM))
+#define G_DB_ITEM_GET_CLASS(obj)      (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_ITEM, GDbItemClass))
+
+
+/* Base d'un élément pour collection générique (instance) */
+typedef struct _GDbItem GDbItem;
+
+/* Base d'un élément pour collection générique (classe) */
+typedef struct _GDbItemClass GDbItemClass;
+
+
+/* Indique le type défini pour une base d'élément de collection générique. */
+GType g_db_item_get_type(void);
+
+/* Effectue la comparaison entre deux éléments de collection. */
+gint g_db_item_compare(GDbItem *, GDbItem *);
+
+/* Importe la définition d'une base d'éléments pour collection. */
+bool g_db_item_recv(GDbItem *, int, int);
+
+/* Exporte la définition d'une base d'éléments pour collection. */
+bool g_db_item_send(const GDbItem *, int, int);
+
+/* Définit si l'élément contient des données à oublier ou non. */
+void g_db_item_set_volatile(GDbItem *, bool);
+
+/* Indique si l'élément contient des données à oublier ou non. */
+bool g_db_item_is_volatile(const GDbItem *);
+
+
+
+#endif  /* _ANALYSIS_DB_ITEM_H */
diff --git a/src/analysis/db/items/Makefile.am b/src/analysis/db/items/Makefile.am
new file mode 100644
index 0000000..f026d44
--- /dev/null
+++ b/src/analysis/db/items/Makefile.am
@@ -0,0 +1,17 @@
+
+noinst_LTLIBRARIES  = libanalysisdbitems.la
+
+libanalysisdbitems_la_SOURCES =			\
+	bookmark.h bookmark.c				\
+	comment.h comment.c
+
+libanalysisdbitems_la_LIBADD =	
+
+libanalysisdbitems_la_LDFLAGS = 
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = 
diff --git a/src/analysis/db/items/bookmark.c b/src/analysis/db/items/bookmark.c
new file mode 100644
index 0000000..c28a837
--- /dev/null
+++ b/src/analysis/db/items/bookmark.c
@@ -0,0 +1,416 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bookmark.h - prototypes pour la gestion des signets au sein d'un binaire
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+
+#include "bookmark.h"
+
+
+#include <stdio.h>
+#include <sys/socket.h>
+
+
+#include "../item-int.h"
+#include "../misc/rlestr.h"
+
+
+
+/* Signet à l'intérieur d'une zone de texte (instance) */
+struct _GDbBookmark
+{
+    GDbItem parent;                         /* A laisser en premier        */
+
+    vmpa2t addr;                            /* Adresse du signet           */
+    rle_string comment;                     /* Eventuel commentaire associé*/
+
+};
+
+/* Signet à l'intérieur d'une zone de texte (classe) */
+struct _GDbBookmarkClass
+{
+    GDbItemClass parent;                    /* A laisser en premier        */
+
+};
+
+
+
+/* Initialise la classe des signets dans une zone de texte. */
+static void g_db_bookmark_class_init(GDbBookmarkClass *);
+
+/* Initialise un signet dans une zone de texte. */
+static void g_db_bookmark_init(GDbBookmark *);
+
+/* Supprime toutes les références externes. */
+static void g_db_bookmark_dispose(GDbBookmark *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_db_bookmark_finalize(GDbBookmark *);
+
+
+
+/* Effectue la comparaison entre deux signets de collection. */
+static gint g_db_bookmark_cmp(GDbBookmark *, GDbBookmark *);
+
+/* Importe la définition d'un signet dans un flux réseau. */
+static bool g_db_bookmark_recv_from_fd(GDbBookmark *, int, int);
+
+/* Exporte la définition d'un signet dans un flux réseau. */
+static bool g_db_bookmark_send_to_fd(const GDbBookmark *, int, int);
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  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 ("            \
+             "id INT PRIMARY KEY NOT NULL, "    \
+             "user TEXT NOT NULL, "             \
+             "created INT NOT NULL, "           \
+             "address INT NOT NULL, "           \
+             "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);
+
+}
+
+
+
+
+
+
+
+
+
+
+/* Indique le type défini pour un signet à l'intérieur d'une zone de texte. */
+G_DEFINE_TYPE(GDbBookmark, g_db_bookmark, G_TYPE_DB_ITEM);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des signets dans une zone de texte.     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_bookmark_class_init(GDbBookmarkClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GDbItemClass *item;                     /* Encore une autre vision...  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_db_bookmark_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_db_bookmark_finalize;
+
+    item = G_DB_ITEM_CLASS(klass);
+
+    item->cmp = (GCompareFunc)g_db_bookmark_cmp;
+
+    item->recv = (recv_db_item_fc)g_db_bookmark_recv_from_fd;
+    item->send = (send_db_item_fc)g_db_bookmark_send_to_fd;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bookmark = instance à initialiser.                           *
+*                                                                             *
+*  Description : Initialise un signet dans une zone de texte.                 *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_bookmark_init(GDbBookmark *bookmark)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bookmark = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_bookmark_dispose(GDbBookmark *bookmark)
+{
+    G_OBJECT_CLASS(g_db_bookmark_parent_class)->dispose(G_OBJECT(bookmark));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bookmark = instance d'objet GLib à traiter.                  *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_bookmark_finalize(GDbBookmark *bookmark)
+{
+    G_OBJECT_CLASS(g_db_bookmark_parent_class)->finalize(G_OBJECT(bookmark));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : addr    = adresse inamovible localisant une position donnée. *
+*                comment = commentaire construit ou NULL.                     *
+*                                                                             *
+*  Description : Crée une définition d'un signet dans une zone de texte.      *
+*                                                                             *
+*  Retour      : Signet mis en place ou NULL en cas d'erreur.                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GDbBookmark *g_db_bookmark_new(const vmpa2t *addr, const char *comment)
+{
+    GDbBookmark *result;                    /* Instance à retourner        */
+
+    result = g_object_new(G_TYPE_DB_BOOKMARK, NULL);
+
+
+
+
+    /* TODO */
+
+    //dup addr;
+
+
+    g_db_bookmark_set_comment(result, comment);
+
+    return result;
+
+}
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier élément à analyser.                              *
+*                b = second élément à analyser.                               *
+*                                                                             *
+*  Description : Effectue la comparaison entre deux signets de collection.    *
+*                                                                             *
+*  Retour      : Bilan de la comparaison : -1, 0 ou 1.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+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);
+
+    if (result == 0)
+        result = cmp_rle_string(&a->comment, &b->comment);
+
+    return 0;
+
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bookmark = signet dont les informations sont à charger. [OUT]*
+*                fd       = flux ouvert en lecture pour l'importation.        *
+*                flags    = éventuelles options d'envoi supplémentaires.      *
+*                                                                             *
+*  Description : Importe la définition d'un signet dans un flux réseau.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_db_bookmark_recv_from_fd(GDbBookmark *bookmark, int fd, int flags)
+{
+    bool status;                            /* Bilan d'opération initiale  */
+
+    status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->recv(G_DB_ITEM(bookmark), fd, flags);
+    if (!status) return false;
+
+    if (!recv_vmpa(&bookmark->addr, fd, 0))
+        return false;
+
+    if (!recv_rle_string(&bookmark->comment, fd, 0))
+        return false;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bookmark = informations à sauvegarder.                       *
+*                fd       = flux ouvert en écriture pour l'exportation.       *
+*                flags    = éventuelles options d'envoi supplémentaires.      *
+*                                                                             *
+*  Description : Exporte la définition d'un signet dans un flux réseau.       *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_db_bookmark_send_to_fd(const GDbBookmark *bookmark, int fd, int flags)
+{
+    bool status;                            /* Bilan d'opération initiale  */
+
+    status = G_DB_ITEM_CLASS(g_db_bookmark_parent_class)->send(G_DB_ITEM(bookmark), fd, MSG_MORE | flags);
+    if (!status) return false;
+
+
+    printf("<sending> FROM %s...\n", __FUNCTION__);
+
+
+    if (!send_vmpa(&bookmark->addr, fd, MSG_MORE | flags))
+        return false;
+
+    if (!send_rle_string(&bookmark->comment, fd, flags))
+        return false;
+
+    return true;
+
+}
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bookmark = informations à consulter.                         *
+*                                                                             *
+*  Description : Fournit l'adresse associée à un signet.                      *
+*                                                                             *
+*  Retour      : Adresse mémoire.                                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+vmpa2t *g_db_bookmark_get_address(GDbBookmark *bookmark)
+{
+    return &bookmark->addr;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bookmark = informations à consulter.                         *
+*                                                                             *
+*  Description : Fournit le commentaire associé à un signet.                  *
+*                                                                             *
+*  Retour      : Commentaire existant ou NULL.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_db_bookmark_get_comment(const GDbBookmark *bookmark)
+{
+    return get_rle_string(&bookmark->comment);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : bookmark = informations à consulter.                         *
+*                comment  = commentaire construit ou NULL.                    *
+*                                                                             *
+*  Description : Définit le commentaire associé à un signet.                  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_db_bookmark_set_comment(GDbBookmark *bookmark, const char *comment)
+{
+    set_rle_string(&bookmark->comment, comment);
+
+}
diff --git a/src/analysis/db/items/bookmark.h b/src/analysis/db/items/bookmark.h
new file mode 100644
index 0000000..d1b073c
--- /dev/null
+++ b/src/analysis/db/items/bookmark.h
@@ -0,0 +1,79 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bookmark.h - prototypes pour la gestion des signets au sein d'un binaire
+ *
+ * Copyright (C) 2014 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_ITEMS_BOOKMARK_H
+#define _ANALYSIS_DB_ITEMS_BOOKMARK_H
+
+
+
+#include <glib-object.h>
+#include <sqlite3.h>
+#include <stdbool.h>
+
+
+#include "../../../arch/vmpa.h"
+
+
+
+/* Crée la table des signets dans une base de données. */
+bool create_bookmark_db_table(sqlite3 *);
+
+
+
+
+
+
+
+#define G_TYPE_DB_BOOKMARK               g_db_bookmark_get_type()
+#define G_DB_BOOKMARK(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_bookmark_get_type(), GDbBookmark))
+#define G_IS_DB_BOOKMARK(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_bookmark_get_type()))
+#define G_DB_BOOKMARK_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_BOOKMARK, GDbBookmarkClass))
+#define G_IS_DB_BOOKMARK_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_BOOKMARK))
+#define G_DB_BOOKMARK_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_BOOKMARK, GDbBookmarkClass))
+
+
+/* Signet à l'intérieur d'une zone de texte (instance) */
+typedef struct _GDbBookmark GDbBookmark;
+
+/* Signet à l'intérieur d'une zone de texte (classe) */
+typedef struct _GDbBookmarkClass GDbBookmarkClass;
+
+
+/* Indique le type défini pour un signet à l'intérieur d'une zone de texte. */
+GType g_db_bookmark_get_type(void);
+
+/* Crée une définition d'un signet dans une zone de texte. */
+GDbBookmark *g_db_bookmark_new(const vmpa2t *, const char *);
+
+/* Fournit l'adresse associée à un signet. */
+vmpa2t *g_db_bookmark_get_address(GDbBookmark *);
+
+/* Fournit le commentaire associé à un signet. */
+const char *g_db_bookmark_get_comment(const GDbBookmark *);
+
+/* Définit le commentaire associé à un signet. */
+void g_db_bookmark_set_comment(GDbBookmark *, const char *);
+
+
+
+#endif  /* _ANALYSIS_DB_ITEMS_BOOKMARK_H */
diff --git a/src/analysis/db/items/comment.c b/src/analysis/db/items/comment.c
new file mode 100644
index 0000000..73a18b0
--- /dev/null
+++ b/src/analysis/db/items/comment.c
@@ -0,0 +1,398 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * comment.c - gestion des commentaires dans du texte
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+
+#include "comment.h"
+
+
+#include <stdio.h>
+#include <sys/socket.h>
+
+
+#include "../item-int.h"
+#include "../misc/rlestr.h"
+
+
+
+/* Commentaire à placer dans du texte quelconque (instance) */
+struct _GDbComment
+{
+    GDbItem parent;                         /* A laisser en premier        */
+
+    vmpa2t *addr;                           /* Adresse du commentaire      */
+    rle_string text;                        /* Contenu du commentaire      */
+
+};
+
+/* Commentaire à placer dans du texte quelconque (classe) */
+struct _GDbCommentClass
+{
+    GDbItemClass parent;                    /* A laisser en premier        */
+
+};
+
+
+
+/* Initialise la classe des commentaires dans une zone de texte. */
+static void g_db_comment_class_init(GDbCommentClass *);
+
+/* Initialise un commentaire dans une zone de texte. */
+static void g_db_comment_init(GDbComment *);
+
+/* Supprime toutes les références externes. */
+static void g_db_comment_dispose(GDbComment *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_db_comment_finalize(GDbComment *);
+
+/* Effectue la comparaison entre deux commentaires enregistrés. */
+static gint g_db_comment_cmp(GDbComment *, GDbComment *);
+
+/* Importe la définition d'un commentaire dans un flux réseau. */
+static bool g_db_comment_recv_from_fd(GDbComment *, int, int);
+
+/* Exporte la définition d'un commentaire dans un flux réseau. */
+static bool g_db_comment_send_to_fd(const GDbComment *, int, int);
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : db = accès à la base de données.                             *
+*                                                                             *
+*  Description : Crée la table des commentaires dans une base de données.     *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool create_comment_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 Comments ("            \
+             "id INT PRIMARY KEY NOT NULL, "    \
+             "user TEXT NOT NULL, "             \
+             "created INT NOT NULL, "           \
+             "address INT NOT NULL, "           \
+             "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);
+
+}
+
+
+
+
+
+
+
+
+
+
+/* Indique le type défini pour un commentaire à l'intérieur d'une zone de texte. */
+G_DEFINE_TYPE(GDbComment, g_db_comment, G_TYPE_DB_ITEM);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des commentaires dans une zone de texte.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_comment_class_init(GDbCommentClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GDbItemClass *item;                     /* Encore une autre vision...  */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_db_comment_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_db_comment_finalize;
+
+    item = G_DB_ITEM_CLASS(klass);
+
+    item->cmp = (GCompareFunc)g_db_comment_cmp;
+
+    item->recv = (recv_db_item_fc)g_db_comment_recv_from_fd;
+    item->send = (send_db_item_fc)g_db_comment_send_to_fd;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = instance à initialiser.                            *
+*                                                                             *
+*  Description : Initialise un commentaire dans une zone de texte.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_comment_init(GDbComment *comment)
+{
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_comment_dispose(GDbComment *comment)
+{
+    G_OBJECT_CLASS(g_db_comment_parent_class)->dispose(G_OBJECT(comment));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = instance d'objet GLib à traiter.                   *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_db_comment_finalize(GDbComment *comment)
+{
+    delete_vmpa(comment->addr);
+
+    exit_rle_string(comment->text);
+
+    G_OBJECT_CLASS(g_db_comment_parent_class)->finalize(G_OBJECT(comment));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : addr        = adresse inamovible localisant une position.    *
+*                text        = commentaire construit ou NULL.                 *
+*                is_volatile = état du besoin en sauvegarde.                  *
+*                                                                             *
+*  Description : Crée une définition de commentaire dans une zone de texte.   *
+*                                                                             *
+*  Retour      : Commentaire mis en place ou NULL en cas d'erreur.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GDbComment *g_db_comment_new(const vmpa2t *addr, const char *text, bool is_volatile)
+{
+    GDbComment *result;                    /* Instance à retourner        */
+
+    result = g_object_new(G_TYPE_DB_COMMENT, NULL);
+
+    result->addr = dup_vmpa(addr);
+
+    g_db_comment_set_text(result, text);
+
+    g_db_item_set_volatile(G_DB_ITEM(result), is_volatile);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : a = premier élément à analyser.                              *
+*                b = second élément à analyser.                               *
+*                                                                             *
+*  Description : Effectue la comparaison entre deux commentaires enregistrés. *
+*                                                                             *
+*  Retour      : Bilan de la comparaison : -1, 0 ou 1.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gint g_db_comment_cmp(GDbComment *a, GDbComment *b)
+{
+    gint result;                            /* Bilan de la comparaison     */
+
+    result = cmp_vmpa_by_phy(a->addr, b->addr);
+
+    if (result == 0)
+        result = cmp_rle_string(&a->text, &b->text);
+
+    return 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = commentaire avec informations sont à charger. [OUT]*
+*                fd      = flux ouvert en lecture pour l'importation.         *
+*                flags   = éventuelles options d'envoi supplémentaires.       *
+*                                                                             *
+*  Description : Importe la définition d'un commentaire dans un flux réseau.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_db_comment_recv_from_fd(GDbComment *comment, int fd, int flags)
+{
+    bool status;                            /* Bilan d'opération initiale  */
+
+    status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->recv(G_DB_ITEM(comment), fd, flags);
+    if (!status) return false;
+
+    if (!recv_vmpa(comment->addr, fd, 0))
+        return false;
+
+    if (!recv_rle_string(&comment->text, fd, 0))
+        return false;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = informations à sauvegarder.                        *
+*                fd      = flux ouvert en écriture pour l'exportation.        *
+*                flags   = éventuelles options d'envoi supplémentaires.       *
+*                                                                             *
+*  Description : Exporte la définition d'un commentaire dans un flux réseau.  *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool g_db_comment_send_to_fd(const GDbComment *comment, int fd, int flags)
+{
+    bool status;                            /* Bilan d'opération initiale  */
+
+    status = G_DB_ITEM_CLASS(g_db_comment_parent_class)->send(G_DB_ITEM(comment), fd, MSG_MORE | flags);
+    if (!status) return false;
+
+    if (!send_vmpa(comment->addr, fd, MSG_MORE | flags))
+        return false;
+
+    if (!send_rle_string(&comment->text, fd, flags))
+        return false;
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = informations à consulter.                          *
+*                                                                             *
+*  Description : Fournit l'adresse associée à un commentaire.                 *
+*                                                                             *
+*  Retour      : Adresse mémoire.                                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const vmpa2t *g_db_comment_get_address(GDbComment *comment)
+{
+    return comment->addr;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = informations à consulter.                          *
+*                                                                             *
+*  Description : Fournit le commentaire associé à un commentaire.             *
+*                                                                             *
+*  Retour      : Commentaire existant ou NULL.                                *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+const char *g_db_comment_get_text(const GDbComment *comment)
+{
+    return get_rle_string(&comment->text);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : comment = informations à consulter.                          *
+*                text    = commentaire construit ou NULL.                     *
+*                                                                             *
+*  Description : Définit le commentaire associé à un commentaire.             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_db_comment_set_text(GDbComment *comment, const char *text)
+{
+    set_rle_string(&comment->text, text);
+
+}
diff --git a/src/analysis/db/items/comment.h b/src/analysis/db/items/comment.h
new file mode 100644
index 0000000..792fb92
--- /dev/null
+++ b/src/analysis/db/items/comment.h
@@ -0,0 +1,77 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * comment.h - prototypes pour la gestion des commentaires dans du texte
+ *
+ * Copyright (C) 2014 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_ITEMS_COMMENT_H
+#define _ANALYSIS_DB_ITEMS_COMMENT_H
+
+
+
+#include <glib-object.h>
+#include <sqlite3.h>
+#include <stdbool.h>
+
+
+#include "../../../arch/vmpa.h"
+
+
+
+/* Crée la table des commentaires dans une base de données. */
+bool create_comment_db_table(sqlite3 *);
+
+
+
+
+
+#define G_TYPE_DB_COMMENT               g_db_comment_get_type()
+#define G_DB_COMMENT(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_db_comment_get_type(), GDbComment))
+#define G_IS_DB_COMMENT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_db_comment_get_type()))
+#define G_DB_COMMENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_DB_COMMENT, GDbCommentClass))
+#define G_IS_DB_COMMENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_DB_COMMENT))
+#define G_DB_COMMENT_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_DB_COMMENT, GDbCommentClass))
+
+
+/* Commentaire à placer dans du texte quelconque (instance) */
+typedef struct _GDbComment GDbComment;
+
+/* Commentaire à placer dans du texte quelconque (classe) */
+typedef struct _GDbCommentClass GDbCommentClass;
+
+
+/* Indique le type défini pour un commentaire à l'intérieur d'une zone de texte. */
+GType g_db_comment_get_type(void);
+
+/* Crée une définition de commentaire dans une zone de texte. */
+GDbComment *g_db_comment_new(const vmpa2t *, const char *, bool);
+
+/* Fournit l'adresse associée à un commentaire. */
+const vmpa2t *g_db_comment_get_address(GDbComment *);
+
+/* Fournit le commentaire associé à un commentaire. */
+const char *g_db_comment_get_text(const GDbComment *);
+
+/* Définit le commentaire associé à un commentaire. */
+void g_db_comment_set_text(GDbComment *, const char *);
+
+
+
+#endif  /* _ANALYSIS_DB_ITEMS_COMMENT_H */
diff --git a/src/analysis/db/misc/Makefile.am b/src/analysis/db/misc/Makefile.am
new file mode 100755
index 0000000..b3829e3
--- /dev/null
+++ b/src/analysis/db/misc/Makefile.am
@@ -0,0 +1,16 @@
+
+noinst_LTLIBRARIES  = libanalysisdbmisc.la
+
+libanalysisdbmisc_la_SOURCES =			\
+	rlestr.h rlestr.c
+
+libanalysisdbmisc_la_LIBADD = 
+
+libanalysisdbmisc_la_LDFLAGS = 
+
+
+AM_CPPFLAGS = $(LIBGTK_CFLAGS) $(LIBXML_CFLAGS) $(LIBARCHIVE_CFLAGS) $(LIBSQLITE_CFLAGS)
+
+AM_CFLAGS = $(DEBUG_CFLAGS) $(WARNING_FLAGS) $(COMPLIANCE_FLAGS)
+
+SUBDIRS = 
diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c
new file mode 100644
index 0000000..d75e7ab
--- /dev/null
+++ b/src/analysis/db/misc/rlestr.c
@@ -0,0 +1,345 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rlestr.c - encodage par plage unique d'une chaîne de caractères
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+
+#include "rlestr.h"
+
+
+#include <endian.h>
+#include <malloc.h>
+#include <string.h>
+
+
+#include "../../../common/io.h"
+
+
+
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <time.h>
+#include <unistd.h>
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : str  = représentation de chaîne à traiter.                   *
+*                data = données à conserver en mémoire.                       *
+*                                                                             *
+*  Description : Définit une représentation de chaîne de caractères.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void init_rle_string(rle_string *str, const char *data)
+{
+    if (data != NULL)
+    {
+        str->data = strdup(data);
+        str->length = strlen(data);
+    }
+    else
+    {
+        str->data = NULL;
+        str->length = 0;
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : str  = représentation de chaîne à traiter.                   *
+*                data = données à conserver en mémoire.                       *
+*                                                                             *
+*  Description : Constitue une représentation de chaîne de caractères.        *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void set_rle_string(rle_string *str, const char *data)
+{
+    if (str->data != NULL)
+        unset_rle_string(str);
+
+    if (data != NULL)
+    {
+        str->data = strdup(data);
+        str->length = strlen(data);
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : str = représentation de chaîne à traiter.                    *
+*                                                                             *
+*  Description : Libère la mémoire associée à la représentation.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void unset_rle_string(rle_string *str)
+{
+    if (str->data != NULL)
+    {
+        free(str->data);
+        str->data = NULL;
+
+        str->length = 0;
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : s1 = première chaîne à comparer.                             *
+*                s2 = seconde chaîne à comparer.                              *
+*                                                                             *
+*  Description : Effectue la comparaison entre deux chaînes de caractères.    *
+*                                                                             *
+*  Retour      : Résultat de la comparaison : -1, 0 ou 1.                     *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int cmp_rle_string(const rle_string *s1, const rle_string *s2)
+{
+    int result;                             /* Bilan à retourner           */
+
+    if (s1->length < s2->length)
+        result = -1;
+
+    else if (s1->length > s2->length)
+        result = 1;
+
+    else
+    {
+        if (s1->data == NULL && s2->data == NULL)
+            result = 0;
+
+        else if (s1->data != NULL && s2->data == NULL)
+            result = 1;
+
+        else if (s1->data == NULL && s2->data != NULL)
+            result = -1;
+
+        else
+            result = strcmp(s1->data, s2->data);
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : str = informations à constituer. [OUT]                       *
+*                fd  = flux ouvert en lecture pour l'importation.             *
+*                                                                             *
+*  Description : Importe la définition d'une chaîne de caractères.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_rle_string(rle_string *str, int fd)
+{
+#if 0
+    uint32_t val32;                         /* Valeur sur 32 bits          */
+    ssize_t got;                            /* Quantité de données reçues  */
+
+    got = safe_recv(fd, &val32, sizeof(uint32_t), MSG_WAITALL);
+    if (got != sizeof(uint32_t)) return false;
+
+    str->length = le32toh(val32);
+
+    if (str->length > 0)
+    {
+        str->data = (char *)malloc(str->length + 1);
+
+        got = safe_recv(fd, str->data, str->length + 1, MSG_WAITALL);
+        if (got != (str->length + 1))
+        {
+            unset_rle_string(str);
+            return false;
+        }
+
+        str->data[str->length] = '\0';
+
+    }
+#endif
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : str = informations à sauvegarer.                             *
+*                fd  = flux ouvert en écriture pour l'exportation.            *
+*                                                                             *
+*  Description : Exporte la définition d'une chaîne de caractères.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool store_rle_string(const rle_string *str, int fd)
+{
+#if 0
+    ssize_t got;                            /* Quantité de données reçues  */
+
+    got = safe_send(fd, (uint32_t []) { htole32(str->length) }, sizeof(uint32_t), MSG_WAITALL);
+    if (got != sizeof(uint32_t)) return false;
+
+    if (str->length > 0)
+    {
+        got = safe_send(fd, str->data, str->length + 1, MSG_WAITALL);
+        if (got != (str->length + 1)) return false;
+    }
+#endif
+    return true;
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : str   = informations à constituer. [OUT]                     *
+*                fd    = flux ouvert en lecture pour l'importation.           *
+*                flags = éventuelles options de réception supplémentaires.    *
+*                                                                             *
+*  Description : Importe la définition d'une chaîne de caractères.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool recv_rle_string(rle_string *str, int fd, int flags)
+{
+    uint32_t val32;                         /* Valeur sur 32 bits          */
+    bool status;                            /* Bilan d'une opération       */
+
+    str->data = NULL;
+    str->length = 0;
+
+    status = safe_recv(fd, &val32, sizeof(uint32_t), flags);
+    if (!status) return false;
+
+    str->length = be32toh(val32);
+
+    if (str->length > 0)
+    {
+        str->data = (char *)malloc(str->length + 1);
+
+        status = safe_recv(fd, str->data, str->length + 1, flags);
+        if (!status)
+        {
+            unset_rle_string(str);
+            return false;
+        }
+
+        str->data[str->length] = '\0';
+
+    }
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : str   = informations à sauvegarer.                           *
+*                fd    = flux ouvert en écriture pour l'exportation.          *
+*                flags = éventuelles options d'envoi supplémentaires.         *
+*                                                                             *
+*  Description : Exporte la définition d'une chaîne de caractères.            *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool send_rle_string(const rle_string *str, int fd, int flags)
+{
+    bool status;                            /* Bilan d'une opération       */
+
+    status = safe_send(fd, (uint32_t []) { htobe32(str->length) }, sizeof(uint32_t), flags);
+    if (!status) return false;
+
+    if (str->length > 0)
+    {
+        status = safe_send(fd, str->data, str->length + 1, flags);
+        if (!status) return false;
+    }
+
+    return true;
+
+}
diff --git a/src/analysis/db/misc/rlestr.h b/src/analysis/db/misc/rlestr.h
new file mode 100644
index 0000000..2aa863f
--- /dev/null
+++ b/src/analysis/db/misc/rlestr.h
@@ -0,0 +1,83 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * rlestr.h - prototypes pour l'encodage par plage unique d'une chaîne de caractères
+ *
+ * Copyright (C) 2014 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_MISC_RLESTR_H
+#define _ANALYSIS_DB_MISC_RLESTR_H
+
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+
+
+/* Informations de base pour tout élément ajouté */
+typedef struct _rle_string
+{
+    char *data;                             /* Chaîne de caractères        */
+    uint32_t length;                        /* Taille de la chaîne         */
+
+} rle_string;
+
+
+/* Définit une représentation de chaîne de caractères. */
+void init_rle_string(rle_string *, const char *);
+
+#define exit_rle_string(rle) /* TODO */
+
+#define dup_rle_string(dst, src) init_rle_string(dst, (src)->data);
+
+#define get_rle_string(rle) (rle)->data
+
+/* Constitue une représentation de chaîne de caractères. */
+void set_rle_string(rle_string *, const char *);
+
+/* Libère la mémoire associée à la représentation. */
+void unset_rle_string(rle_string *);
+
+/* Effectue la comparaison entre deux chaînes de caractères. */
+int cmp_rle_string(const rle_string *, const rle_string *);
+
+
+
+/* Importe la définition d'une chaîne de caractères. */
+bool load_rle_string(rle_string *, int);
+
+/* Exporte la définition d'une chaîne de caractères. */
+bool store_rle_string(const rle_string *, int);
+
+
+
+#define is_rle_string_empty(rle) ((rle)->data == NULL)
+
+
+
+/* Importe la définition d'une chaîne de caractères. */
+bool recv_rle_string(rle_string *, int, int);
+
+/* Exporte la définition d'une chaîne de caractères. */
+bool send_rle_string(const rle_string *, int, int);
+
+
+
+#endif  /* _ANALYSIS_DB_MISC_RLESTR_H */
diff --git a/src/analysis/db/protocol.h b/src/analysis/db/protocol.h
index b1cdfaf..05b559e 100644
--- a/src/analysis/db/protocol.h
+++ b/src/analysis/db/protocol.h
@@ -27,10 +27,12 @@
 
 
 /**
- * Nombre maximal de connexions à un serveur.
- * cf. listen().
+ * Version de la définition courante du protocole.
  */
-#define CDB_SEVER_BACKLOG 100
+#define CDB_PROTOCOL_VERSION 0xc0de0001
+
+
+
 
 /**
  * Délai maximal de réaction pour les coupures de flux (en ms).
@@ -41,27 +43,102 @@
 
 
 
-/* Fonctionnalités offertes */
+/* Comportement vis à vis des éléments */
+typedef enum _DBStorage
+{
+    DBS_ALL_LOCAL           = 0x01,         /* Enregistrements locaux      */
+    DBS_ALL_REMOTE          = 0x02,         /* Enregistrements distants    */
+    DBS_LOCAL_AND_REMOTE    = 0x03,         /* Enreg. locaux + infos dists.*/
+
+    DBS_MAX = 3
+
+} DBStorage;
+
+
+
+
+
+
+
+
+
+
+
+
+/**
+ * Une fois la connexion établie, les paquets ont tous la forme suivante :
+
+
+
+
+
+ *
+ *    [ type de collection visée ; cf. DBFeatures ]
+ *    [ action à mener ; cf. DBAction             ]
+ *    [ élément de type GDbItem sérialisé...      ]
+ *
+ */
+
+/* Fonctionnalités offertes nativement */
 typedef enum _DBFeatures
 {
+    DBF_BOOKMARKS,                          /* Signets dans le code        */
     DBF_COMMENTS,                           /* Commentaires ajoutés        */
     DBF_SEGMENTS_DISPLAY,                   /* Choix d'affichage           */
-    DBF_BOOKMARKS,                          /* Signets dans le code        */
 
     DBF_COUNT
 
 } DBFeatures;
 
-/* Comportement vis à vis des éléments */
-typedef enum _DBStorage
+/* Interactions disponibles vis à vis d'une collection. */
+typedef enum _DBAction
 {
-    DBS_ALL_LOCAL           = 0x01,         /* Enregistrements locaux      */
-    DBS_ALL_REMOTE          = 0x02,         /* Enregistrements distants    */
-    DBS_LOCAL_AND_REMOTE    = 0x03,         /* Enreg. locaux + infos dists.*/
+    DBA_ADD_ITEM,                           /* Ajout d'un élément          */
+    DBA_REM_ITEM,                           /* Suppression d'un élément    */
+    DBA_MOD_ITEM,                           /* Modification de l'existant  */
+
+    DBA_COUNT
+
+} DBAction;
+
+
+
+
+
+
+/**
+ * Commandes envoyées d'un côté à un autre.
+ */
+typedef enum _DBCommand
+{
+    DBC_HELO,                               /* Connexion initiale C -> S   */
+    DBC_WELCOME,                            /* Réponse initiale S -> C     */
+    DBC_COLLECTION,                         /* Implication d'une collection*/
+
+    DBC_COUNT
+
+} DBCommand;
+
+
+
+
+
+
+
+/**
+ * Erreurs pouvant survenir...
+ */
+typedef enum _DBError
+{
+    DBE_NONE,                               /* Succès d'une opération      */
+    DBE_WRONG_VERSION,                      /* Proto Client != Serveur     */
+
+    DBE_COUNT
+
+} DBError;
+
 
-    DBS_MAX = 3
 
-} DBStorage;
 
 
 
diff --git a/src/analysis/db/server.c b/src/analysis/db/server.c
index 3d75b71..42688c8 100644
--- a/src/analysis/db/server.c
+++ b/src/analysis/db/server.c
@@ -29,10 +29,15 @@
 #include <poll.h>
 #include <string.h>
 #include <unistd.h>
+#include <arpa/inet.h>
 #include <sys/socket.h>
 
 
+#include "cdb.h"
 #include "protocol.h"
+#include "misc/rlestr.h"
+#include "../../common/io.h"
+#include "../../core/params.h"
 #include "../../gui/panels/log.h"
 
 
@@ -56,10 +61,12 @@ struct _GDbServer
 
     int fd;                                 /* Canal de communication      */
     char *hostname;                         /* Désignation humaine         */
+    char *desc;                             /* Désignation du serveur      */
     struct sockaddr_in addr;                /* Adresse d'écoute            */
 
     GThread *listener;                      /* Procédure de traitement     */
 
+    GList *archives;                        /* Liste des binaires ouverts  */
     cdb_client **clients;                   /* Connexions en place         */
     size_t count;                           /* Quantité de clients         */
     GMutex mutex;                           /* Verrou pour l'accès         */
@@ -87,7 +94,7 @@ static void g_db_server_finalize(GDbServer *);
 static void *g_db_server_listener(GDbServer *);
 
 /* Assure le traitement des requêtes de clients. */
-static void *g_db_server_process(cdb_client **);
+//static void *g_db_server_process(cdb_client **);
 
 
 
@@ -177,19 +184,38 @@ GDbServer *g_db_server_new(const char *host, short port)
 {
     GDbServer *result;                      /* Adresse à retourner         */
     struct hostent *hp;                     /* Informations sur l'hôte     */
+    size_t desclen;                         /* Taille de désignation       */
+
+    const char *ip;                         /* Adresse IPv4 ou IPv6        */
 
     result = g_object_new(G_TYPE_DB_SERVER, NULL);
 
     result->hostname = strdup(host);
 
     hp = gethostbyname(host);
-    if (hp == NULL) goto gdsn_error;
+    if (hp == NULL)
+    {
+        perror("gethostbyname");
+        goto gdsn_error;
+    }
 
     result->addr.sin_family = hp->h_addrtype;
     memcpy(&result->addr.sin_addr, hp->h_addr_list[0], sizeof(struct in_addr));
 
     result->addr.sin_port = htons(port);
 
+    desclen = INET6_ADDRSTRLEN + 1 + 5 + 1;
+    result->desc = (char *)calloc(desclen, sizeof(char));
+
+    ip = inet_ntop(AF_INET, &result->addr.sin_addr, result->desc, INET6_ADDRSTRLEN);
+    if (ip == NULL)
+    {
+        perror("inet_ntop");
+        goto gdsn_error;
+    }
+
+    snprintf(result->desc + strlen(ip), 1 + 5, ":%hu", port);
+
     return result;
 
  gdsn_error:
@@ -219,7 +245,27 @@ static void *g_db_server_listener(GDbServer *server)
     int ret;                                /* Bilan d'un appel            */
     struct sockaddr_in peer;                /* Adresse cliente             */
     int fd;                                 /* Canal établi vers un client */
-    cdb_client *client;                     /* Mémorisation pour poursuite */
+    char source[INET6_ADDRSTRLEN];          /* Adresse du client (IPv4/6)  */
+    const char *ip;                         /* Statut de la conversion     */
+
+
+    DBError error;                          /* Validation de la connexion  */
+
+    uint32_t data;                          /* Mot de données lues         */
+
+
+    rle_string hash;                        /* Empreinte du binaire visé   */
+    rle_string user;                        /* Nom d'utilisateur du client */
+
+    GList *iter;                            /* Boucle de parcours          */
+    GCdbArchive *archive;                   /* Destinataire final du client*/
+
+
+
+    //cdb_client *client;                     /* Mémorisation pour poursuite */
+
+
+
 
     fds.fd = server->fd;
     fds.events = POLLIN | POLLPRI;
@@ -236,8 +282,122 @@ static void *g_db_server_listener(GDbServer *server)
         if (fds.revents & (POLLIN | POLLPRI))
         {
             fd = accept(server->fd, &peer, (socklen_t []) { sizeof(struct sockaddr_in) });
-            if (fd == -1) continue;
+            if (fd == -1)
+            {
+                perror("accept");
+                continue;
+            }
+
+            ip = inet_ntop(AF_INET, &peer.sin_addr, source, sizeof(source));
+            if (ip == NULL)
+            {
+                perror("inet_ntop");
+                goto gdsl_error;
+            }
+
+            error = DBE_NONE;
+
+            /**
+             * Le premier "paquet" reçu de la part d'un client doit contenir les informations suivantes :
+             *    - la commande 'DBC_HELO'.
+             *    - le numéro de version du client.
+             *    - l'empreinte du binaire analysé.
+             *    - l'identifiant de l'utilisateur effectuant des modifications.
+             *
+             * Tout ceci est à synchroniser avec la fonction g_db_client_start().
+             */
+
+            if (!safe_recv(fd, &data, sizeof(uint32_t), 0))
+                goto gdsl_error;
+
+            if (be32toh(data) != DBC_HELO)
+            {
+                log_variadic_message(LMT_ERROR, _("The client from '%s:%hu' did not introduce itself!"),
+                                     source, ntohs(peer.sin_port));
+                goto gdsl_error;
+            }
+
+            if (!safe_recv(fd, &data, sizeof(uint32_t), 0))
+                goto gdsl_error;
+
+            if (be32toh(data) != CDB_PROTOCOL_VERSION)
+            {
+                log_variadic_message(LMT_ERROR, _("The client from '%s:%hu' does not use the same protocol: 0x%08x vs 0x%08x..."),
+                                     source, ntohs(peer.sin_port), be32toh(data), CDB_PROTOCOL_VERSION);
+                error = DBE_WRONG_VERSION;
+                goto gdsl_error_sending;
+            }
+
+            if (!recv_rle_string(&hash, fd, 0) || is_rle_string_empty(&hash))
+            {
+                log_variadic_message(LMT_ERROR, _("Error while getting the binary hash from '%s:%hu'..."),
+                                     source, ntohs(peer.sin_port));
+                goto gdsl_error;
+            }
+
+            if (!recv_rle_string(&user, fd, 0) || is_rle_string_empty(&user))
+            {
+                log_variadic_message(LMT_ERROR, _("Error while getting the user name from '%s:%hu'..."),
+                                     source, ntohs(peer.sin_port));
+                goto gdsl_error;
+            }
+
+            /**
+             * On met en place le maximum ici, de manière à pouvoir indiquer une erreur
+             * en cas d'échec, et être le plus précis possible dans la courte réponse.
+             */
+
+            for (iter = g_list_first(server->archives);
+                 iter != NULL;
+                 iter = g_list_next(iter))
+            {
+                archive = G_CDB_ARCHIVE(iter->data);
+                if (g_cdb_archive_compare_hash(archive, &hash) == 0)
+                    break;
+            }
+
+            if (iter == NULL)
+            {
+                archive = g_cdb_archive_new(server->desc, &hash, &user, &error);
+
+                if (archive != NULL)
+                    server->archives = g_list_append(server->archives, archive);
+
+            }
+
+            if (archive != NULL)
+                error = g_cdb_archive_add_client(archive, fd, &user);
+
+            /**
+             * Le serveur doit répondre pour un message type :
+             *    - la commande 'DBC_WELCOME'.
+             *    - un identifiant d'erreur ('DBE_NONE' ou 'DBE_WRONG_VERSION').
+             */
+
+ gdsl_error_sending:
+
+            if (!safe_send(fd, (uint32_t []) { htobe32(DBC_WELCOME) }, sizeof(uint32_t), MSG_MORE))
+                goto gdsl_error;
+
+            if (!safe_send(fd, (uint32_t []) { htobe32(error) }, sizeof(uint32_t), 0))
+                goto gdsl_error;
+
+            if (error == DBE_NONE) continue;
+
+ gdsl_error:
+
+
+            /* free RLE !!!! */
+
 
+            close(fd);
+
+        }
+
+
+
+
+#if 0
             g_mutex_lock(&server->mutex);
 
             client = (cdb_client *)calloc(1, sizeof(cdb_client));
@@ -256,80 +416,13 @@ static void *g_db_server_listener(GDbServer *server)
                                           &server->clients[server->count - 1]);
 
             g_mutex_unlock(&server->mutex);
+#endif
 
-        }
 
-    }
 
-    return NULL;
-
-}
-
-
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : client = informations sur une connexion établie à utiliser.  *
-*                                                                             *
-*  Description : Assure le traitement des requêtes de clients.                *
-*                                                                             *
-*  Retour      : NULL.                                                        *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
-
-static void *g_db_server_process(cdb_client **client)
-{
-    struct pollfd fds;                      /* Surveillance des flux       */
-    int ret;                                /* Bilan d'un appel            */
-    GDbServer *server;                      /* Accès facile en mémoire     */
-    size_t index;                           /* Indice courant du client    */
-    size_t remaining;                       /* Quantité à déplacer         */
-
-    fds.fd = (*client)->fd;
-    fds.events = POLLIN | POLLPRI;
-
-    while (1)
-    {
-        ret = poll(&fds, 1, -1);
-        if (ret != 1) continue;
-
-        printf("fds.revents :: %x\n", fds.revents);
-
-        /* Le canal est fermé, une sortie doit être demandée... */
-        if (fds.revents & POLLNVAL)
-            break;
-
-        if (fds.revents & (POLLIN | POLLPRI))
-        {
-
-            /* TODO */
-            pause();
-
-
-        }
 
     }
 
-    /* Retrait de la liste avant la terminaison */
-
-    server = (*client)->server;
-
-    g_mutex_lock(&server->mutex);
-
-    index = (client - server->clients);
-    remaining = server->count - index - 1;
-
-    if (remaining > 0)
-        memmove(&server->clients[index], &server->clients[index + 1],
-                remaining * sizeof(cdb_client *));
-
-    g_object_unref(G_OBJECT(server));
-
-    free(*client);
-
-    g_mutex_unlock(&server->mutex);
-
     return NULL;
 
 }
@@ -350,6 +443,7 @@ static void *g_db_server_process(cdb_client **client)
 bool g_db_server_start(GDbServer *server)
 {
     int ret;                                /* Bilan d'un appel            */
+    int backlog;                            /* Nombre de connexions maximal*/
 
     server->fd = socket(AF_INET, SOCK_STREAM, 0);
     if (server->fd == -1)
@@ -362,27 +456,24 @@ bool g_db_server_start(GDbServer *server)
     if (ret == -1)
     {
         perror("setsockopt");
-        close(server->fd);
-        server->fd = -1;
-        return false;
+        goto gdss_error;
     }
 
     ret = bind(server->fd, (struct sockaddr *)&server->addr, sizeof(struct sockaddr_in));
     if (ret == -1)
     {
         perror("bind");
-        close(server->fd);
-        server->fd = -1;
-        return false;
+        goto gdss_error;
     }
 
-    ret = listen(server->fd, CDB_SEVER_BACKLOG);
+    if (!g_generic_config_get_value(get_main_configuration(), MPK_SERVER_BACKLOG, &backlog))
+        goto gdss_error;
+
+    ret = listen(server->fd, backlog);
     if (ret == -1)
     {
         perror("listen");
-        close(server->fd);
-        server->fd = -1;
-        return false;
+        goto gdss_error;
     }
 
     server->listener = g_thread_new("cdb_listener", (GThreadFunc)g_db_server_listener, server);
@@ -392,6 +483,13 @@ bool g_db_server_start(GDbServer *server)
 
     return true;
 
+ gdss_error:
+
+    close(server->fd);
+    server->fd = -1;
+
+    return false;
+
 }
 
 
diff --git a/src/arch/vmpa.h b/src/arch/vmpa.h
index 7f417b5..d89c290 100644
--- a/src/arch/vmpa.h
+++ b/src/arch/vmpa.h
@@ -26,6 +26,7 @@
 
 
 #include <limits.h>
+#include <malloc.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <sys/types.h>
diff --git a/src/common/io.c b/src/common/io.c
index 2275cb4..23fad54 100644
--- a/src/common/io.c
+++ b/src/common/io.c
@@ -24,16 +24,118 @@
 #include "io.h"
 
 
+#include <errno.h>
 #include <libgen.h>
 #include <malloc.h>
+#include <stdint.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/socket.h>
 #include <sys/stat.h>
 
 
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : sockfd = flux ouvert en lecture.                             *
+*                buf    = données à recevoir.                                 *
+*                len    = quantité de ces données.                            *
+*                flags  = options de réception.                               *
+*                                                                             *
+*  Description : Réceptionne des données depuis un flux réseau.               *
+*                                                                             *
+*  Retour      : true si toutes les données ont été reçues, false sinon.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool safe_recv(int sockfd, const void *buf, size_t len, int flags)
+{
+    uint8_t *iter;                          /* Données en attente          */
+    size_t remaining;                       /* Quantité restante           */
+    ssize_t got;                            /* Données envoyées            */
+
+    iter = (uint8_t *)buf;
+    remaining = len;
+
+    while (remaining > 0)
+    {
+        got = recv(sockfd, iter, remaining, MSG_NOSIGNAL | flags);
+        if (got == -1)
+        {
+            if (errno == EINTR) continue;
+            else
+            {
+                perror("recv");
+                break;
+            }
+        }
+
+        iter += got;
+        remaining -= got;
+
+    }
+
+    return (remaining == 0);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : sockfd = flux ouvert en écriture.                            *
+*                buf    = données à émettre.                                  *
+*                len    = quantité de ces données.                            *
+*                flags  = options d'envoi.                                    *
+*                                                                             *
+*  Description : Envoie des données au travers un flux réseau.                *
+*                                                                             *
+*  Retour      : true si toutes les données ont été émises, false sinon.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool safe_send(int sockfd, const void *buf, size_t len, int flags)
+{
+    uint8_t *iter;                          /* Données en attente          */
+    size_t remaining;                       /* Quantité restante           */
+    ssize_t sent;                           /* Données envoyées            */
+
+    iter = (uint8_t *)buf;
+    remaining = len;
+
+    while (remaining > 0)
+    {
+        sent = send(sockfd, iter, remaining, MSG_NOSIGNAL | flags);
+        if (sent == -1)
+        {
+            if (errno == EINTR) continue;
+            else
+            {
+                perror("send");
+                break;
+            }
+        }
+
+        iter += sent;
+        remaining -= sent;
+
+    }
+
+    return (remaining == 0);
+
+}
+
+
+
+
+
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : path = chemin d'accès à valider.                             *
 *                                                                             *
 *  Description : S'assure qu'un chemin donné existe dans le système.          *
diff --git a/src/common/io.h b/src/common/io.h
index 491d8d0..8dd38c8 100644
--- a/src/common/io.h
+++ b/src/common/io.h
@@ -25,14 +25,19 @@
 #define _COMMON_IO_H
 
 
-
+#include <stdbool.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 
 
-#define safe_recv recv
 
-#define safe_send send
+/* Réceptionne des données depuis un flux réseau. */
+bool safe_recv(int, const void *, size_t, int);
+
+/* Envoie des données au travers un flux réseau. */
+bool safe_send(int, const void *, size_t, int);
+
+
 
 
 #define safe_read read
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index 0724a3f..02b6877 100755
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -2,6 +2,7 @@
 noinst_LTLIBRARIES = libcore.la
 
 libcore_la_SOURCES =					\
+	collections.h collections.c			\
 	core.h core.c						\
 	params.h params.c
 
diff --git a/src/core/collections.c b/src/core/collections.c
new file mode 100644
index 0000000..860b7f6
--- /dev/null
+++ b/src/core/collections.c
@@ -0,0 +1,175 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * collections.c - enregistrement et la diffusion des collections
+ *
+ * Copyright (C) 2014 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/>.
+ */
+
+
+#include "collections.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <pthread.h>
+
+
+#include "../analysis/db/collection.h"
+#include "../analysis/db/protocol.h"
+#include "../analysis/db/items/bookmark.h"
+
+
+
+/* Caractéristiques d'une collection */
+typedef struct _collec_t
+{
+    GType items;                            /* Type d'éléments rassemblés  */
+    create_db_table_fc create;              /* Création de la BD associée  */
+
+} collec_t;
+
+
+/* Mémorisation des types de collection enregistrés */
+static collec_t *_collection_definitions = NULL;
+static uint32_t _collection_definitions_count = 0;
+
+/* Verrou pour des accès atomiques */
+/* ... */
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : items  = type GLib des éléments constituant une collection.  *
+*                create = création de la base de données correspondante.      *
+*                                                                             *
+*  Description : Enregistre un type d'élément à gérer par collection.         *
+*                                                                             *
+*  Retour      : Identifiant unique attribué "dynamiquement".                 *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+uint32_t register_collection_type(GType items, create_db_table_fc create)
+{
+    uint32_t result;                        /* Identifiant à retourner     */
+
+    /* TODO : lock */
+
+    result = _collection_definitions_count++;
+
+    _collection_definitions = (collec_t *)realloc(_collection_definitions,
+                                                  _collection_definitions_count * sizeof(collec_t));
+
+    _collection_definitions[result].items = items;
+    _collection_definitions[result].create = create;
+
+    /* TODO : unlock */
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Charge les définitions de collections "natives".             *
+*                                                                             *
+*  Retour      : Bilan de l'opération.                                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool load_hard_coded_collection_definitions(void)
+{
+    uint32_t id;                            /* Identifiant unique retourné */
+
+    /**
+     * La liste des chargements doit se faire dans le même ordre que
+     * la définition de l'énumération 'DBFeatures' dans le fichier 'protocol.h',
+     * afin de garder la correspondance entre les identifiants.
+     */
+
+    id = register_collection_type(G_TYPE_DB_BOOKMARK, create_bookmark_db_table);
+    assert(id == DBF_BOOKMARKS);
+
+    return true;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Décharge toutes les définitions de collections.              *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void unload_collection_definitions(void)
+{
+    if (_collection_definitions != NULL)
+        free(_collection_definitions);
+
+    _collection_definitions = NULL;
+    _collection_definitions_count = 0;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Construit un nouvel ensemble de collections.                 *
+*                                                                             *
+*  Retour      : Liste complète de collections vierges.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GList *create_collections_list(void)
+{
+    GList *result;                          /* Groupe à retourner          */
+    uint32_t i;                             /* Boucle de parcours          */
+    const collec_t *def;                    /* Définition brute à lire     */
+    GDbCollection *collec;                  /* Nouveau groupe à intégrer   */
+
+    result = NULL;
+
+    for (i = 0; i < _collection_definitions_count; i++)
+    {
+        def = &_collection_definitions[i];
+        collec = g_db_collection_new(i, def->items);
+
+        result = g_list_append(result, collec);
+
+    }
+
+    return result;
+
+}
diff --git a/src/core/collections.h b/src/core/collections.h
new file mode 100644
index 0000000..b84bdd9
--- /dev/null
+++ b/src/core/collections.h
@@ -0,0 +1,54 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * collections.h - prototypes pour l'enregistrement et la diffusion des collections
+ *
+ * Copyright (C) 2014 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 _CORE_COLLECTIONS_H
+#define _CORE_COLLECTIONS_H
+
+
+#include <glib-object.h>
+#include <sqlite3.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+
+
+/* Crée la table dans une base de données. */
+typedef bool (* create_db_table_fc) (sqlite3 *);
+
+
+
+/* Enregistre un type d'élément à gérer par collection. */
+uint32_t register_collection_type(GType, create_db_table_fc);
+
+/* Charge les définitions de collections "natives". */
+bool load_hard_coded_collection_definitions(void);
+
+/* Décharge toutes les définitions de collections. */
+void unload_collection_definitions(void);
+
+/* Construit un nouvel ensemble de collections. */
+GList *create_collections_list(void);
+
+
+
+#endif  /* _ANALYSIS_DB_COLLECTION_H */
diff --git a/src/core/core.c b/src/core/core.c
index d90dd5c..d7e7755 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -24,6 +24,7 @@
 #include "core.h"
 
 
+#include "collections.h"
 #include "params.h"
 
 
@@ -50,6 +51,8 @@ bool load_all_basic_components(void)
 
     result &= g_generic_config_read(get_main_configuration());
 
+    result &= load_hard_coded_collection_definitions();
+
     return result;
 
 }
@@ -69,6 +72,8 @@ bool load_all_basic_components(void)
 
 void unload_all_basic_components(void)
 {
+    unload_collection_definitions();
+
     g_generic_config_write(get_main_configuration());
 
     unload_main_config_parameters();
diff --git a/src/core/params.c b/src/core/params.c
index c8263f0..7bc1162 100644
--- a/src/core/params.c
+++ b/src/core/params.c
@@ -24,6 +24,75 @@
 #include "params.h"
 
 
+#include <limits.h>
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : -                                                            *
+*                                                                             *
+*  Description : Détermine une fois pour toute la désignation de l'usager.    *
+*                                                                             *
+*  Retour      : Nom déterminé à libérer de la mémoire.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static char *get_author_name(void)
+{
+    char *result;                           /* Désignation à retourner     */
+    char *chrysalide_user;                  /* Eventuel nom spécifique     */
+    char *logname;                          /* Nom depuis l'environnement  */
+    char hostname[HOST_NAME_MAX];           /* Nom de la machine courante  */
+    int ret;                                /* Bilan d'un appel            */
+    size_t length;                          /* Taille de la désignation    */
+
+    chrysalide_user = getenv("CHRYSALIDE_USER");
+
+    if (chrysalide_user != NULL)
+        result = strdup(chrysalide_user);
+
+    else
+    {
+        logname = getenv("LOGNAME");
+
+        ret = gethostname(hostname, HOST_NAME_MAX);
+        if (ret != 0)
+            hostname[0] = '\0';
+
+        if (logname != NULL && hostname[0] != '\0')
+        {
+            length = strlen(logname) + 1 + strlen(hostname) + 1;
+            result = (char *)calloc(length, sizeof(char));
+            snprintf(result, length, "%s@%s", logname, hostname);
+        }
+        else if (logname != NULL && hostname[0] == '\0')
+        {
+            length = strlen(logname) + 1;
+            result = (char *)calloc(length, sizeof(char));
+            snprintf(result, length, "%s", logname);
+        }
+        else if (logname == NULL && hostname[0] != '\0')
+        {
+            length = 1 + strlen(hostname) + 1;
+            result = (char *)calloc(length, sizeof(char));
+            snprintf(result, length, "@%s", hostname);
+        }
+        else
+            result = strdup("anonymous");
+
+    }
+
+    return result;
+
+}
+
 
 /******************************************************************************
 *                                                                             *
@@ -41,10 +110,31 @@ bool load_main_config_parameters(void)
 {
     GGenConfig *config;                     /* Configuration à charger     */
     GCfgParam *param;                       /* Paramètre chargé            */
+    char *string;                           /* Valeur sous forme de texte  */
 
     config = g_generic_config_new("main");
     set_main_configuration(config);
 
+    string = get_author_name();
+    param = g_generic_config_create_param(config, MPK_AUTHOR_NAME, CPT_STRING, string);
+    free(string);
+    if (param == NULL) return false;
+
+    param = g_generic_config_create_param(config, MPK_REMOTE_HOST, CPT_STRING, "localhost");
+    if (param == NULL) return false;
+
+    param = g_generic_config_create_param(config, MPK_REMOTE_PORT, CPT_INTEGER, 9999);
+    if (param == NULL) return false;
+
+    param = g_generic_config_create_param(config, MPK_LOCAL_HOST, CPT_STRING, "localhost");
+    if (param == NULL) return false;
+
+    param = g_generic_config_create_param(config, MPK_LOCAL_PORT, CPT_INTEGER, 1337);
+    if (param == NULL) return false;
+
+    param = g_generic_config_create_param(config, MPK_SERVER_BACKLOG, CPT_INTEGER, 20);
+    if (param == NULL) return false;
+
     param = g_generic_config_create_param(config, MPK_LAST_PROJECT, CPT_STRING, NULL);
     if (param == NULL) return false;
 
diff --git a/src/core/params.h b/src/core/params.h
index b79cc3a..db01d20 100644
--- a/src/core/params.h
+++ b/src/core/params.h
@@ -33,6 +33,12 @@
  * Clefs de paramètres de configuration principale.
  */
 
+#define MPK_AUTHOR_NAME         "cdb.default.author"
+#define MPK_REMOTE_HOST         "cdb.default.network.remote.server"
+#define MPK_REMOTE_PORT         "cdb.default.network.remote.port"
+#define MPK_LOCAL_HOST          "cdb.network.local.server"
+#define MPK_LOCAL_PORT          "cdb.network.local.port"
+#define MPK_SERVER_BACKLOG      "cdb.network.server.backlog"
 #define MPK_LAST_PROJECT        "gui.editor.last_project"
 #define MPK_ELLIPSIS_HEADER     "gui.editor.panels.ellipsis_header"
 #define MPK_ELLIPSIS_TAB        "gui.editor.panels.ellipsis_tab"
diff --git a/src/gui/panels/Makefile.am b/src/gui/panels/Makefile.am
index 0f7768c..ad8c6b2 100644
--- a/src/gui/panels/Makefile.am
+++ b/src/gui/panels/Makefile.am
@@ -2,6 +2,7 @@
 noinst_LTLIBRARIES  = libguipanels.la
 
 libguipanels_la_SOURCES =				\
+	bookmarks.h bookmarks.c				\
 	glance.h glance.c					\
 	log.h log.c							\
 	panel.h panel.c						\
diff --git a/src/gui/panels/bookmarks.c b/src/gui/panels/bookmarks.c
new file mode 100644
index 0000000..a61f6bc
--- /dev/null
+++ b/src/gui/panels/bookmarks.c
@@ -0,0 +1,1179 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bookmarks.c - panneau d'affichage des signets d'un binaire
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#include "bookmarks.h"
+
+
+#include <assert.h>
+#include <malloc.h>
+#include <regex.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cairo-gobject.h>
+#include <gtk/gtk.h>
+
+
+#include "panel-int.h"
+#include "../../analysis/db/items/bookmark.h"
+#include "../../core/params.h"
+#include "../../common/cpp.h"
+#include "../../common/extstr.h"
+#include "../../gtkext/easygtk.h"
+#include "../../gtkext/support.h"
+
+
+
+/* -------------------------- PARTIE PRINCIPALE DU PANNEAU -------------------------- */
+
+
+/* Panneau d'affichage des signets liés à un binaire (instance) */
+struct _GBookmarksPanel
+{
+    GPanelItem parent;                      /* A laisser en premier        */
+
+    GtkTreeView *treeview;                  /* Composant d'affichage       */
+    regex_t *filter;                        /* Filtre appliqué ou NULL     */
+
+    GtkMenu *menu;                          /* Menu contextuel pour param. */
+
+    GLoadedBinary *binary;                  /* Binaire en cours d'analyse  */
+
+};
+
+/* Panneau d'affichage des signets liés à un binaire (classe) */
+struct _GBookmarksPanelClass
+{
+    GPanelItemClass parent;                 /* A laisser en premier        */
+
+    cairo_surface_t *bookmark_img;          /* Image pour les signets      */
+
+};
+
+
+/* Colonnes de la liste visuelle */
+typedef enum _BookmarkColumn
+{
+    BMC_BOOKMARK,                           /* Elément GLib représenté     */
+
+    BMC_PICTURE,                            /* Image d'agrément            */
+    BMC_PHYSICAL,                           /* Adresse phyisque            */
+    BMC_VIRTUAL,                            /* Adresse virtuelle           */
+    BMC_COMMENT,                            /* Commentaire associé         */
+
+    BMC_COUNT                               /* Nombre de colonnes          */
+
+} CfgParamColumn;
+
+
+
+
+/* Initialise la classe des panneaux des paramètres de config. */
+static void g_bookmarks_panel_class_init(GBookmarksPanelClass *);
+
+/* Initialise une instance de panneau de paramètres de config. */
+static void g_bookmarks_panel_init(GBookmarksPanel *);
+
+/* Supprime toutes les références externes. */
+static void g_bookmarks_panel_dispose(GBookmarksPanel *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_bookmarks_panel_finalize(GBookmarksPanel *);
+
+
+
+/* ------------------------- AFFICHAGE A L'AIDE D'UNE LISTE ------------------------- */
+
+
+/* Recharge une collection de signets à l'affichage. */
+static void reload_bookmarks_into_treeview(GBookmarksPanel *, GLoadedBinary *);
+
+
+
+
+/* Actualise l'affichage des données d'un paramètre modifié. */
+static void on_config_param_modified(GCfgParam *, GBookmarksPanel *);
+
+/* Actualise la valeur affichée d'un paramètre de configuration. */
+static void update_config_param_value(GtkTreeStore *, GtkTreeIter *);
+
+/* Etablit une comparaison entre deux lignes de paramètres. */
+static gint compare_bookmarks_list_columns(GtkTreeModel *, GtkTreeIter *, GtkTreeIter *, gpointer);
+
+/* Réagit à une pression sur <Shift+F2> et simule l'édition. */
+static gboolean on_key_pressed_over_params(GtkTreeView *, GdkEventKey *, GBookmarksPanel *);
+
+/* Réagit à une édition de la valeur d'un paramètre. */
+static void on_param_value_edited(GtkCellRendererText *, gchar *, gchar *, GtkTreeStore *);
+
+
+
+/* ------------------------- FILTRAGE DES SYMBOLES PRESENTS ------------------------- */
+
+
+/* Démarre l'actualisation du filtrage des paramètres. */
+static void on_param_search_changed(GtkSearchEntry *, GBookmarksPanel *);
+
+/*Détermine si un paramètre doit être filtré ou non. */
+static bool is_param_filtered(GBookmarksPanel *, const char *);
+
+
+
+/* ------------------------ ATTRIBUTION D'UN MENU CONTEXTUEL ------------------------ */
+
+
+/* Assure la gestion des clics de souris sur les signets. */
+static gboolean on_button_press_over_bookmarks(GtkWidget *, GdkEventButton *, GBookmarksPanel *);
+
+/* Construit le menu contextuel pour les signets. */
+GtkMenu *build_bookmarks_panel_menu(GBookmarksPanel *);
+
+/* Fournit le signet sélectionné dans la liste. */
+static GDbBookmark *get_selected_panel_bookmark(GtkTreeView *, GtkTreeIter *);
+
+/* Réagit avec le menu "Editer". */
+static void mcb_bookmarks_panel_edit(GtkMenuItem *, GBookmarksPanel *);
+
+/* Réagit avec le menu "Supprimer". */
+static void mcb_bookmarks_panel_delete(GtkMenuItem *, GBookmarksPanel *);
+
+/* Réagit avec le menu "Filtrer...". */
+static void mcb_bookmarks_panel_filter(GtkMenuItem *, GBookmarksPanel *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                            PARTIE PRINCIPALE DU PANNEAU                            */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Indique le type définit pour un panneau d'affichage des signets liés à un binaire. */
+G_DEFINE_TYPE(GBookmarksPanel, g_bookmarks_panel, G_TYPE_PANEL_ITEM);
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : klass = classe à initialiser.                                *
+*                                                                             *
+*  Description : Initialise la classe des panneaux des paramètres de config.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bookmarks_panel_class_init(GBookmarksPanelClass *klass)
+{
+    GObjectClass *object;                   /* Autre version de la classe  */
+    GEditorItemClass *editem;               /* Encore une autre vision...  */
+    gchar *filename;                        /* Chemin d'accès à utiliser   */
+
+    object = G_OBJECT_CLASS(klass);
+
+    object->dispose = (GObjectFinalizeFunc/* ! */)g_bookmarks_panel_dispose;
+    object->finalize = (GObjectFinalizeFunc)g_bookmarks_panel_finalize;
+
+    editem = G_EDITOR_ITEM_CLASS(klass);
+
+    editem->update_binary = (update_item_binary_fc)reload_bookmarks_into_treeview;
+
+    filename = find_pixmap_file("bookmark.png");
+    /* assert(filename != NULL); */
+
+    klass->bookmark_img = cairo_image_surface_create_from_png(filename);
+
+    g_free(filename);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = instance à initialiser.                              *
+*                                                                             *
+*  Description : Initialise une instance de panneau de paramètres de config.  *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bookmarks_panel_init(GBookmarksPanel *panel)
+{
+    GEditorItem *base;                      /* Version basique d'instance  */
+    GObject *ref;                           /* Espace de référencement     */
+    GtkWidget *label;                       /* Etiquette à utiliser        */
+    GtkWidget *search;                      /* Zone de recherche           */
+    GtkWidget *scrolled;                    /* Fenêtre défilante           */
+    GtkTreeStore *store;                    /* Modèle de gestion           */
+    GtkWidget *treeview;                    /* Affichage de la liste       */
+    GtkCellRenderer *renderer;              /* Moteur de rendu de colonne  */
+    GtkTreeViewColumn *column;              /* Colonne de la liste         */
+    GtkTreeSortable *sortable;              /* Autre vision de la liste    */
+
+    base = G_EDITOR_ITEM(panel);
+
+    base->widget = gtk_grid_new();
+    gtk_widget_show(base->widget);
+
+    gtk_grid_set_row_spacing(GTK_GRID(base->widget), 8);
+
+    ref = G_OBJECT(base->widget);
+    g_object_set_data(ref, "panel", panel);
+
+    /* Partie recherche */
+
+    label = qck_create_label(NULL, NULL, _("Look for:"));
+    g_object_set(label, "margin", 8, NULL);
+    gtk_grid_attach(GTK_GRID(base->widget), label, 0, 0, 1, 1);
+
+    search = gtk_search_entry_new();
+    ///g_signal_connect(search, "search-changed", G_CALLBACK(on_param_search_changed), panel);
+    gtk_widget_show(search);
+    gtk_widget_set_hexpand(search, TRUE);
+    gtk_grid_attach_next_to(GTK_GRID(base->widget), search, label, GTK_POS_RIGHT, 1, 1);
+
+    /* Partie paramètres */
+
+    scrolled = gtk_scrolled_window_new(NULL, NULL);
+    gtk_widget_show(scrolled);
+    gtk_widget_set_vexpand(scrolled, TRUE);
+    gtk_grid_attach_next_to(GTK_GRID(base->widget), scrolled, label, GTK_POS_BOTTOM, 2, 1);
+
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
+
+    store = gtk_tree_store_new(BMC_COUNT, G_TYPE_OBJECT,
+                               CAIRO_GOBJECT_TYPE_SURFACE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+    treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+    gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
+    panel->treeview = GTK_TREE_VIEW(treeview);
+
+    g_signal_connect(G_OBJECT(treeview), "button-press-event",
+                     G_CALLBACK(on_button_press_over_bookmarks), panel);
+    g_signal_connect(G_OBJECT(treeview), "key-press-event",
+                     G_CALLBACK(on_key_pressed_over_params), panel);
+
+    gtk_widget_show(treeview);
+    gtk_container_add(GTK_CONTAINER(scrolled), treeview);
+
+    g_object_unref(G_OBJECT(store));
+
+    /* Cellules d'affichage */
+
+    renderer = gtk_cell_renderer_pixbuf_new();
+    column = gtk_tree_view_column_new_with_attributes("", renderer,
+                                                      "surface", BMC_PICTURE,
+                                                      NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+    renderer = gtk_cell_renderer_text_new();
+    column = gtk_tree_view_column_new_with_attributes(_("Physical address"), renderer,
+                                                      "text", BMC_VIRTUAL,
+                                                      NULL);
+    gtk_tree_view_column_set_sort_column_id(column, BMC_PHYSICAL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+    renderer = gtk_cell_renderer_text_new();
+    column = gtk_tree_view_column_new_with_attributes(_("Virtual address"), renderer,
+                                                      "text", BMC_VIRTUAL,
+                                                      NULL);
+    gtk_tree_view_column_set_sort_column_id(column, BMC_VIRTUAL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+    renderer = gtk_cell_renderer_text_new();
+    g_object_set(G_OBJECT(renderer), "editable", TRUE, NULL);
+    ///g_signal_connect(renderer, "edited", G_CALLBACK(on_param_value_edited), store);
+    column = gtk_tree_view_column_new_with_attributes(_("Comment"), renderer,
+                                                      "text", BMC_COMMENT,
+                                                      NULL);
+    gtk_tree_view_column_set_sort_column_id(column, BMC_COMMENT);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+
+    /* Tri de la liste */
+
+    sortable = GTK_TREE_SORTABLE(store);
+
+    gtk_tree_sortable_set_sort_func(sortable, BMC_PHYSICAL, compare_bookmarks_list_columns,
+                                    GINT_TO_POINTER(BMC_PHYSICAL), NULL);
+
+    gtk_tree_sortable_set_sort_func(sortable, BMC_VIRTUAL, compare_bookmarks_list_columns,
+                                    GINT_TO_POINTER(BMC_VIRTUAL), NULL);
+
+    gtk_tree_sortable_set_sort_func(sortable, BMC_COMMENT, compare_bookmarks_list_columns,
+                                    GINT_TO_POINTER(BMC_COMMENT), NULL);
+
+    gtk_tree_sortable_set_sort_column_id(sortable, BMC_COMMENT, GTK_SORT_ASCENDING);
+
+    /* Préparation du menu contextuel */
+
+    panel->menu = build_bookmarks_panel_menu(panel);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Supprime toutes les références externes.                     *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bookmarks_panel_dispose(GBookmarksPanel *panel)
+{
+    if (panel->binary != NULL)
+        g_object_unref(G_OBJECT(panel->binary));
+
+    G_OBJECT_CLASS(g_bookmarks_panel_parent_class)->dispose(G_OBJECT(panel));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = instance d'objet GLib à traiter.                     *
+*                                                                             *
+*  Description : Procède à la libération totale de la mémoire.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void g_bookmarks_panel_finalize(GBookmarksPanel *panel)
+{   
+    if (panel->filter != NULL)
+        regfree(panel->filter);
+
+    G_OBJECT_CLASS(g_bookmarks_panel_parent_class)->finalize(G_OBJECT(panel));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ref = espace de référencement global.                        *
+*                                                                             *
+*  Description : Crée un panneau d'affichage des paramètres de configuration. *
+*                                                                             *
+*  Retour      : Adresse de la structure mise en place.                       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GEditorItem *g_bookmarks_panel_new(GObject *ref)
+{
+    GEditorItem *result;                    /* Structure à retourner       */
+
+    result = g_object_new(G_TYPE_BOOKMARKS_PANEL, NULL);
+
+    g_panel_item_init_ext(G_PANEL_ITEM(result), ref, PANEL_BOOKMARKS_ID,
+                          _("Bookmarks"), G_EDITOR_ITEM(result)->widget, "SE");
+
+    //reload_config_into_treeview(G_BOOKMARKS_PANEL(result), get_main_configuration());
+
+
+    //GDbCollection *g_loaded_binary_find_collection(GLoadedBinary *binary, DBFeatures feature)
+
+
+
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ref = espace de référencement global.                        *
+*                                                                             *
+*  Description : Construit le panneau d'affichage des signets courants.       *
+*                                                                             *
+*  Retour      : Adresse du panneau mis en place.                             *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GPanelItem *create_bookmarks_panel(GObject *ref)
+{
+    GEditorItem *result;                    /* Elément réactif à renvoyer  */
+
+    result = g_bookmarks_panel_new(ref);
+
+    /* Enregistre correctement le tout */
+    register_editor_item(result);
+
+    return G_PANEL_ITEM(result);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           AFFICHAGE A L'AIDE D'UNE LISTE                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel  = panneau d'affichage des signets liés à un binaire.  *
+*                binary = propriétaire de la collection à présenter.          *
+*                                                                             *
+*  Description : Recharge une collection de signets à l'affichage.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void reload_bookmarks_into_treeview(GBookmarksPanel *panel, GLoadedBinary *binary)
+{
+    GtkTreeStore *store;                    /* Modèle de gestion           */
+    GDbCollection *collec;                  /* Collection à lister ici     */
+    GList *items;                           /* Liste des éléments groupés  */
+    GList *b;                               /* Boucle de parcours          */
+    GDbBookmark *bookmark;                  /* Signet en cours d'étude     */
+    vmpa2t *addr;                           /* Adressse associée au signet */
+    GtkTreeIter iter;                       /* Point d'insertion           */
+
+    printf("RELOAD :: %p\n", binary);
+
+    /* Basculement du binaire utilisé */
+
+    if (panel->binary != NULL)
+        g_object_unref(G_OBJECT(panel->binary));
+
+    panel->binary = binary;
+
+    if (panel->binary != NULL)
+        g_object_ref(G_OBJECT(binary));
+
+    store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview));
+    gtk_tree_store_clear(store);
+
+    /* Si le panneau actif ne représente pas un binaire... */
+
+    if (binary == NULL) return;
+
+    /* Actualisation de l'affichage */
+
+    sleep(1);
+
+    collec = g_loaded_binary_find_collection(binary, DBF_BOOKMARKS);
+
+    g_db_collection_rlock(collec);
+
+    items = g_db_collection_list_items(collec);
+
+
+    printf(" ... items = %p\n", items);
+
+    /*
+    gtk_tree_store_append(store, &iter, NULL);
+    gtk_tree_store_set(store, &iter,
+                       BMC_BOOKMARK, bookmark,
+                       BMC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img,
+                       BMC_PHYSICAL, "0x01",
+                       BMC_VIRTUAL, "0x02",
+                       BMC_COMMENT, "desc",
+                       -1);
+    */
+
+
+    for (b = g_list_first(items); b != NULL; b = g_list_next(b))
+    {
+        bookmark = G_DB_BOOKMARK(b->data);
+
+
+        printf("Adding // %p\n", bookmark);
+
+        //printf("add.virt = %s\n", vmpa2_virt_to_string(&addr, MDS_32_BITS));
+
+        fflush(NULL);
+
+
+        addr = g_db_bookmark_get_address(bookmark);
+
+        gtk_tree_store_append(store, &iter, NULL);
+        gtk_tree_store_set(store, &iter,
+                           BMC_BOOKMARK, bookmark,
+                           BMC_PICTURE, G_BOOKMARKS_PANEL_GET_CLASS(panel)->bookmark_img,
+                           BMC_PHYSICAL, "vmpa2_phy_to_string(addr, MDS_32_BITS)",    /* FIXME : pareil qu'en bas */
+                           BMC_VIRTUAL, "vmpa2_virt_to_string(&addr, MDS_32_BITS)", /* FIXME : choisir en fonction de l'architecture */
+                           BMC_COMMENT, "g_db_bookmark_get_comment(bookmark)",
+                           -1);
+
+    }
+
+    g_db_collection_runlock(collec);
+
+
+
+#if 0
+    GtkTreeStore *store;                    /* Modèle de gestion           */
+    GList *params;                          /* Paramètres de configuration */
+    GCfgParam *param;                       /* Paramètre en cours d'étude  */
+    GList *p;                               /* Boucle de parcours          */
+    char *type_desc;                        /* Type de paramètre           */
+    GtkTreeIter iter;                       /* Point d'insertion           */
+
+    store = GTK_TREE_STORE(gtk_tree_view_get_model(panel->treeview));
+    gtk_tree_store_clear(store);
+
+    g_generic_config_rlock(config);
+
+    params = g_generic_config_list_params(config);
+
+    for (p = g_list_first(params); p != NULL; p = g_list_next(p))
+    {
+        param = G_CFG_PARAM(p->data);
+
+        if (is_param_filtered(panel, g_config_param_get_path(param)))
+            continue;
+
+        switch (g_config_param_get_ptype(param))
+        {
+            case CPT_BOOLEAN:
+                type_desc = _("Boolean");
+                break;
+
+            case CPT_INTEGER:
+                type_desc = _("Integer");
+                break;
+
+            case CPT_STRING:
+                type_desc = _("String");
+                break;
+
+            default:
+                type_desc = _("<Unknown type>");
+                break;
+
+        }
+
+        gtk_tree_store_append(store, &iter, NULL);
+        gtk_tree_store_set(store, &iter,
+                           CPC_BOOKMARK, param,
+                           CPC_PATH, g_config_param_get_path(param),
+                           CPC_TYPE, type_desc,
+                           -1);
+
+        update_config_param_value(store, &iter);
+
+        g_signal_connect(param, "modified", G_CALLBACK(on_config_param_modified), panel);
+
+    }
+
+    g_generic_config_runlock(config);
+#endif
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : param = instance dont le contenu a évolué.                   *
+*                panel = panneau d'affichage de paramètres à mettre à jour.   *
+*                                                                             *
+*  Description : Actualise l'affichage des données d'un paramètre modifié.    *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void on_config_param_modified(GCfgParam *param, GBookmarksPanel *panel)
+{
+    GtkTreeModel *model;                    /* Gestionnaire de données     */
+    GtkTreeIter iter;                       /* Point de recherche          */
+    gboolean looping;                       /* Autorisation de bouclage    */
+    GCfgParam *item;                        /* Elément de la liste         */
+
+    model = gtk_tree_view_get_model(panel->treeview);
+
+    for (looping = gtk_tree_model_get_iter_first (model, &iter);
+         looping;
+         looping = gtk_tree_model_iter_next(model, &iter))
+    {
+        gtk_tree_model_get(model, &iter, BMC_BOOKMARK, &item, -1);
+
+        if (item == param)
+        {
+            update_config_param_value(GTK_TREE_STORE(model), &iter);
+            break;
+        }
+
+    }
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : store = gestionnaire du tableau de données.                  *
+*                iter  = point de modification dans les lignes.               *
+*                param = paramètre dont la valeur est à afficher.             *
+*                                                                             *
+*  Description : Actualise la valeur affichée d'un paramètre de configuration.*
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void update_config_param_value(GtkTreeStore *store, GtkTreeIter *iter)
+{
+    GCfgParam *param;                       /* Paramètre à consulter       */
+    ConfigParamState state;                 /* Etat du paramètre           */
+    char *state_desc;                       /* Version chaînée de l'état   */
+    bool boolean;                           /* Valeur booléenne            */
+    int integer;                            /* Valeur entière              */
+    char int_val[sizeof(XSTR(INT_MIN)) + 1];/* Valeur en chaîne de carac.  */
+    char *string;                           /* Chaîne de caractères        */
+    char *desc;                             /* Description à afficher      */
+
+    gtk_tree_model_get(GTK_TREE_MODEL(store), iter, BMC_BOOKMARK, &param, -1);
+
+    state = g_config_param_get_state(param);
+
+    if (state & CPS_DEFAULT)
+        state_desc = strdup(_("By default"));
+    else
+        state_desc = strdup(_("Changed"));
+
+    if (state & CPS_EMPTY)
+        state_desc = stradd(state_desc, _(" + empty"));
+
+    if (state & CPS_EMPTY)
+        desc = "";
+
+    else
+        switch (g_config_param_get_ptype(param))
+        {
+            case CPT_BOOLEAN:
+                g_config_param_get_value(param, &boolean);
+                desc = (boolean ? _("true") : _("false"));
+                break;
+
+            case CPT_INTEGER:
+                g_config_param_get_value(param, &integer);
+                snprintf(int_val, sizeof(int_val), "%d", integer);
+                desc = int_val;
+                break;
+
+            case CPT_STRING:
+                g_config_param_get_value(param, &string);
+                desc = (string != NULL ? string : "");
+                break;
+
+            default:
+                assert(false);
+                desc = "???";
+                break;
+
+        }
+
+    /*
+    gtk_tree_store_set(store, iter,
+                       CPC_BOLD, state & CPS_DEFAULT ? 400 : 800,
+                       CPC_STATUS, state_desc,
+                       CPC_VALUE, desc, -1);
+    */
+
+    free(state_desc);
+
+    g_object_unref(G_OBJECT(param));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : model  = gestionnaire du tableau de données.                 *
+*                a      = première ligne de données à traiter.                *
+*                b      = seconde ligne de données à traiter.                 *
+*                column = indice de la colonne à considérer, encodée.         *
+*                                                                             *
+*  Description : Etablit une comparaison entre deux lignes de signets.        *
+*                                                                             *
+*  Retour      : Indication de tri entre les deux lignes fournies.            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gint compare_bookmarks_list_columns(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer column)
+{
+    gint result;                            /* Valeur calculée à retourner */
+    gchar *value_a;                         /* Cellule de la ligne 'a'     */
+    gchar *value_b;                         /* Cellule de la ligne 'b'     */
+
+    gtk_tree_model_get(model, a, GPOINTER_TO_INT(column), &value_a, -1);
+    gtk_tree_model_get(model, b, GPOINTER_TO_INT(column), &value_b, -1);
+
+    if (value_a == NULL || value_b == NULL)
+    {
+        if (value_a == NULL && value_b == NULL)
+            result = 0;
+        else
+            result = (value_a == NULL ? -1 : 1);
+    }
+    else
+        result = g_utf8_collate(value_a,value_b);
+
+    g_free(value_a);
+    g_free(value_b);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : treeview = composant graphique présentant les paramètres.    *
+*                event    = informations liées à l'événement.                 *
+*                panel    = panneau d'affichage sur lequel s'appuyer.         *
+*                                                                             *
+*  Description : Réagit à une pression sur <Shift+F2> et simule l'édition.    *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean on_key_pressed_over_params(GtkTreeView *treeview, GdkEventKey *event, GBookmarksPanel *panel)
+{
+    const gchar *accelerator;               /* Combinaison de raccourci    */
+    guint accel_key;                        /* Touche de raccourci         */
+    GdkModifierType accel_mod;              /* Modifiateurs attendus aussi */
+    GtkTreeIter iter;                       /* Point de la sélection       */
+    GtkTreeModel *model;                    /* Gestionnaire de données     */
+    GtkTreePath *path;                      /* Chemin d'accès à ce point   */
+
+    if (!g_generic_config_get_value(get_main_configuration(), MPK_KEYBINDINGS_EDIT, &accelerator))
+        return FALSE;
+
+    if (accelerator == NULL)
+        return FALSE;
+
+    gtk_accelerator_parse(accelerator, &accel_key, &accel_mod);
+
+    if (event->keyval == accel_key && event->state == accel_mod)
+    {
+        /* FIXME : unref(result) */
+        if (get_selected_panel_bookmark(treeview, &iter) != NULL)
+        {
+            model = gtk_tree_view_get_model(treeview);
+            path = gtk_tree_model_get_path(model, &iter);
+
+            gtk_tree_view_set_cursor(treeview, path,
+                                     gtk_tree_view_get_column(treeview, BMC_COMMENT - BMC_PHYSICAL),
+                                     TRUE);
+
+            gtk_tree_path_free(path);
+
+        }
+
+    }
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : renderer = moteur de rendu pour la cellule.                  *
+*                path     = chemin d'accès vers la cellule éditée.            *
+*                new      = nouvelle valeur sous forme de texte à valider.    *
+*                store    = gestionnaire des données de la liste affichée.    *
+*                                                                             *
+*  Description : Réagit à une édition de la valeur d'un paramètre.            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void on_param_value_edited(GtkCellRendererText *renderer, gchar *path, gchar *new, GtkTreeStore *store)
+{
+    GtkTreePath *tree_path;                 /* Chemin d'accès natif        */
+    GtkTreeIter iter;                       /* Point de la modification    */
+    GCfgParam *param;                       /* Paramètre à actualiser      */
+    bool boolean;                           /* Valeur booléenne            */
+    int integer;                            /* Valeur entière              */
+    char *end;                              /* Pointeur vers '\0' final ?  */
+
+    tree_path = gtk_tree_path_new_from_string(path);
+    if (tree_path == NULL) return;
+
+    if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, tree_path))
+        goto opve_bad_iter;
+
+    gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, BMC_BOOKMARK, &param, -1);
+
+    switch (g_config_param_get_ptype(param))
+    {
+        case CPT_BOOLEAN:
+
+            if (strcmp(new, "true") != 0 && strcmp(new, "false") != 0)
+                goto opve_bad_value;
+
+            boolean = (strcmp(new, "true") == 0);
+            g_config_param_set_value(param, boolean);
+
+            break;
+
+        case CPT_INTEGER:
+
+            integer = strtol(new, &end, 10);
+            if (*end != '\0') goto opve_bad_value;
+ 
+            g_config_param_set_value(param, integer);
+
+            break;
+
+        case CPT_STRING:
+            g_config_param_set_value(param, new);
+            break;
+
+        default:
+            assert(false);
+            goto opve_bad_value;
+            break;
+
+    }
+
+ opve_bad_value:
+
+    g_object_unref(G_OBJECT(param));
+
+ opve_bad_iter:
+
+    gtk_tree_path_free(tree_path);
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                           FILTRAGE DES SYMBOLES PRESENTS                           */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : entry  = entrée de texte contenant le filtre brut.           *
+*                panel  = panneau assurant l'affichage des paramètres.        *
+*                                                                             *
+*  Description : Démarre l'actualisation du filtrage des paramètres.          *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void on_param_search_changed(GtkSearchEntry *entry, GBookmarksPanel *panel)
+{
+    const gchar *text;                      /* Texte de l'utilisateur      */
+    int ret;                                /* Bilan de mise en place      */
+    GdkRGBA error;                          /* Couleur d'erreur            */
+
+    if (panel->filter != NULL)
+    {
+        regfree(panel->filter);
+        free(panel->filter);
+        panel->filter = NULL;
+    }
+
+    text = gtk_entry_get_text(GTK_ENTRY(entry));
+
+    if (strlen(text) > 0)
+    {
+        panel->filter = (regex_t *)calloc(1, sizeof(regex_t));
+        ret = regcomp(panel->filter, text, REG_EXTENDED);
+
+        if (ret != 0)
+        {
+            free(panel->filter);
+            panel->filter = NULL;
+
+            error.red = 1.0;
+            error.green = 0.0;
+            error.blue = 0.0;
+            error.alpha = 1.0;
+            gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, &error);
+
+            return;
+
+        }
+
+    }
+
+    gtk_widget_override_color(GTK_WIDGET(entry), GTK_STATE_NORMAL, NULL);
+
+    reload_config_into_treeview(panel, get_main_configuration());
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau assurant l'affichage des paramètres.         *
+*                name  = chemin d'accès au paramètre à traiter.               *
+*                                                                             *
+*  Description : Détermine si un paramètre doit être filtré ou non.           *
+*                                                                             *
+*  Retour      : true si le paramètre ne doit pas être affiché, false sinon.  *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static bool is_param_filtered(GBookmarksPanel *panel, const char *name)
+{
+    regmatch_t match;                       /* Récupération des trouvailles*/
+    int ret;                                /* Bilan du filtrage           */
+
+    if (panel->filter == NULL)
+        return false;
+
+    ret = regexec(panel->filter, name, 1, &match, 0);
+    if (ret == REG_NOMATCH)
+        return true;
+
+    return false;
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                          ATTRIBUTION D'UN MENU CONTEXTUEL                          */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : widget = composant GTK visé par l'opération.                 *
+*                event  = informations liées à l'événement.                   *
+*                panel  = informations liées au panneau associé.              *
+*                                                                             *
+*  Description : Assure la gestion des clics de souris sur les signets.       *
+*                                                                             *
+*  Retour      : FALSE pour poursuivre la propagation de l'événement.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static gboolean on_button_press_over_bookmarks(GtkWidget *widget, GdkEventButton *event, GBookmarksPanel *panel)
+{
+    if (event->button == 3)
+        gtk_menu_popup(panel->menu, NULL, NULL, NULL, NULL, event->button, event->time);
+
+    return FALSE;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : panel = panneau d'affichage des signets liés à un binaire.   *
+*                                                                             *
+*  Description : Construit le menu contextuel pour les signets.               *
+*                                                                             *
+*  Retour      : Panneau de menus mis en place.                               *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+GtkMenu *build_bookmarks_panel_menu(GBookmarksPanel *panel)
+{
+    GtkWidget *result;                      /* Support à retourner         */
+    GtkWidget *submenuitem;                 /* Sous-élément de menu        */
+
+    result = gtk_menu_new();
+
+    submenuitem = qck_create_menu_item(NULL, NULL, _("Edit"), G_CALLBACK(mcb_bookmarks_panel_edit), panel);
+    gtk_container_add(GTK_CONTAINER(result), submenuitem);
+
+    submenuitem = qck_create_menu_item(NULL, NULL, _("Delete"), G_CALLBACK(mcb_bookmarks_panel_delete), panel);
+    gtk_container_add(GTK_CONTAINER(result), submenuitem);
+
+    submenuitem = qck_create_menu_separator();
+    gtk_container_add(GTK_CONTAINER(result), submenuitem);
+
+    submenuitem = qck_create_menu_item(NULL, NULL, _("Filter..."), G_CALLBACK(mcb_bookmarks_panel_filter), panel);
+    gtk_container_add(GTK_CONTAINER(result), submenuitem);
+
+    return GTK_MENU(result);
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : treeview = liste d'affichage à consulter.                    *
+*                save     = zone de conservation du point de trouvaille. [OUT]*
+*                                                                             *
+*  Description : Fournit le signet sélectionné dans la liste.                 *
+*                                                                             *
+*  Retour      : Signet en cours d'édition ou NULL en cas de soucis.          *
+*                                                                             *
+*  Remarques   : Le résultat non nul est à déréférencer après usage.          *
+*                                                                             *
+******************************************************************************/
+
+static GDbBookmark *get_selected_panel_bookmark(GtkTreeView *treeview, GtkTreeIter *save)
+{
+    GDbBookmark *result;                    /* Paramètre à renvoyer        */
+    GtkTreeSelection *selection;            /* Représentation de sélection */
+    GtkTreeModel *model;                    /* Gestionnaire des données    */
+    GtkTreeIter iter;                       /* Point de la sélection       */
+
+    result = NULL;
+
+    selection = gtk_tree_view_get_selection(treeview);
+
+    if (gtk_tree_selection_get_selected(selection, &model, &iter))
+        gtk_tree_model_get(model, &iter, BMC_BOOKMARK, &result, -1);
+
+    if (save != NULL)
+        *save = iter;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : menuitem = élément de menu sélectionné.                      *
+*                panel    = panneau d'affichage des signets liés à un binaire.*
+*                                                                             *
+*  Description : Réagit avec le menu "Editer".                                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void mcb_bookmarks_panel_edit(GtkMenuItem *menuitem, GBookmarksPanel *panel)
+{
+    GtkTreeIter iter;                       /* Point de la sélection       */
+    GDbBookmark *mark;                      /* Signet sélectionné          */
+    GtkTreeModel *model;                    /* Gestionnaire de données     */
+    GtkTreePath *path;                      /* Chemin d'accès à ce point   */
+
+    mark = get_selected_panel_bookmark(panel->treeview, &iter);
+    if (mark == NULL) return;
+
+    model = gtk_tree_view_get_model(panel->treeview);
+    path = gtk_tree_model_get_path(model, &iter);
+
+    gtk_tree_view_set_cursor(panel->treeview, path,
+                             gtk_tree_view_get_column(panel->treeview, BMC_COMMENT - BMC_PHYSICAL),
+                             TRUE);
+
+    gtk_tree_path_free(path);
+
+    g_object_unref(G_OBJECT(mark));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : menuitem = élément de menu sélectionné.                      *
+*                panel    = panneau d'affichage des signets liés à un binaire.*
+*                                                                             *
+*  Description : Réagit avec le menu "Supprimer".                             *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void mcb_bookmarks_panel_delete(GtkMenuItem *menuitem, GBookmarksPanel *panel)
+{
+    GDbBookmark *mark;                      /* Signet sélectionné          */
+
+    mark = get_selected_panel_bookmark(panel->treeview, NULL);
+    if (mark == NULL) return;
+
+    g_loaded_binary_remove_from_collection(panel->binary, DBF_BOOKMARKS, G_DB_ITEM(mark));
+
+    g_object_unref(G_OBJECT(mark));
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : menuitem = élément de menu sélectionné.                      *
+*                panel    = panneau d'affichage des signets liés à un binaire.*
+*                                                                             *
+*  Description : Réagit avec le menu "Filtrer...".                            *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static void mcb_bookmarks_panel_filter(GtkMenuItem *menuitem, GBookmarksPanel *panel)
+{
+#if 0
+    GCfgParam *param;                       /* Paramètre sélectionné       */
+
+    param = get_selected_panel_bookmark(panel->treeview, NULL);
+    if (param == NULL) return;
+
+    g_config_param_make_empty(param);
+
+    g_object_unref(G_OBJECT(param));
+#endif
+}
diff --git a/src/gui/panels/bookmarks.h b/src/gui/panels/bookmarks.h
new file mode 100644
index 0000000..507cc09
--- /dev/null
+++ b/src/gui/panels/bookmarks.h
@@ -0,0 +1,65 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * bookmarks.h - prototypes pour le panneau d'affichage des signets d'un binaire
+ *
+ * Copyright (C) 2014 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 this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#ifndef _GUI_PANELS_BOOKMARKS_H
+#define _GUI_PANELS_BOOKMARKS_H
+
+
+#include <i18n.h>
+
+
+#include "panel.h"
+
+
+
+#define PANEL_BOOKMARKS_ID _("Bookmarks")
+
+
+#define G_TYPE_BOOKMARKS_PANEL               g_bookmarks_panel_get_type()
+#define G_BOOKMARKS_PANEL(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), g_bookmarks_panel_get_type(), GBookmarksPanel))
+#define G_IS_BOOKMARKS_PANEL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_bookmarks_panel_get_type()))
+#define G_BOOKMARKS_PANEL_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_BOOKMARKS_PANEL, GBookmarksPanelClass))
+#define G_IS_BOOKMARKS_PANEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_BOOKMARKS_PANEL))
+#define G_BOOKMARKS_PANEL_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_BOOKMARKS_PANEL, GBookmarksPanelClass))
+
+
+/* Panneau d'affichage des signets liés à un binaire (instance) */
+typedef struct _GBookmarksPanel GBookmarksPanel;
+
+/* Panneau d'affichage des signets liés à un binaire (classe) */
+typedef struct _GBookmarksPanelClass GBookmarksPanelClass;
+
+
+/* Indique le type définit pour un panneau d'affichage des signets liés à un binaire. */
+GType g_bookmarks_panel_get_type(void);
+
+/* Crée un panneau d'affichage des paramètres de configuration. */
+GEditorItem *g_bookmarks_panel_new(GObject *);
+
+/* Construit le panneau d'affichage des signets courants. */
+GPanelItem *create_bookmarks_panel(GObject *);
+
+
+
+#endif  /* _GUI_PANELS_BOOKMARKS_H */
diff --git a/src/gui/panels/panel.c b/src/gui/panels/panel.c
index 5a7fc53..06be865 100644
--- a/src/gui/panels/panel.c
+++ b/src/gui/panels/panel.c
@@ -30,6 +30,7 @@
 #include <sys/param.h>
 
 
+#include "bookmarks.h"
 #include "glance.h"
 #include "log.h"
 #include "panel-int.h"
@@ -388,6 +389,9 @@ void load_main_panels(GObject *ref)
     item = create_glance_panel(ref);
     g_panel_item_dock(item);
 
+    item = create_bookmarks_panel(ref);
+    g_panel_item_dock(item);
+
 }
 
 
diff --git a/src/gui/panels/regedit.c b/src/gui/panels/regedit.c
index 77fea39..159a4d0 100644
--- a/src/gui/panels/regedit.c
+++ b/src/gui/panels/regedit.c
@@ -263,7 +263,7 @@ static void g_regedit_panel_init(GRegeditPanel *panel)
 
     g_object_unref(G_OBJECT(store));
 
-    /* Cellule d'affichage */
+    /* Cellules d'affichage */
 
     renderer = gtk_cell_renderer_text_new();
     column = gtk_tree_view_column_new_with_attributes(_("Access path"), renderer,
-- 
cgit v0.11.2-87-g4458