/* ***********************IMPORTANT *********************************************
 *  Copyright (C) 2004-2007 Thierry Lagarde <tlagarde@users.sourceforge.net>
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License.
 *
 *
 *                      ********************
 *
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *
 *                      ********************
 *
 *
 * You are highly encouraged to send your changes to <tlagarde@users.sourceforge.net>
 * for possible incorporation into the main distribution.
 * By sending these changes to <tlagarde@users.sourceforge.net>,
 * it is assumed that you are offering <tlagarde@users.sourceforge.net>
 * the unlimited, non-exclusive right to reuse, modify, and relicense the code.
 *
 *
 *                      ********************
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **************************************************************************************/
#include "Restoration_Agent.h"
#include "Equipement.h"
#include "Equipement_Port.h"
#include "Equipement_Historique.h"
#include "Reseau.h"
#include "Debug.h"
#include "Objet.h"
#include "Com/Commun.h"
#include "Com/Initialisation_Com.h"
#include "Settings.h"
#include "Gconf.h"
#include "Declaration_Constante.h"
#include "Macro.h"



void Lit_Donnee_Xml_Restoration_Agent (xmlNodePtr xmlnode, gboolean Ip_Dynamic)
{
#define FORMAT_DATE "%a %b %e %H:%M:%S %Y"
	gchar    *Char = NULL, *Date_Erreur = NULL, *Address_IP = NULL, *Address_MAC = NULL, *Date = NULL;
	xmlNodePtr xml_Enfant = NULL;
	struct Struct_Subnet *Subnet = NULL;
	struct struct_Restauration_Machine Message;
	struct tm tm;
	gint      Nb_Port_Ajouter, NumPort;
	gint      Nb_Objet_Liste, i;
	gchar    *cAgent = NULL;

	ERROR_if (xmlnode == NULL);
	if (xmlnode->name && g_strcasecmp (xmlnode->name, "Subnet") == 0) {
		if (Subnet_Restauration != NULL) {
		
			Nb_Objet_Liste = g_list_length (Subnet_Restauration);
			for (i = 0; i < Nb_Objet_Liste; i++) {
				Subnet = g_list_nth_data (Subnet_Restauration, 0);
				G_LIST_REMOVE (Subnet_Restauration, Subnet);
			
				MYFREE (Subnet);
			}
		}
	
		xml_Enfant = xmlnode->children;
		while ((xml_Enfant != NULL) && (xml_Enfant->type != XML_ELEMENT_NODE))
			xml_Enfant = xml_Enfant->next;
		while (xml_Enfant) {
			if (!xmlnode->name || g_strcasecmp (xml_Enfant->name, "Subnet") != 0)
				return;
			MALLOC (Subnet, sizeof (struct Struct_Subnet));
			Char = xmlGetProp (xml_Enfant, "Masque");
			if (sscanf (Char, "%d", &Subnet->Masque) != 1) {
				debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restoration Masque : [%s]", Char);
				Subnet->Masque = 1;
			}
			MYFREE (Char);
			Char = xmlGetProp (xml_Enfant, "A");
			if (sscanf (Char, "%d", &Subnet->A) != 1) {
				debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restoration A : [%s]", Char);
				Subnet->A = 192;
			}
			MYFREE (Char);
			Char = xmlGetProp (xml_Enfant, "B");
			if (sscanf (Char, "%d", &Subnet->B) != 1) {
				debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restoration B : [%s]", Char);
				Subnet->B = 168;
			}
			MYFREE (Char);
			Char = xmlGetProp (xml_Enfant, "C");
			if (sscanf (Char, "%d", &Subnet->C) != 1) {
				debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restoration C : [%s]", Char);
				Subnet->C = 0;
			}
			MYFREE (Char);
		
			G_LIST_APPEND (Subnet_Restauration, Subnet);
			xml_Enfant = xml_Enfant->next;
			while ((xml_Enfant != NULL) && (xml_Enfant->type != XML_ELEMENT_NODE))
				xml_Enfant = xml_Enfant->next;
		}
	
		return;
	}

	bzero (&Message, sizeof (struct struct_Restauration_Machine));

	if (!xmlnode->name || g_strcasecmp (xmlnode->name, "Equipment") != 0) {
		return;
	}


	Address_IP = xmlGetProp (xmlnode, "Address_IP");
	strcpy (Message.Adresse_Ip_Char, Address_IP);
	MYFREE (Address_IP);

	Address_MAC = xmlGetProp (xmlnode, "Address_MAC");
	strcpy (Message.Adresse_MAC_Char, Address_MAC);
	MYFREE (Address_MAC);

	xmlnode = xmlnode->children;
	while ((xmlnode != NULL) && (xmlnode->type != XML_ELEMENT_NODE))
		xmlnode = xmlnode->next;
	if (xmlnode) {
	
		while (xmlnode->name && g_strcasecmp (xmlnode->name, "Ports") != 0) {
		
			xmlnode = xmlnode->next;
			while ((xmlnode != NULL) && (xmlnode->type != XML_ELEMENT_NODE))
				xmlnode = xmlnode->next;
		}
	
		if (!xmlnode->name || g_strcasecmp (xmlnode->name, "Ports") != 0)
			return;
		xmlnode = xmlnode->children;
		while ((xmlnode != NULL) && (xmlnode->type != XML_ELEMENT_NODE))
			xmlnode = xmlnode->next;
	
		while (xmlnode->name && g_strcasecmp (xmlnode->name, "Open") != 0) {
		
			xmlnode = xmlnode->next;
			while ((xmlnode != NULL) && (xmlnode->type != XML_ELEMENT_NODE))
				xmlnode = xmlnode->next;
		}
	
		if (!xmlnode->name || g_strcasecmp (xmlnode->name, "Open") != 0)
			return;
		xmlnode = xmlnode->children;
		while ((xmlnode != NULL) && (xmlnode->type != XML_ELEMENT_NODE))
			xmlnode = xmlnode->next;
	
		Nb_Port_Ajouter = 0;
		while (xmlnode) {
			if (!xmlnode->name || g_strcasecmp (xmlnode->name, "Port") != 0)
				return;
			Char = xmlGetProp (xmlnode, "Num");
		
			if (sscanf (Char, "%d", &NumPort) != 1) {
				debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restoration port : [%s]", Char);
				NumPort = 0;
			}
			Message.Port[Nb_Port_Ajouter].Num_Port = NumPort;
			MYFREE (Char);
			Date = xmlGetProp (xmlnode, "Last_State_Change");
			Date_Erreur = (gchar *) strptime (Date, FORMAT_DATE, &tm);
			if (Date_Erreur == NULL)
				debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restoration date : [%s] [%s]", xmlGetProp (xmlnode, "Last_State_Change"), Date_Erreur);
			Message.Port[Nb_Port_Ajouter].Derniere_Modification_Etat_Port = mktime (&tm);
			MYFREE (Date);
			Nb_Port_Ajouter++;
			xmlnode = xmlnode->next;
			while ((xmlnode != NULL) && (xmlnode->type != XML_ELEMENT_NODE))
				xmlnode = xmlnode->next;
		}
	}
	/*cAgent = xmlGetProp (xmlnode, "Agent_AutoScan");     
	 * if (cAgent != NULL){
	 * if (cAgent[0] == '0')
	 * Message.Ip_Dynamic = Ip_Dynamic;
	 * else
	 * Message.Ip_Dynamic = FALSE;
	 * MYFREE (cAgent);
	 * }
	 * else */
	Message.Ip_Dynamic = Ip_Dynamic;

	Communication_Envoie_Donnee (Pid_Agent_Initialisation, RESTAURATION_MACHINE, (gpointer *) & Message, sizeof (Message), NULL);
}


