/*************************************************
File name:  beatSend.c
Author: 	Cui Ticun
Version:	9:00:00 
Date:  		2007-8-28
Description:该文件定义了发送EMS的Heartbeat的函数
			
			调用snmp模块的函数
			snmp_send();
			
												
History:               
No. 		
Author:		  
Date:		 
Version:	   
Description:
*************************************************/

#include "beatSend.h"
#include "string.h"

#if beatSend_DEBUG
	#include <mcheck.h>
#endif

#define BEATSEND_LOG "beatSend"

#define		MaxOidLen			20
#define		trapMsg				7
#define		nOctetString		0x04

#define RESTART_PROCESS 1

static void beatSend_loadConf();
static int beatSend_parseConfLine(char *str, char (*row)[64], int maxrow);

/* by simon at 23/9/25 */
unsigned int HbDstIp;

int stop_timeout[64];
int suspend_timeout[64];

char masterProcList[512] ="mariadbd apache2 omcMain";
char slaveProcList[512] = "mariadbd apache2 omcMain";

int beatSend_mkBeatInfo(BeatInfo * beatInfo, DetailInfo * detailInfo);
int beatSend_mkVarList(var_list * varList, BeatInfo * beatInfo);
int beatSend_mkPdu(snmp_pdu * snmpPdu, var_list * varArr);
int beatSend_mkAddr(snmp_addr * addr);

void run_proc(char *cmdstr);
void kill_proc(char *proc_name);

int uIntToByte(BYTE * buf, int bufLen, unsigned long uIntValue);

DWORD wxc2OmcHbOid[MaxOidLen] = { 1, 3, 6, 1, 4, 1, 1373, 2, 4, 1, 0};

static DetailInfo omcDetailInfo;
static BeatInfo omcBeatInfo;

static DWORD *omcHbOid;
static BYTE omcTypeNo;
static BYTE omcSysNo;
static BYTE omcSubSysNo;
static BYTE omcVersion[3];

static MYSQL *beatSend_dbConn;

BYTE beatSendSequenceNum[4]={0,0,0,0};

unsigned long beatsend_prev_time;
unsigned long beatsend_next_time;

#define IPLIST_CONFILE "./conf/omctrap_iplist.conf"

int readTranIPList();
unsigned long trapIPList[64];
int trapIPCount=0;
extern void init_sys_stat();
extern int get_sys_stat(unsigned char *pBuf, int bufLen);
/*
return 
0-fail, 1-success
*/
int readTranIPList()
{
	FILE *handle;
	unsigned char rb;
	char line[64][256];
	int pos,line_pos;
	
	handle=fopen(IPLIST_CONFILE,"r");
	if(handle == NULL)
		return 0;
		
	pos=0;
	line_pos=0;
	while((1 == fread(&rb,1,1,handle)))
	{
		printf("%c", rb);
		if(rb == '\n')
		{
			line[line_pos][pos]=0;
			if(pos > 4)
				line_pos++;
			pos=0;
			if(line_pos == 64)
			{
				printf("%s's IP is too much\n",IPLIST_CONFILE);
				break;
			}			
			continue;
		}
		
		if(rb == '\t' || rb ==' ')
			continue;
		
		line[line_pos][pos]=rb;
		pos++;
	}

	printf("line_pos=%d\n", line_pos);
	for(rb=0;rb<line_pos;rb++)
	{
		if(line[rb][0] == '#' || line[rb][0] == '/')
			continue;
		
		trapIPList[trapIPCount]=inet_addr(line[rb]);
		printf("%d %08X\n",trapIPCount,trapIPList[trapIPCount]);
		trapIPCount++;
	}
	
	fclose(handle);
	return 1;
}

/*************************************************
Function:        // beatSendInit
Description:     // 该模块的初始化函数
Calls:           // beatSend_loadConf;
Called By:       // omcMain.c
Table Accessed:  // 
Table Updated:   // 
Input:           // omcInfo:OMC基本信息结构; sequenceNum:序列号
Output:          // 
Return:          // 1:successful; other:failed;
Others:          // 
*************************************************/

