From 55bc8570f25a479b222733c4093f9ae996c9f68e Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sun, 29 Sep 2019 22:57:16 +0200
Subject: Handled disabled update items.

---
 src/analysis/binary.c        | 90 ++++++++++++++++----------------------------
 src/analysis/binary.h        |  9 +----
 src/analysis/db/client.c     | 67 ++++++++++++++++++++++++++++++++-
 src/analysis/db/client.h     |  9 ++---
 src/analysis/db/collection.c | 84 ++++++++++++++++++++++++++++++++++++-----
 src/analysis/db/collection.h |  2 +-
 src/analysis/db/item-int.h   |  1 +
 src/analysis/db/item.c       | 54 ++++++++++++++++++++++++++
 src/analysis/db/item.h       |  6 +++
 src/gui/menus/edition.c      |  2 +-
 10 files changed, 240 insertions(+), 84 deletions(-)

diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index fb715bb..61dbbf1 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -1056,12 +1056,10 @@ GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *binary, DBFe
 }
 
 
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : binary = élément binaire à consulter.                        *
 *                item   = élémnent à pousser vers un serveur de collection.   *
-*                lock   = indique si le verrou d'écriture doit être posé.     *
 *                                                                             *
 *  Description : Demande l'intégration d'une modification dans une collection.*
 *                                                                             *
@@ -1071,84 +1069,44 @@ GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *binary, DBFe
 *                                                                             *
 ******************************************************************************/
 
-bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item, bool lock)
+bool g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item)
 {
     bool result;                            /* Bilan à faire remonter      */
     DBFeatures feature;                     /* Domaine de fonctionnalité   */
-    GDbCollection *collec;                  /* Collection visée au final   */
     DBStorage storage;                      /* Forme d'enregistrement      */
     GHubClient *client;                     /* Liaison à utiliser          */
-    packed_buffer out_pbuf;                 /* Tampon d'émission           */
-    SSL *tls_fd;                            /* Canal de communication SSL  */
 
     feature = g_db_item_get_feature(item);
 
-    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_get_flags(item) & DIF_VOLATILE)
-        result = _g_db_collection_add_item(collec, item, lock);
+    storage = g_loaded_binary_get_storage(binary, feature);
 
-    /* Sinon on envoie par le réseau ! */
+    if (storage == DBS_ALL_REMOTE)
+        client = binary->remote;
     else
-    {
-        storage = g_loaded_binary_get_storage(binary, feature);
-
-        if (storage == DBS_ALL_REMOTE)
-            client = binary->remote;
-        else
-            client = binary->local;
-
-        if (client == NULL)
-        {
-            log_simple_message(LMT_ERROR, _("No connection to a server in order to forward the item"));
-            result = false;
-        }
-
-        else
-        {
-            init_packed_buffer(&out_pbuf);
-
-            tls_fd = g_hub_client_get_ssl_fd(client);
-
-            if (tls_fd == NULL)
-                result = false;
-
-            else
-            {
-                result = g_db_collection_pack(collec, &out_pbuf, DBA_ADD_ITEM, item);
-
-                if (result)
-                    result = ssl_send_packed_buffer(&out_pbuf, tls_fd);
-
-                g_hub_client_put_ssl_fd(client, tls_fd);
-
-            }
-
-            exit_packed_buffer(&out_pbuf);
-
-        }
-
-        g_object_unref(G_OBJECT(item));
+        client = binary->local;
 
+    if (client == NULL)
+    {
+        log_simple_message(LMT_ERROR, _("No connection to a server in order to forward the item"));
+        result = false;
     }
 
-    g_object_unref(G_OBJECT(collec));
+    else
+        result = g_hub_client_add_item(client, item);
+
+    g_object_unref(G_OBJECT(item));
 
     return result;
 
 }
 
 