void Lit_Xml_Restoration_Agent (xmlDocPtr doc, gboolean Ip_Dynamic)
{
	xmlNodePtr node = NULL;
	xmlNode  *root_element = NULL;

	ERROR_if (doc == NULL);

	root_element = xmlDocGetRootElement (doc);
	for (node = root_element->children; node != NULL; node = node->next) {
		if (node->type == XML_ELEMENT_NODE)
			Lit_Donnee_Xml_Restoration_Agent (node, Ip_Dynamic);
	}
	debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restoration_Agent : OK");
}


gboolean Restoration_Agent (char *fname)
{
	xmlDocPtr doc = NULL;
	gchar    *Tbool = NULL;
	xmlNode  *root_element = NULL;
	gboolean  Ip_Dynamic;


	ERROR_if (fname == NULL);
	if (!g_file_test(fname,G_FILE_TEST_EXISTS))
		debug_printf (INTERFACE, D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error loading file : [%s]", fname);

	doc = xmlParseFile (fname);
	if (!doc) {
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fichier XML restoration : [%s]", fname);
		return FALSE;
	}
	root_element = xmlDocGetRootElement (doc);

	if (!root_element || !root_element->name || g_strcasecmp (root_element->name, "AutoScan_V2") != 0) {
		if (!root_element)
			debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "l'element n'est pas root");
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fichier XML Port mal formaté : [%s]", fname);
		xmlFreeDoc (doc);
		return FALSE;
	}
	/*if (!doc->root || !doc->root->name || g_strcasecmp (doc->root->name, "AutoScan") != 0) {
	 * if (!doc->root)
	 * debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "l'element n'est pas root");
	 * debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fichier XML Port mal formaté : [%s]", fname);
	 * xmlFreeDoc (doc);
	 * return FALSE;
	 * } */

	free_gchar_if_no_null (Nom_Reseau_Restauration);
	Nom_Reseau_Restauration = xmlGetProp (root_element, "Network");
	if (Nom_Reseau_Restauration == NULL)
		Nom_Reseau_Restauration = "No Name";
	free_gchar_if_no_null (Interface_Restauration);
	Interface_Restauration = xmlGetProp (root_element, "Interface");
	if (Interface_Restauration == NULL)
		Interface_Restauration = "eth0";
	free_gchar_if_no_null (Icon_Restauration);
	Icon_Restauration = xmlGetProp (root_element, "Icon");
	if (Icon_Restauration == NULL)
		Icon_Restauration = PATH_ICONE "Network/home.png";
	free_gchar_if_no_null (Communaute_Snmp_Restauration);
	Communaute_Snmp_Restauration = xmlGetProp (root_element, "Communaute_Snmp");
	if (Communaute_Snmp_Restauration == NULL)
		Communaute_Snmp_Restauration = "public";
	Tbool = xmlGetProp (root_element, "Intrusion_Alert");
	if (Tbool[0] == '1')
		Intrusion_Alert_Restauration = TRUE;
	else
		Intrusion_Alert_Restauration = FALSE;
	MYFREE (Tbool);

	Tbool = xmlGetProp (root_element, "Ip_Dynamic");
	if (Tbool != NULL) {
		if (Tbool[0] == '1')
			Ip_Dynamic = TRUE;
		else
			Ip_Dynamic = FALSE;
	}
	else
		Ip_Dynamic = FALSE;
	MYFREE (Tbool);
	debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restauration %s-%s-%s-%s-%i", Nom_Reseau_Restauration, Interface_Restauration, Icon_Restauration, Communaute_Snmp_Restauration, Intrusion_Alert_Restauration);
	Lit_Xml_Restoration_Agent (doc, Ip_Dynamic);

	xmlFreeDoc (doc);
	return TRUE;
}