FILE *fp = NULL;
//#define NETWORK_FILE "/etc/network/interfaces"  //ubuntu12
//#define NETWORK_FILE "/etc/netplan/01-netcfg.yaml" //ubuntu18
#define NETWORK_FILE "/etc/netplan/00-installer-config.yaml" //ubuntu22
int getNetworkInfo(char *maches, char* szNetwork )
{
    char szBuf[64];
    int i = 0;
    if((fp=fopen(NETWORK_FILE, "r"))==NULL)             //判断文件是否为空
    {
        printf( "Can't open network info file!\n"); 
        return 0;
    }
    while(fgets(szBuf,128,fp))                         //从文件开关开始向下读，把读到的内容放到szBuf中
    {                         
        if(strstr(szBuf,maches) != NULL)                 //找到maches在文件中第一次出现的位置。。如address 
        {
	        while (!feof(fp))
	        {
	            for(i =0;i < strlen(szBuf);i++)
	            {              
	                if(isdigit(*(szBuf+i)))                      //从szBuf字符串中找出数字。
	                {
	                    strcpy(szNetwork,szBuf+i);             
	                    fclose(fp);
	                    return 1;
	                }
	            }
		     fgets(szBuf,128,fp);
	        }
        }
    }
    fclose(fp);
    return 0;
}
int getmask(int n) //转换为掩吗标准格式
{
	int ns[]={128,64,32,16,8,4,2,1};
        int y=0,sum=0;
        y=n%8;
	if(n==8)return 255;

        for(int j=0;j<y;j++)/*将2转换为192*/
        sum+=ns[j];

        return sum;

}

/* by simon at 23/9/27 */
extern int corefile_flag;

int GetFileNamesInDir(char *DirPath,char *FileExtName)
{    
	DIR *dir;    
	struct dirent *ptr;    
	
	char *CurFileExtName = NULL;    
	if ((dir=opendir(DirPath)) == NULL)
       {
           perror("Open dir error...");
           exit(1);
       }
    
  	while ((ptr=readdir(dir)) != NULL)    
	{        
		if(strcmp(ptr->d_name,".")==0 || strcmp(ptr->d_name,"..")==0) ///current dir OR parrent dir            
		continue;//跳过.和..目录       
		else if(ptr->d_type == 8)    ///d_type=8 means file       
		{              
			//printf("d_name=%s\n", ptr->d_name);
			CurFileExtName = strstr(ptr->d_name,FileExtName);
		//	printf("CurFileExtName=%s\n", CurFileExtName);
			if(CurFileExtName!=NULL)            
			{                 
				corefile_flag = 1;
				break;
			}             
		}         
	}  
	closedir(dir);    
	return 1;
}

