/* ***********************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 "Thread.h"
#include "Macro.h"
#include "Debug.h"

#ifdef __LOG_ENABLE
extern struct Struct_Categorie Liste_Categorie[];
#endif


void demmarrage_Thread (void *thread, gpointer * pointeur)
{
	PROTECT_CODE (Semaphore_Thread);
	struct Struct_Liste_Thread *Thread = NULL;

	MALLOC(Thread,sizeof (struct Struct_Liste_Thread));
	if (pthread_create (&Thread->pThread, NULL, (void *) thread, pointeur) != 0) {
		DEPROTECT_CODE (Semaphore_Thread);
		debug_printf (D_ERRO, __FILE__, __PRETTY_FUNCTION__, __LINE__, "Demarage_Thread (%d): Impossible de démarrer le thread%d", getpid ());
	}
	pthread_detach (Thread->pThread);
	Nb_Thead++;
	Id_Thread++;	
	Thread->Id_Thread = Id_Thread;
	G_LIST_APPEND(GList_Liste_Thread, Thread);
	DEPROTECT_CODE (Semaphore_Thread);
}

void Stop_Thread (void *retval)
{		
	PROTECT_CODE (Semaphore_Thread);
	struct Struct_Liste_Thread *Thread = NULL, *Thread_Trouver = NULL;
	struct struct_Cle_Privee *pCle = NULL;
	pthread_t Thread_Id;
	gint      i, Nb_Objet_Liste;

	Thread_Id = pthread_self ();
	Thread_Trouver = NULL;

	Nb_Objet_Liste = g_list_length (GList_Liste_Thread);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Thread = g_list_nth_data (GList_Liste_Thread, i);
		if (pthread_equal (Thread->pThread, Thread_Id)) {
			Thread_Trouver = Thread; 
			break;
		}
	}

	if (Thread_Trouver != NULL){
		G_LIST_REMOVE(GList_Liste_Thread, Thread_Trouver);
		MYFREE(Thread_Trouver);
	}
	else
		printf ("[WARNING] Thread Non référencé\n");
#ifndef         __WINDOWS_ENABLE

	if ((pCle = pthread_getspecific (Cle_privee_thread)) == NULL)
		pCle = Donnee_Cle_Main;
	Log(pCle, "Stop Thread\n");
	Close_Log_Thread(pCle);
#endif

	Nb_Thead--;
	DEPROTECT_CODE (Semaphore_Thread);
	pthread_exit (retval);
}


#ifndef         __WINDOWS_ENABLE
void Pause_Thread( int signum, siginfo_t *info, void *secret )
{
	PROTECT_CODE(Semaphore_Etat_Thread);
	struct struct_Cle_Privee *pCle = NULL;
	struct Struct_Liste_Equipement *Equipement=NULL;
	GList    *GList_Log = NULL;
	char   Texte[255];
		
	if ((pCle = pthread_getspecific (Cle_privee_thread)) == NULL)
		pCle = Donnee_Cle_Main;
	strcpy(Texte,"Thread [");
	strcat (Texte, Liste_Categorie[pCle->Categorie].Info);
	strcat (Texte,"] (");
	switch (pCle->Categorie) {
	    case CATEG_THREAD_SCAN:
		    Equipement = pCle->Pointeur_Data;
		    strcat (Texte, Equipement->Adresse_Ip_Char);
		    break;
	    case CATEG_NESSUS:
		    Equipement = pCle->Pointeur_Data;
		    strcat (Texte, Equipement->Adresse_Ip_Char);
		    break;
	    case CATEG_THREAD_SNMP_LISTE_ALL:
		    Equipement = pCle->Pointeur_Data;
		    strcat (Texte, Equipement->Adresse_Ip_Char);
		    break;
	    case CATEG_THREAD_SNMP_LISTE:
		    Equipement = pCle->Pointeur_Data;
		    strcat (Texte, Equipement->Adresse_Ip_Char);
		    break;
		case CATEG_SCAN_PLAGE :
			strcat (Texte, pCle->Pointeur_Data);
			break;
		case CATEG_THREAD_SNMP_SCALAIRE:
		    Equipement = pCle->Pointeur_Data;
		    strcat (Texte, Equipement->Adresse_Ip_Char);
		    break;
		default:
			strcat (Texte,"none");
	}
	strcat (Texte,")\n");
	printf("%s",Texte);

	Log (pCle, "#####################################\n");
	Log (pCle, Texte);
	display_backtrace(pCle,NULL,0);

	Close_Log_Thread(pCle);
	Nb_Thead--; 
	DEPROTECT_CODE(Semaphore_Etat_Thread); 
	while (1)	pause(); 
}

void envoie_Signal_All_Thread (int signum)
{
	PROTECT_CODE (Semaphore_Thread);
	struct Struct_Liste_Thread *Thread = NULL;
	pthread_t Thread_Id;
	gint      i, Nb_Objet_Liste;

	Nb_Objet_Liste = g_list_length (GList_Liste_Thread);
	for (i = 0; i < Nb_Objet_Liste; i++) {
		Thread = g_list_nth_data (GList_Liste_Thread, i);
		pthread_kill (Thread->pThread, signum);
	}
	DEPROTECT_CODE (Semaphore_Thread);
}
#endif
