/*************************************************
File name:sftp.c
Author: 	JianHui Zheng
Version:	9:00:00 
Date:  		2007-10-9
Description:该文件实现了向远端主机发送文件的功能
			

			
												
History:               
No. 		
Author:		  
Date:		 
Version:	   
Description:
*************************************************/
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include "sftp.h"

/******************************************************/
/******            Heartbeat Parameter           ******/
/******************************************************/
DWORD PROC_HEARTBEAT_OID[12]={1,3,6,1,4,1,1373,2,4,10,11};
int PROC_HEARTBEAT_OIDLEN=11;

/******************************************************/
/******           Function Declaration           ******/
/******************************************************/
void sftp_init(void);
int initNRConf(void);
int sendFile(char *remoteip, char *username, char *userpass, char *srcdir, char *filename, char *desdir,int fileIndex);
void checkToSend(void);
void checkToTransfer(void);
int hpmnServersInfoUpdate(void);
void sftpsend_timer(void);
int initDatabase(void);
void initDirectory(void);
void printfHPMNServer(HpmnServer* server);
void printfFileObject(FileTransfer* ft);
void logMessage(const char *fmt,...);
void printfInColor(char *message,int color);

void createSendTask(int fileIndex);
void sendTask(int fileIndex);

void deleteFile(char* fileName);
int addFile(char* fileName);
int checkFile(char* fileName);

//2009-06-10
int sendHeartbeat();

int getCdrConf(FileTransfer *fileTransfer,int *file_object_count);
int getCstaConf(FileTransfer *fileTransfer,int *file_object_count);
/******************************************************/
/******       Public Parameter Declaration       ******/
/******************************************************/
/* The hpmn servers array, now suport 100 servers */
HpmnServer servers[HPMN_SERVER_COUNT];
/* The OMC_PUB database connection */
MYSQL *g_omcPubConn;
/* The CDR_DB database connection */
MYSQL *g_cdrConn;
/* The total count of hpmn servers in the hpmnConf table */
int g_hpmn_server_count;
/* The hpmn servers info will be updated every minute */
int g_hpmn_update_timeout;

/* The file transfer array, now support 32 objects */
FileTransfer file_transfers[MAX_FILE_TRANSFER_NUM];

/* The count of the file transfer object */
int g_file_transfer_count;

/* The source directory to send the file */
char SEND_DIR[256];
/* The directory to receive the file */
char RECV_DIR[256];

/* The backup directory */
char NR_RECV_BAK_DIR[256];
char NR_SEND_BAK_DIR[256];
char ND_RECV_BAK_DIR[256];
char ND_SEND_BAK_DIR[256];
char NE_RECV_BAK_DIR[256];
char NE_SEND_BAK_DIR[256];
char LOCAL_CSV_DIR[256];

/* Use to check the receive files */
long recvfileSize;
char recvFileName[512]="NoFile";

char fileVector[MAX_THREAD_NUM][256];
pthread_t threads[MAX_THREAD_NUM];


unsigned long heartbeat_timeout=0;

/*************************************************
Function:        // sftp_init
Description:     // 初始化
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void sftp_init()
{
	int i;
	
	logMessage("The sftp module is starting....\n");
	printfInColor("The sftp module is starting....\n",4);
	
	debug_init(1);
	iptrans_init();
	snmp_init(4957);
	//heartbeat_init(0);
	
	//Get the conf info from the NR.conf file
	initNRConf();
	
	//Init the database connection
	initDatabase();
	
	//Init the Directory
	initDirectory();
	
	//Init the server information update time
	g_hpmn_update_timeout=HPMN_INFO_UPDATE_TIME;
	
	
	//Init the server keys
	hpmnServersInfoUpdate();
	
	//Init the fileVector,these stand for 100 thread
	for(i=0;i<MAX_THREAD_NUM;i++)
	{
		sprintf(fileVector[i],"NoFile");
		threads[i]=0;
	}	
	
	//Init the curFileIndex of every file transfer object,-1 stand for no file
	for(i=0;i<MAX_FILE_TRANSFER_NUM;i++)
	{
		file_transfers[i].curFileIndex=-1;
		file_transfers[i].waitTime=10;
	}
	
	heartbeat_timeout=time(NULL);
	
}

/*************************************************
Function:        // initNRConf
Description:     // Get the information in file NR.conf 
Calls:           // 
Called By:       // nrtrdeInit;
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // SUCCESSFUL; FAIL;
Others:          // 
*************************************************/
int initNRConf(void)
{
	char fileName[512];
	char message[512];
	unsigned char buf[4096];
	unsigned char param[32][512];
	char paramName[128];
	char paramValue[384];
	char* temp;
	FILE* fp;
	int fi;
	int i;
	//int j;
	int paramCount;
	int byteCount;
	
	paramCount=0;
	byteCount=0;
	memset(buf,0,4096);
	memset(param,0,32*512);
	sprintf(fileName,"./conf/NR.conf");
	fp=fopen(fileName,"r");
	if(fp)
	{
		sprintf(message,"Read the NR.conf\n");
		logMessage(message);
		printfInColor(message,6);
		
		fi=fileno(fp);
		if(read(fi,buf,4096))
		{
			for(i=0;i<4096;i++)
			{
				
				if(buf[i] == 0x0A)
				{
					//printf("\n");
					if(byteCount<512 && param[paramCount][0] != 0x00 && param[paramCount][0] != 0x23)
						paramCount++;
					else
						memset(param[paramCount],0,512);	
					byteCount=0;
				}	
				else
				{	
					param[paramCount][byteCount]=buf[i];
					byteCount++;
				}
				
				//printf("%02x ",buf[i]);
			}
			/*for test
			printf("\n=================================\n");
			printf("paramCount=%d\n",paramCount);
			for(i=0;i<paramCount;i++)
			{
				for(j=0;j<512;j++)
				{
					printf("%02x ",param[i][j]);
				}
				printf("\n");
			}
			*/
			
			sprintf(message,"==================================================\n");
			logMessage(message);
			printfInColor(message,0);
			
			for(i=0;i<paramCount;i++)
			{
				temp=strtok((char*)param[i],"=");
				sprintf(paramName,"%s",temp);
				//printf("Name=%s,",temp);
				temp=strtok(NULL,"=");
				sprintf(paramValue,"%s",temp);
				//printf("Value=%s\n",temp);
				

				if(strcasecmp(paramName,"NR_RECV_BAK_DIR") == 0)
				{
					sprintf(NR_RECV_BAK_DIR,"%s",paramValue);
				}	
				else if(strcasecmp(paramName,"NR_SEND_BAK_DIR") == 0)
				{
					sprintf(NR_SEND_BAK_DIR,"%s",paramValue);
				}	
				else if(strcasecmp(paramName,"ND_RECV_BAK_DIR") == 0)
				{
					sprintf(ND_RECV_BAK_DIR,"%s",paramValue);
				}	
				else if(strcasecmp(paramName,"ND_SEND_BAK_DIR") == 0)
				{
					sprintf(ND_SEND_BAK_DIR,"%s",paramValue);
				}
				else if(strcasecmp(paramName,"NE_RECV_BAK_DIR") == 0)
				{
					sprintf(NE_RECV_BAK_DIR,"%s",paramValue);
				}
				else if(strcasecmp(paramName,"NE_SEND_BAK_DIR") == 0)
				{
					sprintf(NE_SEND_BAK_DIR,"%s",paramValue);
				}
				else if(strcasecmp(paramName,"LOCAL_CSV_DIR") == 0)
				{
					sprintf(LOCAL_CSV_DIR,"%s",paramValue);
				}
				else if(strcasecmp(paramName,"SEND_DIR") == 0)
				{
					sprintf(SEND_DIR,"%s",paramValue);
				}	
				else if(strcasecmp(paramName,"RECV_DIR") == 0)
				{
					sprintf(RECV_DIR,"%s",paramValue);
				}	

				sprintf(message,"%s=%s\n",paramName,paramValue);
				logMessage(message);
				printfInColor(message,0);
			}
			sprintf(message,"==================================================\n");
			logMessage(message);
			printfInColor(message,0);
			
		}	
		close(fi);
		fclose(fp);
	}	
	else
	{
		sprintf(message,"Fatal Error: The NR.conf does not exist!\n");
		logMessage(message);
		printfInColor(message,1);
		printf("%s",message);
		exitLog("sftpSend:initNRConf, The NR.conf does not exist");
		exit(1);
	}		
	
	return SUCCESSFUL;
}

