/* OpenIDA - Outil d'analyse de fichiers binaires * configuration.c - éléments de configuration du programme * * Copyright (C) 2009-2011 Cyrille Bagard * * This file is part of OpenIDA. * * 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 "configuration.h" #include #include #include #include #include #include #include "xdg.h" #include "common/extstr.h" #include "common/xml.h" /* Paramètres de configuration */ struct _configuration { config_param *params; /* Paramètres à consulter */ unsigned int count; /* Quantité de ces paramètres */ char *filename; /* Fichier externe */ xmlDocPtr xdoc; /* Document XML de configurat° */ xmlXPathContextPtr context; /* Contexte de recherche XPath */ }; /* S'assure qu'un chemin donné existe dans le système. */ static int ensure_path_exists(const char *); /****************************************************************************** * * * Paramètres : name = désignation de la configuration. * * params = tableau de paramètres à consulter / mettre à jour. * * count = taille du tableau en question. * * * * Description : Charge la configuration principale. * * * * Retour : Configuration prête à emploi. * * * * Remarques : - * * * ******************************************************************************/ configuration *load_configuration(const char *name, config_param *params, unsigned int count) { configuration *result; /* Structure à retourner */ char *suffix; /* Fin du nom de fichier */ unsigned int i; /* Boucle de parcours */ char *strval; /* Valeur en chaîne de carac. */ result = (configuration *)calloc(1, sizeof(configuration)); for (i = 0; i < count; i++) params[i].cur = params[i].def; result->params = params; result->count = count; suffix = strdup("openida/"); suffix = stradd(suffix, name); suffix = stradd(suffix, ".xml"); result->filename = get_xdg_config_dir(suffix); free(suffix); if (!open_xml_file(result->filename, &result->xdoc, &result->context)) create_new_xml_file(&result->xdoc, &result->context); else for (i = 0; i < count; i++) switch (params[i].type) { case CVT_BOOLEAN: strval = get_node_text_value(result->context, params[i].path); if (strval != NULL) { set_boolean_config_value(result, i, strcmp(strval, "true") == 0); free(strval); } break; case CVT_INTEGER: strval = get_node_text_value(result->context, params[i].path); if (strval != NULL) { set_integer_config_value(result, i, atoi(strval)); free(strval); } break; case CVT_STRING: strval = get_node_text_value(result->context, params[i].path); set_string_config_value(result, i, strval); if (strval != NULL) free(strval); break; default: break; } return result; } /****************************************************************************** * * * Paramètres : path = chemin d'accès à valider. * * * * Description : S'assure qu'un chemin donné existe dans le système. * * * * Retour : 0 si le chemin est actuellement présent, -1 sinon. * * * * Remarques : - * * * ******************************************************************************/ static int ensure_path_exists(const char *path) { int result; /* Bilan de l'assurance */ char *tmp; /* Chemin altérable */ tmp = strdup(path); tmp = dirname(tmp); result = access(tmp, W_OK | X_OK); if (result != 0) { result = ensure_path_exists(tmp); if (result == 0) result = mkdir(tmp, 0700); } free(tmp); return result; } /****************************************************************************** * * * Paramètres : config = configuration à libérer de la mémoire. * * * * Description : Décharge la configuration principale. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void unload_configuration(configuration *config) { int ret; /* Bilan de l'assurance */ unsigned int i; /* Boucle de parcours */ config_param *params; /* Confort d'utilisation */ char tmp[12 /* -INT_MIN */]; /* Reconstruction en chaîne */ close_xml_file(config->xdoc, config->context); ret = ensure_path_exists(config->filename); if (ret != 0) goto uc_exit; create_new_xml_file(&config->xdoc, &config->context); for (i = 0; i < config->count; i++) { params = &config->params[i]; switch (params->type) { case CVT_BOOLEAN: if (params->cur.boolean == params->def.boolean) continue; add_content_to_node(config->xdoc, config->context, params->path, params->cur.boolean ? "true" : "false"); break; case CVT_INTEGER: if (params->cur.integer == params->def.integer) continue; snprintf(tmp, 12, "%d", params->cur.integer); add_content_to_node(config->xdoc, config->context, params->path, tmp); break; case CVT_STRING: if (params->cur.string == NULL && params->def.string == NULL) continue; if (params->def.string != NULL && params->def.string != NULL && strcmp(params->cur.string, params->def.string) == 0) continue; add_content_to_node(config->xdoc, config->context, params->path, params->cur.string != NULL ? params->cur.string : ""); break; default: break; } } save_xml_file(config->xdoc, config->filename); uc_exit: free(config); } /****************************************************************************** * * * Paramètres : config = configuration à venir consulter. * * index = indice de l'élément à traiter. * * value = valeur à considérer comme valeur courante. * * * * Description : Définit une valeur booléenne dans la configuration. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ bool set_boolean_config_value(configuration *config, unsigned int index, bool value) { if (index >= config->count) return false; if (config->params[index].type != CVT_BOOLEAN) return false; config->params[index].defined = true; config->params[index].cur.boolean = value; return true; } /****************************************************************************** * * * Paramètres : config = configuration à venir consulter. * * index = indice de l'élément à traiter. * * * * Description : Fournit une valeur booléenne issue de la configuration. * * * * Retour : Valeur courante ou par défaut de la configuration. * * * * Remarques : - * * * ******************************************************************************/ bool get_boolean_config_value(configuration *config, unsigned int index) { bool result; /* Valeur à retourner */ if (index >= config->count) return false; if (config->params[index].type != CVT_BOOLEAN) return false; if (config->params[index].defined) result = config->params[index].cur.boolean; else result = config->params[index].def.boolean; return result; } /****************************************************************************** * * * Paramètres : config = configuration à venir consulter. * * index = indice de l'élément à traiter. * * value = valeur à considérer comme valeur courante. * * * * Description : Définit une valeur entière dans la configuration. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ bool set_integer_config_value(configuration *config, unsigned int index, int value) { if (index >= config->count) return false; if (config->params[index].type != CVT_INTEGER) return false; config->params[index].defined = true; config->params[index].cur.integer = value; return true; } /****************************************************************************** * * * Paramètres : config = configuration à venir consulter. * * index = indice de l'élément à traiter. * * * * Description : Fournit une valeur entière issue de la configuration. * * * * Retour : Valeur courante ou par défaut de la configuration. * * * * Remarques : - * * * ******************************************************************************/ int get_integer_config_value(configuration *config, unsigned int index) { int result; /* Valeur à retourner */ if (index >= config->count) return 0; if (config->params[index].type != CVT_INTEGER) return 0; if (config->params[index].defined) result = config->params[index].cur.integer; else result = config->params[index].def.integer; return result; } /****************************************************************************** * * * Paramètres : config = configuration à venir consulter. * * index = indice de l'élément à traiter. * * value = valeur à considérer comme valeur courante. * * * * Description : Définit une chaîne de caractères dans la configuration. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ bool set_string_config_value(configuration *config, unsigned int index, const char *value) { if (index >= config->count) return false; if (config->params[index].type != CVT_STRING) return false; config->params[index].defined = true; if (config->params[index].cur.string != NULL) free(config->params[index].cur.string); config->params[index].cur.string = (value != NULL ? strdup(value) : NULL); return true; } /****************************************************************************** * * * Paramètres : config = configuration à venir consulter. * * index = indice de l'élément à traiter. * * * * Description : Fournit une chaîne de caractères issue de la configuration. * * * * Retour : Valeur courante ou par défaut de la configuration. * * * * Remarques : - * * * ******************************************************************************/ const char *get_string_config_value(configuration *config, unsigned int index) { const char *result; /* Valeur à retourner */ if (index >= config->count) return NULL; if (config->params[index].type != CVT_STRING) return NULL; if (config->params[index].defined) result = config->params[index].cur.string; else result = config->params[index].def.string; return result; }