liblog-bdm/lib/liblog.c
2000-07-31 13:15:35 +00:00

4726 lines
164 KiB
C

/* Utilisation des API sans vérification des arguments */
#define ND_MODE 1
#define SM_MODE 1
#define DS_MODE 1
#define MSG_MODE 1
#include <liblog.h>
VER_INFO_EXPORT (liblog,"$Revision: 1.1 $", "$Name: $",__FILE__,"$Author: smas $")
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* FONCTIONS PUBLIQUES */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* FONCTIONS OPTIMISEES (LOG_MODE = 1) */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Ouverture de la librairie */
/*------------------------------------------------------------------------------*/
/* (I) Instance : numéro de l'instance à ouvrir */
/* (I) Context : contexte d'utilisation de la librairie */
/* (I) Open_Mode : mode d'ouverture de la librairie */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Library_Open_I ( int Instance, const char * Context, LOGT_Flags Open_Mode )
{
LOGT_Status rc;
int Locked;
int MSG_Debug_Mode = MSGD_DEBUG_NONE;
/* Définition du mode debug */
if (Open_Mode & LOGD_DEBUG)
{
LOG_stderr = stderr;
MSG_Debug_Mode = MSGD_DEBUG;
}
else if (Open_Mode & LOGD_DEBUG_ALL)
{
LOG_stderr = stderr;
MSG_Debug_Mode = MSGD_DEBUG_ALL;
}
/* Ouverture de la librairie LIBMSG */
rc = MSG_Library_Open (Instance, Context, MSGD_OPEN | MSG_Debug_Mode);
if (rc != MSGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the LIBMSG library");
LOG_Error_Print ();
return rc;
}
/* Accès aux ressources partagées de la librairie */
if (Open_Mode & LOGD_CREATE)
{
/* On vérifie que le processus courant n'a pas déjà ouvert la librairie */
if (LOG_Open_Counter > 0)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : the current process has already opened the LIBLOG library");
LOG_Error_Print ();
MSG_Library_Close (MSGD_CLOSE);
return LOGS_ERRAPI;
}
/* Création de la base LIBLOG */
rc = SM_Heap_Open (LOG_Name_Prefix (LOGD_BASE_HEAP_NAME), &LOG_Base_Heap, LOGD_BASE_HEAP_SEGMENT_SIZE, SMD_CREATE | SMD_WRITE, &Locked);
if (rc != SMS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the heap for the LIBLOG base");
LOG_Error_Print ();
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
rc = SM_Chunk_Alloc (LOG_Base_Heap, sizeof (LOGT_Base), (void **)&LOG_Base);
if (rc != SMS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to allocate memory for the LIBLOG base structure");
LOG_Error_Print ();
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Création du cache des modules */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_KMOD_NAME), &(LOG_Base->KMOD), NDD_DS_TREE | NDD_MN_AUTO_EQU, LOG_FILE_MANAGER, LOGD_KMOD_SEGMENT_SIZE, DSD_CREATE, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the KMOD data structure");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else strcpy (LOG_Base->KMOD->Manager, "LOG_KMOD_Manager");
/* Création du cache des formats d'événement */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_KFORMAT_NAME), &(LOG_Base->KFORMAT), NDD_DS_TREE | NDD_MN_AUTO_EQU, LOG_FILE_MANAGER, LOGD_KFORMAT_SEGMENT_SIZE, DSD_CREATE, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the KFORMAT data structure");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else strcpy (LOG_Base->KFORMAT->Manager, "LOG_KFORMAT_Manager");
/* Création de la table de routage globale par défaut (GDRT) */
rc = SM_Chunk_Alloc (LOG_Base_Heap, sizeof (LOGT_RTab) + strlen (LOGD_GDRT_NAME) + 1, (void **)(&LOG_Base->GDRT));
if (rc != SMS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to allocate memory for the GDRT rooting table");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else
{
LOG_Base->GDRT->Name = (char *)((size_t)(LOG_Base->GDRT) + sizeof (LOGT_RTab));
strcpy (LOG_Base->GDRT->Name, LOGD_GDRT_NAME);
LOG_Base->GDRT->Type = LOGD_GDRT;
}
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_GDRT_NAME), &(LOG_Base->GDRT->Root), NDD_DS_TREE | NDD_MN_AUTO_EQU, LOG_FILE_MANAGER, LOGD_GDRT_SEGMENT_SIZE, DSD_CREATE, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the GDRT data structure");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else strcpy (LOG_Base->GDRT->Root->Manager, "LOG_GDRT_Manager");
/* Création de la table de routage globale maître (GMRT) */
rc = SM_Chunk_Alloc (LOG_Base_Heap, sizeof (LOGT_RTab) + strlen (LOGD_GMRT_NAME) + 1, (void **)(&LOG_Base->GMRT));
if (rc != SMS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to allocate memory for the GMRT rooting table");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else
{
LOG_Base->GMRT->Name = (char *)((size_t)(LOG_Base->GMRT) + sizeof (LOGT_RTab));
strcpy (LOG_Base->GMRT->Name, LOGD_GMRT_NAME);
LOG_Base->GMRT->Type = LOGD_GMRT;
}
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_GMRT_NAME), &(LOG_Base->GMRT->Root), NDD_DS_TREE | NDD_MN_AUTO_EQU, LOG_FILE_MANAGER, LOGD_EMPTY_RTAB_SEGMENT_SIZE, DSD_CREATE, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the GMRT data structure");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else strcpy (LOG_Base->GMRT->Root->Manager, "LOG_RTab_Manager");
/* Création de la liste des tables de routage locales maître (LMRT) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_LMRT_LIST_NAME), &(LOG_Base->LMRT_List), NDD_DS_LIST | NDD_MN_ORDERED, LOG_FILE_MANAGER, LOGD_RTAB_LIST_SEGMENT_SIZE, DSD_CREATE, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the LMRT list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else strcpy (LOG_Base->LMRT_List->Manager, "LOG_Base_RTabList_Manager");
/* Création de la liste des tables de routage locale par défaut (LDRT) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_LDRT_LIST_NAME), &(LOG_Base->LDRT_List), NDD_DS_LIST | NDD_MN_ORDERED, LOG_FILE_MANAGER, LOGD_RTAB_LIST_SEGMENT_SIZE, DSD_CREATE, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the LDRT list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else strcpy (LOG_Base->LDRT_List->Manager, "LOG_Base_RTabList_Manager");
/* Création de la liste des tables de routage utilisateur (URT) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_URT_LIST_NAME), &(LOG_Base->URT_List), NDD_DS_LIST | NDD_MN_ORDERED, LOG_FILE_MANAGER, LOGD_RTAB_LIST_SEGMENT_SIZE, DSD_CREATE, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the URT list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else strcpy (LOG_Base->URT_List->Manager, "LOG_Base_RTabList_Manager");
/* Création de la liste des channels */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_CHANNEL_LIST_NAME), &(LOG_Base->Channel_List), NDD_DS_LIST | NDD_MN_ORDERED, LOG_FILE_MANAGER, LOGD_RTAB_LIST_SEGMENT_SIZE, DSD_CREATE, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the channel list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
else strcpy (LOG_Base->Channel_List->Manager, "LOG_Base_ChannelList_Manager");
/* Création du port de messages des événements */
rc = MSG_Port_Open (LOGD_EVENT_PORT_NAME, &Send_Port, MSGD_CREATE);
if (rc != MSGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to create the event port list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Verrouillage de la base LIBLOG en lecture */
rc = SM_Heap_Unlock (LOG_Base_Heap);
if (rc != SMS_OK && SM_Heap_Lock (LOG_Base_Heap, SMD_READ, &Locked) != SMS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to lock the LIBLOG base for reading");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
}
else
{
SMT_DSH * DSH;
NDT_Root * Root;
/* Ouverture de la base LIBLOG */
rc = SM_Heap_Open (LOG_Name_Prefix (LOGD_BASE_HEAP_NAME), &LOG_Base_Heap, 0, SMD_OPEN | SMD_READ, &Locked);
if (rc != SMS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the heap for the LIBLOG base");
LOG_Error_Print ();
return rc;
}
DSH = LOG_Base_Heap->MHH->DSR->Head->Value;
/* La structure de la base se trouve dans le premier chunk du premier segment du heap */
LOG_Base = (LOGT_Base *)((size_t)(DSH->Start) + sizeof (NDT_Node) + sizeof (SMT_Chunk));
/* Ouverture du cache des modules */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_KMOD_NAME), &Root, NULL, NULL, 0, DSD_OPEN, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the KMOD data structure");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Ouverture du cache des formats d'événement */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_KFORMAT_NAME), &Root, NULL, NULL, 0, DSD_OPEN, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the KFORMAT data structure");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Ouverture de la table de routage globale par défaut (GDRT) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_GDRT_NAME), &Root, NULL, NULL, 0, DSD_OPEN, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the GDRT data structure");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Ouverture de la table de routage globale maître (GMRT) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_GMRT_NAME), &Root, NULL, NULL, 0, DSD_OPEN, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the GMRT data structure");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Ouverture de la liste des tables de routage locales maître (LMRT) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_LMRT_LIST_NAME), &Root, NULL, NULL, 0, DSD_OPEN, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the LMRT list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Ouverture de la liste des tables de routage locale par défaut (LDRT) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_LDRT_LIST_NAME), &Root, NULL, NULL, 0, DSD_OPEN, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the LDRT list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Ouverture de la liste des tables de routage utilisateur (URT) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_URT_LIST_NAME), &Root, NULL, NULL, 0, DSD_OPEN, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the URT list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Ouverture de la liste des channels */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_CHANNEL_LIST_NAME), &Root, NULL, NULL, 0, DSD_OPEN, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the channel list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
/* Ouverture du port de messages des événements */
rc = MSG_Port_Open (LOGD_EVENT_PORT_NAME, &Send_Port, MSGD_OPEN);
if (rc != MSGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Open : unable to open the event port list");
LOG_Error_Print ();
LOG_Base = NULL;
MSG_Library_Close (MSGD_CLOSE);
return rc;
}
}
/* Mise à jour du compteur d'ouverture */
LOG_Open_Counter++;
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Fermeture de la librairie */
/*------------------------------------------------------------------------------*/
/* (I) Close_Mode : mode de fermeture de la librairie */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Library_Close_I ( LOGT_Flags Close_Mode )
{
LOGT_Status rc;
if (Close_Mode == LOGD_DESTROY)
{
/* Suppression du port de messages des événements */
MSG_Port_Close (Send_Port, MSGD_DESTROY);
/* Déverrouillage de la base LIBLOG */
rc = SM_Heap_Unlock (LOG_Base_Heap);
if (rc != SMS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to unlock the LIBLOG base");
LOG_Error_Print ();
return rc;
}
/* Destruction de la liste des channels */
rc = DS_DataStruct_Close (LOG_Base->Channel_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the channel list");
LOG_Error_Print ();
return rc;
}
/* Destruction du cache des modules */
rc = DS_DataStruct_Close (LOG_Base->KMOD, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the KMOD data structure");
LOG_Error_Print ();
return rc;
}
/* Destruction du cache des formats d'événement */
rc = DS_DataStruct_Close (LOG_Base->KFORMAT, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the KFORMAT data structure");
LOG_Error_Print ();
return rc;
}
/* Destruction de la table de routage globale par défaut (GDRT) */
rc = DS_DataStruct_Close (LOG_Base->GDRT->Root, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the GDRT data structure");
LOG_Error_Print ();
return rc;
}
/* Destruction de la table de routage globale maître (GMRT) */
rc = DS_DataStruct_Close (LOG_Base->GMRT->Root, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the GMRT data structure");
LOG_Error_Print ();
return rc;
}
/* Destruction de la liste des tables de routage locale maître (LMRT) */
rc = DS_DataStruct_Close (LOG_Base->LMRT_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the LMRT list");
LOG_Error_Print ();
return rc;
}
/* Destruction de la liste des tables de routage locale maître (LMRT) */
rc = DS_DataStruct_Close (LOG_Base->LDRT_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the LDRT list");
LOG_Error_Print ();
return rc;
}
/* Destruction de la liste des tables de routage utilisateur (URT) */
rc = DS_DataStruct_Close (LOG_Base->URT_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the URT list");
LOG_Error_Print ();
return rc;
}
/* Destruction du heap contenant la structure de base */
rc = SM_Heap_End (LOG_Name_Prefix (LOGD_BASE_HEAP_NAME));
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to destroy the heap of the base structure");
LOG_Error_Print ();
return rc;
}
/* Réinitialisation du compteur d'ouverture */
LOG_Open_Counter = 0;
}
else
{
/* On ne libère les ressources que lors de la dernière fermeture */
if (LOG_Open_Counter == 1)
{
pid_t Pid = getpid ();
NDT_Node * Node, * Next_Node;
/* Fermeture du port de messages des événements */
MSG_Port_Close (Send_Port, MSGD_CLOSE);
/* Ménage des channels du processus courant qui n'auraient pas été fermés */
DS_Node_First_Get (LOG_Base->Channel_List, &Node);
while (Node)
{
LOGT_Channel * Channel = (LOGT_Channel *)(Node->Value);
DS_Node_Next_Get (Node, &Next_Node);
if (Channel->Pid == Pid)
{
rc = LOG_Channel_Close (Channel);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close a channel which belongs to the current process");
LOG_Error_Print ();
}
else
{
/*
Petit message d'alerte à l'encontre de l'utilisateur de la librairie
pour lui préciser qu'il a oublié de fermer l'un de ses channels.
*/
sprintf (LOG_Error_Msg, "Warning LOG_Library_Close : a channel which belongs to the current process has not been closed. The garbage collector has done the work for you !");
LOG_Error_Print ();
}
}
Node = Next_Node;
}
/* Ménage des tables de routage utilisateur du processus courant qui n'auraient pas été supprimées */
DS_Node_First_Get (LOG_Base->URT_List, &Node);
while (Node)
{
LOGT_RTab * RTab = (LOGT_RTab *)(Node->Value);
DS_Node_Next_Get (Node, &Next_Node);
if (RTab->Pid == Pid)
{
rc = LOG_RTab_Free (RTab);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close a user rooting table which belongs to the current process");
LOG_Error_Print ();
}
else
{
/*
Ici, on n'affiche pas de message d'alerte car ce cas peut ne pas être du fait de l'utilisateur
(notamment si une table de routage est supprimée d'un channel sur trigger, l'utilisateur
ne sait pas forcément qu'elle l'a été et ne peut donc pas savoir qu'il faut la supprimer).
*/
}
}
Node = Next_Node;
}
/* Fermeture du cache des modules */
rc = DS_DataStruct_Close (LOG_Base->KMOD, DSD_CLOSE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the KMOD data structure");
LOG_Error_Print ();
return rc;
}
/* Fermeture du cache des formats d'événement */
rc = DS_DataStruct_Close (LOG_Base->KFORMAT, DSD_CLOSE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the KFORMAT data structure");
LOG_Error_Print ();
return rc;
}
/* Fermeture de la table de routage globale par défaut (GDRT) */
rc = DS_DataStruct_Close (LOG_Base->GDRT->Root, DSD_CLOSE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the GDRT data structure");
LOG_Error_Print ();
return rc;
}
/* Fermeture de la table de routage globale maître (GMRT) */
rc = DS_DataStruct_Close (LOG_Base->GMRT->Root, DSD_CLOSE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the GMRT data structure");
LOG_Error_Print ();
return rc;
}
/* Fermeture de la liste des tables de routage locale maître (LMRT) */
rc = DS_DataStruct_Close (LOG_Base->LMRT_List, DSD_CLOSE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the LMRT list");
LOG_Error_Print ();
return rc;
}
/* Fermeture de la liste des tables de routage locale maître (LDRT) */
rc = DS_DataStruct_Close (LOG_Base->LDRT_List, DSD_CLOSE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the LDRT list");
LOG_Error_Print ();
return rc;
}
/* Fermeture de la liste des tables de routage utilisateur (URT) */
rc = DS_DataStruct_Close (LOG_Base->URT_List, DSD_CLOSE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the URT list");
LOG_Error_Print ();
return rc;
}
/* Fermeture de la liste des channels */
rc = DS_DataStruct_Close (LOG_Base->Channel_List, DSD_CLOSE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the channel list");
LOG_Error_Print ();
return rc;
}
/* Fermeture du heap contenant la structure de base */
rc = SM_Heap_Close (LOG_Base_Heap);
if (rc != SMS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Library_Close : unable to close the heap of the base structure");
LOG_Error_Print ();
return rc;
}
LOG_Base = NULL;
/* Mise à jour du compteur d'ouverture */
LOG_Open_Counter--;
}
}
/* Fermeture de la librairie LIBDATASTR */
rc = DS_Library_Close ();
return rc;
}
/*------------------------------------------------------------------------------*/
/* Définition de la sortie standard des messages d'erreur de la librairie */
/*------------------------------------------------------------------------------*/
/* (I) Out : flux de sortie des messages d'erreur */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Library_Stderr_Set_I ( FILE * Out )
{
LOG_stderr = Out;
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Création d'un canal de communication */
/*------------------------------------------------------------------------------*/
/* (O) Channel : adresse du pointeur sur le canal créé */
/* (I) Pid : numéro du processus propriétaire du canal */
/* (I) Channel_Id : identifiant du canal au sein du processus */
/* (I) Module_Name : nom du module propriétaire du canal */
/* (I) Master_Module_Name : nom du module primaire */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Open_I ( LOGT_Channel ** Channel, int Pid, int Channel_Id, const char * Module_Name, const char * Master_Module_Name )
{
LOGT_Status rc;
NDT_Node * Node;
LOGT_RTab * LMRT, * LDRT;
char DS_Name [100];
LOGT_Module To_Find;
/************************ VERSION AVEC LA LIBRAIRIE LOGEVT **********************
Id Id_Module;
Id_Module = logevt_get_id_module (Module_Name);
if (Id_Module < 0)
{
fprintf (stderr, "Error LOG_Channel_Open : logevt_get_id_module a retourn\351 %d", (int)Id_Module);
return rc;
}
*Channel = (LOGT_Channel *) malloc (sizeof (LOGT_Channel));
(*Channel)->Id = logevt_open_channel (Id_Module, 0, 0);
if ((int)(*Channel)->Id < 0 )
{
fprintf (stderr, "Error LOG_Channel_Open : logevt_open_channel a retourn\351 %d", (int)(*Channel));
return rc;
}
*********************************************************************************/
*Channel = NULL;
/* Recherche de l'identifiant du module envoyeur */
To_Find.Name = Module_Name;
rc = DS_Node_Find (LOG_Base->KMOD, &Node, &To_Find, NULL);
if (DS_ERROR(rc)) return rc;
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to find module \"%s\"", Module_Name);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
/* Création du channel */
rc = DS_Value_Alloc (LOG_Base->Channel_List, (void **)Channel);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to create a channel");
LOG_Error_Print ();
return rc;
}
if (!Pid) (*Channel)->Pid = (int)getpid ();
else (*Channel)->Pid = Pid;
(*Channel)->Id = Channel_Id;
(*Channel)->ModuleId = ((LOGT_Module *)(Node->Value))->Id;
(*Channel)->Master_ModuleId = 0;
(*Channel)->RTab_List = NULL;
(*Channel)->SubModule_List = NULL;
(*Channel)->Trigger_List = NULL;
(*Channel)->Event_Cpt_List = NULL;
/* Recherche de l'identifiant du module maître */
if (Master_Module_Name) To_Find.Name = Master_Module_Name;
else To_Find.Name = getenv (MASTER_MODULE_ENV);
if (To_Find.Name)
{
rc = DS_Node_Find (LOG_Base->KMOD, &Node, &To_Find, NULL);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to find master module \"%s\"", Master_Module_Name);
LOG_Error_Print ();
}
(*Channel)->Master_ModuleId = ((LOGT_Module *)(Node->Value))->Id;
}
/* Création de la liste des sous-modules associée au channel (dans le même heap que la liste des channels) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_CHANNEL_LIST_NAME), &((*Channel)->SubModule_List), NDD_DS_LIST | NDD_MN_FILO, LOG_FILE_MANAGER, 0, DSD_NEW, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to create the channel submodule list");
LOG_Error_Print ();
return rc;
}
else strcpy ((*Channel)->SubModule_List->Manager, "LOG_Channel_SubModuleList_Manager");
/* Ajout d'un premier sous-module correspondant au nom du module */
rc = LOG_Channel_Enter (*Channel, Module_Name);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to add a first submodule to the channel");
LOG_Error_Print ();
return rc;
}
/* Création de la liste des triggers associée au channel (dans le même heap que la liste des channels) */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_CHANNEL_LIST_NAME), &((*Channel)->Trigger_List), NDD_DS_LIST | NDD_MN_FILO, LOG_FILE_MANAGER, 0, DSD_NEW, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to create the channel trigger list");
LOG_Error_Print ();
return rc;
}
else strcpy ((*Channel)->Trigger_List->Manager, "LOG_Channel_TriggerList_Manager");
/* Création de la liste de compteurs d'événements associée au channel (dans le même heap que la liste des channels)*/
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_CHANNEL_LIST_NAME), &((*Channel)->Event_Cpt_List), NDD_DS_TREE | NDD_MN_AUTO_EQU, LOG_FILE_MANAGER, 0, DSD_NEW, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to create the channel event counter list");
LOG_Error_Print ();
return rc;
}
else strcpy ((*Channel)->Event_Cpt_List->Manager, "LOG_Channel_Event_CptList_Manager");
/* Création de la liste des tables de routage associée au channel (dans le même heap que la liste des channels)*/
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_CHANNEL_LIST_NAME), &((*Channel)->RTab_List), NDD_DS_LIST | NDD_MN_ORDERED, LOG_FILE_MANAGER, 0, DSD_NEW, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to create the channel rooting table list");
LOG_Error_Print ();
return rc;
}
else strcpy ((*Channel)->RTab_List->Manager, "LOG_Channel_RTabList_Manager");
/* Ajout de la table de routage globale maître (GMRT) à la liste (pas la GDRT) */
rc = LOG_RTab_Add (*Channel, LOG_Base->GMRT);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to add the GDRT table to the rooting table list");
LOG_Error_Print ();
return rc;
}
/* Création de la table de routage locale maître */
sprintf (DS_Name, "%s_%d_%d_%d", LOGD_LMRT_NAME, (*Channel)->ModuleId, (int)(*Channel)->Pid, Channel_Id);
rc = DS_Value_Alloc (LOG_Base->LMRT_List, (void **)&LMRT, LOGD_LMRT, DS_Name);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to create the LMRT rooting table");
LOG_Error_Print ();
return rc;
}
/* Création de la table de routage locale par défaut */
sprintf (DS_Name, "%s_%d_%d_%d", LOGD_LDRT_NAME, (*Channel)->ModuleId, (int)(*Channel)->Pid, Channel_Id);
rc = DS_Value_Alloc (LOG_Base->LDRT_List, (void **)&LDRT, LOGD_LDRT, DS_Name);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to create the LMRT rooting table");
LOG_Error_Print ();
return rc;
}
/* Ajout des tables de routage locales à la liste des tables de routage du channel */
rc = LOG_RTab_Add (*Channel, LMRT);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to add the LMRT table to the channel rooting table list");
LOG_Error_Print ();
return rc;
}
rc = LOG_RTab_Add (*Channel, LDRT);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to add the LDRT table to the channel rooting table list");
LOG_Error_Print ();
return rc;
}
/* Ajout des tables de routage locales aux listes de tables de routage locales de la base */
rc = DS_Value_Add (LOG_Base->LMRT_List, (void *)LMRT);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to add the LMRT table to the base LMRT list");
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Add (LOG_Base->LDRT_List, (void *)LDRT);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to add the LDRT table to the base LDRT list");
LOG_Error_Print ();
return rc;
}
/* Ajout du channel à la liste des channels */
rc = DS_Value_Add (LOG_Base->Channel_List, (void *)(*Channel));
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : unable to add the channel to the base channel list");
LOG_Error_Print ();
return rc;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Entrée dans un sous-module pour un canal de communication */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le canal */
/* (I) SubModule_Name : nom du sous-module */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Enter_I ( LOGT_Channel * Channel, const char * SubModule_Name )
{
LOGT_Status rc;
char * SubModule;
rc = DS_Value_Alloc (Channel->SubModule_List, (void **)&SubModule, SubModule_Name);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Enter : unable to create a submodule in channel submodule list");
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Add (Channel->SubModule_List, (void *)SubModule);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Enter : unable to add a submodule to the channel submodule list");
LOG_Error_Print ();
return rc;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Sortie d'un sous-module pour un canal de communication */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le canal */
/* (I) SubModule_Name : nom du sous-module */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Leave_I ( LOGT_Channel * Channel, const char * SubModule_Name )
{
LOGT_Status rc;
char * Name;
rc = DS_Value_Remove (Channel->SubModule_List, (void *)SubModule_Name, (void **)&Name);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Leave : unable to remove the submodule from the channel submodule list");
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Free (Channel->SubModule_List, Name);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Leave : unable to free the submodule name");
LOG_Error_Print ();
return rc;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Fermeture d'un channel */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le channel à fermer */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Close_I ( LOGT_Channel * Channel )
{
LOGT_Status rc;
/************************ VERSION AVEC LA LIBRAIRIE LOGEVT **********************
logevt_close_channel ((Channel)Channel->Id);
********************************************************************************/
rc = DS_Value_Remove (LOG_Base->Channel_List, (void *)Channel, (void **)&Channel);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Close : unable to remove a channel from the base channel list");
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Free (LOG_Base->Channel_List, (void *)Channel);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Close : unable to free the channel");
LOG_Error_Print ();
return rc;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Création d'une table de routage utilisateur */
/*------------------------------------------------------------------------------*/
/* (O) RTab : adresse du pointeur sur la table de routage */
/* (I) Name : nom de la table de routage */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Alloc_I ( LOGT_RTab ** RTab, char * Name )
{
LOGT_Status rc;
*RTab = NULL;
/* Allocation de la nouvelle table */
rc = DS_Value_Alloc (LOG_Base->URT_List, (void **)RTab, LOGD_URT, Name);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Alloc : unable to create a rooting table");
LOG_Error_Print ();
return rc;
}
/* Ajout de la nouvelle table de routage dans la base */
rc = DS_Value_Add (LOG_Base->URT_List, (void *)(*RTab));
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Alloc : unable to add the new rooting table to the base list");
LOG_Error_Print ();
DS_Value_Free (LOG_Base->URT_List, RTab);
return rc;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une règle à une table de routage */
/*------------------------------------------------------------------------------*/
/* (I) RTab : pointeur sur la table de routage */
/* (I) Rule_Class : classe de la nouvelle règle */
/* (I) Rule : pointeur sur la nouvelle règle */
/* (I) Value : valeur de la nouvelle règle */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Setup_I ( LOGT_RTab * RTab, LOGT_RuleClass Rule_Class, LOGT_Rule * Rule, LOGT_Rooting Value )
{
RegExp_t * Compiled_RegExp = NULL;
/* Si la sélection se fait sur le nom du type d'événement, on compile l'expression régulière */
if (Rule_Class == LOGD_SELECT_TYPE)
{
Compiled_RegExp = (RegExp_t *) malloc (RegExp_Size);
if (!RegExp_Compile ((char *)Rule, Compiled_RegExp))
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Setup : unable to compile the regular expression \"%s\"", (char *)Rule);
LOG_Error_Print ();
if (Compiled_RegExp) free (Compiled_RegExp);
return LOGS_ERRAPI;
}
}
/* Sélection récursive de tous les types d'événement de la table de routage par défaut (GDRT) */
LOG_GDRT_Recursive_Select (0, LOG_Base->GDRT->Root, RTab, Rule_Class, Rule, Value, "", Compiled_RegExp);
if (Compiled_RegExp) free (Compiled_RegExp);
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une table de routage utilisateur à un channel */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le channel */
/* (I) RTab : pointeur sur la table de routage */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Add_I ( LOGT_Channel * Channel, LOGT_RTab * RTab )
{
LOGT_Status rc;
rc = ND_Value_Add (Channel->RTab_List, (void *)RTab);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Add : unable to add the rooting table to the channel");
LOG_Error_Print ();
return rc;
}
(RTab->Nb_Channel)++;
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Suppression d'une table de routage utilisateur d'un channel */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le channel */
/* (I) RTab : pointeur sur la table de routage */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Remove_I ( LOGT_Channel * Channel, LOGT_RTab * RTab )
{
LOGT_Status rc;
NDT_Node * Node;
/* On vérifie qu'il s'agit bien d'une table de routage utilisateur */
if (RTab->Type != LOGD_URT)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Remove : the rooting table is not a user rooting table");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
/*
Pour rechercher la table de routage à supprimer, on ne peut pas utiliser la fonction ND_Node_Find
car le manager compare les tables selon leur type ce qui ne nous intéresse pas dans le cas présent.
*/
ND_Node_First_Get (Channel->RTab_List, &Node);
while (Node && strcmp (RTab->Name, ((LOGT_RTab *)(Node->Value))->Name))
ND_Node_Next_Get (Node, &Node);
if (!Node)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Remove : unable to find the rooting table \"%s\" in the channel", RTab->Name);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
rc = ND_Node_Remove (Node);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Remove : unable to remove the rooting table from the channel");
LOG_Error_Print ();
return rc;
}
(RTab->Nb_Channel)--;
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une table de routage utilisateur */
/*------------------------------------------------------------------------------*/
/* (I) RTab : pointeur sur la table de routage utilisateur */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Free_I ( LOGT_RTab * RTab )
{
LOGT_Status rc;
char RTab_Name [50];
strcpy (RTab_Name, RTab->Name);
/* On ne supprime la table de routage que si elle n'est plus rattachée à aucun channel */
if (RTab->Nb_Channel > 0)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Free : unable to free rooting table \"%s\" because it is referenced by some channel", RTab_Name);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
rc = DS_Value_Remove (LOG_Base->URT_List, (void *)RTab, (void **)&RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Free : unable to remove user rooting table \"%s\" from the base list", RTab_Name);
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Free (LOG_Base->URT_List, (void *)RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Free : unable to free the user rooting table \"%s\"", RTab_Name);
LOG_Error_Print ();
return rc;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Ajout d'un trigger */
/*------------------------------------------------------------------------------*/
/* (O) Trigger : adresse du pointeur sur le trigger mis en place */
/* (I) Channel : pointeur sur le channel */
/* (I) RTab : pointeur sur la table de routage à appliquer */
/* (I) Event_Name : type d'événement déclencheur (expression régulière) */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Trigger_Add_I ( LOGT_Trigger ** Trigger, LOGT_Channel * Channel, LOGT_RTab * RTab, char * Event_Name, LOGT_Flags Mode )
{
LOGT_Status rc;
*Trigger = NULL;
rc = DS_Value_Alloc (Channel->Trigger_List, (void **)Trigger, Event_Name);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Trigger_Add : unable to create a trigger in the channel trigger list");
LOG_Error_Print ();
return rc;
}
(*Trigger)->RTab = RTab;
(*Trigger)->Channel = Channel;
(*Trigger)->Mode = Mode;
rc = DS_Value_Add (Channel->Trigger_List, (void *)(*Trigger));
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Trigger_Add : unable to add a trigger to the channel trigger list");
LOG_Error_Print ();
return rc;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Suppression d'un trigger */
/*------------------------------------------------------------------------------*/
/* (I) Trigger : pointeur sur le trigger mis en place */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Trigger_Remove_I ( LOGT_Trigger * Trigger )
{
LOGT_Status rc;
rc = DS_Value_Remove (Trigger->Channel->Trigger_List, (void *)Trigger, (void **)&Trigger);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Trigger_Remove : unable to remove a trigger from the channel trigger list");
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Free (Trigger->Channel->Trigger_List, (void *)Trigger);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Trigger_Remove : unable to free the trigger");
LOG_Error_Print ();
return rc;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Envoi d'un événement */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur un channel */
/* (O) RC : pointeur sur le code retour associé au type de l'événement */
/* (I) Support : code du support source */
/* (I) Data : données de l'événement */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Send_I ( LOGT_Channel * Channel, LOGT_RC * RC, char * Support, va_list Data )
{
/************************ VERSION AVEC LA LIBRAIRIE LOGEVT **********************
if ((*RC = (LOGT_RC)evtutils_vsend_evt ((Channel)(Channel->Id), Support, Data)) < 0)
return rc;
*********************************************************************************/
return LOG_Event_Internal_Send (DATA_ARG_LIST, Channel, RC, Support, Data, NULL);
}
/*------------------------------------------------------------------------------*/
/* Envoi d'un événement (PL/SQL ou shell) */
/*------------------------------------------------------------------------------*/
/* (I) Channel : identifiant du channel */
/* (I) Support : code du support source */
/* (I) Data : données de l'événement */
/*------------------------------------------------------------------------------*/
/* (O) Retourne le code retour associé au type d'événement */
/*------------------------------------------------------------------------------*/
LOGT_RC LOG_Event_External_Send_I ( LOGT_Channel * Channel, char * Support, char * Data )
{
/************************ VERSION AVEC LA LIBRAIRIE LOGEVT **********************
char * Commande;
char sChannel[256];
char Erreur[256];
LOGT_RC RC;
sprintf (sChannel, "%d", (int)Channel);
Commande = (char *) malloc (strlen (sChannel) + strlen (Support) + strlen (Data) + 3);
sprintf (Commande, "%d %s %s", (int)Channel, Support, Data);
RC = evtutils_send_shell_evt (Commande, Erreur);
free (Commande);
*********************************************************************************/
LOGT_RC RC = LOGD_RC_WARNING;
LOG_Event_Internal_Send (DATA_STRING, Channel, &RC, Support, NULL, Data);
return RC;
}
/*------------------------------------------------------------------------------*/
/* Retourne les informations du type par lequel un événement est résolu */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur un channel */
/* (O) Info : pointeur sur les informations à récupérer */
/* (I) Event_Name : nom de l'événement */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Info_Get_I ( LOGT_Channel * Channel, LOGT_Info ** Info, char * Event_Name )
{
LOGT_Status rc;
LOGT_GDRT_Evt * GDRT_Evt;
char * ptr;
NDT_Node * Node;
LOGT_Event_Format To_Find;
ptr = (char *) malloc (81);
ptr [80] = (char)0;
ptr += 80;
/* Recherche des informations dans la table de routage par défaut */
rc = LOG_GDRT_Event_Find (&GDRT_Evt, &ptr, Event_Name);
if (LOG_ERROR(rc)) return rc;
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Info_Get : unable to find event %s in the GDRT rooting table", Event_Name);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
(*Info)->Event_Name = ptr;
(*Info)->Event_Type = GDRT_Evt->Id;
(*Info)->RC = GDRT_Evt->RC;
(*Info)->Gravite = GDRT_Evt->Gravite;
/* Recherche du routage dans la liste des tables de routage du channel, sinon routage par défaut */
rc = LOG_Channel_Rooting_Find (Channel, GDRT_Evt->Id, &((*Info)->Rooting));
if (rc != LOGS_OK || (*Info)->Rooting == LOGD_ROOTING_DEFAULT)
(*Info)->Rooting = GDRT_Evt->Rooting;
/* Recherche du format du type d'événement */
To_Find.Event_Type = (*Info)->Event_Type;
rc = DS_Node_Find (LOG_Base->KFORMAT, &Node, &To_Find, NULL);
if (rc != DSS_OK) (*Info)->Data_List = NULL;
else (*Info)->Data_List = (NDT_Root *)(((LOGT_Event_Format *)(Node->Value))->Data_List);
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Retourne le nombre d'événements envoyés pour chaque code retour */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur un channel */
/* (O) Cpt : pointeur sur un tableau de compteurs d'événement */
/* (I) RegExpr : expression régulière sur le nom d'événement */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Cpt_Get_I ( LOGT_Channel * Channel, int * Cpt [LOGD_RC_SIZE], char * RegExpr )
{
LOGT_Status rc;
NDT_Node * Node;
LOGT_Event_Cpt * Event_Cpt;
LOGT_Info * Info;
int i;
RegExp_t * Compiled_RegExp = NULL;
/* Initialisation du tableau de compteurs */
for (i = 0; i < LOGD_RC_SIZE; i++) (*Cpt)[i] = 0;
/* Compilation de l'expression régulière */
Compiled_RegExp = (RegExp_t *) malloc (RegExp_Size);
if (!RegExp_Compile (RegExpr, Compiled_RegExp))
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Cpt_Get : unable to compile the regular expression \"%s\"", RegExpr);
LOG_Error_Print ();
if (Compiled_RegExp) free (Compiled_RegExp);
return LOGS_ERRAPI;
}
/* Traversée de la structure de compteurs */
ND_Node_First_Get (Channel->Event_Cpt_List, &Node);
while (Node)
{
Event_Cpt = (LOGT_Event_Cpt *)(Node->Value);
/* L'événement matche-t'il avec l'expression régulière ? */
if (RegExp_Match (Event_Cpt->Name, Compiled_RegExp))
{
/* Recherche des informations concernant l'événement */
rc = LOG_Event_Info_Get (Channel, &Info, Event_Cpt->Name);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Cpt_Get : unable to retrieve information about event \"%s\"", Event_Cpt->Name);
LOG_Error_Print ();
if (Compiled_RegExp) free (Compiled_RegExp);
return rc;
}
/* Incrémentation du compteur */
(*Cpt)[(int)Info->RC] += Event_Cpt->Total;
}
ND_Node_Next_Get (Node, &Node);
}
if (Compiled_RegExp) free (Compiled_RegExp);
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* FONCTIONS SECURISEES (LOG_MODE = 0) */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Ouverture de la librairie */
/*------------------------------------------------------------------------------*/
/* (I) Instance : numéro de l'instance à ouvrir */
/* (I) Context : contexte d'utilisation de la librairie */
/* (I) Open_Mode : mode d'ouverture de la librairie */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Library_Open_C ( int Instance, const char * Context, LOGT_Flags Open_Mode )
{
return LOG_Library_Open_I (Instance, Context, Open_Mode);
}
/*------------------------------------------------------------------------------*/
/* Fermeture de la librairie */
/*------------------------------------------------------------------------------*/
/* (I) Close_Mode : mode de fermeture de la librairie */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Library_Close_C ( LOGT_Flags Close_Mode )
{
return LOG_Library_Close_I (Close_Mode);
}
/*------------------------------------------------------------------------------*/
/* Définition de la sortie standard des messages d'erreur de la librairie */
/*------------------------------------------------------------------------------*/
/* (I) Out : flux de sortie des messages d'erreur */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Library_Stderr_Set_C ( FILE * Out )
{
return LOG_Library_Stderr_Set_I (Out);
}
/*------------------------------------------------------------------------------*/
/* Création d'un canal de communication */
/*------------------------------------------------------------------------------*/
/* (O) Channel : adresse du pointeur sur le canal créé */
/* (I) Pid : numéro du processus propriétaire du canal */
/* (I) Channel_Id : identifiant du canal au sein du processus */
/* (I) Module_Name : nom du module propriétaire du canal */
/* (I) Master_Module_Name : nom du module primaire */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Open_C (LOGT_Channel ** Channel, int Pid, int Channel_Id, const char * Module_Name, const char * Master_Module_Name )
{
*Channel = NULL;
if (!LOG_Base)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : the library is not open");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : the channel address is undefined");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Module_Name)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Open : the module name is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Channel_Open_I (Channel, Pid, Channel_Id, Module_Name, Master_Module_Name);
}
/*------------------------------------------------------------------------------*/
/* Entrée dans un sous-module pour un canal de communication */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le canal */
/* (I) SubModule_Name : nom du sous-module */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Enter_C (LOGT_Channel * Channel, const char * SubModule_Name )
{
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Enter : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!SubModule_Name)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Enter : the submodule name is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Channel_Enter_I (Channel, SubModule_Name);
}
/*------------------------------------------------------------------------------*/
/* Sortie d'un sous-module pour un canal de communication */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le canal */
/* (I) SubModule_Name : nom du sous-module */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Leave_C (LOGT_Channel * Channel, const char * SubModule_Name )
{
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Leave : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!SubModule_Name)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Leave : the submodule name is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Channel_Leave_I (Channel, SubModule_Name);
}
/*------------------------------------------------------------------------------*/
/* Fermeture d'un channel */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le channel à fermer */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Close_C (LOGT_Channel * Channel)
{
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Close : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Channel_Close_I (Channel);
}
/*------------------------------------------------------------------------------*/
/* Création d'une table de routage utilisateur */
/*------------------------------------------------------------------------------*/
/* (O) RTab : adresse du pointeur sur la table de routage */
/* (I) Name : nom de la table de routage */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Alloc_C ( LOGT_RTab ** RTab, char * Name )
{
if (!LOG_Base)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Alloc : the library is not open");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Name)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Alloc : the rooting table name is undefined");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_RTab_Alloc_I (RTab, Name);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une règle à une table de routage */
/*------------------------------------------------------------------------------*/
/* (I) RTab : pointeur sur la table de routage */
/* (I) Rule_Class : classe de la nouvelle règle */
/* (I) Rule : pointeur sur la nouvelle règle */
/* (I) Value : valeur de la nouvelle règle */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Setup_C (LOGT_RTab * RTab, LOGT_RuleClass Rule_Class, LOGT_Rule * Rule, LOGT_Rooting Value )
{
if (!RTab)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Setup : the rooting table is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
/* On vérifie qu'il s'agit bien d'une table de routage utilisateur */
if (RTab->Type != LOGD_URT)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Setup : the rooting table is not a user rooting table");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_RTab_Setup_I (RTab, Rule_Class, Rule, Value);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'une table de routage utilisateur à un channel */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le channel */
/* (I) RTab : pointeur sur la table de routage */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Add_C (LOGT_Channel * Channel, LOGT_RTab * RTab )
{
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Add : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!RTab)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Add : the rooting table is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_RTab_Add_I (Channel, RTab);
}
/*------------------------------------------------------------------------------*/
/* Suppression d'une table de routage utilisateur d'un channel */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur le channel */
/* (I) RTab : pointeur sur la table de routage */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Remove_C (LOGT_Channel * Channel, LOGT_RTab * RTab )
{
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Remove : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!RTab)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Remove : the rooting table is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_RTab_Remove_I (Channel, RTab );
}
/*------------------------------------------------------------------------------*/
/* Destruction d'une table de routage utilisateur */
/*------------------------------------------------------------------------------*/
/* (I) RTab : pointeur sur la table de routage utilisateur */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_RTab_Free_C ( LOGT_RTab * RTab )
{
if (!RTab)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Free : the rooting table is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
/* On vérifie qu'il s'agit bien d'une table de routage utilisateur */
if (RTab->Type != LOGD_URT)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Free : rooting table \"%s\" is not a user rooting table", RTab->Name);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_RTab_Free_I (RTab);
}
/*------------------------------------------------------------------------------*/
/* Ajout d'un trigger */
/*------------------------------------------------------------------------------*/
/* (O) Trigger : adresse du pointeur sur le trigger mis en place */
/* (I) Channel : pointeur sur le channel */
/* (I) RTab : pointeur sur la table de routage à appliquer */
/* (I) Event_Name : type d'événement déclencheur (expression régulière) */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Trigger_Add_C ( LOGT_Trigger ** Trigger, LOGT_Channel * Channel, LOGT_RTab * RTab, char * Event_Name, LOGT_Flags Mode )
{
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Trigger_Add : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!RTab)
{
sprintf (LOG_Error_Msg, "Error LOG_Trigger_Add : the rooting table is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Event_Name)
{
sprintf (LOG_Error_Msg, "Error LOG_Trigger_Add : the event type is undefined");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Trigger_Add_I (Trigger, Channel, RTab, Event_Name, Mode);
}
/*------------------------------------------------------------------------------*/
/* Suppression d'un trigger */
/*------------------------------------------------------------------------------*/
/* (I) Trigger : pointeur sur le trigger mis en place */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Trigger_Remove_C ( LOGT_Trigger * Trigger )
{
if (!Trigger)
{
sprintf (LOG_Error_Msg, "Error LOG_Trigger_Remove : the trigger is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Trigger_Remove_I (Trigger);
}
/*------------------------------------------------------------------------------*/
/* Envoi d'un événement */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur un channel */
/* (O) RC : pointeur sur le code retour associé au type de l'événement */
/* (I) Support : code du support source */
/* (I) Data : données de l'événement */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Send_C (LOGT_Channel * Channel, LOGT_RC * RC, char * Support, va_list Data )
{
if (!LOG_Base)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Send : the library is not open");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Send : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Event_Send_I (Channel, RC, Support, Data);
}
/*------------------------------------------------------------------------------*/
/* Envoi d'un événement (PL/SQL ou shell) */
/*------------------------------------------------------------------------------*/
/* (I) Channel : identifiant du channel */
/* (I) Support : code du support source */
/* (I) Data : données de l'événement */
/*------------------------------------------------------------------------------*/
/* (O) Retourne le code retour associé au type d'événement */
/*------------------------------------------------------------------------------*/
LOGT_RC LOG_Event_External_Send_C ( LOGT_Channel * Channel, char * Support, char * Data )
{
if (!LOG_Base)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_External_Send : the library is not open");
LOG_Error_Print ();
return LOGD_RC_WARNING;
}
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_External_Send : the channel is null");
LOG_Error_Print ();
return LOGD_RC_WARNING;
}
return LOG_Event_External_Send_I (Channel, Support, Data);
}
/*------------------------------------------------------------------------------*/
/* Retourne les informations du type par lequel un événement est résolu */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur un channel */
/* (O) Info : pointeur sur les informations à récupérer */
/* (I) Event_Name : nom de l'événement */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Info_Get_C ( LOGT_Channel * Channel, LOGT_Info ** Info, char * Event_Name )
{
if (!LOG_Base)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Info_Get : the library is not open");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Info_Get : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Info)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Info_Get : the info address is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Event_Name)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Info_Get : the event name is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Event_Info_Get_I (Channel, Info, Event_Name);
}
/*------------------------------------------------------------------------------*/
/* Retourne le nombre d'événements envoyés pour chaque code retour */
/*------------------------------------------------------------------------------*/
/* (I) Channel : pointeur sur un channel */
/* (O) Cpt : pointeur sur un tableau de compteurs d'événement */
/* (I) RegExpr : expression régulière sur le nom d'événement */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Cpt_Get_C ( LOGT_Channel * Channel, int * Cpt [LOGD_RC_SIZE], char * RegExpr )
{
if (!Channel)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Cpt_Get : the channel is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!Cpt)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Cpt_Get : the counter array address is undefined");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!RegExpr)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Cpt_Get : the regular expression is null");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOG_Event_Cpt_Get_I (Channel, Cpt, RegExpr);
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* FONCTIONS PRIVEES */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Envoi d'un événement (partie commune aux fonctions 'LOG_Event_Send' */
/* et 'LOG_Event_External_Send' : */
/*------------------------------------------------------------------------------*/
/* - récupération des données de l'événement */
/* - résolution du nom d'événement */
/* - mise à jour du compteur d'événement */
/* - traitement de l'événement en fonction du routage */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Internal_Send (int Mode, LOGT_Channel * Channel, LOGT_RC * RC, char * Support, va_list Data_Arg, char * Data_Str)
{
LOGT_Status rc;
NDT_Node * Node;
LOGT_Info * Info;
char Event_Name [81];
char * Event_Data, * Event_Data_Ptr;
size_t Data_Size;
LOGT_Event_Cpt To_Find;
unsigned int Length;
RegExp_t * Compiled_RegExp = NULL;
size_t Msg_Size;
LOGT_Event_Msg_Data * Event_Msg_Data;
*RC = LOGD_RC_WARNING;
/* Récupération des données de l'événement */
rc = LOG_Event_Data_Get (Mode, Support, &Event_Data, &Data_Size, &Data_Arg, Data_Str);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to retrieve event data from the %s", Mode == DATA_ARG_LIST ? "argument list" : "string");
LOG_Error_Print ();
if (Event_Data) free (Event_Data);
return rc;
}
/* Récupération du nom de l'événement */
Length = (unsigned int)Event_Data [0];
strncpy (Event_Name, Event_Data + 1, Length);
Event_Name [Length] = (char)0;
/* Résolution du nom d'événement */
Info = (LOGT_Info *) malloc (sizeof (LOGT_Info));
if (!Info)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to allocate memory for event information");
LOG_Error_Print ();
if (Event_Data) free (Event_Data);
return LOGS_ERRMEM;
}
rc = LOG_Event_Info_Get (Channel, &Info, Event_Name);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to resolve event \"%s\"", Event_Name);
LOG_Error_Print ();
if (Event_Data) free (Event_Data);
return rc;
}
/* Ajout au compteur d'événements du channel */
To_Find.Name = Event_Name;
rc = ND_Node_Find (Channel->Event_Cpt_List, &Node, &To_Find, NULL);
if (rc != NDS_OK)
{
int Locked;
LOGT_Event_Cpt * Event_Cpt;
/*
Optimisation : on verrouille nous-même la data structure et
on fait appel aux API sans verrouillage systématique (DS_*_I).
*/
rc = DS_DataStruct_Lock (Channel->Event_Cpt_List, DSD_WRITE, &Locked);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to lock the channel counter list");
LOG_Error_Print ();
if (Event_Data) free (Event_Data);
return rc;
}
rc = DS_Value_Alloc_I (Channel->Event_Cpt_List, (void **)&Event_Cpt, Event_Name);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to create a counter for event \"%s\"", Event_Name);
LOG_Error_Print ();
if (Locked == TRUE) DS_DataStruct_Unlock (Channel->Event_Cpt_List);
if (Event_Data) free (Event_Data);
return rc;
}
rc = DS_Value_Add_I (Channel->Event_Cpt_List, (void *)Event_Cpt);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to add the event counter \"%s\" to the data structure", Event_Name);
LOG_Error_Print ();
if (Locked == TRUE) DS_DataStruct_Unlock (Channel->Event_Cpt_List);
if (Event_Data) free (Event_Data);
return rc;
}
if (Locked == TRUE) DS_DataStruct_Unlock (Channel->Event_Cpt_List);
}
else ((LOGT_Event_Cpt *)(Node->Value))->Total++;
/* Traitement de l'événement en fonction du routage */
if (Info->Rooting & LOGD_ROOTING_STDERR)
{
/* Affichage de l'événement sur la sortie standard du process */
fprintf (stderr, "[EVENT] %s\n", Event_Name);
}
if (Info->Rooting & LOGD_ROOTING_DATABASE)
{
MSGT_Message * Event_Msg;
/* Allocation du message : entête du format de l'événement + données de l'événement (Data_Size) */
Msg_Size = sizeof (LOGT_Event_Msg_Header) + 2 * sizeof (unsigned int) + Data_Size;
rc = MSG_Message_Alloc (&Event_Msg, Msg_Size);
if (rc != MSGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to allocate %d byte(s) for a new message", Msg_Size);
LOG_Error_Print ();
if (Event_Data) free (Event_Data);
return rc;
}
rc = MSG_Message_Config (Event_Msg, MSGD_CONFIG_TYPE, LOGD_EVENT_MSG_TYPE);
if (rc != MSGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to configure the message as an event message");
LOG_Error_Print ();
if (Event_Data) free (Event_Data);
MSG_Message_Free (Event_Msg);
return rc;
}
/* On remplit la zone de données du message selon le format d'un message d'événement */
Event_Msg_Data = (LOGT_Event_Msg_Data *)(Event_Msg->Data);
strcpy (Event_Msg_Data->Header.Version, EVENT_FORMAT_VERSION);
Event_Msg_Data->Header.Sending_Pid = Channel->Pid;
Event_Msg_Data->Header.ModuleId = Channel->ModuleId;
Event_Msg_Data->Header.Master_ModuleId = Channel->Master_ModuleId;
Event_Msg_Data->Event_Type = Info->Event_Type;
Event_Msg_Data->Data_Size = Data_Size;
Event_Data_Ptr = &(Event_Msg_Data->Event_Data);
strncpy (Event_Data_Ptr, Event_Data, Data_Size);
/* Envoi du message pour insertion de l'événement en base */
rc = MSG_Message_Send (0, Send_Port, Event_Msg);
if (rc != MSGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to send the event through message port \"%s\"", Send_Port->Name);
LOG_Error_Print ();
if (Event_Data) free (Event_Data);
MSG_Message_Free (Event_Msg);
return rc;
}
}
if (Event_Data) free (Event_Data);
Compiled_RegExp = (RegExp_t *) malloc (RegExp_Size);
/* Déclenchement des triggers */
ND_Node_First_Get (Channel->Trigger_List, &Node);
while (Node)
{
LOGT_Trigger * Trigger = (LOGT_Trigger *)(Node->Value);
NDT_Node * Next_Node;
ND_Node_Next_Get (Node, &Next_Node);
/* Compilation de l'expression régulière du trigger */
if (!RegExp_Compile (Trigger->Event_Name, Compiled_RegExp))
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to compile the trigger regular expression \"%s\"", Trigger->Event_Name);
LOG_Error_Print ();
if (Compiled_RegExp) free (Compiled_RegExp);
return LOGS_ERRAPI;
}
/* L'événement déclencheur matche-t'il avec l'événement courant ? */
if (RegExp_Match (Event_Name, Compiled_RegExp))
{
/* Déclenchement du trigger */
if (LOGD_ADD_MSK (Trigger->Mode))
{
rc = LOG_RTab_Add (Channel, Trigger->RTab);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to add a rooting table on event \"%s\" when specified by a trigger", Event_Name);
LOG_Error_Print ();
if (Compiled_RegExp) free (Compiled_RegExp);
return rc;
}
}
else if (LOGD_REMOVE_MSK (Trigger->Mode))
{
rc = LOG_RTab_Remove (Channel, Trigger->RTab);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to remove rooting table \"%s\" on event \"%s\" when specified by a trigger", Trigger->RTab->Name, Event_Name);
LOG_Error_Print ();
/* On continue quand même */
}
}
/* Retrait du trigger s'il n'est actif qu'une seule fois */
if (LOGD_ONE_SHOT_MSK (Trigger->Mode))
{
rc = LOG_Trigger_Remove (Trigger);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Internal_Send : unable to remove a \"one-shot\" trigger on event %s", Event_Name);
LOG_Error_Print ();
if (Compiled_RegExp) free (Compiled_RegExp);
return rc;
}
}
}
Node = Next_Node;
}
if (Compiled_RegExp) free (Compiled_RegExp);
/* Récupération du code retour */
*RC = Info->RC;
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* BASE */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
NDT_Status LOG_Base_ChannelList_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Channel ** Channel = va_arg (Args, LOGT_Channel **);
*Channel = NULL;
rc = DS_Alloc (Root, sizeof (LOGT_Channel), (void **)Channel);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_ChannelList_Manager : unable to allocate a new channel");
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_Channel * Channel = (LOGT_Channel *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Channel (address %d) :\n\t- pid = %ld\n\t- ID = %d\n\t- module = %d\n\t- %ld sous-module(s)\n\t- %ld table(s)\n\t- %ld trigger(s)\n\t- %ld compteur(s) d'événement", (int)Channel, Channel->Pid, Channel->Id, Channel->ModuleId, Channel->SubModule_List->Node_Number, Channel->RTab_List->Node_Number, Channel->Trigger_List->Node_Number, Channel->Event_Cpt_List->Node_Number);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Channel * Channel = (LOGT_Channel *) va_arg (Args, void *);
rc = DS_DataStruct_Close (Channel->RTab_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_ChannelList_Manager : unable to destroy the channel rooting table list");
LOG_Error_Print ();
return rc;
}
rc = DS_DataStruct_Close (Channel->SubModule_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_ChannelList_Manager : unable to destroy the channel submodule list");
LOG_Error_Print ();
return rc;
}
rc = DS_DataStruct_Close (Channel->Trigger_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_ChannelList_Manager : unable to destroy the channel trigger list");
LOG_Error_Print ();
return rc;
}
rc = DS_DataStruct_Close (Channel->Event_Cpt_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_ChannelList_Manager : unable to destroy the channel event counter list");
LOG_Error_Print ();
return rc;
}
rc = DS_Free (Root, Channel);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_ChannelList_Manager : unable to free the channel");
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de channels = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_Channel * Channel1, *Channel2;
long comp;
Channel1 = (LOGT_Channel *) va_arg (Args, void *);
Channel2 = (LOGT_Channel *) va_arg (Args, void *);
va_end (Args);
comp = (int)Channel1 - (int)Channel2;
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Manager d'une liste de tables de routage attachées à la base */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_Base_RTabList_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_RTab ** RTab = va_arg (Args, LOGT_RTab **);
va_list Args_Value = va_arg (Args, va_list);
LOGT_RTType Type = va_arg (Args_Value, LOGT_RTType);
char * Name = va_arg (Args_Value, char *);
char * Heap_Name;
*RTab = NULL;
/* Allocation de la table de routage dans le même heap que celui de la liste des tables de routage */
rc = DS_Alloc (Root, sizeof (LOGT_RTab) + strlen (Name) + 1, (void **)RTab);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_RTabList_Manager : unable to allocate a new table %s", Name);
LOG_Error_Print ();
return rc;
}
(*RTab)->Type = Type;
(*RTab)->Nb_Channel = 0;
(*RTab)->Root = NULL;
(*RTab)->Pid = getpid ();
(*RTab)->Name = (char *)((size_t)(*RTab) + sizeof (LOGT_RTab));
strcpy ((*RTab)->Name, Name);
/* Création de la data structure sous-jacente toujours dans le même heap */
switch ((int)Type)
{
case LOGD_LMRT:
Heap_Name = LOG_Name_Prefix (LOGD_LMRT_LIST_NAME);
break;
case LOGD_LDRT:
Heap_Name = LOG_Name_Prefix (LOGD_LDRT_LIST_NAME);
break;
case LOGD_URT:
default :
Heap_Name = LOG_Name_Prefix (LOGD_URT_LIST_NAME);
break;
}
rc = DS_DataStruct_Open (Heap_Name, &((*RTab)->Root), NDD_DS_TREE | NDD_MN_AUTO_EQU, LOG_FILE_MANAGER, 0, DSD_NEW, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_RTabList_Manager : unable to create the data structure for the rooting table \"%s\"", Name);
LOG_Error_Print ();
return rc;
}
else strcpy ((*RTab)->Root->Manager, "LOG_RTab_Manager");
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_RTab * RTab = (LOGT_RTab *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Table de routage \"%s\" :\n\t- creator = %d\n\t- type = %s\n\t- nombre d'événements = %ld\n\t- attachée à %d channel(s)", RTab->Name, (int)RTab->Pid, LOG_RTType_Label_Get (RTab->Type), RTab->Root->Node_Number, RTab->Nb_Channel);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_RTab * RTab = (LOGT_RTab *) va_arg (Args, void *);
char RTab_Name [50];
strcpy (RTab_Name, RTab->Name);
rc = DS_DataStruct_Close (RTab->Root, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_RTabList_Manager : unable to destroy the data structure of rooting table \"%s\"", RTab_Name);
LOG_Error_Print ();
return rc;
}
rc = DS_Free (Root, RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Base_RTabList_Manager : unable to desallocate the rooting table \"%s\"", RTab_Name);
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de tables de routage = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_RTab * RTab1, * RTab2;
long comp;
RTab1 = (LOGT_RTab *) va_arg (Args, void *);
RTab2 = (LOGT_RTab *) va_arg (Args, void *);
va_end (Args);
comp = strcmp (RTab1->Name, RTab2->Name);
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* CHANNEL */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Manager de la liste de tables de routage d'un channel */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_Channel_RTabList_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_RTab * RTab = (LOGT_RTab *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Table de routage \"%s\" :\n\t- type = %s\n\t- nombre d'événements = %ld\n\t- attachée à %d channel(s)", RTab->Name, LOG_RTType_Label_Get (RTab->Type), RTab->Root->Node_Number, RTab->Nb_Channel);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_RTab * RTab = (LOGT_RTab *) va_arg (Args, void *);
/* La table de routage globale maître n'est même pas fermée car peut être utilisée par d'autres channels */
/* Les tables de routage locales sont supprimées */
if (RTab->Type == LOGD_LMRT)
{
rc = DS_Value_Remove (LOG_Base->LMRT_List, (void *)RTab, (void **)&RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_RTabList_Manager : unable to remove the LMRT rooting table from the base list");
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Free (LOG_Base->LMRT_List, (void *)RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_RTabList_Manager : unable to free the LMRT rooting table");
LOG_Error_Print ();
return rc;
}
}
if (RTab->Type == LOGD_LDRT)
{
rc = DS_Value_Remove (LOG_Base->LDRT_List, (void *)RTab, (void **)&RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_RTabList_Manager : unable to remove a LDRT rooting table from the base list");
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Free (LOG_Base->LDRT_List, (void *)RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_RTabList_Manager : unable to free the LDRT rooting table");
LOG_Error_Print ();
return rc;
}
}
/* Les tables de routage utilisateur ne sont supprimées que si elles ne sont plus rattachées à aucun channel */
if (RTab->Type == LOGD_URT && RTab->Nb_Channel == 1)
{
rc = DS_Value_Remove (LOG_Base->URT_List, (void *)RTab, (void **)&RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_RTabList_Manager : unable to remove a user rooting table (%p) from the base list", (void *)RTab);
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Free (LOG_Base->URT_List, (void *)RTab);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_RTabList_Manager : unable to free the user rooting table (%p)", (void *)RTab);
LOG_Error_Print ();
return rc;
}
}
else (RTab->Nb_Channel)--;
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de tables de routage = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_RTab * RTab1, * RTab2;
long comp;
RTab1 = (LOGT_RTab *) va_arg (Args, void *);
RTab2 = (LOGT_RTab *) va_arg (Args, void *);
va_end (Args);
/*
Pour le tri des tables de routage, la comparaison se fait sur le type :
- GMRT en 1er
- LMRT en 2ème
- URT ensuite
- LDRT en dernier
Les types ont été choisis pour qu'on puisse se contenter de trier sur leur valeur.
*/
comp = RTab1->Type - RTab2->Type;
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
if (comp == 0) return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Manager de la structure de compteurs d'événements d'un channel */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_Channel_Event_CptList_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Event_Cpt ** Event_Cpt = va_arg (Args, LOGT_Event_Cpt **);
va_list Args_Value = va_arg (Args, va_list);
char * Name = va_arg (Args_Value, char *);
*Event_Cpt = NULL;
rc = DS_Alloc (Root, sizeof (LOGT_Event_Cpt) + strlen (Name) + 1, (void **)Event_Cpt);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Event_CptList_Manager : unable to allocate a new event counter");
LOG_Error_Print ();
return rc;
}
(*Event_Cpt)->Total = 1;
(*Event_Cpt)->Name = (char *)((size_t)(*Event_Cpt) + sizeof (LOGT_Event_Cpt));
strcpy ((*Event_Cpt)->Name, Name);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_Event_Cpt * EventCpt = (LOGT_Event_Cpt *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Compteur :\n\t- événement = %s\n\t- valeur = %d", EventCpt->Name, EventCpt->Total);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Event_Cpt * EventCpt = (LOGT_Event_Cpt *) va_arg (Args, void *);
rc = DS_Free (Root, EventCpt);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_Event_CptList_Manager : unable to free an event counter");
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de compteurs = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_Event_Cpt *Event_Cpt1, *Event_Cpt2;
long comp;
Event_Cpt1 = (LOGT_Event_Cpt *) va_arg (Args, void *);
Event_Cpt2 = (LOGT_Event_Cpt *) va_arg (Args, void *);
va_end (Args);
comp = strcmp (Event_Cpt1->Name, Event_Cpt2->Name);
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Manager de la liste de sous-modules d'un channel */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_Channel_TriggerList_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Trigger ** Trigger = va_arg (Args, LOGT_Trigger **);
va_list Args_Value = va_arg (Args, va_list);
char * Event_Name = va_arg (Args_Value, char *);
*Trigger = NULL;
rc = DS_Alloc (Root, sizeof (LOGT_Trigger) + strlen (Event_Name) + 1, (void **)Trigger);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_TriggerList_Manager : unable to allocate a new trigger");
LOG_Error_Print ();
return rc;
}
(*Trigger)->Event_Name = (char *)((size_t)(*Trigger) + sizeof (LOGT_Trigger));
strcpy ((*Trigger)->Event_Name, Event_Name);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_Trigger * Trigger = (LOGT_Trigger *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Trigger :\n\t- événement déclencheur = \"%s\"\n\t- mode = %s (%s)\n\t- table de routage concernée = \"%s\"", Trigger->Event_Name, LOGD_ADD_MSK (Trigger->Mode) == LOGD_ADD ? "ajout" : "suppression", LOGD_ONE_SHOT_MSK (Trigger->Mode) == LOGD_ONE_SHOT ? "une seule fois" : "permanent", Trigger->RTab->Name);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Trigger * Trigger = (LOGT_Trigger *) va_arg (Args, void *);
rc = DS_Free (Root, Trigger);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_TriggerList_Manager : unable to free submodule");
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de sous-module = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
char * Trigger1, * Trigger2;
long comp;
Trigger1 = (char *) va_arg (Args, void *);
Trigger2 = (char *) va_arg (Args, void *);
va_end (Args);
comp = (long)Trigger1 - (long)Trigger2;
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Manager de la liste de sous-modules d'un channel */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_Channel_SubModuleList_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
char ** SubModule = va_arg (Args, char **);
va_list Args_Value = va_arg (Args, va_list);
char * Name = va_arg (Args_Value, char *);
*SubModule = NULL;
rc = DS_Alloc (Root, strlen (Name) + 1, (void **) SubModule);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_SubModuleList_Manager : unable to allocate a new submodule");
LOG_Error_Print ();
return rc;
}
strcpy (*SubModule, Name);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
char *SubModule = (char *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Sous-module \"%s\"", SubModule);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
char *SubModule = (char *) va_arg (Args, void *);
rc = DS_Free (Root, SubModule);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Channel_SubModuleList_Manager : unable to free submodule");
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de sous-module = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
char * SubModule1, * SubModule2;
long comp;
SubModule1 = (char *) va_arg (Args, void *);
SubModule2 = (char *) va_arg (Args, void *);
va_end (Args);
comp = strcmp (SubModule1, SubModule2);
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Recherche du routage d'un événement pour un channel donné */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Channel_Rooting_Find (LOGT_Channel * Channel, int EvtId, LOGT_Rooting * Rooting)
{
LOGT_Status rc;
LOGT_RTab * RTab;
NDT_Node * RTab_Node;
NDT_Node * Event_Node = NULL;
LOGT_RTab_Evt To_Find;
if (!Channel) return LOGS_ERRAPI;
To_Find.Id = EvtId;
/* Recherche dans toutes les tables de routage du channel */
ND_Node_First_Get (Channel->RTab_List, &RTab_Node);
while (RTab_Node)
{
RTab = (LOGT_RTab *)(RTab_Node->Value);
rc = DS_Node_Find (RTab->Root, &Event_Node, &To_Find, NULL);
if (DS_ERROR(rc)) return rc;
if (rc == DSS_OK)
{
*Rooting = ((LOGT_RTab_Evt *)(Event_Node->Value))->Rooting;
/* Si le routage n'est pas celui de la table précédente, alors on a trouvé ! */
if (*Rooting != LOGD_ROOTING_PREVIOUS) return LOGS_OK;
}
ND_Node_Next_Get (RTab_Node, &RTab_Node);
}
return LOGS_KO;
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* CACHE DES MODULES */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Manager du cache de modules */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_KMOD_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Module ** Module = va_arg (Args, LOGT_Module **);
va_list Args_Value = va_arg (Args, va_list);
char * Name = va_arg (Args_Value, char *);
int Id = va_arg (Args_Value, int);
*Module = NULL;
rc = DS_Alloc (Root, sizeof (LOGT_Module) + strlen (Name) + 1, (void **)Module);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_KMOD_Manager : unable to allocate a new module for the module cache data structure");
LOG_Error_Print ();
return rc;
}
(*Module)->Id = Id;
(*Module)->Name = (char *)((size_t)(*Module) + sizeof (LOGT_Module));
strcpy ((*Module)->Name, Name);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_Module * Module = (LOGT_Module *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Module \"%s\" (ID = %d)", Module->Name, Module->Id);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Module * Module = (LOGT_Module *) va_arg (Args, void *);
DS_Free (Root, Module);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de modules = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_Module * Module1, * Module2;
long comp;
Module1 = (LOGT_Module *) va_arg (Args, void *);
Module2 = (LOGT_Module *) va_arg (Args, void *);
va_end (Args);
comp = strcmp (Module1->Name, Module2->Name);
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* CACHE DES FORMATS D'EVENEMENT */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Manager du cache des formats d'événement */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_KFORMAT_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Event_Format ** Event_Format = va_arg (Args, LOGT_Event_Format **);
va_list Args_Value = va_arg (Args, va_list);
unsigned int Event_Type = va_arg (Args_Value, unsigned int);
*Event_Format = NULL;
/* Allocation de la structure LOGT_Event_Format */
rc = DS_Alloc (Root, sizeof (LOGT_Event_Format), (void **)Event_Format);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_KFORMAT_Manager : unable to allocate a new event format for the KFORMAT data structure");
LOG_Error_Print ();
return rc;
}
(*Event_Format)->Event_Type = Event_Type;
/* Création de la liste des données associée au format */
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_KFORMAT_NAME), &((*Event_Format)->Data_List), NDD_DS_LIST | NDD_MN_FIFO, LOG_FILE_MANAGER, 0, DSD_NEW, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_KFORMAT_Manager : unable to create the event format data list");
LOG_Error_Print ();
DS_Free (Root, *Event_Format);
return rc;
}
else strcpy ((*Event_Format)->Data_List->Manager, "LOG_KFORMAT_DataList_Manager");
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_Event_Format * Event_Format = (LOGT_Event_Format *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Format du type d'événement %d : %ld donnée(s) associée(s)", Event_Format->Event_Type, Event_Format->Data_List->Node_Number);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_Event_Format * Event_Format = (LOGT_Event_Format *) va_arg (Args, void *);
rc = DS_DataStruct_Close (Event_Format->Data_List, DSD_DESTROY);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_KFORMAT_Manager : unable to destroy the event format data list");
LOG_Error_Print ();
return rc;
}
DS_Free (Root, Event_Format);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de formats d'événement = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_Event_Format * Event_Format1, *Event_Format2;
long comp;
Event_Format1 = (LOGT_Event_Format *) va_arg (Args, void *);
Event_Format2 = (LOGT_Event_Format *) va_arg (Args, void *);
va_end (Args);
comp = Event_Format1->Event_Type - Event_Format2->Event_Type;
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Manager d'une liste de données associée à un format d'événement */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_KFORMAT_DataList_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
char ** Event_Data = va_arg (Args, char **);
va_list Args_Value = va_arg (Args, va_list);
char * Data = va_arg (Args_Value, char *);
*Event_Data = NULL;
rc = DS_Alloc (Root, strlen (Data) + 1, (void **)Event_Data);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_KFORMAT_DataList_Manager : unable to allocate a new data for the event format data list");
LOG_Error_Print ();
return rc;
}
strcpy (*Event_Data, Data);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
char * Event_Data = (char *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Données de format \"%s\"", Event_Data);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
char * Event_Data = (char *) va_arg (Args, void *);
DS_Free (Root, Event_Data);
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de données associées aux format = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
char * Event_Data1, *Event_Data2;
long comp;
Event_Data1 = (char *) va_arg (Args, void *);
Event_Data2 = (char *) va_arg (Args, void *);
va_end (Args);
comp = strcmp (Event_Data1, Event_Data2);
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* TABLE GDRT */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Manager de la table GDRT */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_GDRT_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
char * Event_Name = va_arg (Args, char *);
int EvtId = va_arg (Args, int);
LOGT_Gravite Gravite = va_arg (Args, LOGT_Gravite);
LOGT_RC RC = va_arg (Args, LOGT_RC);
LOGT_Rooting Rooting = va_arg (Args, LOGT_Rooting);
int * Nb_Tree = va_arg (Args, int *);
return LOG_GDRT_Event_Create (Event_Name, EvtId, Gravite, RC, Rooting, Nb_Tree);
}
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_GDRT_Evt * GDRT_Evt = (LOGT_GDRT_Evt *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Evénement \"%s\" : ", GDRT_Evt->Name);
if (GDRT_Evt->Terminal == TRUE)
fprintf (Out, "terminal (ID=%d Gravité='%c' RC=%s Routage=%s) / %ld sous-valeur(s)", GDRT_Evt->Id, (char)(GDRT_Evt->Gravite), LOG_RC_Label_Get (GDRT_Evt->RC), LOG_Rooting_Label_Get (GDRT_Evt->Rooting), GDRT_Evt->Next_Dim ? ((NDT_Root *)(GDRT_Evt->Next_Dim))->Node_Number : 0);
else
fprintf (Out, "non terminal / %ld sous-valeur(s)", GDRT_Evt->Next_Dim ? ((NDT_Root *)(GDRT_Evt->Next_Dim))->Node_Number : 0);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_GDRT_Evt *GDRT_Evt = (LOGT_GDRT_Evt *) va_arg (Args, void *);
if (GDRT_Evt->Next_Dim)
{
rc = DS_DataStruct_Traverse (GDRT_Evt->Next_Dim, NDD_CMD_DELETE_VALUE, NULL);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_GDRT_Manager : unable to destroy the next dimension of value %s from the GDRT data structure", GDRT_Evt->Name);
LOG_Error_Print ();
return rc;
}
}
rc = DS_Free (Root, GDRT_Evt);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_GDRT_Manager : unable to free a value from the GDRT data structure");
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre d'événements = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_GDRT_Evt *GDRT_Evt1, *GDRT_Evt2;
long comp;
GDRT_Evt1 = (LOGT_GDRT_Evt *) va_arg (Args, void *);
GDRT_Evt2 = (LOGT_GDRT_Evt *) va_arg (Args, void *);
va_end (Args);
comp = strcmp (GDRT_Evt1->Name, GDRT_Evt2->Name);
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Manager des dimensions des événements de la table GDRT */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_GDRT_Dim_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_GDRT_Evt *GDRT_Evt = (LOGT_GDRT_Evt *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Dimension \"%s\" :\n\t- ID = %d\n\t- Gravité = '%c'\n\t- Code retour = %s\n\t- Routage = %s\n\t- Dimension suivante = %ld valeur(s)", GDRT_Evt->Name, GDRT_Evt->Id, (char)(GDRT_Evt->Gravite), LOG_RC_Label_Get (GDRT_Evt->RC), LOG_Rooting_Label_Get (GDRT_Evt->Rooting), GDRT_Evt->Next_Dim ? ((NDT_Root *)(GDRT_Evt->Next_Dim))->Node_Number : 0);
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_GDRT_Evt *GDRT_Evt = (LOGT_GDRT_Evt *) va_arg (Args, void *);
if (GDRT_Evt->Next_Dim)
{
rc = DS_DataStruct_Traverse (GDRT_Evt->Next_Dim, NDD_CMD_DELETE_VALUE, NULL);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_GDRT_Dim_Manager : unable to destroy the next dimension of value %s from the GDRT data structure", GDRT_Evt->Name);
LOG_Error_Print ();
return rc;
}
}
rc = DS_Free (Root, GDRT_Evt);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_GDRT_Dim_Manager : unable to free a value from the GDRT data structure");
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre de contextes = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_GDRT_Evt *GDRT_Evt1, *GDRT_Evt2;
long comp;
GDRT_Evt1 = (LOGT_GDRT_Evt *) va_arg (Args, void *);
GDRT_Evt2 = (LOGT_GDRT_Evt *) va_arg (Args, void *);
va_end (Args);
comp = strcmp (GDRT_Evt1->Name, GDRT_Evt2->Name);
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/* Création d'un événement dans la table GDRT */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_GDRT_Event_Create (const char * Event_Name, int Id, LOGT_Gravite Gravite, LOGT_RC RC, LOGT_Rooting Rooting, int *Nb_Tree)
{
LOGT_Status rc;
int i;
char * ptr;
NDT_Node * Node;
char * Tab_Dim [EVENT_NB_DIM];
LOGT_GDRT_Evt * Evt;
NDT_Root * Root;
LOGT_GDRT_Evt To_Find;
ptr = strdup (Event_Name);
for (i = 0; i < EVENT_NB_DIM; i++) Tab_Dim [i] = NULL;
/* Récupération des dimensions du type d'événement */
i = 0;
while (i < EVENT_NB_DIM)
{
Tab_Dim [i] = ptr;
if (i < EVENT_NB_DIM - 1)
{
char sep = (i == 0 ? '@' : ':');
if ((ptr = strchr (Tab_Dim [i], sep)))
{
*ptr = (char)0;
ptr++;
}
else i = EVENT_NB_DIM;
}
i++;
}
/* Création des différentes dimensions (1 dimension = 1 arbre) */
Root = LOG_Base->GDRT->Root;
for (i = 0; i < EVENT_NB_DIM; i++)
{
if (!Tab_Dim [i]) return LOGS_OK;
/* Ajout de la dimension si elle n'existe pas */
To_Find.Name = Tab_Dim [i];
rc = ND_Node_Find (Root, &Node, &To_Find, NULL);
if (rc != NDS_OK)
{
/* Allocation de la nouvelle valeur */
rc = DS_Alloc (Root, sizeof (LOGT_GDRT_Evt) + strlen (Tab_Dim [i]) + 1, (void **)(&Evt));
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_GDRT_Event_Create : unable to allocate memory for a new value of the dimension %d", i);
LOG_Error_Print ();
return rc;
}
Evt->Id = 0;
Evt->Gravite = 0;
Evt->RC = 0;
Evt->Rooting = 0;
Evt->Next_Dim = NULL;
Evt->Terminal = FALSE;
Evt->Name = (char *)((size_t)Evt + sizeof (LOGT_GDRT_Evt));
strcpy (Evt->Name, Tab_Dim [i]);
/* Ajout de la valeur */
rc = ND_Value_Add (Root, Evt);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_GDRT_Event_Create : unable to add a new value in the data structureof dimension %d", i);
LOG_Error_Print ();
return rc;
}
}
else Evt = (LOGT_GDRT_Evt *)(Node->Value);
/* Est-on à la fin du nom du type d'événement */
if (i == EVENT_NB_DIM - 1 || !Tab_Dim [i + 1])
{
Evt->Terminal = TRUE;
Evt->Id = Id;
Evt->Gravite = Gravite;
Evt->RC = RC;
Evt->Rooting = Rooting;
return LOGS_OK;
}
/* Création de la dimension suivante si elle n'existe pas déjà */
if (!Evt->Next_Dim)
{
rc = DS_DataStruct_Open (LOG_Name_Prefix (LOGD_GDRT_NAME), &(Evt->Next_Dim), NDD_DS_TREE | NDD_MN_AUTO_EQU, LOG_FILE_MANAGER, 0, DSD_NEW, TRUE);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_GDRT_Event_Create : unable to create a data structure for the dimension %d", i + 1);
LOG_Error_Print ();
return rc;
}
strcpy (Evt->Next_Dim->Manager, "LOG_GDRT_Dim_Manager");
(*Nb_Tree)++;
}
Root = Evt->Next_Dim;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Recherche dans la table de routage par défaut (GDRT) */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_GDRT_Event_Find (LOGT_GDRT_Evt ** Evt, char ** Complete_Name, char * Event_Name)
{
LOGT_Status rc;
char * ptr;
int i;
char * Tab_Dim [EVENT_NB_DIM];
*Evt = NULL;
**Complete_Name = (char)0;
ptr = strdup (Event_Name);
for (i = 0; i < EVENT_NB_DIM; i++) Tab_Dim [i] = NULL;
/* Récupération des dimensions du type d'événement */
i = 0;
while (i < EVENT_NB_DIM)
{
Tab_Dim [i] = ptr;
if (i < EVENT_NB_DIM - 1)
{
char sep = (i == 0 ? '@' : ':');
if ((ptr = strchr (Tab_Dim [i], sep)))
{
*ptr = (char)0;
ptr++;
}
else i = EVENT_NB_DIM;
}
i++;
}
/* Recherche de l'événement */
rc = LOG_GDRT_Recursive_Find (Tab_Dim, LOG_Base->GDRT->Root, 0, Evt, Complete_Name);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_GDRT_Event_Find : unable to find event \"%s\"", Event_Name);
LOG_Error_Print ();
free (Tab_Dim [0]);
return rc;
}
free (*Tab_Dim);
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Fonction de recherche récursive dans les différentes dimensions */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_GDRT_Recursive_Find (char ** Tab_Dim, NDT_Root * Root, int Dim, LOGT_GDRT_Evt ** Evt, char ** Complete_Name)
{
LOGT_Status rc;
int Found, End;
NDT_Node * Node;
char Default_Name [10];
char * Dim_Name;
char * ptr;
LOGT_GDRT_Evt To_Find;
if (!Root || !Tab_Dim [Dim]) return LOGS_ERRAPI;
/* Définition de la valeur par défaut à rechercher */
if (Dim == 0) strcpy (Default_Name, "DEFAULT");
else strcpy (Default_Name, "");
Dim_Name = strdup (Tab_Dim [Dim]);
/* Recherche du type d'événement le plus proche */
Found = End = FALSE;
while (Found == FALSE && End == FALSE)
{
To_Find.Name = Dim_Name;
if (ND_Node_Find (Root, &Node, &To_Find, NULL) == NDS_OK)
{
/* Résolution de la dimension suivante */
if (LOG_GDRT_Recursive_Find (Tab_Dim, ((LOGT_GDRT_Evt *)(Node->Value))->Next_Dim, Dim + 1, Evt, Complete_Name) == LOGS_OK)
{
Found = TRUE;
End = TRUE;
}
else
{
/* Le noeud trouvé est-il terminal ? */
if (((LOGT_GDRT_Evt *)(Node->Value))->Terminal == TRUE)
{
*Evt = (LOGT_GDRT_Evt *)(Node->Value);
Found = TRUE;
End = TRUE;
}
}
}
if (End == FALSE)
{
ptr = strchr (Dim_Name, '.');
if (ptr) *ptr = (char)0;
else
{
/*
Dernière chance de résoudre la dimension :
- "DEFAULT" pour le nom du type d'événement
- "" pour le contexte
*/
if (!strcmp (Dim_Name, Default_Name)) End = TRUE;
else strcpy (Dim_Name, Default_Name);
}
}
}
if (Found == TRUE)
{
if (strlen (Dim_Name))
{
*Complete_Name -= strlen (Dim_Name);
memcpy (*Complete_Name, Dim_Name, strlen (Dim_Name));
}
if (Dim > 0)
{
*Complete_Name -= 1;
**Complete_Name = (Dim == 1 ? '@' : ':');
}
rc = LOGS_OK;
}
else rc = LOGS_KO;
free (Dim_Name);
return rc;
}
/*------------------------------------------------------------------------------*/
/* Sélection récursive des types d'événements dans la GDRT */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_GDRT_Recursive_Select (int Dim, NDT_Root * Root, LOGT_RTab * RTab, LOGT_RuleClass Rule_Class, LOGT_Rule * Rule, LOGT_Rooting Value, const char * Name, char * Compiled_RegExp)
{
LOGT_Status rc;
NDT_Node * Node;
if (!Root) return LOGS_ERRAPI;
ND_Node_First_Get (Root, &Node);
while (Node)
{
LOGT_GDRT_Evt * GDRT_Evt = (LOGT_GDRT_Evt *)(Node->Value);
int Selected = FALSE;
char Event_Name [81];
LOGT_Rooting Rooting = (Value == LOGD_ROOTING_DEFAULT ? GDRT_Evt->Rooting : Value);
if (Dim == 0) strcpy (Event_Name, GDRT_Evt->Name);
else sprintf (Event_Name, "%s%c%s", Name, Dim == 1 ? '@' : ':', GDRT_Evt->Name);
if (GDRT_Evt->Terminal == TRUE)
{
/* On vérifie si le type d'événement correspond au critère de sélection */
switch (Rule_Class)
{
case LOGD_SELECT_ALL:
Selected = TRUE;
break;
case LOGD_SELECT_GRV:
if (GDRT_Evt->Gravite == *(LOGT_Gravite *)Rule) Selected = TRUE;
break;
case LOGD_SELECT_RC:
if (GDRT_Evt->RC == *(LOGT_RC *)Rule) Selected = TRUE;
break;
case LOGD_SELECT_TYPE:
/* L'événement matche-t'il avec l'expression régulière ? */
if (RegExp_Match (Event_Name, Compiled_RegExp) && GDRT_Evt->Terminal == TRUE) Selected = TRUE;
break;
}
}
if (Selected == TRUE)
{
NDT_Node * Tmp_Node;
LOGT_RTab_Evt Tmp_Evt;
Tmp_Evt.Id = GDRT_Evt->Id;
/* Si le type d'événement n'existe pas déjà, on l'ajoute à la table de routage utilisateur */
rc = DS_Node_Find (RTab->Root, &Tmp_Node, (void *)&Tmp_Evt, NULL);
if (rc != DSS_OK)
{
LOGT_RTab_Evt * RTab_Evt;
rc = DS_Value_Alloc (RTab->Root, (void **)&RTab_Evt, GDRT_Evt->Id, Rooting);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Setup : unable to create event type %d for the user rooting table", GDRT_Evt->Id);
LOG_Error_Print ();
return rc;
}
rc = DS_Value_Add (RTab->Root, (void *)RTab_Evt);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Setup : unable to add event type %d to the user rooting table", GDRT_Evt->Id);
LOG_Error_Print ();
return rc;
}
}
}
LOG_GDRT_Recursive_Select (Dim + 1, GDRT_Evt->Next_Dim, RTab, Rule_Class, Rule, Value, Event_Name, Compiled_RegExp);
ND_Node_Next_Get (Node, &Node);
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* AUTRES TABLES DE ROUTAGE (GMRT, LMRT, LDRT, URT) */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Manager des tables de routage autres que GDRT */
/*------------------------------------------------------------------------------*/
NDT_Status LOG_RTab_Manager (va_list Args)
{
LOGT_Status rc;
NDT_Command Command = va_arg (Args, NDT_Command);
if (Command == NDD_CMD_MAKE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_RTab_Evt ** RTab_Evt = (LOGT_RTab_Evt **) va_arg (Args, void **);
va_list Args_Value = va_arg (Args, va_list);
int Id = (int) va_arg (Args_Value, int);
LOGT_Rooting Rooting = (LOGT_Rooting) va_arg (Args_Value, LOGT_Rooting);
DST_RootDesc * RootDesc = (DST_RootDesc *)(Root->User);
rc = DS_Alloc (Root, sizeof (LOGT_RTab_Evt), (void **)RTab_Evt);
if (rc != NDS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Manager : unable to allocate a new event for rooting table \"%s\"", RootDesc ? RootDesc->Heap_Name : "User");
LOG_Error_Print ();
return rc;
}
(*RTab_Evt)->Id = Id;
(*RTab_Evt)->Rooting = Rooting;
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_VALUE)
{
LOGT_RTab_Evt * RTab_Evt = (LOGT_RTab_Evt *) va_arg (Args, void *);
FILE * Out = va_arg (Args, FILE *);
fprintf (Out, "Evénement :\n\t- ID = %d\n\t- Routage = %s", RTab_Evt->Id, LOG_Rooting_Label_Get (RTab_Evt->Rooting));
return NDS_OK;
}
if (Command == NDD_CMD_DELETE_VALUE)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
LOGT_RTab_Evt * RTab_Evt = (LOGT_RTab_Evt *) va_arg (Args, void *);
DST_RootDesc * RootDesc = (DST_RootDesc *)(Root->User);
rc = DS_Free (Root, (void *)RTab_Evt);
if (rc != DSS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_RTab_Manager : unable to free an event of rooting table \"%s\"", RootDesc ? RootDesc->Heap_Name : "User");
LOG_Error_Print ();
return rc;
}
return NDS_OK;
}
if (Command == NDD_CMD_PRINT_INFO)
{
NDT_Root * Root = va_arg (Args, NDT_Root *);
FILE * Out = va_arg (Args, FILE *);
const char * Root_Type;
DST_RootDesc * RootDesc;
switch ((int)(Root->Type & NDD_DS_MSK))
{
case NDD_DS_LIST :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_ORDERED : Root_Type = "liste triée"; break;
case NDD_MN_FILO : Root_Type = "liste FILO"; break;
case NDD_MN_FIFO : Root_Type = "liste FIFO"; break;
default : Root_Type = "inconnu"; break;
}
break;
case NDD_DS_TREE :
switch ((int)(Root->Type & NDD_MN_MSK))
{
case NDD_MN_AUTO_EQU : Root_Type = "arbre auto-équilibré"; break;
default : Root_Type = "arbre non auto-équilibré"; break;
}
break;
default : Root_Type = "inconnu"; break;
}
RootDesc = (DST_RootDesc *)(Root->User);
fprintf (Out, "\n%s\n\t- Structure = %s\n\t- Manager = %s\n\t- Nombre d'événements = %ld\n", RootDesc->Heap_Name, Root_Type, RootDesc->Manager_FileName, Root->Node_Number);
if (Root->Type & NDD_DS_TREE)
fprintf (Out, "\t- Profondeur maxi = %ld\n\t- Profondeur mini = %ld\n\t- Différence maximale autorisée = %ld\n\t- Nombre d'équilibrages = %ld\n", Root->Max_Depth, Root->Min_Depth, Root->Max_Dif, Root->Nb_Equ);
return NDS_OK;
}
if (Command == NDD_CMD_COMP_VALUE)
{
LOGT_RTab_Evt * RTab_Evt1, * RTab_Evt2;
long comp;
RTab_Evt1 = (LOGT_RTab_Evt *) va_arg (Args, void *);
RTab_Evt2 = (LOGT_RTab_Evt *) va_arg (Args, void *);
va_end (Args);
comp = RTab_Evt1->Id - RTab_Evt2->Id;
if (comp < 0) return NDS_LOWER;
if (comp > 0) return NDS_GREATER;
return NDS_EQUAL;
}
return NDS_OK;
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* FONCTIONS RELATIVES AUX EVENEMENTS */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Récupération des données de l'événement à partir d'une liste d'arguments */
/* ou d'une chaîne de caractères. */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Data_Get (int Mode, char * Support, char ** Event_Data, size_t * Data_Size, va_list * Arg_Data, char * Str_Data)
{
LOGT_Status rc;
char Event_Name [81];
int Tag;
char Value [256];
char Macro [256];
int End = FALSE;
int Context = FALSE;
char * even [3] = {NULL, NULL, NULL};
char * module [3] = {NULL, NULL, NULL};
char * mode [3] = {NULL, NULL, NULL};
char * geo [3] = {NULL, NULL, NULL};
char * ptr;
char * Ptr_Data = Str_Data;
unsigned int i;
size_t New_Size;
*Event_Data = NULL;
*Data_Size = 0;
/*
Récupération des composants du nom de l'événement :
EVEN1[.EVEN2[.EVEN3]]@[MODULE1[.MODULE2[.MODULE3]]]:[MODE1[.MODE2[.MODE3]]]:[GEO1[.GEO2[.GEO3]]]
NB : le nom de l'événement est délimité par le tag END_NAME.
*/
while (End == FALSE)
{
rc = LOG_Event_Data_Tag_Get (Mode, Arg_Data, &Ptr_Data, &Tag, Value);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Get : unable to retrieve event name from the data %s", Mode == DATA_ARG_LIST ? "argument list" : "string");
LOG_Error_Print ();
return rc;
}
switch (Tag)
{
case EVEN1:
even [0] = strdup (Value);
break;
case EVEN2:
even [1] = strdup (Value);
break;
case EVEN3:
even [2] = strdup (Value);
break;
case MODULE1:
module [0] = strdup (Value);
Context = TRUE;
break;
case MODULE2:
module [1] = strdup (Value);
Context = TRUE;
break;
case MODULE3:
module [2] = strdup (Value);
Context = TRUE;
break;
case MODE1:
mode [0] = strdup (Value);
Context = TRUE;
break;
case MODE2:
mode [1] = strdup (Value);
Context = TRUE;
break;
case MODE3:
mode [2] = strdup (Value);
Context = TRUE;
break;
case GEO1:
geo [0] = strdup (Value);
Context = TRUE;
break;
case GEO2:
geo [1] = strdup (Value);
Context = TRUE;
break;
case GEO3:
geo [2] = strdup (Value);
Context = TRUE;
break;
case END_NAME:
End = TRUE;
break;
default :
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Get : unexpected tag %d before END_NAME", Tag);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
}
/* Reconstitution du nom de l'événement */
if (!even [0])
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Get : tag EVEN1 must be defined before END_NAME");
LOG_Error_Print ();
return LOGS_ERRAPI;
}
strcpy (Event_Name, even [0]);
for (i = 1; i < 3; i++)
{
if (even [i])
{
strcat (Event_Name, ".");
strcat (Event_Name, even [i]);
free (even [i]);
}
else break;
}
if (Context == TRUE) strcat (Event_Name, "@");
else return LOGS_OK;
for (i = 0; i < 3; i++)
{
if (module [i])
{
strcat (Event_Name, i > 0 ? "." : "");
strcat (Event_Name, module [i]);
free (module [i]);
}
else break;
}
strcat (Event_Name, ":");
for (i = 0; i < 3; i++)
{
if (mode [i])
{
strcat (Event_Name, i > 0 ? "." : "");
strcat (Event_Name, mode [i]);
free (mode [i]);
}
else break;
}
strcat (Event_Name, ":");
for (i = 0; i < 3; i++)
{
if (geo [i])
{
strcat (Event_Name, i > 0 ? "." : "");
strcat (Event_Name, geo [i]);
free (geo [i]);
}
else break;
}
/* On recopie le nom de l'événement au début de la chaîne de caractères contenant les données */
*Data_Size = 0;
*Event_Data = NULL;
i = strlen (Event_Name);
New_Size = *Data_Size + i + 1;
*Event_Data = (char *)realloc (*Event_Data, New_Size);
ptr = *Event_Data + *Data_Size;
*Data_Size = New_Size;
*ptr = (char)i;
ptr ++;
memcpy (ptr, (void *)Event_Name, i);
/* On recopie le code support comme étant la première macro-donnée */
i = strlen (Support);
New_Size = *Data_Size + i + 1;
*Event_Data = (char *)realloc (*Event_Data, New_Size);
ptr = *Event_Data + *Data_Size;
*Data_Size = New_Size;
*ptr = (char)i;
ptr ++;
memcpy (ptr, (void *)Support, i);
/* Récupération des macro-données associées à l'événement */
End = FALSE;
while (End == FALSE)
{
unsigned int j;
rc = LOG_Event_Data_Macro_Get (Mode, Arg_Data, &Ptr_Data, Macro, Value);
if (rc != LOGS_OK)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Get : unable to retrieve event macro data from the data %s", Mode == DATA_ARG_LIST ? "argument list" : "string");
LOG_Error_Print ();
return rc;
}
if (!strcmp (Macro, END_DATA)) break;
i = strlen (Macro);
j = strlen (Value);
New_Size = *Data_Size + i + j + 2;
*Event_Data = (char *)realloc (*Event_Data, New_Size);
ptr = *Event_Data + *Data_Size;
*Data_Size = New_Size;
*ptr = (char)i;
ptr ++;
memcpy (ptr, (void *)Macro, i);
ptr += i;
*ptr = (char)j;
ptr ++;
memcpy (ptr, (void *)Value, j);
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Récupération d'un composant (tag et valeur) d'un nom d'événement */
/* à partir d'une liste d'arguments ou d'une chaîne de caractères. */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Data_Tag_Get (int Mode, va_list * Arg_Data, char ** ptr, int * Tag, char * Value)
{
if (Mode == DATA_ARG_LIST)
{
*Tag = va_arg (*Arg_Data, int);
if (*Tag != END_NAME) strcpy (Value, va_arg (*Arg_Data, char *));
return LOGS_OK;
}
if (Mode == DATA_STRING)
{
char sTag [256];
if (LOG_NextString_Get (ptr, sTag) != TRUE)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Tag_Get : missing tag after value %s", Value);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!strcmp (sTag, "EVEN1")) *Tag = EVEN1;
else if (!strcmp (sTag, "EVEN2")) *Tag = EVEN2;
else if (!strcmp (sTag, "EVEN3")) *Tag = EVEN3;
else if (!strcmp (sTag, "MODULE1")) *Tag = MODULE1;
else if (!strcmp (sTag, "MODULE2")) *Tag = MODULE2;
else if (!strcmp (sTag, "MODULE3")) *Tag = MODULE3;
else if (!strcmp (sTag, "MODE1")) *Tag = MODE1;
else if (!strcmp (sTag, "MODE2")) *Tag = MODE2;
else if (!strcmp (sTag, "MODE3")) *Tag = MODE3;
else if (!strcmp (sTag, "GEO1")) *Tag = GEO1;
else if (!strcmp (sTag, "GEO2")) *Tag = GEO2;
else if (!strcmp (sTag, "GEO3")) *Tag = GEO3;
else if (!strcmp (sTag, "END_NAME")) *Tag = END_NAME;
else *Tag = 0;
if (*Tag != END_NAME)
{
char str [256];
if (LOG_NextString_Get (ptr, str) != TRUE)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Tag_Get : missing value after tag %s", sTag);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
strcpy (Value, str);
}
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Récupération d'une macro donnée (tag et valeur) associé à une événement */
/* à partir d'une liste d'arguments ou d'une chaîne de caractères. */
/*------------------------------------------------------------------------------*/
/* Pour une liste d'arguments, une macro-donnée est donnée par un triplet : */
/* - nom (char *) */
/* - type (int) */
/* - valeur (char *) */
/* */
/* Pour une chaîne de caractères, une macro-donnée est donnée par un couple : */
/* - nom (char *) */
/* - valeur (char *) : les espaces sont remplacés par des '~' */
/* */
/* NB : les macro-données sont délimitées par le tag END_DATA. */
/*------------------------------------------------------------------------------*/
LOGT_Status LOG_Event_Data_Macro_Get (int Mode, va_list * Arg_Data, char ** ptr, char * Macro, char * Value)
{
if (Mode == DATA_ARG_LIST)
{
int Type;
strcpy (Macro, va_arg (*Arg_Data, char *));
if (!strcmp (Macro, END_DATA)) return LOGS_OK;
Type = va_arg (*Arg_Data, int);
switch (Type)
{
case STRING:
strcpy (Value, va_arg (*Arg_Data, char *));
break;
case CHAR:
sprintf (Value, "%c", *va_arg (*Arg_Data, char *));
break;
case SHORT:
sprintf (Value, "%d", *va_arg (*Arg_Data, short *));
break;
case INT:
sprintf (Value, "%d", *va_arg (*Arg_Data, int *));
break;
case LONG:
sprintf (Value, "%ld", *va_arg (*Arg_Data, long *));
break;
case FLOAT:
sprintf (Value, "%f", *va_arg (*Arg_Data, float *));
break;
case DOUBLE:
sprintf (Value, "%f", *va_arg (*Arg_Data, double *));
break;
default :
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Macro_Get : unexpected type %d after macro \"%s\"", Type, Macro);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
return LOGS_OK;
}
if (Mode == DATA_STRING)
{
char * tmp;
if (LOG_NextString_Get (ptr, Macro) != TRUE)
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Macro_Get : missing macro after value %s", Value);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
if (!strcmp (Macro, END_DATA)) return LOGS_OK;
if (LOG_NextString_Get (ptr, Value) != TRUE || !strcmp (Value, END_DATA))
{
sprintf (LOG_Error_Msg, "Error LOG_Event_Data_Macro_Get : missing value after macro %s", Macro);
LOG_Error_Print ();
return LOGS_ERRAPI;
}
/* On remplace les '~' par des espaces */
while ((tmp = strchr (Value, '~'))) *tmp = ' ';
return LOGS_OK;
}
return LOGS_OK;
}
/*------------------------------------------------------------------------------*/
/* Récupération de la prochaine valeur dans une chaîne de caractères (valeurs */
/* séparées par des espaces) */
/*------------------------------------------------------------------------------*/
int LOG_NextString_Get (char ** ptr, char * result)
{
int i = 0;
/* On recherche le premier caractère différent non blanc (espace, tab, newline) */
while (isspace ((int)(**ptr)) && **ptr != (char)0) (*ptr)++;
if (**ptr == (char)0) return FALSE;
/* On recopie le pointeur dans la chaîne résultat jusqu'au premier caractère blanc */
while (!isspace ((int)(**ptr)) && **ptr != (char)0)
{
result [i] = **ptr;
i++;
(*ptr)++;
}
result [i] = (char)0;
return TRUE;
}
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* FONCTIONS DIVERSES */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/* Récupération du libellé d'un code retour */
/*------------------------------------------------------------------------------*/
char * LOG_RC_Label_Get (LOGT_RC RC)
{
static char Label [20];
switch ((int)RC)
{
case LOGD_RC_OK:
strcpy (Label, "OK");
break;
case LOGD_RC_ANOERR:
strcpy (Label, "ANOERR");
break;
case LOGD_RC_REJDON:
strcpy (Label, "REJDON");
break;
case LOGD_RC_REJENR:
strcpy (Label, "REJENR");
break;
case LOGD_RC_WARNING:
strcpy (Label, "WARNING");
break;
case LOGD_RC_RECYCLE:
strcpy (Label, "RECYCLE");
break;
case LOGD_RC_EXIT:
strcpy (Label, "EXIT");
break;
case LOGD_RC_ABEND:
strcpy (Label, "ABEND");
break;
default :
strcpy (Label, "unknown");
break;
}
return Label;
}
/*------------------------------------------------------------------------------*/
/* Récupération du libellé d'un type de routage */
/*------------------------------------------------------------------------------*/
char * LOG_Rooting_Label_Get (LOGT_Rooting Rooting)
{
static char Label [20];
switch ((int)Rooting)
{
case LOGD_ROOTING_NULL:
strcpy (Label, "NULL");
break;
case LOGD_ROOTING_STDERR:
strcpy (Label, "STDERR");
break;
case LOGD_ROOTING_DATABASE:
strcpy (Label, "BASE");
break;
case LOGD_ROOTING_DEFAULT:
strcpy (Label, "DEFAULT");
break;
case LOGD_ROOTING_PREVIOUS:
strcpy (Label, "PREVIOUS");
break;
default :
strcpy (Label, "unknown");
break;
}
return Label;
}
/*------------------------------------------------------------------------------*/
/* Récupération du type de table de routage */
/*------------------------------------------------------------------------------*/
char * LOG_RTType_Label_Get ( LOGT_RTType RTabType )
{
static char Label [20];
switch ((int)RTabType)
{
case LOGD_GDRT:
strcpy (Label, "Global Default Rooting Table");
break;
case LOGD_GMRT:
strcpy (Label, "Global Master Rooting Table");
break;
case LOGD_LDRT:
strcpy (Label, "Local Default Rooting Table");
break;
case LOGD_LMRT:
strcpy (Label, "Local Master Rooting Table");
break;
case LOGD_URT:
strcpy (Label, "User Rooting Table");
break;
default :
strcpy (Label, "unknown");
break;
}
return Label;
}
/*------------------------------------------------------------------------------*/
/* Routine d'affichage d'un message d'erreur */
/*------------------------------------------------------------------------------*/
void LOG_Error_Print ( void )
{
if (LOG_stderr) fprintf (LOG_stderr, "%s\n", LOG_Error_Msg);
}
/*------------------------------------------------------------------------------*/
/* Pour préfixer les noms de heap avec le contexte de la librairie LIBLOG */
/*------------------------------------------------------------------------------*/
static char * LOG_Name_Prefix ( const char * Name )
{
static char Prefixed [256];
sprintf (Prefixed, "%s/%s", LOG_PREFIX, Name);
return Prefixed;
}