-
-
 /******************************************************************************
 *                                                                             *
 *  Paramètres  : binary    = élément binaire à consulter.                     *
 *                timestamp = date du dernier élément à garder comme actif.    *
 *                                                                             *
-*  Description : Active les éléments en amont d'un horodatage donné.      XXXXXXXXXXXXXXXXX    *
+*  Description : Spécifie la bordure temporelle limite des activations.       *
 *                                                                             *
 *  Retour      : true si la commande a bien été envoyée, false sinon.         *
 *                                                                             *
@@ -1159,12 +1117,28 @@ bool _g_loaded_binary_add_to_collection(GLoadedBinary *binary, GDbItem *item, bo
 bool g_loaded_binary_set_last_active(GLoadedBinary *binary, timestamp_t timestamp)
 {
     bool result;                            /* Bilan à retourner           */
+    bool done;                              /* Suivi des actions menées    */
 
+    result = true;
+    done = false;
 
-    result = false;
-
+    if (binary->local != NULL)
+    {
+        result = g_hub_client_set_last_active(binary->local, timestamp);
+        done = true;
+    }
 
+    if (result && binary->remote != NULL)
+    {
+        result = g_hub_client_set_last_active(binary->remote, timestamp);
+        done = true;
+    }
 
+    if (!done)
+    {
+        log_simple_message(LMT_ERROR, _("No connection to a server found in order to set timestamp"));
+        result = false;
+    }
 
     return result;
 
diff --git a/src/analysis/binary.h b/src/analysis/binary.h
index b4c8652..1f94e34 100644
--- a/src/analysis/binary.h
+++ b/src/analysis/binary.h
@@ -126,14 +126,9 @@ GDbCollection **g_loaded_binary_get_collections(const GLoadedBinary *, size_t *)
 GDbCollection *g_loaded_binary_find_collection(const GLoadedBinary *, DBFeatures);
 
 /* Demande l'intégration d'une modification dans une collection. */
-bool _g_loaded_binary_add_to_collection(GLoadedBinary *, GDbItem *, bool);
+bool g_loaded_binary_add_to_collection(GLoadedBinary *, GDbItem *);
 
-#define g_loaded_binary_add_to_collection(b, i) \
-    _g_loaded_binary_add_to_collection(b, i, true)
-
-
-
-/* Active les éléments en amont d'un horodatage donné. */
+/* Spécifie la bordure temporelle limite des activations. */
 bool g_loaded_binary_set_last_active(GLoadedBinary *, timestamp_t);
 
 
diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c
index beb30c1..4c525e1 100644
--- a/src/analysis/db/client.c
+++ b/src/analysis/db/client.c
@@ -104,6 +104,12 @@ static bool g_hub_client_start_common(GHubClient *, char *);
 /* Assure l'accueil des nouvelles mises à jour. */
 static void *g_hub_client_update(GHubClient *);
 
+/* Identifie le canal de communication pour envois au serveur. */
+static SSL *g_hub_client_get_ssl_fd(GHubClient *);
+
+/* Marque le canal de communication comme disponible. */
+static void g_hub_client_put_ssl_fd(GHubClient *, SSL *);
+
 
 
 /* Indique le type défini pour une description de client à l'écoute. */
@@ -890,7 +896,7 @@ void g_hub_client_stop(GHubClient *client)
 *                                                                             *
 ******************************************************************************/
 
