/* Chrysalide - Outil d'analyse de fichiers binaires
* snapshot.c - encodage des informations utiles aux instantanés
*
* Copyright (C) 2019 Cyrille Bagard
*
* This file is part of Chrysalide.
*
* Chrysalide 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.
*
* Chrysalide 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 Chrysalide. If not, see .
*/
#include "snapshot.h"
#include
#include
#include "../../../core/logs.h"
/* ---------------------------------------------------------------------------------- */
/* IDENTIFIANTS DES INSTANTANES */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
* 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. *
* *
* Remarques : - *
* *
******************************************************************************/
bool init_snapshot_id(snapshot_id_t *id)
{
bool result; /* Bilan à retourner */
int ret; /* Bilan d'une génération */
unsigned char rand[SNAP_ID_RAND_SZ]; /* Tirage aléatoire */
size_t i; /* Boucle de parcours */
static char *alphabet = "0123456789abcdef";
ret = RAND_bytes(rand, SNAP_ID_RAND_SZ);
if (ret != 1)
{
LOG_ERROR_OPENSSL;
result = false;
}
else
{
for (i = 0; i < SNAP_ID_RAND_SZ; i++)
{
id->name[i * 2 + 0] = alphabet[rand[i] & 0xf];
id->name[i * 2 + 1] = alphabet[(rand[i] >> 4) & 0xf];
}
id->name[i * 2] = '\0';
result = true;
}
return result;
}
/******************************************************************************
* *
* Paramètres : id = identifiant d'instantané à initialiser. [OUT] *
* text = source de données pour la constitution. *
* *
* Description : Construit un identifiant pour instantané de base de données. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool init_snapshot_id_from_text(snapshot_id_t *id, const char *text)
{
bool result; /* Bilan à retourner */
result = (strlen(text) == (SNAP_ID_HEX_SZ - 1));
if (result)
strcpy(id->name, text);
return result;
}
/******************************************************************************
* *
* Paramètres : dest = destination de la copie d'indentifiant. [OUT] *
* src = source de l'identifiant à copier. *
* *
* Description : Effectue une copie d'identifiant d'instantané. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void copy_snapshot_id(snapshot_id_t *dest, const snapshot_id_t *src)
{
memcpy(dest->name, src->name, SNAP_ID_HEX_SZ);
}
/******************************************************************************
* *
* Paramètres : id1 = premier identifiant à comparer. *
* id2 = second identifiant à comparer. *
* *
* Description : Effectue la comparaison entre deux identifiants. *
* *
* Retour : Résultat de la comparaison : -1, 0 ou 1. *
* *
* Remarques : - *
* *
******************************************************************************/
int cmp_snapshot_id(const snapshot_id_t *id1, const snapshot_id_t *id2)
{
int result; /* Bilan à retourner */
result = memcmp(id1->name, id2->name, SNAP_ID_HEX_SZ);
return result;
}
/******************************************************************************
* *
* Paramètres : id = informations à constituer. [OUT] *
* pbuf = paquet de données où venir puiser les infos. *
* *
* Description : Importe la définition d'un identifiant d'instantané. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool unpack_snapshot_id(snapshot_id_t *id, packed_buffer *pbuf)
{
bool result; /* Bilan à retourner */
result = extract_packed_buffer(pbuf, id->name, SNAP_ID_HEX_SZ, false);
return result;
}
/******************************************************************************
* *
* Paramètres : id = informations à sauvegarder. *
* pbuf = paquet de données où venir inscrire les infos. *
* *
* Description : Exporte la définition d'un identifiant d'instantané. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool pack_snapshot_id(const snapshot_id_t *id, packed_buffer *pbuf)
{
bool result; /* Bilan à retourner */
result = extend_packed_buffer(pbuf, id->name, SNAP_ID_HEX_SZ, false);
return result;
}
/* ---------------------------------------------------------------------------------- */
/* PROPRIETES DES INSTANTANES */
/* ---------------------------------------------------------------------------------- */
/******************************************************************************
* *
* 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. *
* *
* Remarques : - *
* *
******************************************************************************/
bool init_snapshot_info(snapshot_info_t *info)
{
bool result; /* Bilan à retourner */
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);
if (result)
{
info->name = NULL;
info->desc = NULL;
}
return result;
}
/******************************************************************************
* *
* Paramètres : info = description d'instantané à initialiser. [OUT] *
* id = source de données pour l'identifiant. *
* created = source de données pour la date de création. *
* name = source de données éventuelle pour le nom. *
* desc = source de données éventuelle pour la description. *
* *
* Description : Construit une description pour instantané de base de données.*
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
bool init_snapshot_info_from_text(snapshot_info_t *info, const char *id, uint64_t created, const char *name, const char *desc)
{
bool result; /* Bilan à retourner */
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);
if (result)
{
if (name == NULL)
info->name = NULL;
else
info->name = strdup(name);
if (desc == NULL)
info->desc = NULL;
else
info->desc = strdup(desc);
}
return result;
}
/******************************************************************************
* *
* Paramètres : info = description d'instantané à initialiser. [OUT] *
* *
* Description : Libère la mémoire occupée par une description d'instantané. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void exit_snapshot_info(snapshot_info_t *info)
{
if (info->name != NULL)
{
free(info->name);
info->name = NULL;
}
if (info->desc != NULL)
{
free(info->desc);
info->desc = NULL;
}
}
/******************************************************************************
* *
* Paramètres : dest = destination de la copie de description. [OUT] *
* src = source de la description à copier. *
* *
* Description : Effectue une copie de description d'instantané. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
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);
if (src->name != NULL)
dest->name = strdup(src->name);
if (src->desc != NULL)
dest->desc = strdup(src->desc);
}
/******************************************************************************
* *
* Paramètres : info = informations à constituer. [OUT] *
* pbuf = paquet de données où venir puiser les infos. *
* *
* Description : Importe la description d'un identifiant d'instantané. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
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->parent_id, pbuf);
if (result)
result = unpack_snapshot_id(&info->id, pbuf);
if (result)
result = unpack_timestamp(&info->created, pbuf);
if (result)
{
setup_empty_rle_string(&string);
result = unpack_rle_string(&string, pbuf);
if (result)
{
text = get_rle_string(&string);
info->name = (text != NULL ? strdup(text) : NULL);
exit_rle_string(&string);
}
}
if (result)
{
setup_empty_rle_string(&string);
result = unpack_rle_string(&string, pbuf);
if (result)
{
text = get_rle_string(&string);
info->desc = (text != NULL ? strdup(text) : NULL);
exit_rle_string(&string);
}
}
return result;
}
/******************************************************************************
* *
* Paramètres : info = informations à sauvegarder. *
* pbuf = paquet de données où venir inscrire les infos. *
* *
* Description : Exporte la description d'un identifiant d'instantané. *
* *
* Retour : Bilan de l'opération. *
* *
* Remarques : - *
* *
******************************************************************************/
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->parent_id, pbuf);
if (result)
result = pack_snapshot_id(&info->id, pbuf);
if (result)
result = pack_timestamp(&info->created, pbuf);
if (result)
{
init_static_rle_string(&string, info->name);
result = pack_rle_string(&string, pbuf);
exit_rle_string(&string);
}
if (result)
{
init_static_rle_string(&string, info->desc);
result = pack_rle_string(&string, pbuf);
exit_rle_string(&string);
}
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);
}