From b1c08dd388a86d9a9d7c379ca143ae85310c3c68 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Sun, 20 Oct 2019 15:01:24 +0200 Subject: Provided a way to update snapshots name and description. --- plugins/pychrysalide/analysis/db/client.c | 145 ++++++++++++++++++++++++++-- src/analysis/db/cdb.c | 28 ++++++ src/analysis/db/client.c | 153 ++++++++++++++++++++++++++++++ src/analysis/db/client.h | 6 ++ src/analysis/db/misc/snapshot.c | 52 ++++++++++ src/analysis/db/misc/snapshot.h | 6 ++ src/analysis/db/protocol.h | 59 ++++++------ src/analysis/db/snapshot.c | 135 +++++++++++++++++++++++++- src/analysis/db/snapshot.h | 6 ++ 9 files changed, 552 insertions(+), 38 deletions(-) diff --git a/plugins/pychrysalide/analysis/db/client.c b/plugins/pychrysalide/analysis/db/client.c index f9ce001..80e15b8 100644 --- a/plugins/pychrysalide/analysis/db/client.c +++ b/plugins/pychrysalide/analysis/db/client.c @@ -56,6 +56,12 @@ static PyObject *py_hub_client_save(PyObject *, PyObject *); /* Active les éléments en amont d'un horodatage donné. */ static PyObject *py_hub_client_set_last_active(PyObject *, PyObject *); +/* Définit la désignation d'un instantané donné. */ +static PyObject *py_hub_client_set_snapshot_name(PyObject *, PyObject *); + +/* Définit la désignation d'un instantané donné. */ +static PyObject *py_hub_client_set_snapshot_desc(PyObject *, PyObject *); + /* Fournit la liste des instantanés existants. */ static PyObject *py_hub_client_get_snapshots(PyObject *, void *); @@ -92,7 +98,8 @@ static PyObject *py_hub_client_new(PyTypeObject *type, PyObject *args, PyObject GHubClient *client; /* Serveur mis en place */ #define HUB_CLIENT_DOC \ - "HubClient provides binary updates to a given server.\n" \ + "HubClient provides and receives binary updates to and from a connected" \ + " to a server.\n" \ "\n" \ "Such clients must be authenticated and communications are encrypted using TLS.\n" \ "\n" \ @@ -101,10 +108,20 @@ static PyObject *py_hub_client_new(PyTypeObject *type, PyObject *args, PyObject " HubClient(hash, list)" \ "\n" \ "Where hash is a SHA256 fingerprint of the studied binary and list is a list of" \ - " pychrysalide.analysis.db.DbCollection instances.\n" \ + " pychrysalide.analysis.db.DbCollection instances ; this kind of list can be" \ + " retrived with the pychrysalide.analysis.LoadedBinary.collections attribute." \ + "\n" \ + "HubClient instances emit the following signals:\n" \ + "* 'snapshots-updated'\n" \ + " This signal is emitted when the snapshot list has evolved.\n" \ "\n" \ - "This kind of list can be retrived with the" \ - " pychrysalide.analysis.LoadedBinary.collections attribute." + " Handlers are expected to have only one argument: the client managing the" \ + " updated snapshots.\n" \ + "* 'snapshot-changed'\n" \ + " This signal is emitted when the identifier of the current snapshot changed.\n" \ + "\n" \ + " Handlers are expected to have only one argument: the client managing the" \ + " snapshots." ret = PyArg_ParseTuple(args, "sO", &hash, &list); if (!ret) return NULL; @@ -256,8 +273,6 @@ static PyObject *py_hub_client_stop(PyObject *self, PyObject *args) * * * Retour : True si la commande a bien été envoyée, False sinon. * * * -* Retour : - * -* * * Remarques : - * * * ******************************************************************************/ @@ -272,7 +287,7 @@ static PyObject *py_hub_client_save(PyObject *self, PyObject *args) ( \ save, "$self, /", \ METH_NOARGS, py_hub_client, \ - "Ask the server for saving the current state of the analyzed binary," \ + "Ask the server for saving the current state of the analyzed binary" \ " and returns the status of the request transmission." \ ) @@ -297,8 +312,6 @@ static PyObject *py_hub_client_save(PyObject *self, PyObject *args) * * * Retour : True si la commande a bien été envoyée, False sinon. * * * -* Retour : - * -* * * Remarques : - * * * ******************************************************************************/ @@ -340,6 +353,118 @@ static PyObject *py_hub_client_set_last_active(PyObject *self, PyObject *args) /****************************************************************************** * * +* Paramètres : self = client à manipuler. * +* args = arguments d'appel à consulter. * +* * +* Description : Définit la désignation d'un instantané donné. * +* * +* Retour : True si la commande a bien été envoyée, False sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_hub_client_set_snapshot_name(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + const char *raw_id; /* Identifiant brut */ + const char *text; /* Texte fourni à transmettre */ + int ret; /* Bilan de lecture des args. */ + snapshot_id_t id; /* Identifiant utilisable */ + bool status; /* Bilan d'opération */ + GHubClient *client; /* Version native du serveur */ + +#define HUB_CLIENT_SET_SNAPSHOT_NAME_METHOD PYTHON_METHOD_DEF \ +( \ + set_snapshot_name, "$self, id, name, /", \ + METH_VARARGS, py_hub_client, \ + "Ask the server for defining a new name of for a snapshot using its" \ + " identifier and returns the status of the request transmission." \ + "\n" \ + "A 'snapshots-updated' signal is emitted once the request has been" \ + " processed with success." \ +) + + ret = PyArg_ParseTuple(args, "ss", &raw_id, &text); + if (!ret) return NULL; + + status = init_snapshot_id_from_text(&id, raw_id); + if (!status) + { + PyErr_SetString(PyExc_TypeError, _("provided value is not a valid snapshot identifier.")); + return NULL; + } + + client = G_HUB_CLIENT(pygobject_get(self)); + + status = g_hub_client_set_snapshot_name(client, &id, text); + + result = status ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : self = client à manipuler. * +* args = arguments d'appel à consulter. * +* * +* Description : Définit la désignation d'un instantané donné. * +* * +* Retour : True si la commande a bien été envoyée, False sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static PyObject *py_hub_client_set_snapshot_desc(PyObject *self, PyObject *args) +{ + PyObject *result; /* Bilan à retourner */ + const char *raw_id; /* Identifiant brut */ + const char *text; /* Texte fourni à transmettre */ + int ret; /* Bilan de lecture des args. */ + snapshot_id_t id; /* Identifiant utilisable */ + bool status; /* Bilan d'opération */ + GHubClient *client; /* Version native du serveur */ + +#define HUB_CLIENT_SET_SNAPSHOT_DESC_METHOD PYTHON_METHOD_DEF \ +( \ + set_snapshot_desc, "$self, id, desc, /", \ + METH_VARARGS, py_hub_client, \ + "Ask the server for defining a new description for a snapshot using" \ + " its identifier and returns the status of the request transmission." \ + "\n" \ + "A 'snapshots-updated' signal is emitted once the request has been" \ + " processed with success." \ +) + + ret = PyArg_ParseTuple(args, "ss", &raw_id, &text); + if (!ret) return NULL; + + status = init_snapshot_id_from_text(&id, raw_id); + if (!status) + { + PyErr_SetString(PyExc_TypeError, _("provided value is not a valid snapshot identifier.")); + return NULL; + } + + client = G_HUB_CLIENT(pygobject_get(self)); + + status = g_hub_client_set_snapshot_desc(client, &id, text); + + result = status ? Py_True : Py_False; + Py_INCREF(result); + + return result; + +} + + +/****************************************************************************** +* * * Paramètres : self = objet Python concerné par l'appel. * * closure = non utilisé ici. * * * @@ -584,6 +709,8 @@ PyTypeObject *get_python_hub_client_type(void) HUB_CLIENT_STOP_METHOD, HUB_CLIENT_SAVE_METHOD, HUB_CLIENT_SET_LAST_ACTIVE_METHOD, + HUB_CLIENT_SET_SNAPSHOT_NAME_METHOD, + HUB_CLIENT_SET_SNAPSHOT_DESC_METHOD, { NULL } }; diff --git a/src/analysis/db/cdb.c b/src/analysis/db/cdb.c index d569719..125f69d 100644 --- a/src/analysis/db/cdb.c +++ b/src/analysis/db/cdb.c @@ -1007,6 +1007,8 @@ static void *g_cdb_archive_process(GCdbArchive *archive) case DBC_GET_SNAPSHOTS: + force_snapshots_update: + init_packed_buffer(&out_pbuf); status = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SNAPSHOTS_UPDATED }, @@ -1060,6 +1062,32 @@ static void *g_cdb_archive_process(GCdbArchive *archive) case DBC_SET_CUR_SNAPSHOT: + + + break; + + case DBC_SET_SNAPSHOT_NAME: + + error = g_db_snapshot_set_name(archive->snapshot, &in_pbuf); + + if (error == DBE_NONE) + goto force_snapshots_update; + + else if (error == DBE_BAD_EXCHANGE) + goto gcap_bad_exchange; + + break; + + case DBC_SET_SNAPSHOT_DESC: + + error = g_db_snapshot_set_desc(archive->snapshot, &in_pbuf); + + if (error == DBE_NONE) + goto force_snapshots_update; + + else if (error == DBE_BAD_EXCHANGE) + goto gcap_bad_exchange; + break; default: diff --git a/src/analysis/db/client.c b/src/analysis/db/client.c index 15ec27f..9558f85 100644 --- a/src/analysis/db/client.c +++ b/src/analysis/db/client.c @@ -92,6 +92,11 @@ struct _GHubClientClass { GObjectClass parent; /* A laisser en premier */ + /* Signaux */ + + void (* snapshots_updated) (GHubClient *); + void (* snapshot_changed) (GHubClient *); + }; @@ -152,6 +157,22 @@ static void g_hub_client_class_init(GHubClientClass *klass) object->dispose = (GObjectFinalizeFunc/* ! */)g_hub_client_dispose; object->finalize = (GObjectFinalizeFunc)g_hub_client_finalize; + g_signal_new("snapshots-updated", + G_TYPE_HUB_CLIENT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GHubClientClass, snapshots_updated), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + g_signal_new("snapshot-changed", + G_TYPE_HUB_CLIENT, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(GHubClientClass, snapshot_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + } @@ -188,6 +209,7 @@ static void g_hub_client_init(GHubClient *client) client->snap_count = 0; g_mutex_init(&client->snap_lock); + setup_empty_snapshot_id(&client->current); client->has_current = false; g_mutex_init(&client->cur_lock); @@ -857,6 +879,12 @@ static void *g_hub_client_update(GHubClient *client) client->can_get_updates = (tmp8 == 0x1); break; + case DBC_GET_SNAPSHOTS: + log_variadic_message(LMT_INFO, + _("This command is not available on this side: 0x%08x"), command); + goto gdcu_bad_exchange; + break; + case DBC_SNAPSHOTS_UPDATED: status = g_hub_client_update_snapshots(client, &in_pbuf); @@ -878,6 +906,8 @@ static void *g_hub_client_update(GHubClient *client) break; case DBC_SET_CUR_SNAPSHOT: + case DBC_SET_SNAPSHOT_NAME: + case DBC_SET_SNAPSHOT_DESC: log_variadic_message(LMT_INFO, _("This command is not available on this side: 0x%08x"), command); goto gdcu_bad_exchange; @@ -987,6 +1017,9 @@ static bool g_hub_client_update_snapshots(GHubClient *client, packed_buffer *pbu g_mutex_unlock(&client->snap_lock); + if (result) + g_signal_emit_by_name(client, "snapshots-updated"); + return result; } @@ -1023,6 +1056,8 @@ static bool g_hub_client_update_current_snapshot(GHubClient *client, packed_buff g_mutex_unlock(&client->cur_lock); + g_signal_emit_by_name(client, "snapshot-changed"); + } return result; @@ -1416,3 +1451,121 @@ bool g_hub_client_set_current_snapshot(GHubClient *client, const snapshot_id_t * return result; } + + +/****************************************************************************** +* * +* Paramètres : client = client pour les accès distants à manipuler. * +* id = identifiant d'instantané à traiter. * +* name = désignation humaine pour l'instantané. * +* * +* Description : Définit la désignation d'un instantané donné. * +* * +* Retour : true si la commande a bien été envoyée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_hub_client_set_snapshot_name(GHubClient *client, const snapshot_id_t *id, const char *name) +{ + bool result; /* Bilan partiel à remonter */ + packed_buffer out_pbuf; /* Tampon d'émission */ + SSL *tls_fd; /* Canal de communication SSL */ + rle_string string; /* Chaîne à transmettre */ + + init_packed_buffer(&out_pbuf); + + tls_fd = g_hub_client_get_ssl_fd(client); + + if (tls_fd == NULL) + result = false; + + else + { + result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SET_SNAPSHOT_NAME }, sizeof(uint32_t), true); + + if (result) + result = pack_snapshot_id(id, &out_pbuf); + + if (result) + { + init_static_rle_string(&string, name); + + result = pack_rle_string(&string, &out_pbuf); + + exit_rle_string(&string); + + } + + 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); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : client = client pour les accès distants à manipuler. * +* id = identifiant d'instantané à traiter. * +* desc = description humaine pour l'instantané. * +* * +* Description : Définit la description d'un instantané donné. * +* * +* Retour : true si la commande a bien été envoyée, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_hub_client_set_snapshot_desc(GHubClient *client, const snapshot_id_t *id, const char *desc) +{ + bool result; /* Bilan partiel à remonter */ + packed_buffer out_pbuf; /* Tampon d'émission */ + SSL *tls_fd; /* Canal de communication SSL */ + rle_string string; /* Chaîne à transmettre */ + + init_packed_buffer(&out_pbuf); + + tls_fd = g_hub_client_get_ssl_fd(client); + + if (tls_fd == NULL) + result = false; + + else + { + result = extend_packed_buffer(&out_pbuf, (uint32_t []) { DBC_SET_SNAPSHOT_DESC }, sizeof(uint32_t), true); + + if (result) + result = pack_snapshot_id(id, &out_pbuf); + + if (result) + { + init_static_rle_string(&string, desc); + + result = pack_rle_string(&string, &out_pbuf); + + exit_rle_string(&string); + + } + + 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); + + return result; + +} diff --git a/src/analysis/db/client.h b/src/analysis/db/client.h index 039631e..5ad4ed0 100644 --- a/src/analysis/db/client.h +++ b/src/analysis/db/client.h @@ -83,6 +83,12 @@ bool g_hub_client_get_current_snapshot(GHubClient *, snapshot_id_t *); /* Définit l'identifiant de l'instantané courant. */ bool g_hub_client_set_current_snapshot(GHubClient *, const snapshot_id_t *); +/* Définit la désignation d'un instantané donné. */ +bool g_hub_client_set_snapshot_name(GHubClient *, const snapshot_id_t *, const char *); + +/* Définit la description d'un instantané donné. */ +bool g_hub_client_set_snapshot_desc(GHubClient *, const snapshot_id_t *, const char *); + #endif /* _ANALYSIS_DB_CLIENT_H */ diff --git a/src/analysis/db/misc/snapshot.c b/src/analysis/db/misc/snapshot.c index c441ead..723ba75 100644 --- a/src/analysis/db/misc/snapshot.c +++ b/src/analysis/db/misc/snapshot.c @@ -509,3 +509,55 @@ bool pack_snapshot_info(const snapshot_info_t *info, packed_buffer *pbuf) return result; } + + +/****************************************************************************** +* * +* Paramètres : info = informations à mettre à jour. * +* name = nouvelle désignation à considérer. * +* * +* Description : Change la désignation dans les informations d'un instantané. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_snapshot_info_name(snapshot_info_t *info, const char *name) +{ + if (info->name == NULL) + free(info->name); + + if (name == NULL) + info->name = NULL; + else + info->name = strdup(name); + +} + + +/****************************************************************************** +* * +* Paramètres : info = informations à mettre à jour. * +* desc = nouvelle description à considérer. * +* * +* Description : Change la description dans les informations d'un instantané. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void set_snapshot_info_desc(snapshot_info_t *info, const char *desc) +{ + if (info->desc == NULL) + free(info->desc); + + if (desc == NULL) + info->desc = NULL; + else + info->desc = strdup(desc); + +} diff --git a/src/analysis/db/misc/snapshot.h b/src/analysis/db/misc/snapshot.h index 8f9a598..3f55b50 100644 --- a/src/analysis/db/misc/snapshot.h +++ b/src/analysis/db/misc/snapshot.h @@ -122,6 +122,12 @@ bool unpack_snapshot_info(snapshot_info_t *, packed_buffer *); /* Exporte la description d'un identifiant d'instantané. */ bool pack_snapshot_info(const snapshot_info_t *, packed_buffer *); +/* Change la désignation dans les informations d'un instantané. */ +void set_snapshot_info_name(snapshot_info_t *, const char *); + +/* Change la description dans les informations d'un instantané. */ +void set_snapshot_info_desc(snapshot_info_t *, const char *); + #endif /* _ANALYSIS_DB_MISC_SNAPSHOT_H */ diff --git a/src/analysis/db/protocol.h b/src/analysis/db/protocol.h index 273be8e..b57c25c 100644 --- a/src/analysis/db/protocol.h +++ b/src/analysis/db/protocol.h @@ -129,11 +129,6 @@ typedef enum _DBCommand * [ Ordre de sauvegarde : DBC_SAVE ] * [ Statut d'exécution ; cf. DBError ] * - * Les traitements se réalisent dans : - * - g_db_client_save() pour la partie client en émission ; - * - g_cdb_archive_process() pour la partie serveur ; - * - g_db_client_update() pour la partie client en réception. - * */ DBC_SAVE, /* Enregistrement de l'archive */ @@ -167,10 +162,6 @@ typedef enum _DBCommand * [ Notification de maj : DBC_SET_ALL_ITEMS ] * [ marqueur de fin : octet 0x0 ] * - * Les traitements se réalisent dans : - * - g_db_client_update() pour la partie client ; - * - g_cdb_archive_process() pour la partie serveur. - * */ DBC_GET_ALL_ITEMS, /* Mise à jour à la connexion */ @@ -191,10 +182,6 @@ typedef enum _DBCommand * [ Action : DBA_CHANGE_STATE ] * [ <élément dont le statut a évolué> ] * - * Les traitements se réalisent dans : - * - g_db_collection_disable_at() pour la partie serveur ; - * - g_db_collection_update_item_state() pour la partie client. - * */ DBC_SET_LAST_ACTIVE, /* Définition du dernier actif */ // REMME @@ -208,9 +195,6 @@ typedef enum _DBCommand * * [ 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, @@ -224,9 +208,6 @@ typedef enum _DBCommand * [ ] * [ 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*/ @@ -238,9 +219,6 @@ typedef enum _DBCommand * * [ Gestion d'instantané : DBC_GET_CUR_SNAPSHOT ] * - * 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_CUR_SNAPSHOT, /* Demande d'identification */ @@ -253,9 +231,6 @@ typedef enum _DBCommand * [ Gestion d'instantané : DBC_CUR_SNAPSHOT_UPDATED ] * [ ] * - * 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_CUR_SNAPSHOT_UPDATED, /* Mise à jour de l'instantané */ @@ -268,13 +243,40 @@ typedef enum _DBCommand * [ Gestion d'instantané : DBC_SET_CUR_SNAPSHOT ] * [ ] * - * La définition d'un nouvel identifiant d'instantané courant se réalise dans : - * - g_hub_client_set_current_snapshot() pour la partie client ; - * - */ DBC_SET_CUR_SNAPSHOT, /* Définition de l'instantané */ + /** + * Gestion de la commande 'DBC_SET_SNAPSHOT_NAME'. + * + * Le client connecté envoie un paquet de la forme suivante : + * + * [ Gestion d'instantané : DBC_SET_SNAPSHOT_NAME ] + * [ ] + * [ ] + * + * Le serveur renvoie ensuite automatiquement un paquet + * de type 'DBC_SNAPSHOTS_UPDATED'. + */ + + DBC_SET_SNAPSHOT_NAME, /* Désignation de l'instantané */ + + /** + * Gestion de la commande 'DBC_SET_SNAPSHOT_DESC'. + * + * Le client connecté envoie un paquet de la forme suivante : + * + * [ Gestion d'instantané : DBC_SET_SNAPSHOT_DESC ] + * [ ] + * [ ] + * + * Le serveur renvoie ensuite automatiquement un paquet + * de type 'DBC_SNAPSHOTS_UPDATED'. + */ + + DBC_SET_SNAPSHOT_DESC, /* Description de l'instantané */ + DBC_COUNT } DBCommand; @@ -300,6 +302,7 @@ typedef enum _DBError DBE_DB_LOADING_ERROR, /* Erreur pendant le chargement*/ DBE_XML_ERROR, /* Erreur lors d'une définition*/ + DBE_SNAPSHOT_NOT_FOUND, /* Instantané non trouvé */ DBE_COUNT diff --git a/src/analysis/db/snapshot.c b/src/analysis/db/snapshot.c index 79128ef..2cd50f6 100644 --- a/src/analysis/db/snapshot.c +++ b/src/analysis/db/snapshot.c @@ -942,6 +942,9 @@ bool g_db_snapshot_fill(GDbSnapshot *snap, struct archive *archive) node = find_snapshot_node(snap->nodes, &node_id); + if (node == NULL) + break; + if (!setup_snapshot_node_db_path(node, snap->tmpdir, snap->hash)) break; @@ -1059,7 +1062,7 @@ sqlite3 *g_db_snapshot_get_database(const GDbSnapshot *snap, const snapshot_id_t if (node == NULL) { - log_variadic_message(LMT_ERROR, _("Snapshot not found for id '%s'"), *id); + log_variadic_message(LMT_ERROR, _("Snapshot not found for id '%s'"), snapshot_id_as_string(id)); result = NULL; } @@ -1105,3 +1108,133 @@ bool g_db_snapshot_pack_all(const GDbSnapshot *snap, packed_buffer *pbuf) return result; } + + +/****************************************************************************** +* * +* Paramètres : snap = gestionnaire d'instantanés à consulter. * +* pbuf = paquet de données où venir puiser les infos. * +* * +* Description : Actualise la désignation d'un instantané donné. * +* * +* Retour : Bilan de l'opération sous forme de code d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +DBError g_db_snapshot_set_name(const GDbSnapshot *snap, packed_buffer *pbuf) +{ + DBError result; /* Conclusion à retourner */ + snapshot_id_t id; /* Identifiant d'instantané */ + bool status; /* Bilan d'une récupération */ + rle_string string; /* Chaîne à transmettre */ + snapshot_node_t *node; /* Instantané trouvé */ + + result = DBE_NONE; + + /* Lecture des arguments */ + + setup_empty_snapshot_id(&id); + + status = unpack_snapshot_id(&id, pbuf); + if (!status) + { + result = DBE_BAD_EXCHANGE; + goto bad_exchange; + } + + setup_empty_rle_string(&string); + + status = unpack_rle_string(&string, pbuf); + if (!status) + { + result = DBE_BAD_EXCHANGE; + goto bad_exchange; + } + + /* Traitement */ + + node = find_snapshot_node(snap->nodes, &id); + + if (node == NULL) + { + log_variadic_message(LMT_ERROR, _("Snapshot not found for id '%s'"), snapshot_id_as_string(&id)); + result = DBE_SNAPSHOT_NOT_FOUND; + } + + else + set_snapshot_info_name(&node->info, get_rle_string(&string)); + + exit_rle_string(&string); + + bad_exchange: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : snap = gestionnaire d'instantanés à consulter. * +* pbuf = paquet de données où venir puiser les infos. * +* * +* Description : Actualise la description d'un instantané donné. * +* * +* Retour : Bilan de l'opération sous forme de code d'erreur. * +* * +* Remarques : - * +* * +******************************************************************************/ + +DBError g_db_snapshot_set_desc(const GDbSnapshot *snap, packed_buffer *pbuf) +{ + DBError result; /* Conclusion à retourner */ + snapshot_id_t id; /* Identifiant d'instantané */ + bool status; /* Bilan d'une récupération */ + rle_string string; /* Chaîne à transmettre */ + snapshot_node_t *node; /* Instantané trouvé */ + + result = DBE_NONE; + + /* Lecture des arguments */ + + setup_empty_snapshot_id(&id); + + status = unpack_snapshot_id(&id, pbuf); + if (!status) + { + result = DBE_BAD_EXCHANGE; + goto bad_exchange; + } + + setup_empty_rle_string(&string); + + status = unpack_rle_string(&string, pbuf); + if (!status) + { + result = DBE_BAD_EXCHANGE; + goto bad_exchange; + } + + /* Traitement */ + + node = find_snapshot_node(snap->nodes, &id); + + if (node == NULL) + { + log_variadic_message(LMT_ERROR, _("Snapshot not found for id '%s'"), snapshot_id_as_string(&id)); + result = DBE_SNAPSHOT_NOT_FOUND; + } + + else + set_snapshot_info_desc(&node->info, get_rle_string(&string)); + + exit_rle_string(&string); + + bad_exchange: + + return result; + +} diff --git a/src/analysis/db/snapshot.h b/src/analysis/db/snapshot.h index 543d184..457e8c2 100644 --- a/src/analysis/db/snapshot.h +++ b/src/analysis/db/snapshot.h @@ -77,6 +77,12 @@ 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 *); +/* Actualise la désignation d'un instantané donné. */ +DBError g_db_snapshot_set_name(const GDbSnapshot *, packed_buffer *); + +/* Actualise la description d'un instantané donné. */ +DBError g_db_snapshot_set_desc(const GDbSnapshot *, packed_buffer *); + #endif /* _ANALYSIS_DB_SNAPSHOT_H */ -- cgit v0.11.2-87-g4458