int check_coredump_file()
{
	char *DirPath="/usr/local/omc/bin";  
	char *FileExtName="core";   
	//char FileNames[128][128];   
	//int MaxFileNum=128;
	//int FileNum=0;   
	GetFileNamesInDir(DirPath,FileExtName);  
}
int beatSendInit(omcBaseInfo * omcInfo,BYTE *sequenceNum)
{
	int i;
	FILE *confFile=NULL;
	char confBuf[256];
	char mask[320];
	 int maskNew[]={0,0,0,0};
	char ip[320];
	char ipmask[320];
	char maskVal[4];
	char *tmpBuf;
	char ip_flag=0, mask_flag=0;
	tmpBuf=&confBuf[0];
	
	//打开网卡配置文件以获取机器的IP地址和子网掩码
//	confFile=fopen("/etc/sysconfig/network-scripts/ifcfg-eth0", "r");
//	while(fgets(confBuf, 255, confFile)) {
//		tmpBuf=&confBuf[0];
//		if(strncmp("NETMASK",confBuf,7)==0){
//			strsep(&(tmpBuf),"=");
//			sprintf(mask,"%s",tmpBuf);
//		}else if(strncmp("IPADDR",confBuf,6)==0){
//			strsep(&(tmpBuf),"=");
//			sprintf(ip,"%s",tmpBuf);
//		}
//	}
//	fclose(confFile);
//	
//	if (ip[0] == '\"') ip_flag=1;
//	for (i=0; i<32; i++) {
//		if (ip[i] == '\"') {
//			ip[i] = 0;
//		}	
//	}
//	if (mask[0] == '\"') mask_flag=1;
//	for (i=0; i<32; i++) {
//		if (mask[i] == '\"') {
//			mask[i] = 0;
//		}	
//	}
/*ubuntu18 format: ip/mask,eg 192.168.1.57/24  or [192.168.1.57/24]*/
	getNetworkInfo("addresses:", ipmask );
//	getNetworkInfo("netmask", mask );
  	char *token=strtok(ipmask, "/");
	if (token) sprintf(ip, "%s", token);
	token=strtok(NULL, "/");
	char maskInt[3];
	
	if (token)
	{
		sprintf(maskVal, "%s", token);
	
		for (i=0;i<3;i++)
		{
			//printf("%c", maskVal[i]);
			 if(isdigit(maskVal[i]))
			 	maskInt[i]=maskVal[i];
			 else break;
		}
		maskInt[i]="\0";
	}
	printf("\n ip address is %s \n", ip);
	//printf("maskInt is %s \n", maskInt);
	int mask_t=0;
	 mask_t=atoi(maskInt);
	// 	printf("\n mask_t is %d \n", mask_t);
	 if(mask_t>0&&mask_t<33)
        {
                for(i=0;i<mask_t/8;i++)
                {
                        maskNew[i]=getmask(8);
                }
                maskNew[i]=getmask(mask_t%8);
          //      printf("int:%d.%d.%d.%d\n",maskNew[0],maskNew[1],maskNew[2],maskNew[3]);
		 
		sprintf(mask, "%d.%d.%d.%d",maskNew[0],  maskNew[1], maskNew[2], maskNew[3]);
        }
        else
        {
             //   printf("255.255.255.0\n");  //默认掩码/24
             sprintf(mask, "%s", "255.255.255.0");
        }

	printf("mask=%s\n",mask);
      //  if (strstr(maskVal,"24")) strcpy(mask,"255.255.255.0");
	//	printf("\n mask is %s \n", mask);
	//计算出网段的广播地址
	HbDstIp=(inet_addr(ip+ip_flag)&(inet_addr(mask+mask_flag)))|(inet_addr(ip+ip_flag)|(~(inet_addr(mask+mask_flag))));
	//printf("broadcast ip=%08X, mask = %s, host ip=%s\n", HbDstIp, mask+mask_flag, ip+ip_flag);
	
	beatsend_prev_time=time(NULL);
	
	beatSend_loadConf();
	readTranIPList();

	
	omcTypeNo = omcInfo->omcTypeNo;
	omcSysNo = omcInfo->sysNo;
	omcSubSysNo = omcInfo->subSysNo;
	omcVersion[0] = omcInfo->version[0];
	omcVersion[1] = omcInfo->version[1];
	omcVersion[2] = omcInfo->version[2];
	
	/*
	printf("omcTypeNo %d\n",omcTypeNo);
	printf("omcSysNo %d\n",omcSysNo);
	printf("omcSubSysNo %d\n",omcSubSysNo);
	printf("version %d %d %d\n",omcVersion[0],omcVersion[1],omcVersion[2]);
	*/
	
	if (omcInfo->runMode == 0) {	//single
		omcDetailInfo.status = 0x07;
	}
	
	omcHbOid = wxc2OmcHbOid;

	//初始化数据库连接
	beatSend_dbConn = mysql_conn(HOST_NAME, DB_NAME);
	if (beatSend_dbConn == NULL) {
		return (0);
	}

	//初始化序列号
	for(i=0;i<4;i++)
		beatSendSequenceNum[i]=sequenceNum[i];
	init_sys_stat();

	check_coredump_file();
	printf("corefile_flag=%d\n", corefile_flag);
	return (1);
}


