summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/analysis/db/cdb.c21
-rw-r--r--src/analysis/db/client.c185
-rw-r--r--src/analysis/db/client.h3
-rw-r--r--src/analysis/db/misc/rlestr.c2
-rw-r--r--src/analysis/db/misc/snapshot.c78
-rw-r--r--src/analysis/db/misc/snapshot.h14
-rw-r--r--src/analysis/db/misc/timestamp.c19
-rw-r--r--src/analysis/db/misc/timestamp.h3
-rw-r--r--src/analysis/db/protocol.h31
-rw-r--r--src/analysis/db/snapshot.c63
-rw-r--r--src/analysis/db/snapshot.h3
-rw-r--r--src/common/packed.c110
-rw-r--r--src/common/packed.h6
13 files changed, 496 insertions, 42 deletions
diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c
index 8e8813a..2df556b 100644
--- a/src/analysis/db/cdb.c
+++ b/src/analysis/db/cdb.c
@@ -1003,6 +1003,27 @@ static void *g_cdb_archive_process(GCdbArchive *archive)
break;
+ case DBC_GET_SNAPSHOTS:
+
+ init_packed_buffer(&out_pbuf);
+
+ status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SNAPSHOTS_UPDATED },
+ sizeof(uint32_t), true);
+ if (!status) goto gcap_bad_reply;
+
+ status = g_db_snapshot_pack_all(archive->snapshot, &out_pbuf);
+ if (!status) goto gcap_bad_reply;
+
+ status = extend_packed_buffer(&out_pbuf, SNAPSHOT_END_MARK, SNAP_ID_HEX_SZ, false);
+ if (!status) goto gcap_bad_reply;
+
+ status = ssl_send_packed_buffer(&out_pbuf, archive->clients[i].ssl_fd);
+ if (!status) goto gcap_bad_reply;
+
+ exit_packed_buffer(&out_pbuf);
+
+ break;
+
case DBC_GET_CUR_SNAPSHOT:
init_packed_buffer(&out_pbuf);
diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c
index 3372c74..2cab655 100644
--- a/src/analysis/db/client.c
+++ b/src/analysis/db/client.c
@@ -25,6 +25,7 @@
#include <assert.h>
+#include <malloc.h>
#include <netdb.h>
#include <poll.h>
#include <stdio.h>
@@ -76,11 +77,13 @@ struct _GHubClient
bool can_get_updates; /* Réception de maj possibles ?*/
GThread *update; /* Procédure de traitement */
-
-
+ snapshot_info_t *snapshots; /* Liste des instantanés */
+ size_t snap_count; /* Taille de cette liste */
+ GMutex snap_lock; /* Concurrence des accès */
snapshot_id_t current; /* Instantané courant */
bool has_current; /* Validité de l'identifiant */
+ GMutex cur_lock; /* Concurrence des accès */
};
@@ -110,6 +113,9 @@ static bool g_hub_client_start_common(GHubClient *, char *);
/* Assure l'accueil des nouvelles mises à jour. */
static void *g_hub_client_update(GHubClient *);
+/* Met à jour la liste des instantanés courants. */
+static bool g_hub_client_update_snapshots(GHubClient *, packed_buffer *);
+
/* Identifie le canal de communication pour envois au serveur. */
static SSL *g_hub_client_get_ssl_fd(GHubClient *);
@@ -160,6 +166,9 @@ static void g_hub_client_class_init(GHubClientClass *klass)
static void g_hub_client_init(GHubClient *client)
{
+ init_static_rle_string(&client->hash, NULL);
+ client->collections = NULL;
+
client->working = NULL;
client->tls_ctx = NULL;
@@ -168,7 +177,16 @@ static void g_hub_client_init(GHubClient *client)
client->tls_fd = NULL;
client->desc = NULL;
+ g_mutex_init(&client->sending_lock);
+ client->can_get_updates = false;
+ client->update = NULL;
+
+ client->snapshots = NULL;
+ client->snap_count = 0;
+ g_mutex_init(&client->snap_lock);
+
client->has_current = false;
+ g_mutex_init(&client->cur_lock);
}
@@ -189,6 +207,12 @@ static void g_hub_client_dispose(GHubClient *client)
{
g_hub_client_stop(client);
+ g_mutex_clear(&client->cur_lock);
+
+ g_mutex_clear(&client->snap_lock);
+
+ g_mutex_clear(&client->sending_lock);
+
G_OBJECT_CLASS(g_hub_client_parent_class)->dispose(G_OBJECT(client));
}
@@ -208,18 +232,28 @@ static void g_hub_client_dispose(GHubClient *client)
static void g_hub_client_finalize(GHubClient *client)
{
+ size_t i; /* Boucle de parcours */
+
unset_rle_string(&client->hash);
if (client->working != NULL)
free(client->working);
assert(client->tls_ctx == NULL);
-
assert(client->tls_fd == NULL);
if (client->desc != NULL)
free(client->desc);
+ if (client->snapshots != NULL)
+ {
+ for (i = 0; i < client->snap_count; i++)
+ exit_snapshot_info(&client->snapshots[i]);
+
+ free(client->snapshots);
+
+ }
+
G_OBJECT_CLASS(g_hub_client_parent_class)->finalize(G_OBJECT(client));
}
@@ -703,6 +737,13 @@ static void *g_hub_client_update(GHubClient *client)
init_packed_buffer(&out_pbuf);
+ status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_GET_SNAPSHOTS }, sizeof(uint32_t), true);
+ if (!status)
+ {
+ exit_packed_buffer(&out_pbuf);
+ goto exit;
+ }
+
status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_GET_CUR_SNAPSHOT }, sizeof(uint32_t), true);
if (!status)
{
@@ -814,6 +855,13 @@ static void *g_hub_client_update(GHubClient *client)
client->can_get_updates = (tmp8 == 0x1);
break;
+ case DBC_SNAPSHOTS_UPDATED:
+
+ status = g_hub_client_update_snapshots(client, &in_pbuf);
+ if (!status) goto gdcu_bad_exchange;
+
+ break;
+
case DBC_GET_CUR_SNAPSHOT:
log_variadic_message(LMT_INFO,
_("This command is not available on this side: 0x%08x"), command);
@@ -825,9 +873,13 @@ static void *g_hub_client_update(GHubClient *client)
status = unpack_snapshot_id(&id, &in_pbuf);
if (!status) goto gdcu_bad_exchange;
+ g_mutex_lock(&client->cur_lock);
+
copy_snapshot_id(&client->current, &id);
client->has_current = true;
+ g_mutex_unlock(&client->cur_lock);
+
break;
case DBC_SET_CUR_SNAPSHOT:
@@ -872,6 +924,82 @@ static void *g_hub_client_update(GHubClient *client)
/******************************************************************************
* *
* Paramètres : client = client pour les accès distants à manipuler. *
+* pbuf = données présentes à traiter. *
+* *
+* Description : Met à jour la liste des instantanés courants. *
+* *
+* Retour : true si la liste retournée est valide, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_hub_client_update_snapshots(GHubClient *client, packed_buffer *pbuf)
+{
+ bool result; /* Validité à retourner */
+ size_t i; /* Boucle de parcours */
+ char id[SNAP_ID_HEX_SZ]; /* Caractères hexadécimaux */
+ snapshot_info_t info; /* Description d'instantané */
+ snapshot_info_t *dest; /* Destination de description */
+
+ result = true;
+
+ g_mutex_lock(&client->snap_lock);
+
+ if (client->snapshots != NULL)
+ {
+ for (i = 0; i < client->snap_count; i++)
+ exit_snapshot_info(&client->snapshots[i]);
+
+ free(client->snapshots);
+
+ client->snapshots = NULL;
+ client->snap_count = 0;
+
+ }
+
+ do
+ {
+ result = peek_packed_buffer(pbuf, id, SNAP_ID_HEX_SZ, false);
+ if (!result) break;
+
+ if (strncmp(id, SNAPSHOT_END_MARK, SNAP_ID_HEX_SZ) == 0)
+ {
+ advance_packed_buffer(pbuf, SNAP_ID_HEX_SZ);
+ break;
+ }
+
+ else
+ {
+ setup_empty_snapshot_info(&info);
+
+ result = unpack_snapshot_info(&info, pbuf);
+ if (!result) break;
+
+ client->snapshots = realloc(client->snapshots, ++client->snap_count * sizeof(snapshot_info_t));
+
+ dest = &client->snapshots[client->snap_count - 1];
+
+ setup_empty_snapshot_info(dest);
+ copy_snapshot_info(dest, &info);
+
+ exit_snapshot_info(&info);
+
+ }
+
+ }
+ while (true);
+
+ g_mutex_unlock(&client->snap_lock);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : client = client pour les accès distants à manipuler. *
* *
* Description : Arrête la connexion à la base de données. *
* *
@@ -1135,6 +1263,53 @@ bool g_hub_client_set_last_active(GHubClient *client, timestamp_t timestamp)
/******************************************************************************
* *
* Paramètres : client = client pour les accès distants à manipuler. *
+* info = description des instantanés présents. [OUT] *
+* count = taille de la liste retournée. [OUT] *
+* *
+* Description : Fournit la liste des instantanés existants. *
+* *
+* Retour : true si la liste retournée est valide, false sinon. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_hub_client_get_snapshots(GHubClient *client, snapshot_info_t **info, size_t *count)
+{
+ bool result; /* Validité à retourner */
+ size_t i; /* Boucle de parcours */
+ snapshot_info_t *dest; /* Destination de description */
+
+ g_mutex_lock(&client->snap_lock);
+
+ result = (client->snap_count > 0);
+
+ if (result)
+ {
+ *info = malloc(client->snap_count * sizeof(snapshot_info_t));
+ *count = client->snap_count;
+
+ for (i = 0; i < client->snap_count; i++)
+ {
+ dest = &(*info)[i];
+
+ setup_empty_snapshot_info(dest);
+ copy_snapshot_info(dest, &client->snapshots[i]);
+
+ }
+
+ }
+
+ g_mutex_unlock(&client->snap_lock);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : client = client pour les accès distants à manipuler. *
* id = identifiant d'instantané à renseigner. [OUT] *
* *
* Description : Fournit l'identifiant de l'instantané courant. *
@@ -1149,11 +1324,15 @@ bool g_hub_client_get_current_snapshot(GHubClient *client, snapshot_id_t *id)
{
bool result; /* Validité à retourner */
+ g_mutex_lock(&client->cur_lock);
+
result = client->has_current;
if (result)
copy_snapshot_id(id, &client->current);
+ g_mutex_unlock(&client->cur_lock);
+
return result;
}
diff --git a/src/analysis/db/client.h b/src/analysis/db/client.h
index 36d24e6..039631e 100644
--- a/src/analysis/db/client.h
+++ b/src/analysis/db/client.h
@@ -74,6 +74,9 @@ 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);
+/* Fournit la liste des instantanés existants. */
+bool g_hub_client_get_snapshots(GHubClient *, snapshot_info_t **, size_t *);
+
/* Fournit l'identifiant de l'instantané courant. */
bool g_hub_client_get_current_snapshot(GHubClient *, snapshot_id_t *);
diff --git a/src/analysis/db/misc/rlestr.c b/src/analysis/db/misc/rlestr.c
index 0fe182b..c1cc866 100644
--- a/src/analysis/db/misc/rlestr.c
+++ b/src/analysis/db/misc/rlestr.c
@@ -286,7 +286,7 @@ bool unpack_rle_string(rle_string *str, packed_buffer *pbuf)
if (result && str->length > 0)
{
- str->data = (char *)malloc(str->length + 1);
+ str->data = malloc(str->length + 1);
str->dynamic = true;
result = extract_packed_buffer(pbuf, str->data, str->length + 1, false);
diff --git a/src/analysis/db/misc/snapshot.c b/src/analysis/db/misc/snapshot.c
index 546191b..9aa096f 100644
--- a/src/analysis/db/misc/snapshot.c
+++ b/src/analysis/db/misc/snapshot.c
@@ -41,6 +41,25 @@
* *
* Paramètres : id = identifiant d'instantané à initialiser. [OUT] *
* *
+* Description : Prépare un identifiant pour instantané à une définition. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void setup_empty_snapshot_id(snapshot_id_t *id)
+{
+ memset(id, 0, sizeof(snapshot_id_t));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : id = identifiant d'instantané à initialiser. [OUT] *
+* *
* Description : Construit un identifiant pour instantané de base de données. *
* *
* Retour : Bilan de l'opération. *
@@ -214,6 +233,32 @@ bool pack_snapshot_id(const snapshot_id_t *id, packed_buffer *pbuf)
* *
* Paramètres : info = description d'instantané à initialiser. [OUT] *
* *
+* Description : Prépare une description pour instantané à une définition. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void setup_empty_snapshot_info(snapshot_info_t *info)
+{
+ setup_empty_snapshot_id(&info->parent_id);
+
+ setup_empty_snapshot_id(&info->id);
+
+ setup_empty_timestamp(&info->created);
+
+ info->name = NULL;
+ info->desc = NULL;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : info = description d'instantané à initialiser. [OUT] *
+* *
* Description : Construit une description pour instantané de base de données.*
* *
* Retour : Bilan de l'opération. *
@@ -226,7 +271,10 @@ bool init_snapshot_info(snapshot_info_t *info)
{
bool result; /* Bilan à retourner */
- result = init_snapshot_id(&info->id);
+ result = init_snapshot_id_from_text(&info->parent_id, NO_SNAPSHOT_ROOT);
+
+ if (result)
+ result = init_snapshot_id(&info->id);
if (result)
result = init_timestamp(&info->created);
@@ -262,7 +310,10 @@ bool init_snapshot_info_from_text(snapshot_info_t *info, const char *id, uint64_
{
bool result; /* Bilan à retourner */
- result = init_snapshot_id_from_text(&info->id, id);
+ result = init_snapshot_id_from_text(&info->parent_id, NO_SNAPSHOT_ROOT);
+
+ if (result)
+ result = init_snapshot_id_from_text(&info->id, id);
if (result)
result = init_timestamp_from_value(&info->created, created);
@@ -332,6 +383,8 @@ void copy_snapshot_info(snapshot_info_t *dest, const snapshot_info_t *src)
{
exit_snapshot_info(dest);
+ copy_snapshot_id(&dest->parent_id, &src->parent_id);
+
copy_snapshot_id(&dest->id, &src->id);
copy_timestamp(&dest->created, &src->created);
@@ -362,19 +415,26 @@ bool unpack_snapshot_info(snapshot_info_t *info, packed_buffer *pbuf)
{
bool result; /* Bilan à retourner */
rle_string string; /* Chaîne à transmettre */
+ const char *text; /* Valeur textuelle obtenue */
- result = unpack_snapshot_id(&info->id, pbuf);
+ result = unpack_snapshot_id(&info->parent_id, pbuf);
+
+ if (result)
+ result = unpack_snapshot_id(&info->id, pbuf);
if (result)
result = unpack_timestamp(&info->created, pbuf);
if (result)
{
+ init_static_rle_string(&string, NULL);
+
result = unpack_rle_string(&string, pbuf);
if (result)
{
- info->name = strdup(get_rle_string(&string));
+ text = get_rle_string(&string);
+ info->name = (text != NULL ? strdup(text) : NULL);
exit_rle_string(&string);
}
@@ -382,11 +442,14 @@ bool unpack_snapshot_info(snapshot_info_t *info, packed_buffer *pbuf)
if (result)
{
+ init_static_rle_string(&string, NULL);
+
result = unpack_rle_string(&string, pbuf);
if (result)
{
- info->desc = strdup(get_rle_string(&string));
+ text = get_rle_string(&string);
+ info->desc = (text != NULL ? strdup(text) : NULL);
exit_rle_string(&string);
}
@@ -415,7 +478,10 @@ bool pack_snapshot_info(const snapshot_info_t *info, packed_buffer *pbuf)
bool result; /* Bilan à retourner */
rle_string string; /* Chaîne à transmettre */
- result = pack_snapshot_id(&info->id, pbuf);
+ result = pack_snapshot_id(&info->parent_id, pbuf);
+
+ if (result)
+ result = pack_snapshot_id(&info->id, pbuf);
if (result)
result = pack_timestamp(&info->created, pbuf);
diff --git a/src/analysis/db/misc/snapshot.h b/src/analysis/db/misc/snapshot.h
index 37fad7f..8f9a598 100644
--- a/src/analysis/db/misc/snapshot.h
+++ b/src/analysis/db/misc/snapshot.h
@@ -49,6 +49,13 @@ typedef struct _snapshot_id_t
} snapshot_id_t;
+/* Identifiant d'un parent de racine */
+#define NO_SNAPSHOT_ROOT "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+
+
+/* Prépare un identifiant pour instantané à une définition. */
+void setup_empty_snapshot_id(snapshot_id_t *);
+
/* Construit un identifiant pour instantané de base de données. */
bool init_snapshot_id(snapshot_id_t *);
@@ -77,6 +84,7 @@ bool pack_snapshot_id(const snapshot_id_t *, packed_buffer *);
/* Description d'un instantané */
typedef struct _snapshot_info_t
{
+ snapshot_id_t parent_id; /* Identifiant du propriétaire */
snapshot_id_t id; /* Identifiant attribué */
timestamp_t created; /* Date de création */
@@ -87,6 +95,9 @@ typedef struct _snapshot_info_t
} snapshot_info_t;
+/* Prépare une description pour instantané à une définition. */
+void setup_empty_snapshot_info(snapshot_info_t *);
+
/* Construit une description pour instantané de base de données. */
bool init_snapshot_info(snapshot_info_t *);
@@ -96,8 +107,9 @@ bool init_snapshot_info_from_text(snapshot_info_t *, const char *, uint64_t, con
/* Libère la mémoire occupée par une description d'instantané. */
void exit_snapshot_info(snapshot_info_t *);
+#define get_snapshot_info_parent_id(nfo) &(nfo)->parent_id
#define get_snapshot_info_id(nfo) &(nfo)->id
-#define get_snapshot_info_creation(nfo) (nfo)->created
+#define get_snapshot_info_created(nfo) (nfo)->created
#define get_snapshot_info_name(nfo) (nfo)->name
#define get_snapshot_info_desc(nfo) (nfo)->desc
diff --git a/src/analysis/db/misc/timestamp.c b/src/analysis/db/misc/timestamp.c
index dfc6f25..4d457e2 100644
--- a/src/analysis/db/misc/timestamp.c
+++ b/src/analysis/db/misc/timestamp.c
@@ -37,6 +37,25 @@
* *
* Paramètres : timestamp = horodatage à initialiser. [OUT] *
* *
+* Description : Prépare un horodatage à une définition. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void setup_empty_timestamp(timestamp_t *timestamp)
+{
+ *timestamp = 0;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : timestamp = horodatage à initialiser. [OUT] *
+* *
* Description : Obtient un horodatage initialisé au moment même. *
* *
* Retour : Bilan de l'opération. *
diff --git a/src/analysis/db/misc/timestamp.h b/src/analysis/db/misc/timestamp.h
index 7f6290876..52b99f8 100644
--- a/src/analysis/db/misc/timestamp.h
+++ b/src/analysis/db/misc/timestamp.h
@@ -38,6 +38,9 @@
typedef uint64_t timestamp_t;
+/* Prépare un horodatage à une définition. */
+void setup_empty_timestamp(timestamp_t *);
+
/* Obtient un horodatage initialisé au moment même. */
bool init_timestamp(timestamp_t *);
diff --git a/src/analysis/db/protocol.h b/src/analysis/db/protocol.h
index 22f564a..273be8e 100644
--- a/src/analysis/db/protocol.h
+++ b/src/analysis/db/protocol.h
@@ -103,6 +103,9 @@ typedef enum _DBAction
+/* Marqueur de fin pour une transmission d'identifiants */
+#define SNAPSHOT_END_MARK "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
+
@@ -198,6 +201,34 @@ typedef enum _DBCommand
/* ------- Gestion des instantanés ------- */
+ /**
+ * Gestion de la commande 'DBC_GET_SNAPSHOTS'.
+ *
+ * Le client connecté envoie un paquet de la forme suivante :
+ *
+ * [ Gestion d'instantané : DBC_GET_SNAPSHOTS ]
+ *
+ * La définition d'un nouvel identifiant d'instantané courant se réalise dans :
+ * - g_hub_client_update() pour la partie client ;
+ * - g_cdb_archive_process() pour la partie serveur.
+ */
+
+ DBC_GET_SNAPSHOTS,
+
+ /**
+ * Gestion de la commande 'DBC_SNAPSHOTS_UPDATED'.
+ *
+ * Le serveur envoie au client un paquet de la forme suivante :
+ *
+ * [ Gestion d'instantané : DBC_SNAPSHOTS_UPDATED ]
+ * [ <liste de descriptions d'instantanés> ]
+ * [ Marqueur de fin : SNAPSHOT_END_MARK ]
+ *
+ * La définition d'un nouvel identifiant d'instantané courant se réalise dans :
+ * - g_cdb_archive_process() pour la partie serveur ;
+ * - g_hub_client_update() pour la partie client.
+ */
+
DBC_SNAPSHOTS_UPDATED, /* Identification d'instantanés*/
/**
diff --git a/src/analysis/db/snapshot.c b/src/analysis/db/snapshot.c
index 6b762b7..79128ef 100644
--- a/src/analysis/db/snapshot.c
+++ b/src/analysis/db/snapshot.c
@@ -82,6 +82,9 @@ static snapshot_node_t *find_snapshot_node(snapshot_node_t *, const snapshot_id_
/* Ajoute un instantané comme prolongement d'un instantané. */
static void add_snapshot_node(snapshot_node_t *, snapshot_node_t *);
+/* Collecte les descriptions d'une arborescence d'instantanés. */
+static bool pack_snapshot_node(const snapshot_node_t *, packed_buffer *);
+
/* --------------------- MANIPULATIONS D'ENSEMBLE D'INSTANTANES --------------------- */
@@ -378,7 +381,7 @@ static DBError save_snapshot_node(const snapshot_node_t *node, xmlDocPtr xdoc, x
goto exit;
}
- created = get_snapshot_info_creation(&node->info);
+ created = get_snapshot_info_created(&node->info);
status = _add_uint64_attribute_to_node(xml_node, "created", created);
@@ -497,13 +500,47 @@ static snapshot_node_t *find_snapshot_node(snapshot_node_t *node, const snapshot
static void add_snapshot_node(snapshot_node_t *node, snapshot_node_t *child)
{
+ snapshot_id_t *src; /* Identifiant d'instantané #0 */
+ snapshot_id_t *dest; /* Identifiant d'instantané #1 */
+
node->children = realloc(node->children, ++node->count * sizeof(snapshot_node_t *));
node->children[node->count - 1] = child;
+ src = get_snapshot_info_id(&node->info);
+ dest = get_snapshot_info_parent_id(&child->info);
+
+ copy_snapshot_id(dest, src);
+
}
+/******************************************************************************
+* *
+* Paramètres : node = définition d'instantané à consulter. *
+* pbuf = paquet de données où venir inscrire des infos. *
+* *
+* Description : Collecte les descriptions d'une arborescence d'instantanés. *
+* *
+* Retour : Bilan du déroulement des opérations. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool pack_snapshot_node(const snapshot_node_t *node, packed_buffer *pbuf)
+{
+ bool result; /* Bilan à retourner */
+ size_t i; /* Boucle de parcours */
+
+ result = pack_snapshot_info(&node->info, pbuf);
+
+ for (i = 0; i < node->count && result; i++)
+ result = pack_snapshot_node(node->children[i], pbuf);
+
+ return result;
+
+}
@@ -1044,3 +1081,27 @@ sqlite3 *g_db_snapshot_get_database(const GDbSnapshot *snap, const snapshot_id_t
return result;
}
+
+
+/******************************************************************************
+* *
+* Paramètres : snap = gestionnaire d'instantanés à consulter. *
+* pbuf = paquet de données où venir inscrire des infos. *
+* *
+* Description : Collecte les descriptions de l'ensemble des instantanés. *
+* *
+* Retour : Bilan du déroulement des opérations. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_db_snapshot_pack_all(const GDbSnapshot *snap, packed_buffer *pbuf)
+{
+ bool result; /* Bilan à retourner */
+
+ result = pack_snapshot_node(snap->nodes, pbuf);
+
+ return result;
+
+}
diff --git a/src/analysis/db/snapshot.h b/src/analysis/db/snapshot.h
index f568ba3..543d184 100644
--- a/src/analysis/db/snapshot.h
+++ b/src/analysis/db/snapshot.h
@@ -74,6 +74,9 @@ bool g_db_snapshot_get_current_id(const GDbSnapshot *, snapshot_id_t *);
/* Fournit la base de données correspondant à instanné donné. */
sqlite3 *g_db_snapshot_get_database(const GDbSnapshot *, const snapshot_id_t *);
+/* Collecte les descriptions de l'ensemble des instantanés. */
+bool g_db_snapshot_pack_all(const GDbSnapshot *, packed_buffer *);
+
#endif /* _ANALYSIS_DB_SNAPSHOT_H */
diff --git a/src/common/packed.c b/src/common/packed.c
index a8ce3c5..a10155d 100644
--- a/src/common/packed.c
+++ b/src/common/packed.c
@@ -241,7 +241,7 @@ bool extend_packed_buffer(packed_buffer *pbuf, const void *buf, size_t len, bool
* *
******************************************************************************/
-bool extract_packed_buffer(packed_buffer *pbuf, void *buf, size_t len, bool ntoh)
+bool peek_packed_buffer(packed_buffer *pbuf, void *buf, size_t len, bool ntoh)
{
bool result; /* Bilan à retourner */
uint16_t tmp16; /* Valeur intermédiaire 16b */
@@ -250,52 +250,102 @@ bool extract_packed_buffer(packed_buffer *pbuf, void *buf, size_t len, bool ntoh
result = ((pbuf->pos + len - sizeof(uint32_t)) <= pbuf->used);
+ if (!result)
+ goto failed;
+
/* Conversion au formalisme du réseau */
if (!ntoh)
goto skip_conversion;
- if (result)
+ switch (len)
{
- switch (len)
- {
- case 1:
- *((uint8_t *)buf) = *((uint8_t *)(pbuf->data + pbuf->pos));
- break;
+ case 1:
+ *((uint8_t *)buf) = *((uint8_t *)(pbuf->data + pbuf->pos));
+ break;
- case 2:
- tmp16 = be16toh(*(uint16_t *)(pbuf->data + pbuf->pos));
- *((uint16_t *)buf) = tmp16;
- break;
+ case 2:
+ tmp16 = be16toh(*(uint16_t *)(pbuf->data + pbuf->pos));
+ *((uint16_t *)buf) = tmp16;
+ break;
- case 4:
- tmp32 = be32toh(*(uint32_t *)(pbuf->data + pbuf->pos));
- *((uint32_t *)buf) = tmp32;
- break;
+ case 4:
+ tmp32 = be32toh(*(uint32_t *)(pbuf->data + pbuf->pos));
+ *((uint32_t *)buf) = tmp32;
+ break;
- case 8:
- tmp64 = be64toh(*(uint64_t *)(pbuf->data + pbuf->pos));
- *((uint64_t *)buf) = tmp64;
- break;
+ case 8:
+ tmp64 = be64toh(*(uint64_t *)(pbuf->data + pbuf->pos));
+ *((uint64_t *)buf) = tmp64;
+ break;
- default:
+ default:
skip_conversion:
- /**
- * Dans ce cas de figure, c'est à l'appelant de s'assurer que la
- * conversion a bien été réalisée.
- */
- assert(!ntoh);
+ /**
+ * Dans ce cas de figure, c'est à l'appelant de s'assurer que la
+ * conversion a bien été réalisée.
+ */
+ assert(!ntoh);
+
+ memcpy(buf, pbuf->data + pbuf->pos, len);
+ break;
- memcpy(buf, pbuf->data + pbuf->pos, len);
- break;
+ }
- }
+ failed:
- pbuf->pos += len;
+ return result;
- }
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : pbuf = paquet de données à consulter. *
+* len = quantité de ces données. *
+* *
+* Description : Avance la tête de lecture dans les données d'un paquet. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void advance_packed_buffer(packed_buffer *pbuf, size_t len)
+{
+ pbuf->pos += len;
+
+ assert((pbuf->pos - sizeof(uint32_t)) <= pbuf->used);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : pbuf = paquet de données à consulter. *
+* buf = nouvelles données à définir. *
+* len = quantité de ces données. *
+* ntoh = indique si une conversion est à réaliser. *
+* *
+* Description : Récupère des données depuis un paquet après une réception. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool extract_packed_buffer(packed_buffer *pbuf, void *buf, size_t len, bool ntoh)
+{
+ bool result; /* Bilan à retourner */
+
+ result = peek_packed_buffer(pbuf, buf, len, ntoh);
+
+ if (result)
+ advance_packed_buffer(pbuf, len);
return result;
diff --git a/src/common/packed.h b/src/common/packed.h
index 4403ad0..019d21a 100644
--- a/src/common/packed.h
+++ b/src/common/packed.h
@@ -66,6 +66,12 @@ bool has_more_data_in_packed_buffer(const packed_buffer *);
bool extend_packed_buffer(packed_buffer *, const void *, size_t, bool);
/* Récupère des données depuis un paquet après une réception. */
+bool peek_packed_buffer(packed_buffer *, void *, size_t, bool);
+
+/* Avance la tête de lecture dans les données d'un paquet. */
+void advance_packed_buffer(packed_buffer *, size_t);
+
+/* Récupère des données depuis un paquet après une réception. */
bool extract_packed_buffer(packed_buffer *, void *, size_t, bool);
/* Lit des données depuis un flux local. */