void Initialisation_Variable_Restoration_Agent (void)
{
	Nom_Reseau_Restauration = NULL;
	Interface_Restauration = NULL;
	Icon_Restauration = NULL;
	Communaute_Snmp_Restauration = NULL;
	Intrusion_Alert_Restauration = FALSE;
	Subnet_Restauration = NULL;
	

	Nom_Reseau_Fichier_Xml = NULL;
	Dns_Fichier_Xml = NULL;
}



gboolean Lecture_Fichier_Restoration_Agent (char *fname)
{
	xmlDocPtr doc = NULL;
	gchar    *Tbool = NULL;
	xmlNode  *root_element = NULL;
	gboolean  Ip_Dynamic;
	gchar	  *temp = NULL;

	ERROR_if (fname == NULL);
	if (!g_file_test(fname,G_FILE_TEST_EXISTS)){
		debug_printf (INTERFACE, D_WARN_USER, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Error loading file : [%s]", fname);
		return FALSE;	
	}

	doc = xmlParseFile (fname);
	if (!doc) {
		debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Fichier XML restoration : [%s]", fname);
		return FALSE;
	}
	root_element = xmlDocGetRootElement (doc);

	if (!root_element || !root_element->name || g_strcasecmp (root_element->name, "AutoScan_V2") != 0) {
		if (!root_element)
			debug_printf (INTERFACE, D_WARN, __FILE__, __PRETTY_FUNCTION__, __LINE__, "l'element n'est pas root");
		debug_printf (INTERFACE, D_WARN_USER, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Unknown Format  : [%s]", fname);
		xmlFreeDoc (doc);
		return FALSE;
	}


	free_gchar_if_no_null (Nom_Reseau_Fichier_Xml);
	Nom_Reseau_Fichier_Xml = xmlGetProp (root_element, "Network");
	if (Nom_Reseau_Fichier_Xml == NULL)
		Nom_Reseau_Fichier_Xml = "No Name";
	
	free_gchar_if_no_null (Dns_Fichier_Xml);
	Dns_Fichier_Xml = xmlGetProp (root_element, "Ip_Agent");
	if (Dns_Fichier_Xml == NULL)
		Dns_Fichier_Xml="127.0.0.1";
	
	temp = xmlGetProp (root_element, "Port_Agent");
	if (temp == NULL)
		Port_Fichier_Xml=4555;
	else{
		if (sscanf (temp, "%d", &Port_Fichier_Xml) != 1) {
			debug_printf (INTERFACE, D_WARN_USER, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Restore (number port) : failed  (%s)", temp);
			MYFREE(temp);
			return TRUE;
		}		
		MYFREE(temp);
	}	
	

	xmlFreeDoc (doc);
	return TRUE;
}