/*************************************************
Function:        // beatSend
Description:     // 发送EMS的heartbeat的处理函数，主要发送EMS下的模块进程信息
Calls:           // getProcGrpInfo; uIntToByte; beatSend_mkBeatInfo; beatSend_mkVarList; beatSend_mkAddr; beatSend_mkPdu; snmp_send;
Called By:       // omcMain.c;
Table Accessed:  // 
Table Updated:   // 
Input:           // isMaster:主从机状态;
Output:          // 
Return:          // 警报标志
Others:          // 
*************************************************/
int beatSend(int isMaster,int omcRunMode)
{
	BYTE tmpHour = 0;
	BYTE tmpMinute = 0;
	BYTE tmpSecond = 0;
	procGrpInfo myProcGrpInfo;
	snmp_pdu tmpPdu;
	var_list tmpVarArr[BIND_MAX];
	snmp_addr tmpAddr;
	char procList[512];
	int i;
	unsigned long time_past;
	
	memset(&tmpPdu,0,sizeof(snmp_pdu));
	memset(tmpVarArr,0,sizeof(var_list)*BIND_MAX);
	memset(&tmpAddr,0,sizeof(snmp_addr));
	
	beatsend_next_time=time(NULL);
	time_past=beatsend_next_time - beatsend_prev_time;	
	
	if(time_past < HEARTBEAT_INTERVAL)
		return 0;
	
	omcBeatInfo.sysNo = omcSysNo;
	omcBeatInfo.subSysNo = omcSubSysNo;
	
	tmpHour = (int) ((double) beatsend_next_time / 3600) % 24;
	tmpMinute = (int) ((double) (beatsend_next_time % 3600)) / 60;
	tmpSecond = (int) (beatsend_next_time % 60);
	omcDetailInfo.clock[0] = tmpHour;
	omcDetailInfo.clock[1] = tmpMinute;
	omcDetailInfo.clock[2] = tmpSecond;
	uIntToByte(omcBeatInfo.timeStamp, sizeof(omcBeatInfo.timeStamp),beatsend_next_time);
	
	omcDetailInfo.comp_id=0;
	omcDetailInfo.comp_length=sizeof(DetailInfo)-4;
	
	memcpy(omcDetailInfo.version, omcVersion, sizeof(omcVersion));
	
	for(i=0;i<4;i++)
		omcDetailInfo.checkSum[i]=0;

	for(i=0;i<4;i++)
		omcDetailInfo.maxLicenses[i]=0;

	for(i=0;i<4;i++)
		omcDetailInfo.onLineUsers[i]=0;

	for(i=0;i<4;i++)
		omcDetailInfo.sequenceNum[i]=beatSendSequenceNum[i];


	if (isMaster == 1)
		memcpy(procList,masterProcList, sizeof(procList));
	else
		memcpy(procList,slaveProcList, sizeof(procList));
	
	sprintf(myProcGrpInfo.procNameList, "%s", procList);
	getProcGrpInfo(&(myProcGrpInfo));

	for(i=0;i<8;i++)
		omcBeatInfo.ledArr[i]=0xFF;
		
	omcDetailInfo.procNum = myProcGrpInfo.procNum;
	for(i=0;i<omcDetailInfo.procNum;i++) 
		omcDetailInfo.procInfo[i] = myProcGrpInfo.procInfoArr[i].stat;
	
	omcBeatInfo.compCode=0;
	if (corefile_flag) omcBeatInfo.alarmCode=252;
		else omcBeatInfo.alarmCode=0;
	//printf("omcBeatInfo.alarmCode=%d\n", omcBeatInfo.alarmCode);
	omcBeatInfo.reservedForCompCode=0;
	
	beatSend_mkBeatInfo(&(omcBeatInfo), &(omcDetailInfo));
	beatSend_mkVarList(&(tmpVarArr[0]), &(omcBeatInfo));
	//int statlength;
	//statlength=get_sys_stat(&(omcDetailInfo.cpuUsage), sizeof(DetailInfo));
	beatSend_mkAddr(&tmpAddr);
	beatSend_mkPdu(&tmpPdu, tmpVarArr);

	//发送snmp
	if(snmp_send(&tmpPdu, &tmpAddr) > 0) 
	{
#if beatSend_DEBUG
		fprintf(stderr, "send heartbeat message ok!");
#endif
	} 
	else 
	{
#if beatSend_DEBUG
		fprintf(stderr, "failed to send heartbeat message!");
#endif
	}
	
	for(i=0;i<trapIPCount;i++)
	{
		tmpAddr.remote_ip = trapIPList[i];
		tmpAddr.broadcast = 0;
		if(snmp_send(&tmpPdu, &tmpAddr) > 0) 
		{
#if beatSend_DEBUG
			fprintf(stderr, "send heartbeat message ok!");
#endif
		} 
		else 
		{
#if beatSend_DEBUG
			fprintf(stderr, "failed to send heartbeat message!");
#endif
		}
	}
	
	beatsend_prev_time=beatsend_next_time;
	
	return 0;
}

