liblog-bdm/util/logagent.c

505 lines
14 KiB
C
Raw Normal View History

2000-07-31 15:15:35 +02:00
#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);
}
}