-SSL *g_hub_client_get_ssl_fd(GHubClient *client)
+static SSL *g_hub_client_get_ssl_fd(GHubClient *client)
 {
     SSL *result;                            /* Canal à retourner           */
 #ifndef NDEBUG
@@ -932,7 +938,7 @@ SSL *g_hub_client_get_ssl_fd(GHubClient *client)
 *                                                                             *
 ******************************************************************************/
 
-void g_hub_client_put_ssl_fd(GHubClient *client, SSL *tls_fd)
+static void g_hub_client_put_ssl_fd(GHubClient *client, SSL *tls_fd)
 {
     g_mutex_unlock(&client->sending_lock);
 
@@ -986,6 +992,63 @@ bool g_hub_client_save(GHubClient *client)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : client = client pour les accès distants à manipuler.         *
+*                item   = élémnent à pousser vers un serveur de collection.   *
+*                                                                             *
+*  Description : Ajoute un élément à la collection d'un serveur.              *
+*                                                                             *
+*  Retour      : true si la commande a bien été envoyée, false sinon.         *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+bool g_hub_client_add_item(GHubClient *client, const GDbItem *item)
+{
+    bool result;                            /* Bilan partiel à remonter    */
+    packed_buffer out_pbuf;                 /* Tampon d'émission           */
+    SSL *tls_fd;                            /* Canal de communication SSL  */
+    DBFeatures feature;                     /* Domaine de fonctionnalité   */
+    GDbCollection *collec;                  /* Collection visée au final   */
+
+    init_packed_buffer(&out_pbuf);
+
+    tls_fd = g_hub_client_get_ssl_fd(client);
+
+    if (tls_fd == NULL)
+        result = false;
+
+    else
+    {
+        feature = g_db_item_get_feature(item);
+
+        collec = find_collection_in_list(client->collections, feature);
+        if (collec == NULL)
+        {
+            result = false;
+            goto bad_item_feature;
+        }
+
+        result = g_db_collection_pack(collec, &out_pbuf, DBA_ADD_ITEM, item);
+
+        if (result)
+            result = ssl_send_packed_buffer(&out_pbuf, tls_fd);
+
+ bad_item_feature:
+
+        g_hub_client_put_ssl_fd(client, tls_fd);
+
+    }
+
+    exit_packed_buffer(&out_pbuf);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : client    = client pour les accès distants à manipuler.      *
 *                timestamp = date du dernier élément à garder comme actif.    *
 *                                                                             *
diff --git a/src/analysis/db/client.h b/src/analysis/db/client.h
index 2915f77..f7f7bcb 100644
--- a/src/analysis/db/client.h
+++ b/src/analysis/db/client.h
@@ -64,15 +64,12 @@ bool g_hub_client_start_remote(GHubClient *, const char *, const char *, bool);
 /* Arrête la connexion à la base de données. */
 void g_hub_client_stop(GHubClient *);
 
-/* Identifie le canal de communication pour envois au serveur. */
-SSL *g_hub_client_get_ssl_fd(GHubClient *);
-
-/* Marque le canal de communication comme disponible. */
-void g_hub_client_put_ssl_fd(GHubClient *, SSL *);
-
 /* Effectue une demande de sauvegarde de l'état courant. */
 bool g_hub_client_save(GHubClient *);
 
+/* Ajoute un élément à la collection d'un serveur. */
+bool g_hub_client_add_item(GHubClient *, const GDbItem *);
+
 /* Active les éléments en amont d'un horodatage donné. */
 bool g_hub_client_set_last_active(GHubClient *, timestamp_t);
 
diff --git a/src/analysis/db/collection.c b/src/analysis/db/collection.c
index 7b2082a..6e877a4 100644
--- a/src/analysis/db/collection.c
+++ b/src/analysis/db/collection.c
@@ -36,6 +36,7 @@
 #include "collection-int.h"
 #include "misc/rlestr.h"
 #include "../../common/extstr.h"
+#include "../../common/sort.h"
 #include "../../glibext/chrysamarshal.h"
 
 
@@ -56,14 +57,8 @@ static void g_db_collection_dispose(GDbCollection *);
 /* Procède à la libération totale de la mémoire. */
 static void g_db_collection_finalize(GDbCollection *);
 
-
-
-#define g_db_collection_find_by_timestamped(c, i) c->count
-
-#define g_db_collection_find_by_timestamp(c, i) c->count
-
-
-
+/* Retrouve l'élément correspondant à un horodatage. */
+size_t g_db_collection_find_by_timestamped(GDbCollection *, const GDbItem *);
 
 /* Ajoute un élément dans la liste des éléments actifs. */
 static void g_db_collection_set_last_item(GDbCollection *, GDbItem *, bool);
@@ -71,6 +66,9 @@ static void g_db_collection_set_last_item(GDbCollection *, GDbItem *, bool);
 /* Retire un élément de la liste des éléments courants. */
 static void g_db_collection_unset_last_item(GDbCollection *, GDbItem *, size_t);
 
+/* Retrouve le premier élément correspondant à un horodatage. */
+size_t g_db_collection_find_by_timestamp(GDbCollection *, timestamp_t);
+
 
 
 /* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */
@@ -453,7 +451,7 @@ bool g_db_collection_unpack(GDbCollection *collec, packed_buffer *pbuf, sqlite3
 *                                                                             *
 ******************************************************************************/
 
-bool g_db_collection_pack(GDbCollection *collec, packed_buffer *pbuf, DBAction action, GDbItem *item)
+bool g_db_collection_pack(GDbCollection *collec, packed_buffer *pbuf, DBAction action, const GDbItem *item)
 {
     bool result;                            /* Bilan à retourner           */
 
@@ -617,6 +615,37 @@ GDbItem *g_db_collection_has_key(GDbCollection *collec, ...)
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : binary = élément binaire à consulter.                        *
+*                item   = définition de l'élément à retrouver.                *
+*                                                                             *
+*  Description : Retrouve l'élément correspondant à un horodatage.            *
+*                                                                             *
+*  Retour      : Indice valide pour un élément retrouvé, invalide sinon.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_db_collection_find_by_timestamped(GDbCollection *collec, const GDbItem *item)
+{
+    size_t result;                          /* Indice à retourner          */
+    GDbItem **found;                        /* Emplacement de la trouvaille*/
+
+    found = bsearch(&item, collec->items, collec->count, sizeof(GDbItem *),
+                    (__compar_fn_t)g_db_item_cmp_timestamp);
+
+    if (found == NULL)
+        result = collec->count;
+    else
+        result = found - collec->items;
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : collec = ensemble d'éléments à consulter.                    *
 *                item   = élément complet dont un double est à rechercher.    *
 *                                                                             *
@@ -942,6 +971,43 @@ static void g_db_collection_unset_last_item(GDbCollection *collec, GDbItem *item
 *                                                                             *
 *  Paramètres  : binary    = élément binaire à consulter.                     *
 *                timestamp = date du dernier élément à garder comme actif.    *
+*                                                                             *
+*  Description : Retrouve le premier élément correspondant à un horodatage.   *
+*                                                                             *
+*  Retour      : Indice valide pour un élément retrouvé, invalide sinon.      *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+size_t g_db_collection_find_by_timestamp(GDbCollection *collec, timestamp_t timestamp)
+{
+    size_t result;                          /* Indice à retourner          */
+    timestamp_t prev_ts;                    /* Horodatage précédent        */
+
+    bsearch_index(&timestamp, collec->items, collec->count, sizeof(GDbItem *),
+                  (__compar_fn_t)g_db_item_cmp_with_timestamp, &result);
+
+    while (result > 0)
+    {
+        prev_ts = g_db_item_get_timestamp(collec->items[result - 1]);
+
+        if (cmp_timestamp(&prev_ts, &timestamp) != 0)
+            break;
+
+        result--;
+
+    }
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : binary    = élément binaire à consulter.                     *
+*                timestamp = date du dernier élément à garder comme actif.    *
 *                db        = base de données à mettre à jour.                 *
 *                pbuf      = paquet de données où venir inscrire les infos.   *
 *                                                                             *
diff --git a/src/analysis/db/collection.h b/src/analysis/db/collection.h
index 9539229..76d134b 100644
--- a/src/analysis/db/collection.h
+++ b/src/analysis/db/collection.h
@@ -75,7 +75,7 @@ bool _g_db_collection_unpack(GDbCollection *, packed_buffer *, DBAction *, GDbIt
 bool g_db_collection_unpack(GDbCollection *, packed_buffer *, sqlite3 *);
 
 /* Envoie pour traitement une requête réseau pour collection. */
-bool g_db_collection_pack(GDbCollection *, packed_buffer *, DBAction, GDbItem *);
+bool g_db_collection_pack(GDbCollection *, packed_buffer *, DBAction, const GDbItem *);
 
 /* Envoie pour mise à jour tous les éléments courants. */
 bool g_db_collection_pack_all_updates(GDbCollection *, packed_buffer *);
diff --git a/src/analysis/db/item-int.h b/src/analysis/db/item-int.h
index 35fca94..93472c5 100644
--- a/src/analysis/db/item-int.h
+++ b/src/analysis/db/item-int.h
@@ -70,6 +70,7 @@ struct _GDbItem
     GObject parent;                         /* A laisser en premier        */
 
     timestamp_t created;                    /* Date de création            */
+    unsigned long index;                    /* Indice au sein d'un groupe  */
 
     rle_string author;                      /* Utilisateur d'origine       */
 
diff --git a/src/analysis/db/item.c b/src/analysis/db/item.c
index 029b1d6..c880d65 100644
--- a/src/analysis/db/item.c
+++ b/src/analysis/db/item.c
@@ -31,6 +31,7 @@
 
 
 #include "item-int.h"
+#include "../../common/sort.h"
 #include "../../core/params.h"
 
 
@@ -116,6 +117,8 @@ static void g_db_item_class_init(GDbItemClass *klass)
 
 static void g_db_item_init(GDbItem *item)
 {
+    item->index = 0;
+
     set_static_rle_string(&item->author, "");
 
     g_atomic_int_set(&item->atomic_flags, DIF_NONE);
@@ -257,6 +260,57 @@ gboolean g_db_item_cmp_key(const GDbItem *a, const GDbItem *b)
 
 /******************************************************************************
 *                                                                             *
+*  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   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int g_db_item_cmp_timestamp(const GDbItem **a, const GDbItem **b)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = cmp_timestamp(&(*a)->created, &(*b)->created);
+
+    if (result == 0)
+        result = sort_unsigned_long((*a)->index, (*b)->index);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : ts = premier élément à analyser.                             *
+*                b  = second élément à analyser.                              *
+*                                                                             *
+*  Description : Effectue la comparaison entre un élément et un horodatage.   *
+*                                                                             *
+*  Retour      : Bilan de la comparaison : -1, 0 ou 1.                        *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+int g_db_item_cmp_with_timestamp(const timestamp_t *ts, const GDbItem **b)
+{
+    int result;                             /* Bilan à retourner           */
+
+    result = cmp_timestamp(ts, &(*b)->created);
+
+    return result;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : a    = premier élément à analyser.                           *
 *                b    = second élément à analyser.                            *
 *                with = précise les horodatages à prendre en compte.          *
diff --git a/src/analysis/db/item.h b/src/analysis/db/item.h
index b735fb8..32c296a 100644
--- a/src/analysis/db/item.h
+++ b/src/analysis/db/item.h
@@ -84,6 +84,12 @@ guint g_db_item_hash_key(const GDbItem *);
 gboolean g_db_item_cmp_key(const GDbItem *, const GDbItem *);
 
 /* Effectue la comparaison entre deux éléments de collection. */
+int g_db_item_cmp_timestamp(const GDbItem **, const GDbItem **);
+
+/* Effectue la comparaison entre un élément et un horodatage. */
+int g_db_item_cmp_with_timestamp(const timestamp_t *, const GDbItem **);
+
+/* Effectue la comparaison entre deux éléments de collection. */
 gint g_db_item_cmp(GDbItem *, GDbItem *, bool);
 
 /* Effectue la comparaison entre deux éléments de collection. */
diff --git a/src/gui/menus/edition.c b/src/gui/menus/edition.c
index 01f24e8..92596ca 100644
--- a/src/gui/menus/edition.c
+++ b/src/gui/menus/edition.c
@@ -753,7 +753,7 @@ static void mcb_edition_bookmarks_toggle(GtkMenuItem *menuitem, GMenuBar *bar)
 
             }
 
-            _g_loaded_binary_add_to_collection(binary, G_DB_ITEM(bookmark), false);
+            g_loaded_binary_add_to_collection(binary, G_DB_ITEM(bookmark));
 
         mcb_ebt_add_finish:
 
-- 
cgit v0.11.2-87-g4458