505 lines
14 KiB
C
505 lines
14 KiB
C
|
#include <stdlib.h>
|
|||
|
#include <stdio.h>
|
|||
|
#include <string.h>
|
|||
|
#include <unistd.h>
|
|||
|
#include <ver.h>
|
|||
|
#define MSG_MODE 1
|
|||
|
#include <msg.h>
|
|||
|
#include <log.h>
|
|||
|
#include <logagent.h>
|
|||
|
|
|||
|
VER_INFO_EXPORT (logagent, "$Revision: 1.1 $", "$Name: $", __FILE__, "$Author: smas $")
|
|||
|
|
|||
|
void Parse_Arg (int , char **);
|
|||
|
void Event_Msg_Process ( MSGT_Message * );
|
|||
|
void System_Msg_Process ( MSGT_Message * );
|
|||
|
void Info_Trace ( void );
|
|||
|
|
|||
|
unsigned int End_Agent, Nb_Event, Nb_System_Msg;
|
|||
|
MSGT_Port * Private_Port, * Event_Port;
|
|||
|
MSGT_PortList * Private_PortList;
|
|||
|
|
|||
|
unsigned int Num_Agent, Status, Debug;
|
|||
|
char Debug_Trace [512];
|
|||
|
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
/* Fonction principale */
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
int main ( int argc, char ** argv )
|
|||
|
{
|
|||
|
MSGT_Message * Msg;
|
|||
|
char Private_Port_Name [256];
|
|||
|
|
|||
|
/* R<>cup<75>ration des arguments de la ligne de commande */
|
|||
|
|
|||
|
Parse_Arg (argc, argv);
|
|||
|
|
|||
|
/* D<>marrage de l'agent */
|
|||
|
|
|||
|
Status = ACTIVE;
|
|||
|
|
|||
|
/* Ouverture de la librairie LIBMSG */
|
|||
|
|
|||
|
if (MSG_Library_Open (NULL, NULL, MSGD_OPEN) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible d'ouvrir la librairie LIBMSG");
|
|||
|
Info_Trace ();
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
/* Ouverture du port de message dans lequel sont envoy<6F>s les <20>v<EFBFBD>nements */
|
|||
|
|
|||
|
if (MSG_Port_Open (LOGD_EVENT_PORT_NAME, &Event_Port, MSGD_OPEN | MSGD_CREATE) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible d'ouvrir le port de messages des <20>v<EFBFBD>nements");
|
|||
|
Info_Trace ();
|
|||
|
MSG_Library_Close (MSGD_CLOSE);
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
/* Ouverture (cas du restart) ou cr<63>ation du port priv<69> de l'agent */
|
|||
|
|
|||
|
sprintf (Private_Port_Name, "Agent_%d_port", Num_Agent);
|
|||
|
|
|||
|
if (MSG_Port_Open (Private_Port_Name, &Private_Port, MSGD_OPEN | MSGD_CREATE) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible de d'ouvrir ou de cr<63>er mon port de messages priv<69>");
|
|||
|
Info_Trace ();
|
|||
|
MSG_Port_Close (Event_Port, MSGD_CLOSE);
|
|||
|
MSG_Library_Close (MSGD_CLOSE);
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
/* Cr<43>ation d'une liste de ports (port public + port priv<69>) que l'agent va <20>couter */
|
|||
|
|
|||
|
if (MSG_PortList_Open (&Private_PortList) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible de cr<63>er ma liste de ports");
|
|||
|
Info_Trace ();
|
|||
|
MSG_Port_Close (Event_Port, MSGD_CLOSE);
|
|||
|
MSG_Port_Close (Private_Port, MSGD_DESTROY);
|
|||
|
MSG_Library_Close (MSGD_CLOSE);
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
if (MSG_PortList_Port_Add (Private_PortList, Private_Port) != MSGS_OK || MSG_PortList_Port_Add (Private_PortList, Event_Port) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible d'ajouter les ports priv<69> et public <20> ma liste de ports");
|
|||
|
Info_Trace ();
|
|||
|
MSG_PortList_Close (Private_PortList);
|
|||
|
MSG_Port_Close (Event_Port, MSGD_CLOSE);
|
|||
|
MSG_Port_Close (Private_Port, MSGD_DESTROY);
|
|||
|
MSG_Library_Close (MSGD_CLOSE);
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
sprintf (Debug_Trace, "d<EFBFBD>marrage en mode trace %s", Debug == TRUE ? "activ<EFBFBD>" : "d<EFBFBD>sactiv<EFBFBD>");
|
|||
|
Info_Trace ();
|
|||
|
|
|||
|
/* Boucle principale */
|
|||
|
|
|||
|
Nb_System_Msg = 0;
|
|||
|
Nb_Event = 0;
|
|||
|
End_Agent = FALSE;
|
|||
|
|
|||
|
while (End_Agent == FALSE)
|
|||
|
{
|
|||
|
unsigned int Expected_Type;
|
|||
|
|
|||
|
if (Status == ACTIVE)
|
|||
|
{
|
|||
|
/* Quand l'agent est actif, il traite tous les types de messages */
|
|||
|
|
|||
|
Expected_Type = MSGD_NO_TYPE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* Quand l'agent est stopp<70>, il ne traite que les messages syst<73>me */
|
|||
|
|
|||
|
Expected_Type = MSGD_SYSTEM_GENERIC;
|
|||
|
}
|
|||
|
|
|||
|
/* Ecoute des ports de messages de la liste */
|
|||
|
|
|||
|
if (MSG_PortList_Listen (Private_PortList, Expected_Type, &Msg, MSGD_WAIT) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible de r<>ceptionner un message depuis l'un des ports <20>cout<75>s");
|
|||
|
Info_Trace ();
|
|||
|
MSG_PortList_Close (Private_PortList);
|
|||
|
MSG_Port_Close (Private_Port, MSGD_DESTROY);
|
|||
|
MSG_Library_Close (MSGD_CLOSE);
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
/* Traitement du message */
|
|||
|
|
|||
|
switch (Msg->Type)
|
|||
|
{
|
|||
|
case LOGD_EVENT_MSG_TYPE:
|
|||
|
|
|||
|
/* Il s'agit d'un <20>v<EFBFBD>nement */
|
|||
|
|
|||
|
Event_Msg_Process (Msg);
|
|||
|
Nb_Event ++;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
/* Il s'agit d'un message syst<73>me */
|
|||
|
|
|||
|
System_Msg_Process (Msg);
|
|||
|
Nb_System_Msg ++;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Suppression de la liste de ports de l'agent */
|
|||
|
|
|||
|
if (MSG_PortList_Close (Private_PortList) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible de supprimer ma liste de ports");
|
|||
|
Info_Trace ();
|
|||
|
MSG_Port_Close (Private_Port, MSGD_DESTROY);
|
|||
|
MSG_Library_Close (MSGD_CLOSE);
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
/* Suppression du port priv<69> de l'agent */
|
|||
|
|
|||
|
if (MSG_Port_Close (Private_Port, MSGD_DESTROY) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible de supprimer mon port de messages priv<69>");
|
|||
|
Info_Trace ();
|
|||
|
MSG_Library_Close (MSGD_CLOSE);
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
/* Fermeture de la librairie */
|
|||
|
|
|||
|
if (MSG_Library_Close (MSGD_CLOSE) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible de fermer la librairie LIBMSG");
|
|||
|
Info_Trace ();
|
|||
|
return KO;
|
|||
|
}
|
|||
|
|
|||
|
strcpy (Debug_Trace, "termin<EFBFBD>");
|
|||
|
Info_Trace ();
|
|||
|
|
|||
|
return OK;
|
|||
|
}
|
|||
|
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
/* R<>cup<75>ration de la ligne de commande */
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
void Parse_Arg (int argc, char ** argv)
|
|||
|
{
|
|||
|
int i;
|
|||
|
|
|||
|
Debug = FALSE;
|
|||
|
|
|||
|
for (i = 1; i < argc; i++)
|
|||
|
{
|
|||
|
if (!strcmp (argv[i], "--help") || !strcmp (argv[i], "-h"))
|
|||
|
{
|
|||
|
fprintf (stderr, "Usage : %s [ [--help|-h] | --version [-v] | -id <id_agent> [--debug] ]\n", argv [0]);
|
|||
|
exit (1);
|
|||
|
}
|
|||
|
|
|||
|
if (!strcmp (argv[i], "-id"))
|
|||
|
{
|
|||
|
i++;
|
|||
|
if (i == argc)
|
|||
|
{
|
|||
|
fprintf (stderr, "Argument manquant apr<70>s \"%s\"\n", argv[i - 1]);
|
|||
|
exit (0);
|
|||
|
}
|
|||
|
|
|||
|
Num_Agent = atoi (argv[i]);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (!strcmp (argv[i], "--version"))
|
|||
|
{
|
|||
|
if (i+1 < argc && !strcmp (argv[i+1], "-v"))
|
|||
|
{
|
|||
|
VER_Object_Print (stdout, VERD_VERBOSE);
|
|||
|
exit (0);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
VER_Object_Print (stdout, VERD_MINIMAL);
|
|||
|
exit (0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!strcmp (argv[i], "--debug"))
|
|||
|
{
|
|||
|
Debug = TRUE;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
fprintf (stderr, "Option invalide \"%s\"\n", argv[i]);
|
|||
|
exit (0);
|
|||
|
}
|
|||
|
|
|||
|
if (Num_Agent == 0)
|
|||
|
{
|
|||
|
fprintf (stderr, "Option \"-id\" manquante ou bien valeur incorrecte (doit <20>tre > 0)\n");
|
|||
|
exit (0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
/* Traitement d'un message contenant un <20>v<EFBFBD>nement */
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
void Event_Msg_Process (MSGT_Message * Msg)
|
|||
|
{
|
|||
|
LOGT_Event_Msg_Data * Msg_Data;
|
|||
|
unsigned int Length, Event_Type;
|
|||
|
char Event_Name [256];
|
|||
|
char Cd_Support [256];
|
|||
|
char Data_Name [256];
|
|||
|
char Data_Value [256];
|
|||
|
unsigned int i;
|
|||
|
char * Event_Data_Ptr;
|
|||
|
|
|||
|
/* R<>cup<75>ration des donn<6E>es de l'ent<6E>te de l'<27>v<EFBFBD>nement */
|
|||
|
|
|||
|
Msg_Data = (LOGT_Event_Msg_Data *)(Msg->Data);
|
|||
|
|
|||
|
/* V<>rification de la version du format */
|
|||
|
|
|||
|
if (strcmp (Msg_Data->Header.Version, EVENT_FORMAT_VERSION))
|
|||
|
{
|
|||
|
sprintf (Debug_Trace, "version du format de message \"%s\" incorrect (\"%s\" attendu)", Msg_Data->Header.Version, EVENT_FORMAT_VERSION);
|
|||
|
Info_Trace ();
|
|||
|
|
|||
|
/* Suppression du message */
|
|||
|
|
|||
|
MSG_Message_Free (Msg);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
sprintf (Debug_Trace, "r<EFBFBD>ception d'un <20>v<EFBFBD>nement de la part du processus %d (module %d/%d)",
|
|||
|
Msg_Data->Header.Sending_Pid,
|
|||
|
Msg_Data->Header.ModuleId,
|
|||
|
Msg_Data->Header.Master_ModuleId);
|
|||
|
|
|||
|
/* R<>cup<75>ration de l'identifiant du type d'<27>v<EFBFBD>nement */
|
|||
|
|
|||
|
Event_Type = Msg_Data->Event_Type;
|
|||
|
|
|||
|
/* R<>cup<75>ration du nom de l'<27>v<EFBFBD>nement */
|
|||
|
|
|||
|
Event_Data_Ptr = &(Msg_Data->Event_Data);
|
|||
|
|
|||
|
i = 0;
|
|||
|
Length = (unsigned int)(Event_Data_Ptr [i]);
|
|||
|
strncpy (Event_Name, Event_Data_Ptr + i + 1, Length);
|
|||
|
Event_Name [Length] = (char)0;
|
|||
|
|
|||
|
i += 1 + Length;
|
|||
|
|
|||
|
if (Debug == TRUE) fprintf (stderr, "%s\nEv<EFBFBD>nement \"%s\" (type=%d):", Debug_Trace, Event_Name, Event_Type);
|
|||
|
|
|||
|
Length = (unsigned int)(Event_Data_Ptr [i]);
|
|||
|
strncpy (Cd_Support, Event_Data_Ptr + i + 1, Length);
|
|||
|
Cd_Support [Length] = (char)0;
|
|||
|
|
|||
|
if (Debug == TRUE) fprintf (stderr, "%s\n\t- support=\"%s\"\n", Debug_Trace, Cd_Support);
|
|||
|
|
|||
|
i += 1 + Length;
|
|||
|
|
|||
|
/* R<>cup<75>ration des macro-donn<6E>es */
|
|||
|
|
|||
|
while (i < Msg_Data->Data_Size)
|
|||
|
{
|
|||
|
/* R<>cup<75>ration du nom de la macro-donn<6E>e */
|
|||
|
|
|||
|
Length = (unsigned int)(Event_Data_Ptr [i]);
|
|||
|
strncpy (Data_Name, Event_Data_Ptr + i + 1, Length);
|
|||
|
Data_Name [Length] = (char)0;
|
|||
|
|
|||
|
i += 1 + Length;
|
|||
|
|
|||
|
if (i < Msg->Size)
|
|||
|
{
|
|||
|
/* R<>cup<75>ration de la valeur de la macro-donn<6E>e */
|
|||
|
|
|||
|
Length = (unsigned int)(Event_Data_Ptr [i]);
|
|||
|
strncpy (Data_Value, Event_Data_Ptr + i + 1, Length);
|
|||
|
Data_Value [Length] = (char)0;
|
|||
|
|
|||
|
i += 1 + Length;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "mauvais format d'<27>v<EFBFBD>nement");
|
|||
|
Info_Trace ();
|
|||
|
}
|
|||
|
|
|||
|
if (Debug == TRUE) fprintf (stderr, "\t- %s=%s\n", Data_Name, Data_Value);
|
|||
|
}
|
|||
|
|
|||
|
/* Traitement de l'<27>v<EFBFBD>nement
|
|||
|
|
|||
|
...
|
|||
|
...
|
|||
|
...
|
|||
|
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
/* Renvoi du message <20> l'envoyeur */
|
|||
|
|
|||
|
if (MSG_Message_Reply (Msg) != MSGS_OK)
|
|||
|
{
|
|||
|
strcpy (Debug_Trace, "impossible de renvoyer le message de l'<27>v<EFBFBD>nement <20> son envoyeur");
|
|||
|
Info_Trace ();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
/* Traitement d'un message syst<73>me par un agent */
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
void System_Msg_Process (MSGT_Message * Msg)
|
|||
|
{
|
|||
|
/* Pour accuser r<>ception du message syst<73>me, on commence par remplir les donn<6E>es li<6C>es <20> l'agent */
|
|||
|
|
|||
|
((Agent_Stat *)(Msg->Data))->Num_Agent = Num_Agent;
|
|||
|
((Agent_Stat *)(Msg->Data))->Pid = getpid ();
|
|||
|
|
|||
|
switch (Msg->Type)
|
|||
|
{
|
|||
|
case MSGD_SYSTEM_STOP_REQUEST:
|
|||
|
|
|||
|
if (Status == ACTIVE)
|
|||
|
{
|
|||
|
/* On indique que la requ<71>te a bien <20>t<EFBFBD> prise en compte */
|
|||
|
|
|||
|
((Agent_Stat *)(Msg->Data))->Answer = TRUE;
|
|||
|
|
|||
|
/* Pause de l'agent jusqu'<27> r<>ception d'un message MSGD_SYSTEM_CONTINUE_REQUEST */
|
|||
|
|
|||
|
Status = STOPPED;
|
|||
|
|
|||
|
strcpy (Debug_Trace, "pause");
|
|||
|
Info_Trace ();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* On indique que la requ<71>te n'a pas <20>t<EFBFBD> prise en compte */
|
|||
|
|
|||
|
((Agent_Stat *)(Msg->Data))->Answer = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case MSGD_SYSTEM_CONTINUE_REQUEST:
|
|||
|
|
|||
|
if (Status == STOPPED)
|
|||
|
{
|
|||
|
/* On indique que la requ<71>te a bien <20>t<EFBFBD> prise en compte */
|
|||
|
|
|||
|
((Agent_Stat *)(Msg->Data))->Answer = TRUE;
|
|||
|
|
|||
|
/* Reprise de l'agent */
|
|||
|
|
|||
|
Status = ACTIVE;
|
|||
|
|
|||
|
strcpy (Debug_Trace, "reprise");
|
|||
|
Info_Trace ();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
/* On indique que la requ<71>te n'a pas <20>t<EFBFBD> prise en compte */
|
|||
|
|
|||
|
((Agent_Stat *)(Msg->Data))->Answer = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case MSGD_SYSTEM_SHUTDOWN_REQUEST:
|
|||
|
|
|||
|
/* Fin de la boucle principale de l'agent */
|
|||
|
|
|||
|
End_Agent = TRUE;
|
|||
|
|
|||
|
strcpy (Debug_Trace, "terminaison en cours...");
|
|||
|
Info_Trace ();
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case MSGD_SYSTEM_STATUS_REQUEST:
|
|||
|
|
|||
|
/* On informe le superviseur sur l'<27>tat dans lequel on se trouve */
|
|||
|
|
|||
|
((Agent_Stat *)(Msg->Data))->Status = Status;
|
|||
|
((Agent_Stat *)(Msg->Data))->Debug = Debug;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case MSGD_SYSTEM_INFO_REQUEST:
|
|||
|
|
|||
|
/* On informe le superviseur sur le nombre de messages (syst<73>me et <20>v<EFBFBD>nement) trait<69>s */
|
|||
|
|
|||
|
((Agent_Stat *)(Msg->Data))->Cpt_Event = Nb_Event;
|
|||
|
((Agent_Stat *)(Msg->Data))->Cpt_System = Nb_System_Msg;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case MSGD_SYSTEM_TRACEON_REQUEST:
|
|||
|
|
|||
|
Debug = TRUE;
|
|||
|
strcpy (Debug_Trace, "activation du mode trace");
|
|||
|
Info_Trace ();
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
case MSGD_SYSTEM_TRACEOFF_REQUEST:
|
|||
|
|
|||
|
strcpy (Debug_Trace, "d<EFBFBD>sactivation du mode trace");
|
|||
|
Info_Trace ();
|
|||
|
Debug = FALSE;
|
|||
|
|
|||
|
break;
|
|||
|
|
|||
|
default :
|
|||
|
|
|||
|
/* On indique que la requ<71>te n'a pas <20>t<EFBFBD> prise en compte */
|
|||
|
|
|||
|
((Agent_Stat *)(Msg->Data))->Answer = FALSE;
|
|||
|
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
/* On accuse r<>ception du message */
|
|||
|
|
|||
|
MSG_Message_Reply (Msg);
|
|||
|
}
|
|||
|
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
/* Affichage sur la sortie standard d'erreur d'un message g<>n<EFBFBD>r<EFBFBD> par un agent */
|
|||
|
/*--------------------------------------------------------------------------------------------------*/
|
|||
|
void Info_Trace ( void )
|
|||
|
{
|
|||
|
time_t dts;
|
|||
|
struct tm * dt;
|
|||
|
char Current_Date [25];
|
|||
|
|
|||
|
if (Debug == TRUE)
|
|||
|
{
|
|||
|
/* R<>cup<75>re la date courante */
|
|||
|
|
|||
|
time (&dts);
|
|||
|
dt = localtime (&dts);
|
|||
|
sprintf (Current_Date, "%02d/%02d/%04d %02d:%02d:%02d", dt->tm_mday, dt->tm_mon + 1, dt->tm_year + 1900, dt->tm_hour, dt->tm_min, dt->tm_sec);
|
|||
|
|
|||
|
fprintf (stderr, "[%s] Agent n<>%d : %s\n", Current_Date, Num_Agent, Debug_Trace);
|
|||
|
}
|
|||
|
}
|