/*************************************************
Function:        // chOmcStatus
Description:     // 改变EMS的状态
Calls:           // 
Called By:       // dualsrv.c:dualsrv_status;
Table Accessed:  // 
Table Updated:   // 
Input:           // status:状态值;
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void chOmcStatus(BYTE status)
{
	omcDetailInfo.status = status;
}

/*************************************************
Function:        // fillSyncInfo
Description:     // 填充EMS的同步信息
Calls:           // 
Called By:       // dualsrv.c:dualsrv_status;
Table Accessed:  // 
Table Updated:   // 
Input:           // info:同步信息;
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void fillSyncInfo(BYTE * info)
{
	memcpy((BYTE *) & omcDetailInfo.syncInfo, info, 32);
}

void fillProcStatus(BYTE procnum,BYTE *procstatus)
{	
	omcDetailInfo.procNum=procnum;
	memcpy(omcDetailInfo.procInfo, procstatus, procnum*sizeof(BYTE));
}

/*************************************************
Function:        // beatSend_mkBeatInfo
Description:     // 构造EMS heartbeat消息结构
Calls:           // 
Called By:       // beatSend;
Table Accessed:  // 
Table Updated:   // 
Input:           // detailInfo:heartbeat详细消息结构;
Output:          // beatInfo:heartbeat消息结构;
Return:          // 1:successful; other:failed;
Others:          // 
*************************************************/
int beatSend_mkBeatInfo(BeatInfo * beatInfo, DetailInfo * detailInfo)
{

#if beatSend_DEBUG
	int i;
#endif
	//构造EMS heartbeat消息结构
	beatInfo->detailLen = sizeof(*detailInfo);
	memcpy(beatInfo->detail, detailInfo, beatInfo->detailLen);
#if beatSend_DEBUG
	fprintf(stderr, "\n beatInfo->detailLen = %d", beatInfo->detailLen);
	fprintf(stderr, "\n beatInfo->detail");
	for (i = 0; i < beatInfo->detailLen; i++) {
		if (i % 8 == 0) {
			fprintf(stderr, "\n");
		}
		fprintf(stderr, "%02X,", beatInfo->detail[i]);
	}
#endif
	return (1);
}

/*************************************************
Function:        // beatSend_mkVarList
Description:     // 用beatInfo结构构造snmp的var_list结构
Calls:           // 
Called By:       // beatSend;
Table Accessed:  // 
Table Updated:   // 
Input:           // beatInfo:heartbeat消息结构
Output:          // varList:snmp参数列表
Return:          // 1:successful; other:failed;
Others:          // 
*************************************************/
int beatSend_mkVarList(var_list * varList, BeatInfo * beatInfo)
{
	int i = 0;
	for (i = 0; i < MaxOidLen; i++) {
		if (omcHbOid[i] > 0) {
			varList->oid[i] = omcHbOid[i];
		} else {
			break;
		}
	}
	varList->oidlen = i + 1;
	varList->vartype = nOctetString;
	varList->msglen = sizeof(*beatInfo);
#if beatSend_DEBUG
	fprintf(stderr, "\n varList->oidlen = %d", varList->oidlen);
	fprintf(stderr, "\n varList->msglen = %d", varList->msglen);
	fprintf(stderr, "\n beatInfo->detailLen = %d", beatInfo->detailLen);
#endif
	memcpy(varList->msg, (BYTE *) beatInfo, varList->msglen);
#if beatSend_DEBUG
	fprintf(stderr, "\n varLisk memcpy finished!");
#endif
	return (1);
}

