/*****************************************************/
/*Title:    sysctrl.c	                             */
/*Descr:    report operation system status           */
/*Author:   Liang Hanxi                              */
/*Create:   2002-06-24                               */
/*Modify:                                            */
/*****************************************************/

#include "./include/sysctrl.h"

#define MAX_MNT_FILESYS 255 //in CC client >16

static mnt_list			MntInfo[MAX_MNT_FILESYS];
static BYTE				MntNum=0;
static hb_sysinfo3		SysInfo3;

static FILE				*stat_fp;
extern int				errno;

static void get_mntinfo();
static BOOL get_diskinfo(long *p_total,long *p_free);
static void get_idlecpu();
static int parse_infoline(char *str,char (*row)[64],int maxrow);

void sysctrl_init()
{
	struct sysinfo		info;

	if((stat_fp=fopen("/proc/stat","r"))==NULL)
	{
		printf("Fail to open /proc/stat\n");
		exit(1);
	}

	#if 0
	sysinfo(&info);
	SysInfo.totalram = htonl(info.totalram/1024);
	SysInfo.freeram = htonl(info.freeram/1024);
	SysInfo.up_time = htonl(time(NULL));
	#endif
	SysInfo3.up_time = htonl(time(NULL));
	
	get_idlecpu();
	//get_mntinfo();
	fclose(stat_fp);
}

void system_report()
{
	static int			m_state=0;
	struct sysinfo		info;
	unsigned long		totaldisk,freedisk;
	
	switch(m_state)
	{		
	case 50*60*10:			//10min
		m_state=0;
		#if 0
		sysinfo(&info);
		SysInfo.totalram = htonl(info.totalram/1024);
		SysInfo.freeram = htonl(info.freeram/1024);

		SysInfo3.ram_total_used = htonl(info.totalram - info.freeram);
		SysInfo3.ram_total = htonl(info.totalram);
		// set_status(8,22,(BYTE *)&SysInfo.cpu_idle);
		set_status(8,38,(BYTE *)&SysInfo2.start_time);
		break;
		#endif
	default:
		m_state++;
		if(m_state%(50*30)==0)	//30s
		{
			sysinfo(&info);

			SysInfo3.ram_total_used = htonl((info.totalram - info.freeram)>>10);
			SysInfo3.ram_total = htonl(info.totalram>>10);
			SysInfo3.ram_swap_used = htonl((info.totalswap - info.freeswap)>>10);
			SysInfo3.ram_swap_total = htonl(info.totalswap>>10);
			SysInfo3.ram_buffers = htonl(info.bufferram>>10);
			SysInfo3.ram_cached = htonl((info.freeram * info.mem_unit + info.bufferram * info.mem_unit)>>10);

			get_diskinfo(&totaldisk,&freedisk);
			
			SysInfo3.pt_count = 1;
			SysInfo3.pt[0].num = 1;
			SysInfo3.pt[0].pos = 0x2f;
			SysInfo3.pt[0].used_space = htonl(totaldisk - freedisk);
			SysInfo3.pt[0].total_space = htonl(totaldisk);


			get_idlecpu();

			// set_status(8,22,(BYTE *)&SysInfo.cpu_idle);
			set_status(8,40,(BYTE *)&SysInfo3);
		}
		break;
	}
}

void get_idlecpu()
{
	char			buf[128],row[5][64];
	DWORD			timeofuser,timeofsys,timeofnice,timeofidle;
	static DWORD	oldusertime=0,oldsystime=0,oldnicetime=0,oldidletime=0;
	
	double			idlecpu,totalcpu;
	u_short			idlerate;
	
	// by simon at 20240426
	/*
	if(fseek(stat_fp,0,SEEK_SET)!=0)
	{
		snmp_debug(SNMPDB_ERR|SNMPDB_SYS, "Fail to seek to beginning of /proc/stat");
		return;
	}
	if(fgets(buf,128,stat_fp)==NULL)
	{
		snmp_debug(SNMPDB_ERR|SNMPDB_SYS, "Fail to Read information from /proc/stat");
		return;;
	}

	if(parse_infoline(buf,row,5)<5)
		return;

	timeofuser=strtoul(row[1],NULL,10);
	timeofnice=strtoul(row[2],NULL,10);
	timeofsys=strtoul(row[3],NULL,10);
	timeofidle=strtoul(row[4],NULL,10);

	//if((pinfo=strstr(buf,"cpu "))==NULL)
	//	return;
	//sscanf(pinfo,"cpu  %lu %lu %lu %lu",&timeofuser,&timeofnice,&timeofsys,&timeofidle);
	//printf("CPU Time:%ld,%ld,%ld,%ld\n",timeofuser,timeofnice,timeofsys,timeofidle);

	totalcpu=timeofuser-oldusertime+timeofnice-oldnicetime+timeofsys-oldsystime+timeofidle-oldidletime;

	if(totalcpu==0)
		return;

	idlecpu=timeofidle-oldidletime;

	idlerate=(u_short)((idlecpu/totalcpu)*1000);
	//store current time
	oldusertime=timeofuser;
	oldnicetime=timeofnice;
	oldsystime=timeofsys;
	oldidletime=timeofidle;
	
	if(idlerate<=1000)
	{
		SysInfo3.idle_cpu_rate = (u_short)(idlecpu * 100 / totalcpu);
	}
	*/
}




void get_mntinfo()
{
	FILE				*mntfp;
	struct mntent		*pmnt;
	struct statfs		statbuf;

	mntfp = setmntent("/etc/mtab", "r");
	while ((pmnt = getmntent(mntfp))!=NULL && MntNum<MAX_MNT_FILESYS) 
	{
		if(statfs(pmnt->mnt_fsname,&statbuf)!=0)
			continue;
		strcpy(MntInfo[MntNum].mnt_fsname,pmnt->mnt_fsname);
		strcpy(MntInfo[MntNum].mnt_dir,pmnt->mnt_dir);
		MntInfo[MntNum++].limit =20*1024;
	}
	endmntent(mntfp);	
	//free(pmnt);  getmntent return static pointer , not need to free
}

BOOL get_diskinfo(long *p_total,long *p_free)
{
	int					i;
	struct statfs		statbuf;
	mnt_list			*pmnt;
	*p_total=0;
	*p_free=0;
	for(i=0;i<MntNum;i++)
	{
		pmnt=&MntInfo[i];
		if(statfs(pmnt->mnt_dir,&statbuf)!=0)
			continue;

		pmnt->total=statbuf.f_blocks*(statbuf.f_bsize/1024);
		*p_total+=pmnt->total;
		pmnt->free=statbuf.f_bfree*(statbuf.f_bsize/1024);
		*p_free+=pmnt->free;

		if(pmnt->free<=pmnt->limit)
			set_alarm(8,3);
		//printf("%-15s%-15s%-10ld%-10ld\n",pmnt->mnt_fsname,pmnt->mnt_dir,pmnt->total,pmnt->free);
	}

	
	return 1;
}

int parse_infoline(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;
}


