/* Chrysalide - Outil d'analyse de fichiers binaires
* logs.c - diffusion de messages d'alerte ou informatifs
*
* Copyright (C) 2017 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 "logs.h"
#include
#include
#include "../common/extstr.h"
#include "../gui/core/panels.h"
#include "../gui/panels/log.h"
/* Tranche d'allocation pour les messages complexes */
#define VARIADIC_LOG_BUFSIZE 256
/* Conserve le niveau de filtre des messages */
static LogMessageType _verbosity = LMT_COUNT;
/* Affiche un message dans le terminal courant. */
static void print_message_without_gui(LogMessageType, const char *);
/******************************************************************************
* *
* Paramètres : - *
* *
* Description : Fournit la verbosité des messages système. *
* *
* Retour : Plus faible niveau des types de message affichés. *
* *
* Remarques : - *
* *
******************************************************************************/
LogMessageType get_log_verbosity(void)
{
return _verbosity;
}
/******************************************************************************
* *
* Paramètres : level = plus faible niveau des types de message affichés. *
* *
* Description : Définit la verbosité des messages système. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void set_log_verbosity(LogMessageType level)
{
_verbosity = level;
}
/******************************************************************************
* *
* Paramètres : type = espèce du message à ajouter. *
* msg = message à faire apparaître à l'écran. *
* *
* Description : Affiche un message dans le journal des messages système. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void log_simple_message(LogMessageType type, const char *msg)
{
GPanelItem *item; /* Eventuel affichage présent */
if (type >= _verbosity)
{
item = get_panel_item_by_name(PANEL_LOG_ID);
if (item != NULL)
g_log_panel_add_message(G_LOG_PANEL(item), type, msg);
else
print_message_without_gui(type, msg);
}
}
/******************************************************************************
* *
* Paramètres : fmt = format du message à faire apparaître à l'écran. *
* args = éventuels arguments venant compléter le message. *
* *
* Description : Construit un message pour le journal des messages système. *
* *
* Retour : Message prêt à emploi à libérer après usage. *
* *
* Remarques : - *
* *
******************************************************************************/
char *build_variadic_message(const char *fmt, va_list args)
{
char *result; /* Tampon constitué à renvoyer */
size_t len; /* Taille tampon disponible */
int ret; /* Bilan d'une impression */
char *ptr; /* Nouvelle allocation */
va_list ap; /* Liste d'arguments variable */
len = VARIADIC_LOG_BUFSIZE;
result = calloc(len, sizeof(char));
while (result != NULL)
{
va_copy(ap, args);
ret = vsnprintf(result, len, fmt, ap);
va_end(ap);
if (ret >= 0 && ret < len) break;
else
{
if (ret > -1) len += 1; /* glibc 2.1 */
else len *= 2; /* glibc 2.0 */
if ((ptr = realloc(result, len)) == NULL)
{
free(result);
result = NULL;
}
else result = ptr;
}
}
return result;
}
/******************************************************************************
* *
* Paramètres : type = espèce du message à ajouter. *
* fmt = format du message à faire apparaître à l'écran. *
* ... = éventuels arguments venant compléter le message. *
* *
* Description : Affiche un message dans le journal des messages système. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
void log_variadic_message(LogMessageType type, const char *fmt, ...)
{
va_list ap; /* Liste d'arguments variable */
char *buffer; /* Tampon du msg reconstitué */
va_start(ap, fmt);
buffer = build_variadic_message(fmt, ap);
va_end(ap);
if (buffer != NULL)
{
log_simple_message(type, buffer);
free(buffer);
}
}
/******************************************************************************
* *
* Paramètres : type = espèce du message à ajouter. *
* msg = message à faire apparaître à l'écran. *
* *
* Description : Affiche un message dans le terminal courant. *
* *
* Retour : - *
* *
* Remarques : - *
* *
******************************************************************************/
static void print_message_without_gui(LogMessageType type, const char *msg)
{
char *formatted; /* Copie formatée du message */
const char *prefix; /* Introduction de la ligne */
formatted = strdup(msg);
#define FOREGROUND_LIGHT_GRAY "\e[37m"
#define FOREGROUND_RED "\e[91m"
#define BACKGROUND_RED "\e[101m"
#define BOLD "\e[1m"
#define ITALIC "\e[3m"
#define RESET "\e[0m"
switch (type)
{
case LMT_INFO:
default:
prefix = "i";
break;
case LMT_PROCESS:
prefix = FOREGROUND_LIGHT_GRAY "*" RESET;
break;
case LMT_WARNING:
prefix = FOREGROUND_RED "!" RESET;
break;
case LMT_ERROR:
case LMT_BAD_BINARY:
prefix = BACKGROUND_RED "!" RESET;
break;
}
formatted = strrpl(formatted, "", BOLD);
formatted = strrpl(formatted, "", RESET);
formatted = strrpl(formatted, "", ITALIC);
formatted = strrpl(formatted, "", RESET);
printf("[%s] %s\n", prefix, formatted);
free(formatted);
}