/* 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 . */ #include "item.h" #include #include #include "item-int.h" #include "../../common/io.h" #include "../../core/params.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); /* --------------------- MANIPULATIONS AVEC UNE BASE DE DONNEES --------------------- */ /* Constitue les champs destinés à une insertion / modification. */ static bool _g_db_item_prepare_db_statement(const GDbItem *, bool, bound_value **, size_t *); /* 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; klass->prepare_stmt = (prepare_db_statement)_g_db_item_prepare_db_statement; } /****************************************************************************** * * * 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(" 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; } /* ---------------------------------------------------------------------------------- */ /* MANIPULATIONS AVEC UNE BASE DE DONNEES */ /* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * * Paramètres : item = base d'éléments sur laquelle s'appuyer. * * create = indique si la préparation vise une création ou non. * * values = couples de champs et de valeurs à lier. [OUT] * * count = nombre de ces couples. [OUT] * * * * Description : Constitue les champs destinés à une insertion / modification.* * * * Retour : Bilan de l'opération : succès ou non. * * * * Remarques : - * * * ******************************************************************************/ static bool _g_db_item_prepare_db_statement(const GDbItem *item, bool create, bound_value **values, size_t *count) { char *author; /* Identification à diffuser */ bound_value *value; /* Valeur à éditer / définir */ if (!g_generic_config_get_value(get_main_configuration(), MPK_AUTHOR_NAME, &author)) return false; *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; value->name = "user"; value->type = SQLITE_TEXT; value->string = author; value->delete = free; if (!create) { *values = (bound_value *)realloc(*values, ++(*count) * sizeof(bound_value)); value = &(*values)[*count - 1]; value->name = "modified"; value->type = SQLITE_RAW; value->string = "CURRENT_TIMESTAMP"; value->delete = SQLITE_STATIC; } return true; } /****************************************************************************** * * * Paramètres : item = base d'éléments sur laquelle s'appuyer. * * create = indique si la préparation vise une création ou non. * * values = couples de champs et de valeurs à lier. [OUT] * * count = nombre de ces couples. [OUT] * * * * Description : Constitue les champs destinés à une insertion / modification.* * * * Retour : Bilan de l'opération : succès ou non. * * * * Remarques : - * * * ******************************************************************************/ bool g_db_item_prepare_db_statement(const GDbItem *item, bool create, bound_value **values, size_t *count) { *values = NULL; *count = 0; return G_DB_ITEM_GET_CLASS(item)->prepare_stmt(item, create, values, count); }