int getCdrConf(FileTransfer *fileTransfer,int *file_object_count)
{
	char sqlstr[512];
	int len;
	MYSQL_RES *res;
	MYSQL_ROW row;
	char cdr_local[128];
	char cdr_sent[128];
	char serverinfo[128];
	char *username,*pwd,*serverip,*remotepath,*pchr;
	
	//获得CDR_DB.cdrPubVarConf表中sending_directory的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM CDR_DB.cdrPubVarConf WHERE pubVarName='sending_directory'");
	
	res=mysql_getres(g_omcPubConn,sqlstr);
	if(res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s",mysql_errno(g_omcPubConn),sqlstr);
		return 1;
	}
	if((row = mysql_fetch_row(res)) != NULL) 
	{
		strcpy(cdr_local,row[0]);
	}
	mysql_free_result(res);
	
	len = strlen(cdr_local);
	if (cdr_local[len-1] != '/'&&len<127){
		cdr_local[len]='/';
		cdr_local[len+1]='\0';
	}	
	
	
	//获得CDR_DB.cdrPubVarConf表中sent_directory的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM CDR_DB.cdrPubVarConf WHERE pubVarName='sent_directory'");
			
	res=mysql_getres(g_omcPubConn,sqlstr);
	if(res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s",mysql_errno(g_omcPubConn),sqlstr);
		return 1;
	}
	if((row = mysql_fetch_row(res)) != NULL) 
	{
		strcpy(cdr_sent,row[0]);
	}
	mysql_free_result(res);
	
	len = strlen(cdr_sent);
	if (cdr_sent[len-1] != '/'&&len<127){
		cdr_sent[len]='/';
		cdr_sent[len+1]='\0';
	}	
	
	//**********************************************	
	//获取OMC_PUB.omcPubVarConf表中cdr_store_server的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM OMC_PUB.omcPubVarConf WHERE pubVarName='cdr_store_server'");
	
	res=mysql_getres(g_omcPubConn,sqlstr);
	if(res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s",mysql_errno(g_omcPubConn),sqlstr);
		return 1;
	}
	if((row = mysql_fetch_row(res)) != NULL) 
	{
		strcpy(serverinfo,row[0]);
	}
	mysql_free_result(res);
	
	//user:password@ip>location
	
	len = strlen(serverinfo);
	if(len>5)
	{
		if (serverinfo[len-1] != '/'&&len<127)
		{
			serverinfo[len]='/';
			serverinfo[len+1]='\0';
		}	
		
		//ftp登陆用户名
		username = serverinfo;
		if((pchr = strstr(serverinfo, ":"))==NULL){
			logMessage("[ERROR]cdr_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';
		
		//ftp登陆密码
		pwd = pchr;		
		if((pchr = strstr(pwd, "@"))==NULL){
			logMessage("[ERROR]cdr_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';
		
		//ftp服务器IP地址
		serverip = pchr;//get password
		if((pchr = strstr(serverip, ">"))==NULL){
			logMessage("[ERROR]cdr_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';
		
		//将要发送到远程服务器的目录
		remotepath = pchr;
		
		
		//Get the srcDir
		sprintf(file_transfers[*file_object_count].srcDir,"%s",cdr_local);
		//Get the dstDir
		sprintf(file_transfers[*file_object_count].dstDir,"%s",remotepath);
		//Get the dstIP
		sprintf(file_transfers[*file_object_count].dstIP,"%s",serverip);
		//Get the filter
		sprintf(file_transfers[*file_object_count].filter,"csv");
		//Get the loginName
		sprintf(file_transfers[*file_object_count].logName,"%s",username);
		//Get the loginPass
		sprintf(file_transfers[*file_object_count].logPass,"%s",pwd);
		
		
		printfFileObject(&file_transfers[*file_object_count]);
		if(*file_object_count == (MAX_FILE_TRANSFER_NUM-1))
			logMessage("file_object_count is too much");
		(*file_object_count)++;
	}
		
	return 0;
}

// Zed baicells requirement, by simon ---
int getdailycdrConf(FileTransfer *fileTransfer, int *file_object_count)
{
	char sqlstr[512];
	int len;
	MYSQL_RES *res;
	MYSQL_ROW row;
	char cdr_local[128];
	char cdr_sent[128];
	char serverinfo[128];
	char *username, *pwd, *serverip, *remotepath, *pchr;

	// 获得CDR_DB.cdrPubVarConf表中sending_directory的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM CDR_DB.cdrPubVarConf WHERE pubVarName='dailycdr_sending_directory'");

	res = mysql_getres(g_omcPubConn, sqlstr);
	if (res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s", mysql_errno(g_omcPubConn), sqlstr);
		return 1;
	}
	if ((row = mysql_fetch_row(res)) != NULL)
	{
		strcpy(cdr_local, row[0]);
	}
	mysql_free_result(res);

	len = strlen(cdr_local);
	if (cdr_local[len - 1] != '/' && len < 127)
	{
		cdr_local[len] = '/';
		cdr_local[len + 1] = '\0';
	}

	// 获得CDR_DB.cdrPubVarConf表中sent_directory的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM CDR_DB.cdrPubVarConf WHERE pubVarName='dailycdr_sent_directory'");

	res = mysql_getres(g_omcPubConn, sqlstr);
	if (res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s", mysql_errno(g_omcPubConn), sqlstr);
		return 1;
	}
	if ((row = mysql_fetch_row(res)) != NULL)
	{
		strcpy(cdr_sent, row[0]);
	}
	mysql_free_result(res);

	len = strlen(cdr_sent);
	if (cdr_sent[len - 1] != '/' && len < 127)
	{
		cdr_sent[len] = '/';
		cdr_sent[len + 1] = '\0';
	}

	//**********************************************
	// 获取OMC_PUB.omcPubVarConf表中cdr_store_server的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM OMC_PUB.omcPubVarConf WHERE pubVarName='dailycdr_store_server'");

	res = mysql_getres(g_omcPubConn, sqlstr);
	if (res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s", mysql_errno(g_omcPubConn), sqlstr);
		return 1;
	}
	if ((row = mysql_fetch_row(res)) != NULL)
	{
		strcpy(serverinfo, row[0]);
	}
	mysql_free_result(res);

	// user:password@ip>location

	len = strlen(serverinfo);
	if (len > 5)
	{
		if (serverinfo[len - 1] != '/' && len < 127)
		{
			serverinfo[len] = '/';
			serverinfo[len + 1] = '\0';
		}

		// ftp登陆用户名
		username = serverinfo;
		if ((pchr = strstr(serverinfo, ":")) == NULL)
		{
			logMessage("[ERROR]cdr_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';

		// ftp登陆密码
		pwd = pchr;
		if ((pchr = strstr(pwd, "@")) == NULL)
		{
			logMessage("[ERROR]cdr_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';

		// ftp服务器IP地址
		serverip = pchr; // get password
		if ((pchr = strstr(serverip, ">")) == NULL)
		{
			logMessage("[ERROR]cdr_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';

		// 将要发送到远程服务器的目录
		remotepath = pchr;

		// Get the srcDir
		sprintf(file_transfers[*file_object_count].srcDir, "%s", cdr_local);
		// Get the dstDir
		sprintf(file_transfers[*file_object_count].dstDir, "%s", remotepath);
		// Get the dstIP
		sprintf(file_transfers[*file_object_count].dstIP, "%s", serverip);
		// Get the filter
		sprintf(file_transfers[*file_object_count].filter, "csv");
		// Get the loginName
		sprintf(file_transfers[*file_object_count].logName, "%s", username);
		// Get the loginPass
		sprintf(file_transfers[*file_object_count].logPass, "%s", pwd);

		printfFileObject(&file_transfers[*file_object_count]);
		if (*file_object_count == (MAX_FILE_TRANSFER_NUM - 1))
			logMessage("file_object_count is too much");
		(*file_object_count)++;
	}

	return 0;
}
// ---end

int getCstaConf(FileTransfer *fileTransfer,int *file_object_count)
{
	char sqlstr[512];
	int len;
	MYSQL_RES *res;
	MYSQL_ROW row;
	char csta_local[128];
	char csta_sent[128];
	char serverinfo[128];
	char *username,*pwd,*serverip,*remotepath,*pchr;
	
	//获得CSTA_DB.cstaPubVarConf表中sending_directory的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM CSTA_DB.cstaPubVarConf WHERE pubVarName='sending_directory'");

	res=mysql_getres(g_omcPubConn,sqlstr);
	if(res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s",mysql_errno(g_omcPubConn),sqlstr);
		return 1;
	}
	if((row = mysql_fetch_row(res)) != NULL) 
	{
		strcpy(csta_local,row[0]);
	}
	mysql_free_result(res);
	
	len = strlen(csta_local);
	
	if (csta_local[len-1] != '/'&&len<127){
		csta_local[len]='/';
		csta_local[len+1]='\0';
	}	
	
	//获得CSTA_DB.cstaPubVarConf表中sent_directory的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM CSTA_DB.cstaPubVarConf WHERE pubVarName='sent_directory'");
	
	res=mysql_getres(g_omcPubConn,sqlstr);
	if(res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s",mysql_errno(g_omcPubConn),sqlstr);
		return 1;
	}	
	if((row = mysql_fetch_row(res)) != NULL) 
	{
		strcpy(csta_sent,row[0]);
	}
	mysql_free_result(res);
		
	len = strlen(csta_sent);
	if (csta_sent[len-1] != '/'&&len<127){
		csta_sent[len]='/';
		csta_sent[len+1]='\0';
	}
	
	//获取OMC_PUB.omcPubVarConf表中csta_store_server的值
	sprintf(sqlstr,
			"SELECT pubVarValue FROM OMC_PUB.omcPubVarConf WHERE pubVarName='csta_store_server'");
				
	res=mysql_getres(g_omcPubConn,sqlstr);
	if(res == NULL)
	{
		logMessage("[ERR %d][send_init]:%s",mysql_errno(g_omcPubConn),sqlstr);
		return 1;
	}
	if((row = mysql_fetch_row(res)) != NULL) 
	{
		strcpy(serverinfo,row[0]);
	}
	mysql_free_result(res);
	
	//user:password@ip>location
	
	len = strlen(serverinfo);
	if(len>5)
	{	
		if (serverinfo[len-1] != '/'&&len<127){
			serverinfo[len]='/';
			serverinfo[len+1]='\0';
		}	
		
		//ftp登陆用户名
		username = serverinfo;
		if((pchr = strstr(serverinfo, ":"))==NULL){
			logMessage("[ERROR]csta_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';
		
		//ftp登陆密码
		pwd = pchr;		
		if((pchr = strstr(pwd, "@"))==NULL){
			logMessage("[ERROR]csta_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';
		
		//ftp服务器IP地址
		serverip = pchr;//get password
		if((pchr = strstr(serverip, ">"))==NULL){
			logMessage("[ERROR]csta_store_server param error!\n");
			return 1;
		}
		*(pchr++) = '\0';
		
		//将要发送到远程服务器的目录
		remotepath = pchr;
		
		//Get the srcDir
		sprintf(file_transfers[*file_object_count].srcDir,"%s",csta_local);
		//Get the dstDir
		sprintf(file_transfers[*file_object_count].dstDir,"%s",remotepath);
		//Get the dstIP
		sprintf(file_transfers[*file_object_count].dstIP,"%s",serverip);
		//Get the filter
		sprintf(file_transfers[*file_object_count].filter,"csv");
		//Get the loginName
		sprintf(file_transfers[*file_object_count].logName,"%s",username);
		//Get the loginPass
		sprintf(file_transfers[*file_object_count].logPass,"%s",pwd);
		
		
		printfFileObject(&file_transfers[*file_object_count]);
		if(*file_object_count == (MAX_FILE_TRANSFER_NUM-1))
			logMessage("file_object_count is too much");
		(*file_object_count)++;
	}
		
	return 0;
}
/*************************************************
Function:        // logMessage
Description:     // 往日志文件写信息
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // fmt:信息
Output:          // 
Return:          // 
Others:          //
*************************************************/
void logMessage(const char *fmt,...)
{
	char logFile[64];
	FILE *fp;
	time_t l_time;
	va_list ap;
	char buf[8192];
	struct tm *t;
	char timestr[64];
	
	l_time=time(NULL);
	t=localtime(&l_time);
	sprintf(logFile,"/usr/local/omc/log/sftp%04d%02d%02d.log",t->tm_year+1900,t->tm_mon+1,t->tm_mday);
	fp=fopen(logFile,"a");
	if(fp!=NULL)
	{
		va_start(ap,fmt);
		vsprintf(buf,fmt,ap);
		sprintf(timestr,"%02d:%02d:%02d: ",t->tm_hour,t->tm_min,t->tm_sec);
		fputs(timestr,fp);
		fputs(buf,fp);
		fputs("\n",fp);
		fflush(fp);
		va_end(ap);
		fclose(fp);
	}
}

/*************************************************
Function:        // sendFile
Description:     // Sent file to the remote HPMN server
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // remoteip: the ip of the remote server
										username: the login name
										userpass: the login password
										srcdir: the source directory to send the files
										filename: the file to be sent
										desdir: the destination directory to send the files
Output:          // 
Return:          // 0: successful; 
										1: the remote server is unavaliable
										2: the login username or password is not fit
										3: the local don't have the key of the remote server
										4: the login user don't have the permission to access the directory
Others:          // 
*************************************************/
int sendFile(char *remoteip, char *username, char *userpass, char *srcdir, char *filename, char *desdir,int fileIndex)
{
	char res;
	FILE *fp;
	char command[256];
	char message[256];
	char tempFile[16];
	
	//Use the expect script to send the file by sftp
	sprintf(command,"expect sendfile %s %s %s %s %s %s 1>/tmp/result%d.txt 2>/dev/null",remoteip,username,userpass,srcdir,filename,desdir,fileIndex);
	system(command);
	
	//Use the parseResult script to parse the result of sending file
	sprintf(command,"bash parseResult %d",fileIndex);
	system(command);

	sprintf(tempFile,"/tmp/temp%d.txt",fileIndex);
	fp=fopen(tempFile,"r");
	res=fgetc(fp)-48;
	fclose(fp);
	
	sprintf(command,"rm -rf /tmp/result%d.txt",fileIndex);
	system(command);
	//printf("SendFile()---The result is %d\n",res);
	
	if(res==0)
	{
		sprintf(message,"Send the %s to server-%s successfully\n",filename,remoteip);
		logMessage(message);
		printfInColor(message,4);
	}
	else if(res==1)
	{
		sprintf(message,"Send the %s failed, the remote server-%s is unavaliable\n",filename,remoteip);
		logMessage(message);
		printfInColor(message,1);
	}
	else if(res==2)
	{
		sprintf(message,"Send the %s failed, the login name or password is not correct to login server-%s\n",filename,remoteip);
		logMessage(message);
		printfInColor(message,1);
	}
	else if(res==3)
	{
		sprintf(message,"Send the %s failed, the local don not have the key of the remote server-%s\n",filename,remoteip);
		logMessage(message);
		printfInColor(message,1);
	}		
	else if(res==4)
	{
		sprintf(message,"Send the %s failed, the login user do not have the permission to access the remote server-%s destination directory\n",filename,remoteip);
		logMessage(message);
		printfInColor(message,1);
	}
	else
	{
		sprintf(message,"When send the %s to server-%s it happen to unrecognizable result\n",filename,remoteip);
		logMessage(message);
		printfInColor(message,1);
	}
	//printf("%s\n",message);
	sprintf(command,"rm -rf /tmp/temp%d.txt",fileIndex);
	system(command);
	
	return res;
}

/*************************************************
Function:        // sendHeartbeat
Description:     // Send process heartbeat to beatProc
Calls:           // snmp_send
Called By:       // on_Timer
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 1:OK; 0:Fail
Others:          // 
*************************************************/
int sendHeartbeat()
{
	snmp_pdu pdu;
	snmp_addr addr;
	char proc_name[16];
	
	memset(proc_name,0,16);
	sprintf(proc_name,"sftpSend");
	
	//pdu
	memset(&pdu,0,sizeof(snmp_pdu));
	pdu.pdu_type=7;
	pdu.request_id=0;
	sprintf(pdu.community,"public");
	pdu.var_num=1;
	pdu.error_status=0;
	pdu.error_index=0;
	
	//Addr
	addr.local_port = 4957;
	//addr.remote_ip = inet_addr("127.0.0.1");
	addr.remote_ip = GetLocalIP();
	addr.broadcast = 0;
	addr.remote_port = 4957;
	
	//Varlist
	memcpy(pdu.var[0].oid,PROC_HEARTBEAT_OID,PROC_HEARTBEAT_OIDLEN*sizeof(DWORD));

	pdu.var[0].oidlen=PROC_HEARTBEAT_OIDLEN;
	pdu.var[0].vartype=0x04;
	pdu.var[0].msglen=16;
	memcpy(pdu.var[0].msg,proc_name,16);
	
	if(snmp_send(&pdu, &addr) <= 0)
	{
		logMessage("Send heartbeat fail");
		return 0;
	}
	return 1;
}

/*************************************************
Function:        // sftpsend_timer
Description:     // 
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void sftpsend_timer()
{
	char message[256];
	int i;
	
	
	if(time(NULL) - heartbeat_timeout > 5)
	{
		heartbeat_timeout=time(NULL);
		sendHeartbeat();
		logMessage("Send HB");
	}

	//check and send the file to the remote server
	checkToSend();
	
	//check and send the normal file to the remote server
	checkToTransfer();
	
	//server information update time
	g_hpmn_update_timeout--;
	sprintf(message,"Update the HPMN infomation timeout=%d\n",g_hpmn_update_timeout);
	printfInColor(message,0);
	if(g_hpmn_update_timeout<0)
	{
		hpmnServersInfoUpdate();
		g_hpmn_update_timeout=HPMN_INFO_UPDATE_TIME;
	}	
	
	//update the servers timeslot
	for(i=0;i<g_hpmn_server_count;i++)
	{
		if(servers[i].timeSlot >= 0)
		{
			servers[i].timeSlot--;
		}	
	}
	

	

	
}

/*************************************************
Function:        // checkToSend
Description:     // Check the directory and to send file to remote
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // The 'SEND_DIR' define the source directory in the head file
*************************************************/
void checkToSend()
{
	int sendResult;										//the result of sending a file to remote
	char command[512];		  					//the command to send to the linux
	char message[512];
	long fileSize;
	int checkFlag;
	struct dirent* pDirEnt;
	struct stat fileStat;
	DIR* srcDir;
	char tmpFileName[512];
	char fullFileName[512];
	char recipientTadig[8];
	char senderTadig[8];
	int i;
	int mustSend;
	int fileIndex;
	

	srcDir = opendir(SEND_DIR);
	if(srcDir==NULL)
	{	
		//printf("DIR NULL:%s\n",strerror(errno));
		return;
	}
	
	while((pDirEnt = readdir(srcDir))!=NULL)
	{
		//printf("pDirEnt=%ld\n",pDirEnt);
		if(strlen(pDirEnt->d_name)<3)
			continue;	
		//check the file name
		sprintf(tmpFileName,"%s",pDirEnt->d_name);	
		//printf("tmpFileName=%s\n",tmpFileName);
		
		//get the senderTadig
		memset(senderTadig,0,8);
		for(i=2;i<7;i++)
		{
			senderTadig[i-2]=tmpFileName[i];
		}
		senderTadig[i-2]='\0';
		//printf("senderTadig=%s\n",senderTadig);
		
		//get the recipientTadig
		memset(recipientTadig,0,8);
		for(i=7;i<12;i++)
		{
			recipientTadig[i-7]=tmpFileName[i];
		}
		recipientTadig[i-7]='\0';
		//printf("recipientTadig=%s\n",recipientTadig);
		
		checkFlag=0;
		sprintf(fullFileName,"%s%s",SEND_DIR,tmpFileName);
		do
		{
			stat(fullFileName,&fileStat);
			
			//the file size is stable
			if(checkFlag && fileSize==fileStat.st_size)
			{
				//printf("fullFileName=%s,fileSize=%ld\n",fullFileName,fileSize);
				//printf("tmpFileName=%s\n",tmpFileName);
				
				//if the file is NRTRDE file, then parse it
				if(tmpFileName[1] == 'R')
				{
					//send file to remote server	
					sendResult=-1;
					mustSend=0;
					for(i=0;i<g_hpmn_server_count;i++)
					{
						if(strcmp(servers[i].tadig,recipientTadig) == 0)
						{
							mustSend=1;
							if(servers[i].timeSlot<0)
							{
								if(checkFile(tmpFileName) == 0)
								{	
									if((fileIndex=addFile(tmpFileName)) >= 0)
										createSendTask(fileIndex);
								}	
						  }  
					    break;          
						}	
					}
	
					//send successfully or the file is not identified
					if(mustSend == 0)
					{	
						//backup the NRTRDE files
						//printf("senderTadig=%s,recipientTadig=%s,command=%s\n",senderTadig,recipientTadig,command);
						sprintf(command,"mv %s %s",fullFileName,NR_SEND_BAK_DIR);
						system(command);
						sprintf(message,"%s",command);
						logMessage(message);
						printfInColor(message,3);
					}	

					
				}
				//if the file is NRTRDE Delivery report, then backup it
				
				else if(tmpFileName[1] == 'D')
				{
					//send file to remote server	
					sendResult=-1;
					mustSend=0;
					for(i=0;i<g_hpmn_server_count;i++)
					{
						if(strcmp(servers[i].tadig,recipientTadig) == 0)
						{
							mustSend=1;
							if(servers[i].timeSlot<0)
							{
	
								if(checkFile(tmpFileName) == 0)
								{	
									if((fileIndex=addFile(tmpFileName)) >= 0)
										createSendTask(fileIndex);
								}	
						  }  
					    break;          
						}	
					}
	
					//send successfully or the file is not identified
					if(mustSend == 0)
					{	
						//backup the NRTRDE files
						//printf("senderTadig=%s,recipientTadig=%s,command=%s\n",senderTadig,recipientTadig,command);
						sprintf(command,"mv %s %s",fullFileName,ND_SEND_BAK_DIR);
						system(command);
						
						sprintf(message,"%s",command);
						logMessage(message);
						printfInColor(message,3);
					}	
					
				}
				//if the file is NRTRDE Error report, then backup it
				else if(tmpFileName[1] == 'E')
				{
					//send file to remote server	
					sendResult=-1;
					mustSend=0;
					for(i=0;i<g_hpmn_server_count;i++)
					{
						if(strcmp(servers[i].tadig,recipientTadig) == 0)
						{
							mustSend=1;
							if(servers[i].timeSlot<0)
							{
	
								if(checkFile(tmpFileName) == 0)
								{	
									if((fileIndex=addFile(tmpFileName)) >= 0)
										createSendTask(fileIndex);
								}	
						  }  
					    break;          
						}	
					}
	
					//send successfully or the file is not identified
					if(mustSend == 0)
					{	
						//backup the NRTRDE files
						//printf("senderTadig=%s,recipientTadig=%s,command=%s\n",senderTadig,recipientTadig,command);
						sprintf(command,"mv %s %s",fullFileName,NE_SEND_BAK_DIR);
						system(command);
						sprintf(message,"%s",command);
						logMessage(message);
						printfInColor(message,3);
					}	
					
				}
				break;			
			}	
			if(fileSize != fileStat.st_size)
			{	
				sleep(2);
			}	
			fileSize=fileStat.st_size;
			//printf("check the the file=%s,recipientTadig=%s,size=%ld\n",fullFileName,recipientTadig,fileSize);
			checkFlag=1;
		}while(stat(fullFileName,&fileStat)==0);
		break;
	}	
	closedir(srcDir);
}

/*************************************************
Function:        // checkToTransfer
Description:     // Check the directory and to send file to remote, for normal files
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void checkToTransfer()
{
	char message[512];
	char fileName[64];
	char fullFileName[256];
	char filter[32];
	struct dirent* pDirEnt;
	struct stat fileStat;
	DIR* srcDir;
	int fileIndex;
	long fileSize;
	int checkFlag;
	int fileObjIndex;
	
	
	for(fileObjIndex=0;fileObjIndex<g_file_transfer_count;fileObjIndex++)
	{
		if(file_transfers[fileObjIndex].curFileIndex!=-1 || file_transfers[fileObjIndex].waitTime-->0)
		{
			if(file_transfers[fileObjIndex].curFileIndex!=-1)
			{
				file_transfers[fileObjIndex].failTimeout--;
				if(file_transfers[fileObjIndex].failTimeout <= 0)
				{
					logMessage("%d,send %s consume too time\n",fileObjIndex,fileVector[file_transfers[fileObjIndex].curFileIndex]);
					deleteFile(fileVector[file_transfers[fileObjIndex].curFileIndex]);
					file_transfers[fileObjIndex].curFileIndex=-1;
				}
			}
			continue;
		}
		file_transfers[fileObjIndex].waitTime=10;	
		srcDir=opendir(file_transfers[fileObjIndex].srcDir);
		if(srcDir == NULL)
		{
			logMessage("[checkToTransfer]Can not open directory %s",file_transfers[fileObjIndex].srcDir);
			continue;
		}
		
		logMessage("check directory %s",file_transfers[fileObjIndex].srcDir);

		while((pDirEnt = readdir(srcDir))!=NULL)
		{
			if(strlen(pDirEnt->d_name)<3)
				continue;	
			sprintf(fileName,"%s",pDirEnt->d_name);
			if(strcmp("*",file_transfers[fileObjIndex].filter) != 0)
			{	
				sprintf(filter,".%s",file_transfers[fileObjIndex].filter);
				if(strstr(fileName,filter) == NULL)
					continue;
			}		
			
			sprintf(fullFileName,"%s%s",file_transfers[fileObjIndex].srcDir,fileName);
			
			checkFlag=0;
			
			do
			{
				stat(fullFileName,&fileStat);
				if(checkFlag && fileSize==fileStat.st_size)
				{
					if(checkFile(fullFileName) == 0)
					{	
						if((fileIndex=addFile(fullFileName)) >= 0)	
						{	
							sprintf(message,"prepare to send normal file=%s\n",fullFileName);
							logMessage(message);
							createSendTask(fileIndex);
							file_transfers[fileObjIndex].failTimeout=MAX_FAIL_TIMEOUT;
							file_transfers[fileObjIndex].curFileIndex=fileIndex;
							closedir(srcDir);
							return;
						}	
					}	
					break;
				}	
				if(fileSize != fileStat.st_size)
					sleep(2);
				
				fileSize=fileStat.st_size;
				checkFlag=1;
			}while(stat(fullFileName,&fileStat)==0);
			
		}	
		closedir(srcDir);
	}
	
	
}

/*************************************************
Function:        // hpmnServersInfoUpdate
Description:     // Update the HPMN servers information
Calls:           // initDatabase; printfHPMNServer;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 0:failed; 1:successful;
Others:          // This function will modify the 'g_hpmn_server_count' and 'servers' value
*************************************************/
int hpmnServersInfoUpdate()
{
	MYSQL_RES *res;
	MYSQL_ROW row;
	char sqlstr[256];
	char message[256];
	int server_count;
	int len;
	
	int file_object_count;

	
	sprintf(sqlstr,"SELECT * FROM OMC_PUB.hpmnConf");
	
	res=mysql_getres(g_omcPubConn,sqlstr);
	if(res == NULL)
	{
		sprintf(message,"[ERR %d][hpmnServersInfoUpdate]:%s",mysql_errno(g_omcPubConn),sqlstr);
		logMessage(message);
		return FAIL;
	}
	
	//Update the HPMN servers information
	server_count=0;
	while((row = mysql_fetch_row(res)) != NULL)
	{
		//Get the mcc
		sprintf(servers[server_count].mcc,"%s",row[0]);
		//Get the mnc
		sprintf(servers[server_count].mnc,"%s",row[1]);
		//Get the tadig
		sprintf(servers[server_count].tadig,"%s",row[2]);
		//Get the serverIP
		sprintf(servers[server_count].serverIP,"%s",row[3]);
		//Get the loginName
		sprintf(servers[server_count].loginName,"%s",row[4]);
		//Get the loginPass
		sprintf(servers[server_count].loginPass,"%s",row[5]);
		//Get the timeSlot,alway 0
		servers[server_count].timeSlot=0;
		//Get the reportDir
		sprintf(servers[server_count].reportDir,"%s",row[7]);
		//Get the nrtrdeDir
		sprintf(servers[server_count].nrtrdeDir,"%s",row[8]);
		
		len = strlen(servers[server_count].reportDir);
		if (servers[server_count].reportDir[len-1] != '/'&&len<127)
		{
			servers[server_count].reportDir[len]='/';
			servers[server_count].reportDir[len+1]='\0';
		}
		
		len = strlen(servers[server_count].nrtrdeDir);
		if (servers[server_count].nrtrdeDir[len-1] != '/'&&len<127)
		{
			servers[server_count].nrtrdeDir[len]='/';
			servers[server_count].nrtrdeDir[len+1]='\0';
		}
		printfHPMNServer(&servers[server_count]);
		server_count++;
	}
	//Update the server count
	g_hpmn_server_count=server_count;
	//Free the database resource
	mysql_free_result(res);
	
	
	
	//Update the file transfer object from the OMC_PUB.fileTransConf
	sprintf(sqlstr,"SELECT srcDir,dstDir,dstIP,filter,logName,logPass FROM OMC_PUB.fileTransConf where type=1");
	
	res=mysql_getres(g_omcPubConn,sqlstr);
	if(res == NULL)
	{
		sprintf(message,"[ERR %d][hpmnServersInfoUpdate]:%s",mysql_errno(g_omcPubConn),sqlstr);
		logMessage(message);
		return FAIL;
	}
	
	//Update the HPMN servers information
	file_object_count=0;
	while((row = mysql_fetch_row(res)) != NULL)
	{
		//Get the srcDir
		sprintf(file_transfers[file_object_count].srcDir,"%s",row[0]);
		//Get the dstDir
		sprintf(file_transfers[file_object_count].dstDir,"%s",row[1]);
		//Get the dstIP
		sprintf(file_transfers[file_object_count].dstIP,"%s",row[2]);
		//Get the filter
		sprintf(file_transfers[file_object_count].filter,"%s",row[3]);
		//Get the loginName
		sprintf(file_transfers[file_object_count].logName,"%s",row[4]);
		//Get the loginPass
		sprintf(file_transfers[file_object_count].logPass,"%s",row[5]);
		
		
		len = strlen(file_transfers[file_object_count].srcDir);
		if(file_transfers[file_object_count].srcDir[len-1] != '/'&&len<127)
		{
			file_transfers[file_object_count].srcDir[len]='/';
			file_transfers[file_object_count].srcDir[len+1]='\0';
		}
		
		len = strlen(file_transfers[file_object_count].dstDir);
		if (file_transfers[file_object_count].dstDir[len-1] != '/'&&len<127)
		{
			file_transfers[file_object_count].dstDir[len]='/';
			file_transfers[file_object_count].dstDir[len+1]='\0';
		}
		printfFileObject(&file_transfers[file_object_count]);
		if(file_object_count == (MAX_FILE_TRANSFER_NUM-1))
			break;
		file_object_count++;
		
	}
	//get the csta and cdr send conf
	getCdrConf(file_transfers,&file_object_count);
	getCstaConf(file_transfers,&file_object_count);
	// Zed baicells requirement, by simon ---
	getdailycdrConf(file_transfers, &file_object_count);
	// --- end

		// Update the server count
		g_file_transfer_count = file_object_count;
	//printf("g_file_transfer_count=%d\n",g_file_transfer_count);
	//Free the database resource
	mysql_free_result(res);
	
	return SUCCESSFUL;
}

/*************************************************
Function:        // initDatabase
Description:     // Connection the OMC_PUB, CDR_DB databases
Calls:           // 
Called By:       // hpmnServersInfoUpdate;
Table Accessed:  // OMC_PUB.hpmnConf
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 0:failed; 1:successful;
Others:          // 
*************************************************/
int initDatabase()
{

	//Init the OMC_PUB database connection
	g_omcPubConn=mysql_conn("localhost","OMC_PUB");
	if(g_omcPubConn == NULL)
	{
		printf("[ERR][initDatabase]:mysql_conn OMC_PUB");
		return FAIL;
	}
		
	g_cdrConn=mysql_conn("localhost","CDR_DB");
	if(g_cdrConn == NULL)
	{
		printf("[ERR][initDatabase]:mysql_conn CDR_DB");
		return FAIL;
	}
	
	return SUCCESSFUL;
}

/*************************************************
Function:        // printfInColor
Description:     // Print the message in specific color to the standand output
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // message:the message to print; color:the color in printing
Output:          // 
Return:          // 
Others:          // For test,only the NRTRDE_DEBUG flag is open when it show the debug infomation
*************************************************/
void printfInColor(char *message,int color)
{
	
#if SFTP_DEBUG

	if(message==NULL)
		return;
	switch(color)
	{
		//white
		case 0:
			printf("\033[37m%s",message);
			break;
		//red	
		case 1:
			printf("\033[31m%s",message);
			break;
		//green
		case 2:
			printf("\033[32m%s",message);
			break;
		//yellow
		case 3:
			printf("\033[33m%s",message);	
			break;
		//blue
		case 4:
			printf("\033[34m%s",message);		
			break;
		//light green
		case 5:	
			printf("\033[36m%s",message);
			break;
		//pink	
		case 6:
			printf("\033[35m%s",message);
			break;
		//white	
		default:
			printf("\033[37m%s",message);			
	}	
	printf("\033[37m");
#endif	
}

/*************************************************
Function:        // printfHPMNServer
Description:     // Print the information of the specific HPMN server
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // server:the HPMN server to print
Output:          // 
Return:          // 
Others:          // This funtion is for test
*************************************************/
void printfHPMNServer(HpmnServer* server)
{
#if SFTP_DEBUG
	printf("=======================================\n");
	printf("tadig=%s\n",server->tadig);
	printf("mcc=%s\n",server->mcc);
	printf("mnc=%s\n",server->mnc);
	printf("serverIP=%s\n",server->serverIP);
	printf("loginName=%s\n",server->loginName);
	printf("loginPass=%s\n",server->loginPass);
	printf("timeSlot=%d\n",server->timeSlot);
	printf("reportDir=%s\n",server->reportDir);
	printf("nrtrdeDir=%s\n",server->nrtrdeDir);
	printf("\tsendFileTimeout=%d\n",server->sendFileTimeout);
	printf("=======================================\n");
#endif	
}

/*************************************************
Function:        // printfFileObject
Description:     // Print the information of the specific file transfer object
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // ft:the file transfer object to print
Output:          // 
Return:          // 
Others:          // This funtion is for test
*************************************************/
void printfFileObject(FileTransfer* ft)
{
#if SFTP_DEBUG
	printf("=======================================\n");
	printf("srcDir=%s\n",ft->srcDir);
	printf("dstDir=%s\n",ft->dstDir);
	printf("dstIP=%s\n",ft->dstIP);
	printf("filter=%s\n",ft->filter);
	printf("logName=%s\n",ft->logName);
	printf("logPass=%s\n",ft->logPass);
	printf("=======================================\n");
#endif		
}

/*************************************************
Function:        // initDirectory
Description:     // Make the directory for the module
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void initDirectory()
{
	char oldDir[512];
	char message[512];
	char command[512];
	
	getcwd(oldDir,512);

	//make SEND_DIR
	if(chdir(SEND_DIR) == -1)
	{
		chdir(oldDir);
		sprintf(command,"mkdir -p -m755 %s",SEND_DIR);
		system(command);
		sprintf(message,"Make directory SEND_DIR=%s\n",SEND_DIR);
		logMessage(message);
		printfInColor(message,3);
		if(chdir(SEND_DIR) == -1)
		{
			chdir(oldDir);
			sprintf(message,"Make directory SEND_DIR=%s failed\n",SEND_DIR);
			logMessage(message);
			printfInColor(message,3);
			exitLog("sftpSend:initDirectory, Make directory SEND_DIR=%s failed",SEND_DIR);
			exit(1);
		}	
	}	
	
	//make RECV_DIR
	if(chdir(RECV_DIR) == -1)
	{
		chdir(oldDir);
		sprintf(command,"mkdir -p -m755 %s",RECV_DIR);
		system(command);
		sprintf(message,"Make directory RECV_DIR=%s\n",RECV_DIR);
		logMessage(message);
		printfInColor(message,3);
		if(chdir(RECV_DIR) == -1)
		{
			chdir(oldDir);
			sprintf(message,"Make directory RECV_DIR=%s failed\n",RECV_DIR);
			logMessage(message);
			printfInColor(message,3);
			exitLog("sftpSend:initDirectory, Make directory RECV_DIR=%s failed\n",RECV_DIR);
			exit(1);
		}	
	}
	
	//make NR_RECV_BAK_DIR
	if(chdir(NR_RECV_BAK_DIR) == -1)
	{
		chdir(oldDir);
		sprintf(command,"mkdir -p -m755 %s",NR_RECV_BAK_DIR);
		system(command);
		sprintf(message,"Make directory NR_RECV_BAK_DIR=%s\n",NR_RECV_BAK_DIR);
		logMessage(message);
		printfInColor(message,3);
		if(chdir(NR_RECV_BAK_DIR) == -1)
		{
			chdir(oldDir);
			sprintf(message,"Make directory NR_RECV_BAK_DIR=%s failed\n",NR_RECV_BAK_DIR);
			logMessage(message);
			printfInColor(message,3);
			exitLog("sftpSend:initDirectory, Make directory NR_RECV_BAK_DIR=%s failed",NR_RECV_BAK_DIR);
			exit(1);
		}	
	}
	
	//make NR_SEND_BAK_DIR
	if(chdir(NR_SEND_BAK_DIR) == -1)
	{
		chdir(oldDir);
		sprintf(command,"mkdir -p -m755 %s",NR_SEND_BAK_DIR);
		system(command);
		sprintf(message,"Make directory NR_SEND_BAK_DIR=%s\n",NR_SEND_BAK_DIR);
		logMessage(message);
		printfInColor(message,3);
		if(chdir(NR_SEND_BAK_DIR) == -1)
		{
			chdir(oldDir);
			sprintf(message,"Make directory NR_SEND_BAK_DIR=%s failed\n",NR_SEND_BAK_DIR);
			logMessage(message);
			printfInColor(message,3);
			exitLog("sftpSend:initDirectory, Make directory NR_SEND_BAK_DIR=%s failed",NR_SEND_BAK_DIR);
			exit(1);
		}	
	}
	
	//make ND_RECV_BAK_DIR
	if(chdir(ND_RECV_BAK_DIR) == -1)
	{
		chdir(oldDir);
		sprintf(command,"mkdir -p -m755 %s",ND_RECV_BAK_DIR);
		system(command);
		sprintf(message,"Make directory ND_RECV_BAK_DIR=%s\n",ND_RECV_BAK_DIR);
		logMessage(message);
		printfInColor(message,3);
		if(chdir(ND_RECV_BAK_DIR) == -1)
		{
			chdir(oldDir);
			sprintf(message,"Make directory ND_RECV_BAK_DIR=%s failed\n",ND_RECV_BAK_DIR);
			logMessage(message);
			printfInColor(message,3);
			exitLog("sftpSend:initDirectory, Make directory ND_RECV_BAK_DIR=%s failed",ND_RECV_BAK_DIR);
			exit(1);
		}	
	}
	
	//make ND_SEND_BAK_DIR
	if(chdir(ND_SEND_BAK_DIR) == -1)
	{
		chdir(oldDir);
		sprintf(command,"mkdir -p -m755 %s",ND_SEND_BAK_DIR);
		system(command);
		sprintf(message,"Make directory ND_SEND_BAK_DIR=%s\n",ND_SEND_BAK_DIR);
		logMessage(message);
		printfInColor(message,3);
		if(chdir(ND_SEND_BAK_DIR) == -1)
		{
			chdir(oldDir);
			sprintf(message,"Make directory ND_SEND_BAK_DIR=%s failed\n",ND_SEND_BAK_DIR);
			logMessage(message);
			printfInColor(message,3);
			exitLog("sftpSend:initDirectory, Make directory ND_SEND_BAK_DIR=%s failed",ND_SEND_BAK_DIR);
			exit(1);
		}	
	}
	
	//make NE_RECV_BAK_DIR
	if(chdir(NE_RECV_BAK_DIR) == -1)
	{
		chdir(oldDir);
		sprintf(command,"mkdir -p -m755 %s",NE_RECV_BAK_DIR);
		system(command);
		sprintf(message,"Make directory NE_RECV_BAK_DIR=%s\n",NE_RECV_BAK_DIR);
		logMessage(message);
		printfInColor(message,3);
		if(chdir(NE_RECV_BAK_DIR) == -1)
		{
			chdir(oldDir);
			sprintf(message,"Make directory NE_RECV_BAK_DIR=%s failed\n",NE_RECV_BAK_DIR);
			logMessage(message);
			printfInColor(message,3);
			exitLog("sftpSend:initDirectory, Make directory NE_RECV_BAK_DIR=%s failed",NE_RECV_BAK_DIR);
			exit(1);
		}	
	}
	
	//make ND_SEND_BAK_DIR
	if(chdir(NE_SEND_BAK_DIR) == -1)
	{
		chdir(oldDir);
		sprintf(command,"mkdir -p -m755 %s",NE_SEND_BAK_DIR);
		system(command);
		sprintf(message,"Make directory NE_SEND_BAK_DIR=%s\n",NE_SEND_BAK_DIR);
		logMessage(message);
		printfInColor(message,3);
		if(chdir(NE_SEND_BAK_DIR) == -1)
		{
			chdir(oldDir);
			sprintf(message,"Make directory NE_SEND_BAK_DIR=%s failed\n",NE_SEND_BAK_DIR);
			logMessage(message);
			printfInColor(message,3);
			exitLog("sftpSend:initDirectory, Make directory NE_SEND_BAK_DIR=%s failed",NE_SEND_BAK_DIR);
			exit(1);
		}	
	}
	chdir(oldDir);
	
}

/*************************************************
Function:        // deleteFile
Description:     // When the file is sent successfully, then delete the fileName in the fileVector
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file name to delete
Output:          // 
Return:          // 
Others:          // This function will change the value 'fileVector' 
*************************************************/
void deleteFile(char* fileName)
{
	int i;
	
	if(fileName == NULL)
		return;
	
	for(i=0;i<MAX_THREAD_NUM;i++)
	{
		if(strcmp(fileVector[i],fileName) == 0)
		{
			sprintf(fileVector[i],"NoFile");
			break;
		}	
	}	
	
}

/*************************************************
Function:        // addFile
Description:     // When the file is sending, then add it in fileVector for not sending it againg
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file name to add
Output:          // 
Return:          // 
Others:          // This function will change the value 'fileVector' 
*************************************************/
int addFile(char* fileName)
{
	int i;
	
	if(fileName == NULL)
		return -1;
	
	for(i=0;i<MAX_THREAD_NUM;i++)
	{
		if(strcmp(fileVector[i],"NoFile") == 0)
		{
			sprintf(fileVector[i],"%s",fileName);
			return i;
		}	
	}	
	
	return -1;
}

/*************************************************
Function:        // checkFile
Description:     // Check whether the file is in the fileVector
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file name to add
Output:          // 
Return:          // 1:exist; 0:no exist;
Others:          // This function will access the value 'fileVector' 
*************************************************/
int checkFile(char* fileName)
{
	int i;
	
	if(fileName == NULL)
		return 0;
	
	for(i=0;i<MAX_THREAD_NUM;i++)
	{
		if(strcmp(fileVector[i],fileName) == 0)
		{
			return 1;
		}	
	}	
	
	return 0;
	
}

/*************************************************
Function:        // createSendTask
Description:     // Create a new thread for send the file
Calls:           // sendTask;
Called By:       // checkToSend;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file name to send
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void createSendTask(int fileIndex)
{
	pthread_t id;
	int ret;
	char message[256];
	
	
	ret=pthread_create(&id,NULL,(void *) sendTask, (void *)fileIndex);
	threads[fileIndex]=id;
	
	//printf("Create thread id=%ld\n",id);
	
	if(ret!=0)
	{
		sprintf(message,"Create pthread error!\n");
		logMessage(message);
		printfInColor(message,1);
	}
	
	
	
}

/*************************************************
Function:        // sendTask
Description:     // The task to send a file
Calls:           // 
Called By:       // createSendTask;
Table Accessed:  // 
Table Updated:   // 
Input:           // fileName:the file name to send
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void sendTask(int fileIndex)
{
	char tmpFileName[256];
	char senderTadig[8];
	char message[256];
	char command[512];
	char recipientTadig[8];
	int i;
	int serverIndex;
	int sendResult;
	char *np;
	
	
	
	sprintf(tmpFileName,"%s",fileVector[fileIndex]);
	
	//send the normal files, not nrtrde files
	if(strchr(tmpFileName,0x2f) != NULL)
	{
		for(i=0;i<g_file_transfer_count;i++)
		{
			if(file_transfers[i].curFileIndex == fileIndex)
			{
				sendResult=-1;
				np=strrchr(tmpFileName,0x2f)+1;
				sendResult=sendFile(file_transfers[i].dstIP,
								    file_transfers[i].logName,
								    file_transfers[i].logPass,
								    file_transfers[i].srcDir,
								    np,
								    file_transfers[i].dstDir,
								    fileIndex);
								         		    
				//send file successfully
				if(sendResult == 0)
				{
					sprintf(message,"send normal file=%s successfully\n",tmpFileName);
					logMessage(message);
					
					deleteFile(tmpFileName);		
					sprintf(command,"rm -rf %s",tmpFileName);
					
					system(command);
					sprintf(message,"%s\n",command);
					logMessage(message);
					printfInColor(message,3);
					
				}	
				//send file failed
				else
				{
					sprintf(message,"send normal file=%s failed\n",tmpFileName);
					logMessage(message);
					deleteFile(tmpFileName);
				}	
				file_transfers[i].curFileIndex=-1;
				break;
			}	
		}
	}	
	else
	{

		memset(senderTadig,0,8);
		for(i=2;i<7;i++)
		{
			senderTadig[i-2]=tmpFileName[i];
		}
		senderTadig[i-2]='\0';
		
		//get the recipientTadig
		memset(recipientTadig,0,8);
		for(i=7;i<12;i++)
		{
			recipientTadig[i-7]=tmpFileName[i];
		}
		recipientTadig[i-7]='\0';
		
		serverIndex=-1;
		for(i=0;i<g_hpmn_server_count;i++)
		{
			if(strcmp(recipientTadig,servers[i].tadig) == 0)
			{
				serverIndex=i;
				break;
			}	
		}
		
		if(serverIndex>=0)
		{	
				sprintf(message,"Prepare to send file=%s to %s\n",tmpFileName,recipientTadig);
				logMessage(message);
				printfInColor(message,3);
				
				sendResult=-1;
				sendResult=sendFile(servers[serverIndex].serverIP,
									          servers[serverIndex].loginName,
									          servers[serverIndex].loginPass,
									          SEND_DIR,
									          tmpFileName,
									          servers[serverIndex].nrtrdeDir,
									          fileIndex);
									         
									    
				//send file successfully
				if(sendResult == 0)
				{
					deleteFile(tmpFileName);
					//back up the file
					if(tmpFileName[1] == 'R')
					{
						sprintf(command,"mv %s%s %s",SEND_DIR,tmpFileName,NR_SEND_BAK_DIR);
					}	
					else if(tmpFileName[1] == 'D')
					{
						sprintf(command,"mv %s%s %s",SEND_DIR,tmpFileName,ND_SEND_BAK_DIR);
					}	
					else if(tmpFileName[1] == 'E')
					{
						sprintf(command,"mv %s%s %s",SEND_DIR,tmpFileName,NE_SEND_BAK_DIR);
					}
					
					
					//printf("command=%s\n",command);
					system(command);
					sprintf(message,"%s\n",command);
					logMessage(message);
					printfInColor(message,3);
					
				}	
				//send file failed
				else
				{
					deleteFile(tmpFileName);
					servers[i].timeSlot=WAIT_TIME;
				}	
		}
	}	
	
	for(i=0;i<MAX_THREAD_NUM;i++)
	{
		//printf("%d-fileName=%s,threadno=%ld\n",i,fileVector[i],threads[i]);
		if(strcmp(fileVector[i],"NoFile") == 0 && threads[i] != 0)
		{	
			pthread_detach(threads[i]);
			threads[i]=0;
		}	
	}
	
	pthread_exit(0);
	
	return;
}