/*************************************************
Function:        // beatSend_mkPdu
Description:     // 构造snmp数据单元
Calls:           // 
Called By:       // beatSend;
Table Accessed:  // 
Table Updated:   // 
Input:           // varArr:参数列表
Output:          // pdu:snmp数据单元
Return:          // 1:successful; other:failed;
Others:          // 
*************************************************/
int beatSend_mkPdu(snmp_pdu * pdu, var_list * varArr)
{
#if beatSend_DEBUG
	fprintf(stderr, "\n Making snmp_pdu");
#endif

	pdu->pdu_type = trapMsg;
	pdu->request_id = 123;
	pdu->var_num = 1;

#if beatSend_DEBUG
	fprintf(stderr, "\n varArr[0].msglen = %d", varArr[0].msglen);
	fprintf(stderr, "\n varArr[1].msglen = %d", varArr[1].msglen);
#endif

	memcpy(pdu->var, varArr, sizeof(var_list) * BIND_MAX);

#if beatSend_DEBUG
	fprintf(stderr, "\n pdu memcpy finished!");
#endif
	pdu->error_status = 0x0;	//0:no error 1:too big 2:nosuchname 3:badvalue 4:readonly 5:generr
	pdu->error_index = 0x0;
	return (1);
}



/*************************************************
Function:        // beatSend_mkAddr
Description:     // 构造snmp地址结构
Calls:           // 
Called By:       // beatSend;
Table Accessed:  // 
Table Updated:   // 
Input:           // addr:snmp地址结构;
Output:          // 
Return:          // 1:successful; other:failed;
Others:          // 
*************************************************/
int beatSend_mkAddr(snmp_addr * addr)
{
#if beatSend_DEBUG
	fprintf(stderr, "\n\n Initing snmp_addr----");
	fprintf(stderr, "\n local_port %d", HbSrcPort);
	fprintf(stderr, "\n remote_ip:%u", HbDstIp);
	fprintf(stderr, "\n remote_port:%d", HbDstPort);
#endif
	//addr->local_ip    = ;
	addr->local_port = HbSrcPort;
	
	addr->remote_ip = HbDstIp;
	addr->broadcast = 1;
	addr->remote_port = HbDstPort;

	return (1);
}

/*************************************************
Function:        // uIntToByte
Description:     // 把数据的格式转换成BCD码
Calls:           // 
Called By:       // beatSend;
Table Accessed:  // 
Table Updated:   // 
Input:           // uIntValue:被转换的值
Output:          // buf:转换后的值
Return:          // >0:数据长度; 0:failed;
Others:          // 
*************************************************/
int uIntToByte(BYTE * buf, int bufLen, unsigned long uIntValue)
{
#if beatSend_DEBUG
	fprintf(stderr, "\n ,int bufLen=%d,unsigned long uIntValue=%lu",
			bufLen, uIntValue);
#endif

	switch (bufLen) {
	case 1:
		buf[0] = uIntValue;
		break;
	case 2:
		buf[1] = uIntValue & 0xFF;
		buf[0] = uIntValue >> 8;
		break;
	case 3:
		buf[2] = uIntValue & 0xFF;
		buf[1] = (uIntValue & 0xFF00) >> 8;
		buf[0] = uIntValue >> 16;
		break;
	case 4:
		buf[3] = uIntValue & 0xFF;
		buf[2] = (uIntValue & 0xFF00) >> 8;
		buf[1] = (uIntValue & 0xFF0000) >> 16;
		buf[0] = uIntValue >> 24;
		break;
	default:
		return (0);
	}
	return (bufLen);
}

void run_proc(char *cmdstr)
{
	pid_t pid;
	sigset_t oldset, newset;
	int status;
	char start_path[128];
	char command[256];

	sprintf(start_path,"/usr/local/omc/bin/");
	
	//没有命令
	if (cmdstr == NULL)
		return;
	
	if(strstr(cmdstr,"alive") || strstr(cmdstr,"bsscomm"))
		sprintf(command,"/usr/local/omc/bin/%s &",cmdstr);
	else
		sprintf(command,"/usr/local/omc/bin/%s -d",cmdstr);
		
	//进入工作目录
	if (chdir(start_path) != 0) {
		return;
	}

	if ((pid = fork()) == 0) {
		//启动新进程,初始化信号集,设置信号遮罩
		setsid();
		sigemptyset(&newset);
		sigprocmask(SIG_SETMASK, &newset, &oldset);
		//用bash执行相应的命令,启动进程
		execl("/bin/bash", "bash", "-c", command, NULL);
		_exit(127);
	} else {
		while (waitpid(pid, &status, 0) < 0) {
			if (errno != EINTR) {
				status = -1;
				break;
			}
		}
	}

}

void kill_proc(char *proc_name)
{
	char command[256];
	
	if(proc_name == NULL)
		return;
		
	sprintf(command,"kill -9 `pidof %s`",proc_name);
	system(command);
}

/*************************************************
Function:        // beatSend_loadConf
Description:     // 从配置文件中获取主从进程列表
Calls:           // beatSend_parseConfLine
Called By:       // beatSendInit;
Table Accessed:  // 
Table Updated:   // 
Input:           // ./conf/server.conf
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void beatSend_loadConf()
{
	FILE *fp;
	
	char str[256], itemlist[8][64], *pchr, *pkey, *pname;
	int len;

	fp = fopen("./conf/server.conf", "r");

	if (fp == NULL) {
		exitLog("beatSend:beatSend_loadConf, Can not open server.conf");
		exit(1);
	}
	
	//master processor
	fseek(fp, 0, SEEK_SET);
	while (fgets(str, 200, fp) != NULL) {
		if ((pchr = strchr(str, '#')) != NULL)
			pchr[0] = '\0';
		if ((pkey = strstr(str, "[master_task]")) == NULL)
			continue;
		while (fgets(str, 256, fp) != NULL && strchr(str, '[') == NULL) {
			if ((pchr = strchr(str, '#')) != NULL)
				pchr[0] = '\0';
			if (strlen(str) < 5)
				continue;
			if (beatSend_parseConfLine(str, itemlist, 2) < 1)
				continue;
			if (access(itemlist[0], X_OK) != 0)
				continue;

			len = strlen(itemlist[0]);
			if (itemlist[0][len - 1] == '/')
				itemlist[0][len - 1] = '\0';
			if ((pname = strrchr(itemlist[0], '/')) == NULL)
				pname = itemlist[0];
			else
				pname++;

			strcat(masterProcList," ");
			strcat(masterProcList,pname);
		}
	}
	
	
	//slave processor
	fseek(fp, 0, SEEK_SET);
	while (fgets(str, 200, fp) != NULL) {
		if ((pchr = strchr(str, '#')) != NULL)
			pchr[0] = '\0';
		if ((pkey = strstr(str, "[slave_task]")) == NULL)
			continue;
		while (fgets(str, 256, fp) != NULL && strchr(str, '[') == NULL) {
			if ((pchr = strchr(str, '#')) != NULL)
				pchr[0] = '\0';
			if (strlen(str) < 5)
				continue;
			if (beatSend_parseConfLine(str, itemlist, 2) < 1)
				continue;
			if (access(itemlist[0], X_OK) != 0)
				continue;

			len = strlen(itemlist[0]);
			if (itemlist[0][len - 1] == '/')
				itemlist[0][len - 1] = '\0';
			if ((pname = strrchr(itemlist[0], '/')) == NULL)
				pname = itemlist[0];
			else
				pname++;
				
			strcat(slaveProcList," ");
			strcat(slaveProcList,pname);
		}
	}

	fclose(fp);
	return;
}


/*************************************************
Function:        // beatSend_parseConfLine
Description:     // 解析处理配置文件以获得需要的信息
Calls:           // 
Called By:       // beatSend_loadConf
Table Accessed:  // 
Table Updated:   // 
Input:           // str; maxrow;
Output:          // 
Return:          // 返回对应的字符串指针
Others:          // 
*************************************************/
int beatSend_parseConfLine(char *str, char (*row)[64], int maxrow)
{
	char *pstr = str;
	int len, index = 0, i;
	BOOL black = 0;
	len = strlen(str);
	for (i = 0; i < len && index < maxrow; i++) {
		if (isspace(str[i])) {
			if (black == 0)
				pstr = str + i + 1;
			else {
				str[i] = '\0';
				if (strlen(pstr) > 64)
					pstr[63] = 0;
				sprintf(row[index++], "%s", pstr);
				pstr = str + i + 1;
			}
			black = 0;
		} else
			black = 1;
	}
	if (black == 1) {
		if (strlen(pstr) > 64)
			pstr[63] = 0;
		sprintf(row[index++], "%s", pstr);
	}
	return index;
}
