/*************************************************
File name:	smcli.c
Author: 	
Version:	9:00:00 
Date:  		2007-8-4
Description:该文件实现了命令行用户数据管理模块的主要功能，主要有分析用户输入的命令，然后
			把命令转化为合适的格式保存到用户数据命令表，再由subsComm模块处理命令
			
			
			
												
History:               
No. 		
Author:		  
Date:		 
Version:	   
Description:
*************************************************/

#include "smcli.h"
extern CmdBuf defCmdBuf[CmdBufSize];

//must match the command type number define
char CmdList[MaxCmdTypeNum][16] =
	{ {"read"}, {"modify"}, {"create"}, {"delete"}, {"connect"},
{"export"}, {"import"}, {"disconnect"}, {"recharge"}
};								//20041010

char anotherCmdList[MaxCmdTypeNum][16] =
	{ {"read"}, {"modify"}, {"create"}, {"delete"},
{"export"}, {"import"}, {"disconnect"}, {"connect"}, {"recharge"}
};

char smcliTable[CmdBufSize][32] =
	{ {""}, {"OMC_PUB.smcliHLR"}, {"OMC_PUB.smcliPPS"},
{"OMC_PUB.smcliCard"}, {"OMC_PUB.smcliVMS"}, {""}, {""},
{"OMC_PUB.smcliMNP"}
};

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

/* by simon at 23/9/26 */
CmdBuf defCmdBuf[CmdBufSize];
extern struct sockaddr_in cliaddr;
extern _PORT_STATUS port_status[MAX_CLIENTS];
CmdBuf *cmdBuf;
int OptNo_index;

// function
int procInput(char *inputBuf, unsigned char importFlag, int sock,
			  int loop);
int sendCmd(int sock, int loop);
int scanCmd(int sock);
void showCmdBuf(CmdBuf * thisCmdBuf, int sock);
void initCmdBuf(CmdBuf * thisCmdBuf);

int doCmdConnect(int sock, int loop);
int doCmdRead(unsigned char exportFlag, int sock, int loop);
int doCmdModify(int sock, int loop);
int doCmdCreate(unsigned char importFlag, int sock, int loop);
int doCmdDelete(int sock, int loop);
int doCmdExport(int sock, int loop);
int doingCmdExport(int sock, int loop);
int doCmdImport(char *inputBuf, int sock, int loop);
int doingCmdImport(char *inputBuf, int sock, int loop);
int doCmdDisconnect(int sock, int loop);
int doCmdRecharge(int sock, int loop);	//20041010
int doCmdAlive(int sock);
int doCmdHelp(int sock);

void writeDebug(const char *fmt,...);
void CheckDbConnection();
int procAccount(int sock, int loop);

int doCmdReadAccount(unsigned char exportFlag, int sock, int loop);
int doCmdModifyAccount(int sock, int loop);
int doCmdCreateAccount(int sock, int loop);
int doCmdDeleteAccount(int sock, int loop);
int doCmdExportAccount(int sock, int loop);

int getOptNoByName(char *optName);

int ReceiveTCP(int loop, int sock, unsigned char loginFlag);
int CloseTcpConnect(int sock);
int CheckTcpConnect();
int InitialSocket();
void ReceiveMsg();
int CheckPwd(int loop, int sock);
int getServerStat(char *ip);
char *opt_date(char *org_date,char *opt_value,char *result_date);

void changeDefaultValue();
void changeDefaultValueProcInput(char *inputBuf);

extern void pmcli();

int InitDefCmdBuf();

//public var
//static MYSQL *dbConn;
MYSQL *dbConn;

unsigned char CmdTypeNo;
int CmdId;
int ModifyFlag;
char FieldNameList[4096];
int ErrorCode;					//default is 0000
char ErrorMsg[256];				//default is null,if errorCode > 0,print it
char InputBuf[InputBufSize];
char OutputBuf[OutputBufSize];
int OutputLen;
unsigned char usernameFlag;
unsigned char pwdFlag;

char ExportQueryStr[128];
char ExportFieldsStr[1024];

extern int errno;
int sockfd;

int timeOut;
/*************************************************
Function:        // main
Description:     // 模块主函数，初始化命令缓冲区，初始化套接字，初始化参数权限和初始值
Calls:           // mysql_conn; InitialSocket; changeDefaultValue; ReceiveMsg; CheckTcpConnect;
Called By:       // 
Table Accessed:  // OMC_PUB.omcPubVarConf, OMC_PUB.smcliXXX, OBJ_XXX.subsParamConf_X
Table Updated:   // 
Input:           // smcliDefaultValue.txt
Output:          // 
Return:          // >0:errorCode
Others:          // 
*************************************************/
unsigned long heartbeat_timeout=0;
int main(int argc, char *argv[])
{
	pid_t pid;
	int i;
	int j;
	char tmpSql[256];
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;

	

	writeDebug("smcli is starting ...\n");
	//作为精灵进程运行
	if (argc == 2 && strstr(argv[1], "-d")) {
		if ((pid = fork()) != 0)
			exit(0);
		setsid();
	}
	
	debug_init(1);
	iptrans_init();
	snmp_init(4957);
	//heartbeat_init(0);
	
	
	//连接OMC_PUB数据库
	dbConn = mysql_conn("localhost", "OMC_PUB");
	if (dbConn == NULL) {
		exitLog("[ERR][main]:Connect OMC_PUB");
		exit(1);
	}
	
#ifdef SMCLI_DEBUG
	// for (i = 0; i < CmdBufSize; i++) {
	// 	showCmdBuf(&defCmdBuf[i]);
	// }
#endif

	//初始化port_status
	for (i = 0; i < MAX_CLIENTS; i++) {
		port_status[i].failNo = 0;
		port_status[i].loginFlag = 0;
		port_status[i].isConnected[0] = 1;
		for (j = 1; j < CmdBufSize; j++)
			port_status[i].isConnected[j] = 0;
	}
	
	//由于omc没有专门的参数配置表，所有把command.c的参数定义直接导入
	cmdBuf = &defCmdBuf[0];

	if (InitialSocket() < 0)
	{
		exitLog("smcli:main, InitialSocket function error");
		exit(2);
	}

	//获取公共参数，连接超时最大时间值
	sprintf(tmpSql,
			"SELECT pubVarValue FROM OMC_PUB.omcPubVarConf WHERE pubVarName='SMCLI_timeout'");
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

#ifdef SMCLI_DEBUG
	printf("tmpSql= %s\n", tmpSql);
#endif

	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0)
	{
		mysql_free_result(tmpResult);
		timeOut = 15;
	}
	else {
		tmpRow = mysql_fetch_row(tmpResult);
		timeOut = atoi(tmpRow[0]);
		mysql_free_result(tmpResult);
	}
	if (timeOut < 1 || timeOut > 720)
		timeOut = 15;

	if (InitDefCmdBuf() < 0) {
		printf
			("\nRead SMCLI configuration error, please check the database.\n");
		exitLog("smcli:main, InitDefCmdBuf function error");
		exit(1);
	}
#ifdef SMCLI_DEBUG
{
	CmdBuf *buf;
	unitOptDef *un;
	int ii,jj;
	for(ii=0;ii<CmdBufSize;ii++)
	{
		buf=&defCmdBuf[ii];
		if(buf->sysTypeNo==375)
		{
			for(jj=0;jj<buf->optDefNum;jj++)
			{
				un=&buf->optDef[jj];
				printf("optName=%s\n",un->optName);
				printf("exMode=%ld\n",un->exMode);
				printf("fieldName=%s\n",un->fieldName);
			}
			printf("--------\n");
		}	
	}
}	
#endif
	//从数据库OMC_PUB.smcliHLR等表里获取每种设备的命令操作参数的read,modify,create权限，
	//从第九个开始，因为前八个参数都是固定的，在command.c里初始化过了
	for (i = 0; i < CmdBufSize; i++) {
		if (strlen(smcliTable[i]) > 0) {
			//printf("smcliTable_%d=%s\n",i,smcliTable[i]);
			sprintf(tmpSql,
					"SELECT optionalName,readPrivilege,writePrivilege,createPrivilege FROM %s ORDER BY number",
					smcliTable[i]);
			//printf("tmpSql=%s\n",tmpSql);
			tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);
			if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
				mysql_free_result(tmpResult);
				exitLog("smcli:main, InitDefCmdBuf function error");
				exit(3);
			}
			j = 9;
			while ((tmpRow = mysql_fetch_row(tmpResult))) {
				//printf("%d-\n",j);
				strcpy(defCmdBuf[i].optDef[j].optName, tmpRow[0]);
				//read操作权限
				defCmdBuf[i].optDef[j].optFlag[1] = atoi(tmpRow[1]);
				//modify操作权限
				defCmdBuf[i].optDef[j].optFlag[2] = atoi(tmpRow[2]);
				//create操作权限
				defCmdBuf[i].optDef[j].optFlag[3] = atoi(tmpRow[3]);
				j++;
			}
			//printf("j=%d\n",j);
			mysql_free_result(tmpResult);
		}
	}

	// for the recharge command
	//添加recharge命令，optFlag数组多了一位
	for (j = 42; j < 47; j++) {
		defCmdBuf[2].optDef[j].optFlag[9] =
			defCmdBuf[2].optDef[j].optFlag[2];
		defCmdBuf[2].optDef[j].optFlag[2] = 9;
	}

	//init cmdbuf->optDef[]->initFieldValue
	//初始化每个参数在数据库里的值
	for (i = 0; i < CmdBufSize; i++) {
		if (strlen(smcliTable[i]) > 0) {
			for (j = 9; j < defCmdBuf[i].optDefNum; j++) {
				if (strlen(defCmdBuf[i].optDef[j].fieldName) > 0) {
					sprintf(tmpSql,
							"SELECT initValue FROM OBJ_%d.subsParamConf_%d WHERE fieldName=\'%s\'",
							defCmdBuf[i].sysTypeNo,
							defCmdBuf[i].dataTypeNo,
							defCmdBuf[i].optDef[j].fieldName);
					//printf("tmpSql=%s\n", tmpSql);
					tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);
					if (tmpResult == NULL
						|| mysql_num_rows(tmpResult) == 0) {
						mysql_free_result(tmpResult);
						exitLog("smcli:main, Initial defCmdBuf error, sql=%s",tmpSql);
						exit(4);
					}
					if ((tmpRow = mysql_fetch_row(tmpResult))) {
						//  printf("len=%d\n",strlen(tmpRow[0]));
						//  printf("initValue=%s\n", tmpRow[0]);
						strcpy(defCmdBuf[i].optDef[j].initFieldValue,
							   tmpRow[0]);
					}
					mysql_free_result(tmpResult);
				}
			}
		}
	}
	
	//再次从/usr/local/apache/htdocs/smcliDefaultValue.txt文件中获得参数初始化的值，并初始化之
	changeDefaultValue();

	sprintf(tmpSql, "DELETE FROM %s", smcliIndexTable);
	mysql_getnores(dbConn, tmpSql);

	printf("smcli module %s start running..........\n", SMCLI_VERSION);

	while (1) {
		if(time(NULL) - heartbeat_timeout > 5)
		{
			heartbeat_timeout=time(NULL);
			sendHeartbeat();
		}
		ReceiveMsg();
		CheckTcpConnect();
		usleep(100000);
	}
}

/*************************************************
Function:        // sendHeartbeat
Description:     // Send process heartbeat to beatProc
Calls:           // snmp_send
Called By:       // main
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,"smcli");
	
	//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)
	{
		writeDebug("Send heartbeat fail");
		return 0;
	}
	return 1;
}

/*************************************************
Function:        // InitialSocket
Description:     // 初始化TCP套接字
Calls:           // socket; bind; listen;
Called By:       // main
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
int InitialSocket()
{
	int port;
	int on = 1;
	struct sockaddr_in sin_addr;

	port = SMCLI_PORT;
	memset(&sin_addr, 0, sizeof(struct sockaddr));
	sin_addr.sin_family = AF_INET;
	sin_addr.sin_port = htons(port);
	sin_addr.sin_addr.s_addr = INADDR_ANY;
	bzero(&(sin_addr.sin_zero), 8);
	
	//创建套接字
	sockfd = socket(AF_INET, SOCK_STREAM, 0);

	if (sockfd < 0) {
		printf("Socket() failed\n");
		return -3;
	}

	//关掉套接字数据流缓冲区
	if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0) {
		printf("set nonblock failed\n");
		return -7;
	}
	
	if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,
        	 &on,sizeof(on)) !=0){
	    fprintf(stderr,"set addr reusable failed\n");
     	return -9;
  	}
	
	//绑定套接字
	if (bind
		(sockfd, (struct sockaddr *) &sin_addr,
		 sizeof(struct sockaddr)) < 0) {
		sleep(60);
		if (bind
			(sockfd, (struct sockaddr *) &sin_addr,
			 sizeof(struct sockaddr)) < 0) {
			printf("bind failed,port:%d,%s\n", htons(sin_addr.sin_port),
				   strerror(errno));
			close(sockfd);
			return -2;
		}
	}
	
	//等待客户端的连接
	listen(sockfd, MAX_CLIENTS);
	return sockfd;
}

/*************************************************
Function:        // CheckTcpConnect
Description:     // 处理客户端的telnet连接，发送欢迎信息
Calls:           // send; accept;
Called By:       // main
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 0:successful; >0:failed
Others:          // 
*************************************************/
int CheckTcpConnect()
{
	int connfdtmp = 0, index = 0;
	socklen_t clilen;
	for (index = 0; index < MAX_CLIENTS; index++) {
		if (port_status[index].connfd <= 0) {
			//初始化客户端套接字
			memset(&cliaddr, 0, (clilen = sizeof(struct sockaddr)));
			//如果客户端发出连接请求，则分配套接字ID给该连接
			connfdtmp =
				accept(sockfd, (struct sockaddr *) &cliaddr, &clilen);
			if (connfdtmp > 0) {
				port_status[index].connfd = connfdtmp;	
				//获得客户端的IP地址和端口号
				port_status[index].peerip = cliaddr.sin_addr.s_addr;
				port_status[index].peerport = ntohs(cliaddr.sin_port);
				fcntl(port_status[index].connfd, F_SETFL, O_NONBLOCK);
				//发送欢迎信息
				sprintf(OutputBuf, "%s", "Welcome to WXCII SMCLI...\n\r");
				OutputLen = strlen(OutputBuf);
				send(connfdtmp, OutputBuf, OutputLen, 0);
				port_status[index].time = time(NULL);
			}
		}
	}
	return 0;
}

/*************************************************
Function:        // ReceiveMsg
Description:     // 
Calls:           // send; CheckPwd; doingCmdExport; doingCmdImport; CloseTcpConnect; 
Called By:       // main
Table Accessed:  // OMC_PUB.sysOperLog
Table Updated:   // OMC_PUB.sysOperLog
Input:           // 
Output:          // 接收客户端的命令输入
Return:          // 
Others:          // 
*************************************************/
void ReceiveMsg()
{
	int loop;
	long l_time;
	struct tm *t;
	char tmpSql[1024];
	
	CheckDbConnection();
	
	//循环每个客户端连接
	for (loop = 0; loop < MAX_CLIENTS; loop++) {
		//客户端已用telnet连接
		if (port_status[loop].connfd > 0) {
			//客户端连接还未用用户名和密码登陆
			if (!port_status[loop].loginFlag) {
				if (time(NULL) - port_status[loop].time > timeOut * 60) {
					sprintf(OutputBuf, "%s\n\r", ERR_0300);
					OutputLen = strlen(OutputBuf);
					//连接时间超过限定时间，发送提示信息给相应的客户端
					send(port_status[loop].connfd, OutputBuf, OutputLen,
						 0);
					sleep(3);
					//关闭该连接
					CloseTcpConnect(port_status[loop].connfd);

					l_time = time(NULL);
					t = localtime(&l_time);
					//插入操作记录
					sprintf(tmpSql, "INSERT INTO %s	"
							"(operTypeNo,operNo,remark,userName,datetime)"
							"VALUES"
							"(\'0\',\'0\',\'Time out\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
							sysOperLogTable, port_status[loop].username,
							t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
							t->tm_hour, t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
					printf("\n tmpSql=%s \n", tmpSql);
#endif
					mysql_getnores(dbConn, tmpSql);
				} else
					CheckPwd(loop, port_status[loop].connfd);
			}
			//客户端连接已经登陆 
			else 
			{
				//正在进行导入导出操作
				if (port_status[loop].expDoingFlag
					|| port_status[loop].impDoingFlag) {
					OptNo_index = 8;
					if (port_status[loop].expDoingFlag)
						doingCmdExport(port_status[loop].connfd, loop);
					else
						doingCmdImport(InputBuf, port_status[loop].connfd,
									   loop);
				} else {
					//判断是否等待超时
					if (time(NULL) - port_status[loop].time > timeOut * 60) {
						sprintf(OutputBuf, "%s\n\r", ERR_0300);
						OutputLen = strlen(OutputBuf);
						send(port_status[loop].connfd, OutputBuf,
							 OutputLen, 0);
						sleep(3);
						CloseTcpConnect(port_status[loop].connfd);

						l_time = time(NULL);
						t = localtime(&l_time);
						sprintf(tmpSql, "INSERT INTO %s	"
								"(operTypeNo,operNo,remark,userName,datetime)"
								"VALUES"
								"(\'0\',\'0\',\'Time out\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
								sysOperLogTable,
								port_status[loop].username,
								t->tm_year + 1900, t->tm_mon + 1,
								t->tm_mday, t->tm_hour, t->tm_min,
								t->tm_sec);
#ifdef SMCLI_DEBUG
						printf("\n tmpSql=%s \n", tmpSql);
#endif
						mysql_getnores(dbConn, tmpSql);
					} else {
						//gettimeofday(&tpstart, NULL);
						ReceiveTCP(loop, port_status[loop].connfd,
								   port_status[loop].loginFlag);
						//gettimeofday(&tpend, NULL);
						//timeuse = 1000000 * (tpend.tv_sec - tpstart.tv_sec) + tpend.tv_usec - tpstart.tv_usec;
						//printf("Used Time:%f\n", timeuse);
					}
				}
			}
		}
	}
}

/*************************************************
Function:        // CheckPwd
Description:     // 检查客户端的密码是否正确
Calls:           // ReceiveTCP; 
Called By:       // ReceiveMsg;
Table Accessed:  // OMC_PUB.sysUser
Table Updated:   // 
Input:           // loop:the index of port_status; sock:the sockID of the client
Output:          // 
Return:          // 0:successful; >0:failed
Others:          // 
*************************************************/
int CheckPwd(int loop, int sock)
{
	long l_time;
	struct tm *t;
	char selSql[1024] = "\0";
	MYSQL_RES *selRes = NULL;
	MYSQL_ROW selRow;
	char tmpSql[1024];
	
	CheckDbConnection();

	//telnet连接后，向客户端提示输入用户名
	if (1 != port_status[loop].usernameFlag) {
		port_status[loop].usernameFlag = 1;
		port_status[loop].username[0] = '\0';
		port_status[loop].passwd[0] = '\0';
		sprintf(OutputBuf, "%s", "username:");
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		//开始计算等待时间
		port_status[loop].time = time(NULL);
	}

	if (!ReceiveTCP(loop, sock, port_status[loop].loginFlag)) {
		//如未输入用户名，则输入用户名
		if (strlen(port_status[loop].username) <= 0) {
			snprintf(port_status[loop].username,
					 sizeof(port_status[loop].username), "%s", InputBuf);
			sprintf(OutputBuf, "%s", "password:\33[30m");
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
		} else {
			sprintf(OutputBuf, "%s", "\33[0m");
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			//保存密码
			snprintf(port_status[loop].passwd,
					 sizeof(port_status[loop].passwd), "%s", InputBuf);
			sprintf(selSql,
					"SELECT count(*) FROM %s WHERE userName = '%s' AND password=md5('%s')",
					sysUserTable, port_status[loop].username,
					port_status[loop].passwd);
			CheckDbConnection();
			selRes = mysql_getres(dbConn, selSql);
			//check mysql gone away
			/*
			if(selRes == NULL)
			{
				selRes = Reconnect(selSql, "localhost", "OMC_PUB");
			}
			*/
			selRow = mysql_fetch_row(selRes);
			mysql_free_result(selRes);
			//验证用户名和密码的正确性
			//密码正确
			if (atoi(selRow[0]) > 0) {
				sprintf(selSql,
						"SELECT privilege FROM %s WHERE userName = '%s' AND password=md5('%s')",
						sysUserTable, port_status[loop].username,
						port_status[loop].passwd);
				CheckDbConnection();
				selRes = mysql_getres(dbConn, selSql);
				/*
				if(selRes == NULL)
				{
					selRes = Reconnect(selSql, "localhost", "OMC_PUB");
				}
				*/
				selRow = mysql_fetch_row(selRes);
				mysql_free_result(selRes);
				port_status[loop].privilege = atoi(selRow[0]);
				port_status[loop].loginFlag = 1;
				usleep(delayTime);
				sprintf(OutputBuf, "%s", "CLI>");
				port_status[loop].time = time(NULL);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				l_time = time(NULL);
				t = localtime(&l_time);
				//插入操作记录
				sprintf(tmpSql, "INSERT INTO %s	"
						"(operTypeNo,operNo,remark,userName,datetime)"
						"VALUES"
						"(\'0\',\'0\',\'Login succeed\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
						sysOperLogTable, port_status[loop].username,
						t->tm_year + 1900,
						t->tm_mon + 1,
						t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
				printf("\n tmpSql=%s \n", tmpSql);
#endif
				mysql_getnores(dbConn, tmpSql);
			}
			//密码错误 
			else {
				sprintf(OutputBuf, "%s", "Login incorrect\n\r");
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				l_time = time(NULL);
				t = localtime(&l_time);
				sprintf(tmpSql, "INSERT INTO %s	"
						"(operTypeNo,operNo,remark,userName,datetime)"
						"VALUES"
						"(\'0\',\'0\',\'Login failed\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
						sysOperLogTable, port_status[loop].username,
						t->tm_year + 1900,
						t->tm_mon + 1,
						t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
				printf("\n tmpSql=%s \n", tmpSql);
#endif
				mysql_getnores(dbConn, tmpSql);
				port_status[loop].usernameFlag = 0;
				port_status[loop].failNo++;
				port_status[loop].username[0] = '\0';
			}
		}


	}
	if (3 == port_status[loop].failNo)
		CloseTcpConnect(sock);
	return 0;
}

/*************************************************
Function:        // ReceiveTCP
Description:     // 解析命令，分析命令类型，并且执行相应的操作
Calls:           // procAccount; procInput; doCmdDisconnect; doCmdExport; ......
Called By:       // ReceiveMsg
Table Accessed:  // OMC_PUB.sysUser
Table Updated:   // 
Input:           // loop:the index of port_status; sock:the sockID of the client; loginFlag:login or not
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int ReceiveTCP(int loop, int sock, unsigned char loginFlag)
{
	int i, j, nbytes;
	socklen_t len;
	struct sockaddr_in sin;
	char tmpSql[2048];
	long l_time;
	struct tm *t;

	char tmpString[32];

	char *tmpStr;
	
	CheckDbConnection();
	
	//初始化输入缓冲区
	memset(InputBuf, 0, InputBufSize);

	if (port_status[loop].multiPacketFlag != 1) {
		len = sizeof(struct sockaddr);
		nbytes =
			recvfrom(sock, InputBuf, 1600, 0, (struct sockaddr *) &sin,
					 &len);
		if (nbytes < 0) {
			return 1;
		}
		
		//printf("\n==============================\n");
		char *lastR;
		static int flowFlag=0,needCut=0;
		static char lastInput[512];
		static char tmpIn[8192];
		
		if(nbytes == 1600 && InputBuf[nbytes-2] != 0x0d && InputBuf[nbytes-1] != 0x0a)
			needCut=1;
		//printf("l3=%02x,l2=%02x,l1=%02x\n",InputBuf[nbytes-3],InputBuf[nbytes-2],InputBuf[nbytes-1]);
		if(flowFlag == 1)
		{
			//printf("lastInput=%s\n",lastInput);
			memset(tmpIn,0,8192);
			sprintf(tmpIn,"%s%s",lastInput,InputBuf);
			memcpy(InputBuf,tmpIn,8192);
			nbytes+=strlen(lastInput);
			flowFlag=0;
		}
		
		if(needCut)
		{
			
			if((lastR=strrchr(InputBuf,0x0d)) != NULL)
			{
				sprintf(lastInput,"%s",lastR+2);
				//printf("lastR=%s\n",lastR+2);
				*lastR='\0';
				nbytes=strlen(InputBuf);
				//printf("len=%d\n",nbytes);
				flowFlag=1;
			}
		}
		needCut=0;

		//连接错误
		if (nbytes == 0) {
			//printf("tcp link error : %d\n", errno);
			l_time = time(NULL);
			t = localtime(&l_time);
			sprintf(tmpSql, "INSERT INTO %s "
					"(operTypeNo,operNo,remark,userName,datetime)"
					"VALUES"
					"(\'0\',\'0\',\'tcp link error : %d\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
					sysOperLogTable, errno, port_status[loop].username,
					t->tm_year + 1900,
					t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min,
					t->tm_sec);
#ifdef SMCLI_DEBUG
			printf("\n tmpSql=%s \n", tmpSql);
#endif
			mysql_getnores(dbConn, tmpSql);
			CloseTcpConnect(sock);
		}
#ifdef SMCLI_DEBUG
		printf("Recv bytes:%d\n", nbytes);
		printf("Recv Content:%s \n", InputBuf);
#endif
		port_status[loop].multiPacketFlag = 0;
		for (i = 0; i < MaxCmdTypeNum; i++) {
			if ((tmpStr = strstr(InputBuf + 16, anotherCmdList[i]))&&(*(tmpStr-1)!='-')) {
				if (port_status[loop].multiPacketFlag == 0)
					strcpy(port_status[loop].secondPacket, tmpStr);
				else {
					strcat(tmpStr, port_status[loop].secondPacket);
					strcpy(port_status[loop].secondPacket, tmpStr);
				}
				*tmpStr = 0;
				port_status[loop].multiPacketFlag = 1;
			}
		}
	} else {
		strcpy(InputBuf, port_status[loop].secondPacket);
		port_status[loop].multiPacketFlag = 0;
		for (i = 0; i < MaxCmdTypeNum; i++) {
			if ((tmpStr = strstr(InputBuf + 16, anotherCmdList[i]))&&(*(tmpStr-1)!='-')) {
				if (port_status[loop].multiPacketFlag == 0)
					strcpy(port_status[loop].secondPacket, tmpStr);
				else {
					strcat(tmpStr, port_status[loop].secondPacket);
					strcpy(port_status[loop].secondPacket, tmpStr);
				}
				*tmpStr = 0;
				port_status[loop].multiPacketFlag = 1;
			}
		}
	}
	i = strlen(InputBuf);
	/*
	   if (InputBuf[0] < ' ' || InputBuf[0] > '~')
	   return 1;
	   while (' ' > InputBuf[i - 1] || InputBuf[i - 1] > '~') {
	   i = i - 1;
	   }
	 */
	if (!loginFlag && (InputBuf[0] < ' ' || InputBuf[0] > '~'))
		return 1;
	while ('\n' == InputBuf[i - 1] || InputBuf[i - 1] == '\r') {
		i = i - 1;
	}
	InputBuf[i] = '\0';
	for (j = 0; j < i; j++) {
		if (' ' > InputBuf[j] || InputBuf[j] > '~')
			InputBuf[j] = ' ';
	}

	strcpy(port_status[loop].tmpInputBuf, InputBuf);

	if (!loginFlag)
		return 0;

	i = 0;
	tmpString[0]=0;
	while (InputBuf[i] != ' ' && InputBuf[i] != 0)
		i++;
	while (InputBuf[i] == ' ')
		i++;
	if (i != strlen(InputBuf)) {
		for (j = 0; j < 32; j++) {
			if (InputBuf[i + j] == ' ' || InputBuf[i + j] == 0)
				break;
			tmpString[j] = InputBuf[i + j];
		}
		tmpString[j] = 0;
	}
	//added for the configuration of parameters
	if ((!strcmp(tmpString, "hlrParam"))
		|| (!strcmp(tmpString, "ppsParam"))
		|| (!strcmp(tmpString, "vmsParam"))
		|| (!strcmp(tmpString, "oppsParam"))) {
		pmcli(InputBuf, loop);
		return (0);
	}
	
	//解析命令的操作类型
	if (procInput(InputBuf, 0, sock, loop) == 0) {	//check command passed
		if (cmdBuf == &defCmdBuf[0]) {
			procAccount(sock, loop);
			return (0);
		}
		switch (CmdTypeNo) {
		case CMD_CONNECT:
			doCmdConnect(sock, loop);
			break;
		case CMD_READ:
			doCmdRead(0, sock, loop);
			break;
		case CMD_MODIFY:
			CmdTypeNo = CMD_READ;
			ModifyFlag = 1;
			//2008-09-22, register the opr don't need read operation
			if(strcmp(cmdBuf->objectStr,"registerOpr")!=0)
			{
				if (1 == doCmdRead(0, sock, loop)) {
					ModifyFlag = 0;
					break;
				}
			}
			CmdTypeNo = CMD_MODIFY;
			ModifyFlag = 0;
			doCmdModify(sock, loop);
			break;
		case CMD_CREATE:
			doCmdCreate(0, sock, loop);
			break;
		case CMD_DELETE:
			CmdTypeNo = CMD_READ;
			ModifyFlag = 1;
			if (1 == doCmdRead(0, sock, loop)) {
				ModifyFlag = 0;
				break;
			}
			CmdTypeNo = CMD_DELETE;
			ModifyFlag = 0;
			doCmdDelete(sock, loop);
			break;
		case CMD_EXPORT:
			doCmdExport(sock, loop);
			break;
		case CMD_IMPORT:
			doCmdImport(InputBuf, sock, loop);
			break;
		case CMD_DISCONNECT:
			doCmdDisconnect(sock, loop);
			break;
		case CMD_RECHARGE:
			CmdTypeNo = CMD_READ;
			ModifyFlag = 1;
			if (1 == doCmdRead(0, sock, loop)) {
				ModifyFlag = 0;
				break;
			}
			CmdTypeNo = CMD_RECHARGE;
			ModifyFlag = 0;
			doCmdRecharge(sock, loop);	//20041010
			break;
		case CMD_ALIVE:
			doCmdAlive(sock);
			break;
		case CMD_HELP:
			doCmdHelp(sock);
			break;
		default:
			sprintf(OutputBuf, "%s:%d\n\r", ERR_0001, CmdTypeNo);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
		}
	} else {
		//printf("Check Command Error!!\n");    
	}
	//printf("%s\n",OutputBuf);
	//writeDebug("port_status[loop].expDoingFlag:%d,port_status[loop].impDoingFlag:%d!",port_status[loop].expDoingFlag,port_status[loop].impDoingFlag);
	if (!port_status[loop].expDoingFlag && !port_status[loop].impDoingFlag) {
		l_time = time(NULL);
		t = localtime(&l_time);
		sprintf(tmpSql, "INSERT INTO %s	"
				"(operTypeNo,operNo,remark,userName,datetime)"
				"VALUES"
				"(\'0\',\'0\',\'Command:%s,Result:%s\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
				sysOperLogTable, port_status[loop].tmpInputBuf, OutputBuf,
				port_status[loop].username, t->tm_year + 1900,
				t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min,
				t->tm_sec);
#ifdef SMCLI_DEBUG
		printf("\n tmpSql=%s \n", tmpSql);
#endif
		mysql_getnores(dbConn, tmpSql);
		usleep(delayTime);
		//继续等待下一条命令的输入
		sprintf(OutputBuf, "%s", "CLI>");
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		port_status[loop].time = time(NULL);
	}

	return 0;
}

/*************************************************
Function:        // CloseTcpConnect
Description:     // 关闭客户端连接
Calls:           // close;
Called By:       // ReceiveMsg; procInput;
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sock want to be closed
Output:          // 
Return:          // 0:successful; >0:failed
Others:          // 
*************************************************/
int CloseTcpConnect(int sock)
{
	int loop;
	int i;
	for (loop = 0; loop < MAX_CLIENTS; loop++) {
		//关闭指定的套接字
		if (sock == port_status[loop].connfd) {
			close(sock);
			port_status[loop].connfd = -1;
			port_status[loop].peerip = 0;
			port_status[loop].peerport = 0;
			//  port_status[loop].username[0] = '\0';
			//  port_status[loop].passwd[0] = '\0';
			port_status[loop].loginFlag = 0;
			port_status[loop].failNo = 0;
			port_status[loop].usernameFlag = 0;
			for (i = 1; i < CmdBufSize; i++)
				port_status[loop].isConnected[i] = 0;
			break;
		}
	}
	return 0;
}

/*************************************************
Function:        // procInput
Description:     // 解析出输入命令的类型
Calls:           // CloseTcpConnect; send; 
Called By:       // doingCmdImport; changeDefaultValue; ReceiveTCP; 
Table Accessed:  // 
Table Updated:   // 
Input:           // inputBuf:输入缓冲区; importFlag:是否有import操作; sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int procInput(char *inputBuf, unsigned char importFlag, int sock, int loop)
{
	char *paramPart = NULL;
	char *onePart = NULL;
	char tmpStr[32];
	int i = 0;
	int j = 0;
	int k = 0;
	int optNo;

	OptNo_index = 8;

	for (i = 0; i < CmdBufSize; i++)
		defCmdBuf[i].isConnected = port_status[loop].isConnected[i];
	i = 0;

	//断开连接的命令
	if (strstr(InputBuf, "exit") || strstr(InputBuf, "quit")) {
		sprintf(OutputBuf, "%s", "Good bye\n\r");
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		CloseTcpConnect(sock);
		sprintf(OutputBuf, "%s", "Login out");
		return (1);

	}

	
	while ((paramPart = strsep(&(inputBuf), "-"))) {
		//writeDebug("paramPart=%s,inputBuf=%s",paramPart,inputBuf);
		if (strlen(paramPart) < 2) {
			sprintf(OutputBuf, "%s:%s\n\r", ERR_0001, onePart);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}

		switch (i) {
		case 0:				//command and object
			if (importFlag == 0) {
				//first part is command name
				if ((onePart = strsep(&(paramPart), " "))) {
					if (strcasecmp("help", onePart) == 0) {
						CmdTypeNo = CMD_HELP;
						return (0);
					} else if (strcasecmp("?Alive", onePart) == 0) {
						CmdTypeNo = CMD_ALIVE;
						return (0);
					}
					//try to find
					for (j = 0; j < MaxCmdTypeNum; j++) {
						if (strcmp(CmdList[j], onePart) == 0) {
							CmdTypeNo = j + 1;
							break;
						}
					}
					//cannot find
					if (j == MaxCmdTypeNum) {
#ifdef SMCLI_DEBUG
						printf("%d-", __LINE__);
#endif
						sprintf(OutputBuf, "%s:%s\n\r", ERR_0001, onePart);
						OutputLen = strlen(OutputBuf);
						send(sock, OutputBuf, OutputLen, 0);
						return (1);
					}
				} else {
#ifdef SMCLI_DEBUG
					printf("%d-", __LINE__);
#endif
					sprintf(OutputBuf, "%s\n\r", ERR_0002);
					OutputLen = strlen(OutputBuf);
					send(sock, OutputBuf, OutputLen, 0);
					return (1);
				}
			}					//end of if(importFlag == 0)
			//second part is command object
			//if ((onePart = strsep(&(paramPart), " "))) {
			if (paramPart != NULL) {
				k = strlen(paramPart);
				while (' ' == *(paramPart + k - 1)) {
					k = k - 1;
					if (k == 0)
						break;
				}
				*(paramPart + k) = '\0';
			}
			if (paramPart != NULL) {
				onePart = paramPart;
				if (CmdTypeNo == CMD_CONNECT || CmdTypeNo == CMD_DISCONNECT) {	//object string like "hlr" or "pps"
					for (j = 0; j < CmdBufSize; j++) {
						if (strcmp(onePart, defCmdBuf[j].serverStr) == 0) {
							cmdBuf = &defCmdBuf[j];
							if (cmdBuf->cmdFlag[CmdTypeNo - 1] >
								port_status[loop].privilege) {
								sprintf(OutputBuf, "%s:%s %s\n\r",
										ERR_0005, CmdList[CmdTypeNo - 1],
										onePart);
								OutputLen = strlen(OutputBuf);
								send(sock, OutputBuf, OutputLen, 0);
								return (1);
							}
							initCmdBuf(cmdBuf);
							break;
						}
					}
					if (j == CmdBufSize) {
						sprintf(OutputBuf, "%s:%s\n\r", ERR_0003, onePart);
						OutputLen = strlen(OutputBuf);
						send(sock, OutputBuf, OutputLen, 0);
						return (1);
					}
				} else {		//object string like "subscriber" or "pdpcontext" or "ppscard" ...
					for (j = 0; j < CmdBufSize; j++) {
						if (strcmp(onePart, defCmdBuf[j].objectStr) == 0) {
							if (defCmdBuf[j].isConnected == 0) {
								sprintf(OutputBuf, "%s\n\r", ERR_0254);
								OutputLen = strlen(OutputBuf);
								send(sock, OutputBuf, OutputLen, 0);
								return (1);
							}
							cmdBuf = &defCmdBuf[j];
							if (cmdBuf->cmdFlag[CmdTypeNo - 1] >
								port_status[loop].privilege) {
								sprintf(OutputBuf, "%s:%s %s\n\r",
										ERR_0005, CmdList[CmdTypeNo - 1],
										onePart);
								OutputLen = strlen(OutputBuf);
								send(sock, OutputBuf, OutputLen, 0);
								return (1);
							}
							initCmdBuf(cmdBuf);
#ifdef SMCLI_DEBUG
							printf("initing %s\n", cmdBuf->objectStr);
#endif
							break;
						}
					}
					if (j == CmdBufSize) {
						/*if (cmdBuf->isConnected == 0) {
						   sprintf(OutputBuf,
						   "%s:You must connect to server first\n\r",
						   ERR_0200);
						   OutputLen = strlen(OutputBuf);
						   send(sock, OutputBuf, OutputLen, 0);
						   return (1);
						   } else */  {
							//unknown object string
#ifdef SMCLI_DEBUG
							printf("%d-", __LINE__);
#endif
							sprintf(OutputBuf, "%s:%s\n\r", ERR_0003,
									onePart);
							OutputLen = strlen(OutputBuf);
							send(sock, OutputBuf, OutputLen, 0);
							return (1);
						}
					}
				}
			} else {
#ifdef SMCLI_DEBUG
				printf("%d-", __LINE__);
#endif
				sprintf(OutputBuf, "%s\n\r", ERR_0002);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
			break;
		default:				//parameters name and value
			//parameter name
			if(!strstr(paramPart," "))
						{
							sprintf(OutputBuf,
									"%s.\n",ERR_0003);
							OutputLen = strlen(OutputBuf);
							send(sock, OutputBuf, OutputLen, 0);
							return (1);
								
						}
			if ((onePart = strsep(&(paramPart), " "))) {
				//writeDebug("paramPart1:%s,onePart:%s",paramPart,onePart);
				if(!strlen(paramPart))
						{
							sprintf(OutputBuf,
									"%s.\n",ERR_0003);
							OutputLen = strlen(OutputBuf);
							send(sock, OutputBuf, OutputLen, 0);
							return (1);
								
						}
				//try find from cmdBuf(command define array)
				for (optNo = 0; optNo < cmdBuf->optDefNum; optNo++) {
					if (strcmp(onePart, cmdBuf->optDef[optNo].optName) ==
						0) {
						//check option define
						if (cmdBuf->optDef[optNo].optFlag[CmdTypeNo] <=
							port_status[loop].privilege) {
							cmdBuf->optDef[optNo].optFlag[0] = 1;
							break;
						} else {
#ifdef SMCLI_DEBUG
							printf("%d-", __LINE__);
#endif
							sprintf(OutputBuf, "%s:%s\n\r", ERR_0012,
									onePart);
							OutputLen = strlen(OutputBuf);
							send(sock, OutputBuf, OutputLen, 0);
							return (1);
						}
					}
				}
				//cannot find
				if (optNo == cmdBuf->optDefNum) {
#ifdef SMCLI_DEBUG
					printf("%d-", __LINE__);
#endif
					sprintf(OutputBuf, "%s:%s\n\r", ERR_0010, onePart);
					OutputLen = strlen(OutputBuf);
					send(sock, OutputBuf, OutputLen, 0);
					return (1);
				}
			} else {
#ifdef SMCLI_DEBUG
				printf("%d-", __LINE__);
#endif
				sprintf(OutputBuf, "%s\n\r", ERR_0002);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
			//parameter value
			if (CmdTypeNo == CMD_EXPORT
				&& (strcmp(onePart, "query") == 0
					|| strcmp(onePart, "fields") == 0)) {
				//writeDebug("paramPart2:%s,onePart:%s",paramPart,onePart);
				if (strcmp(onePart, "query") == 0) {					
					onePart = strsep(&(paramPart), "\"");	//front of first\"												
					//writeDebug("paramPart3:%s,onePart:%s",paramPart,onePart);
					if(!strlen(paramPart)||!strlen(onePart)&&inputBuf==NULL)
					{
						sprintf(OutputBuf,"%s.\n",ERR_0003);
						OutputLen = strlen(OutputBuf);
						send(sock, OutputBuf, OutputLen, 0);
						return (1);				
					}
					onePart = strsep(&(paramPart), "\"");	//behind of first \" and front of second \"
					paramPart = onePart;
					onePart = strsep(&(paramPart), " ");
					if (strcmp
						(onePart,
						 cmdBuf->optDef[OptNo_index].optName) == 0) {

						char queryList[7][16] =
							{ {"contains"}, {"doesntcontain"},
						{"beginswith"},
						{"endswith"}, {"like"}, {"is"}, {"isnt"}
						};

						strcpy(tmpStr,
							   cmdBuf->optDef[OptNo_index].fieldName);
						optNo = OptNo_index;					
						onePart = strsep(&(paramPart), " ");
						
						for (j = 0; j < 7; j++) {
							if (strcmp(onePart, queryList[j]) == 0) {
								break;
							}
						}
						if (j == 7) {
							sprintf(OutputBuf,
									"%s:unknown comparator \"%s\"\n\r",
									ERR_0003, onePart);
							OutputLen = strlen(OutputBuf);
							send(sock, OutputBuf, OutputLen, 0);
							return (1);
						}
						//writeDebug("j:%d,onePart:%s,cmdBuf->optDef[OptNo_index].fieldName:%s",j,onePart,cmdBuf->optDef[OptNo_index].fieldName);
						switch (j) {
						case 0:	//contains
						case 4:	//like
							sprintf(ExportQueryStr, "%s LIKE ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(tmpStr, "\'%%%s%%\'", onePart);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 1:	//doesntcontains
							sprintf(ExportQueryStr, "%s NOT LIKE ",
									tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(tmpStr, "\'%%%s%%\'", onePart);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 2:	//beginswith
							sprintf(ExportQueryStr, "%s LIKE ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							if (cmdBuf->sysTypeNo == 330) {
								sprintf(tmpStr, "\'0%s%%\'", onePart);
							} else {
								sprintf(tmpStr, "\'%s%%\'", onePart);
							}
							strcat(ExportQueryStr, tmpStr);
							break;
						case 3:	//endswith
							sprintf(ExportQueryStr, "%s LIKE ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(tmpStr, "\'%%%s\'", onePart);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 5:	//is
							sprintf(ExportQueryStr, "%s = ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(cmdBuf->optDef[optNo].optValue, "%s",
									onePart);
							if (exValueOptToField(optNo) == 1) {
								sprintf(OutputBuf, "%s:%s %s\n\r",
										ERR_0203,
										cmdBuf->optDef[optNo].optName,
										cmdBuf->optDef[optNo].optValue);
								OutputLen = strlen(OutputBuf);
								send(sock, OutputBuf, OutputLen, 0);
								//writeDebug("1:%s",OutputBuf);
								return (1);
							}

							sprintf(tmpStr, "\'%s\'",
									cmdBuf->optDef[optNo].fieldValue);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 6:	//isn't
							sprintf(ExportQueryStr, "%s != ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(cmdBuf->optDef[optNo].optValue, "%s",
									onePart);
							if (exValueOptToField(optNo) == 1) {
								sprintf(OutputBuf, "%s:%s %s\n\r",
										ERR_0203,
										cmdBuf->optDef[optNo].optName,
										cmdBuf->optDef[optNo].optValue);
								OutputLen = strlen(OutputBuf);
								send(sock, OutputBuf, OutputLen, 0);
								//writeDebug("2:%s",OutputBuf);
								return (1);
							}
							sprintf(tmpStr, "\'%s\'",
									cmdBuf->optDef[optNo].fieldValue);
							strcat(ExportQueryStr, tmpStr);
							break;
						}

					} else if (cmdBuf->sysTypeNo == 330
							   && strcmp(onePart, "msisdn") == 0) {

						char queryList[7][16] =
							{ {"contains"}, {"doesntcontain"},
						{"beginswith"},
						{"endswith"}, {"like"}, {"is"}, {"isnt"}
						};

						strcpy(tmpStr,
							   cmdBuf->optDef[OptNo_index + 3].fieldName);
						optNo = OptNo_index + 3;

						onePart = strsep(&(paramPart), " ");

						for (j = 0; j < 7; j++) {
							if (strcmp(onePart, queryList[j]) == 0) {
								break;
							}
						}
						if (j == 7) {
							sprintf(OutputBuf,
									"%s:unknown comparator \"%s\"\n\r",
									ERR_0003, onePart);
							OutputLen = strlen(OutputBuf);
							send(sock, OutputBuf, OutputLen, 0);
							return (1);
						}

						switch (j) {
						case 0:	//contains
						case 4:	//like
							sprintf(ExportQueryStr, "%s LIKE ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(tmpStr, "\'%%%s%%\'", onePart);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 1:	//doesntcontains
							sprintf(ExportQueryStr, "%s NOT LIKE ",
									tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(tmpStr, "\'%%%s%%\'", onePart);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 2:	//beginswith
							sprintf(ExportQueryStr, "%s LIKE ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(tmpStr, "\'91%s%%\'", onePart);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 3:	//endswith
							sprintf(ExportQueryStr, "%s LIKE ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(tmpStr, "\'%%%sE%%\'", onePart);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 5:	//is
							sprintf(ExportQueryStr, "%s = ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(cmdBuf->optDef[optNo].optValue, "%s",
									onePart);
							if (exValueOptToField(optNo) == 1) {
								sprintf(OutputBuf, "%s:%s %s\n\r",
										ERR_0203,
										cmdBuf->optDef[optNo].optName,
										cmdBuf->optDef[optNo].optValue);
								OutputLen = strlen(OutputBuf);
								send(sock, OutputBuf, OutputLen, 0);
								//writeDebug("3:%s",OutputBuf);
								return (1);
							}

							sprintf(tmpStr, "\'%s\'",
									cmdBuf->optDef[optNo].fieldValue);
							strcat(ExportQueryStr, tmpStr);
							break;
						case 6:	//isn't
							sprintf(ExportQueryStr, "%s != ", tmpStr);
							onePart = strsep(&(paramPart), " ");
							sprintf(cmdBuf->optDef[optNo].optValue, "%s",
									onePart);
							if (exValueOptToField(optNo) == 1) {
								sprintf(OutputBuf, "%s:%s %s\n\r",
										ERR_0203,
										cmdBuf->optDef[optNo].optName,
										cmdBuf->optDef[optNo].optValue);
								OutputLen = strlen(OutputBuf);
								send(sock, OutputBuf, OutputLen, 0);
								//writeDebug("4:%s",OutputBuf);
								return (1);
							}
							sprintf(tmpStr, "\'%s\'",
									cmdBuf->optDef[optNo].fieldValue);
							strcat(ExportQueryStr, tmpStr);
							break;
						}
					} else {
#ifdef SMCLI_DEBUG
						printf("%d-", __LINE__);
#endif
						sprintf(OutputBuf, "%s:%s\n\r", ERR_0002, onePart);
						OutputLen = strlen(OutputBuf);
						send(sock, OutputBuf, OutputLen, 0);
						return (1);
					}
					sprintf(cmdBuf->optDef[OptNo_query].optValue,
							"ExportQueryStr");
					cmdBuf->optDef[OptNo_query].optFlag[0] = 1;
#ifdef SMCLI_DEBUG
					printf("ExportQueryStr=%s\n", ExportQueryStr);
#endif
				} else {		//strcmp(onePart,"fields") == 0

					onePart = strsep(&(paramPart), "\"");	//front of first\"
					onePart = strsep(&(paramPart), "\"");	//behind of first \" and front of second \"
					paramPart = onePart;

					memset(FieldNameList, 0, sizeof(FieldNameList));
					memset(ExportFieldsStr, 0, sizeof(ExportFieldsStr));

					while ((onePart = strsep(&(paramPart), " "))) {
						optNo = getOptNoByName(onePart);
						if (optNo <= 0) {
#ifdef SMCLI_DEBUG
							printf("%d-", __LINE__);
#endif
							sprintf(OutputBuf,
									"%s:Unknown field name \"%s\"\n\r",
									ERR_0002, onePart);
							OutputLen = strlen(OutputBuf);
							send(sock, OutputBuf, OutputLen, 0);
							return (1);
						}
						cmdBuf->optDef[optNo].optFlag[0] = 1;
						sprintf(ExportFieldsStr, "%s %s", ExportFieldsStr,
								cmdBuf->optDef[optNo].optName);
						sprintf(FieldNameList, "%s,%s", FieldNameList,
								cmdBuf->optDef[optNo].fieldName);
					}
					strcat(ExportFieldsStr, " ");
					sprintf(cmdBuf->optDef[OptNo_fields].optValue,
							"ExportFieldsStr");
					cmdBuf->optDef[OptNo_fields].optFlag[0] = 1;
#ifdef SMCLI_DEBUG
					printf("ExportFieldsStr=%s\n", ExportFieldsStr);
					printf("FieldNameList=%s\n", FieldNameList);
#endif
				}
			} else {
				//if ((onePart = strsep(&(paramPart), " "))) {
				if (paramPart != NULL) {
					k = strlen(paramPart);
					while (' ' == *(paramPart + k - 1)) {
						k = k - 1;
						if (k == 0)
							break;
					}
					*(paramPart + k) = '\0';
				}
				if (paramPart != NULL) {
					onePart = paramPart;
					if (strlen(onePart) >=
						sizeof(cmdBuf->optDef[optNo].optValue)) {
#ifdef SMCLI_DEBUG
						printf("%d-", __LINE__);
#endif
						sprintf(OutputBuf, "%s:%s's length error\n\r",
								ERR_0003, cmdBuf->optDef[optNo].optName);
						OutputLen = strlen(OutputBuf);
						send(sock, OutputBuf, OutputLen, 0);
						return (1);
					}
					//when you operate the VMS subscriber,you must input the server ip
					if (cmdBuf->sysTypeNo == 390) {
						if (strcmp(cmdBuf->optDef[optNo].optName, "srvip")
							== 0) {
							if (cmdBuf->isConnected == 1) {
								if (CmdTypeNo == CMD_CONNECT) {
									if (strcmp
										(cmdBuf->optDef[optNo].optValue,
										 onePart) != 0) {
										sprintf(OutputBuf, "%s\n\r",
												ERR_0261);
										OutputLen = strlen(OutputBuf);
										send(sock, OutputBuf, OutputLen,
											 0);
										return (1);
									}
								} else {
									if (strcmp
										(cmdBuf->optDef[optNo].optValue,
										 onePart) != 0) {
										sprintf(OutputBuf, "%s\n\r",
												ERR_0254);
										OutputLen = strlen(OutputBuf);
										send(sock, OutputBuf, OutputLen,
											 0);
										return (1);
									}
								}
							}
						}
					}

					sprintf(cmdBuf->optDef[optNo].optValue, "%s", onePart);
				} else {
					sprintf(OutputBuf, "%s:-%s's value zero\n\r", ERR_0003,
							cmdBuf->optDef[optNo].optName);
					OutputLen = strlen(OutputBuf);
					send(sock, OutputBuf, OutputLen, 0);
					return (1);
				}
			}
#ifdef SMCLI_DEBUG
			printf("%s=%s\n", cmdBuf->optDef[optNo].optName,
				   cmdBuf->optDef[optNo].optValue);
#endif
			break;
		}						//end of switch
		i++;
	}							//end of while

	//check mandatory flag
	//if (importFlag == 0) {
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if ((cmdBuf->optDef[i].optFlag[CmdTypeNo] == 0)
			&& (cmdBuf->optDef[i].optFlag[0] == 0)) {
			if (cmdBuf == &defCmdBuf[1] && i == OptNo_index
				&& (CmdTypeNo == CMD_READ || CmdTypeNo == CMD_MODIFY
					|| CmdTypeNo == CMD_DELETE)
				&& cmdBuf->optDef[HLR_OptNo_indexSec].optFlag[0] == 1) {
				OptNo_index = HLR_OptNo_indexSec;
				continue;
			}
			sprintf(OutputBuf,
					"%s:Mandatory parameter \"-%s\" no supplied\n\r",
					ERR_0002, cmdBuf->optDef[i].optName);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
	}
	//}

	return (0);
}

/*************************************************
Function:        // sendCmd
Description:     // 把客户端的命令发送到用户数据命令表里，以便让subsComm进行处理
Calls:           // mysql_free_result; mysql_getnores; send; 
Called By:       // doCmdConnect; doCmdDisconnect; .....
Table Accessed:  // OMC_PUB.subscriberComm
Table Updated:   // OMC_PUB.subscriberComm
Input:           // sock:the sockId of the client; loop:the index of port_status;
Output:          // 
Return:          // 0:successful; 1:failed;
Others:          // 
*************************************************/
int sendCmd(int sock, int loop)
{
	char tmpSql[4096];
	int i;

	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;
	int cmdTypeNo;
	int tmpDataTypeNo;
	
	CheckDbConnection();

	if ((cmdBuf->sysTypeNo == 330)
		&&
		(!strcmp(cmdBuf->optDef[OptNo_index].fieldName, "inter_msisdn")))
		tmpDataTypeNo = 1;
	else
		tmpDataTypeNo = cmdBuf->dataTypeNo;

	for (i = 1; i < CmdBufSize; i++) {
		defCmdBuf[i].sysNo = port_status[loop].sysNo[i];
		defCmdBuf[i].subSysNo = port_status[loop].subSysNo[i];
	}

/*
	//delete older command 30 minutes ago
	sprintf(tmpSql,"DELETE %s WHERE sendTime < FROM_UNIXTIME(UNIX_TIMESTAMP() - 1800)",
			CommandTable);
//#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n",tmpSql);
//#endif
	mysql_getnores(dbConn,tmpSql);
*/
	//check command
	sprintf(tmpSql, "SELECT commId FROM %s "
			" WHERE sysTypeNo=\'%d\' AND ( commState=\'1\' OR commState=\'2\')"
			" AND dataTypeNo=\'%d\' "
			" AND indexValueList=\'%s\'",
			CommandTable,
			cmdBuf->sysTypeNo,
			tmpDataTypeNo, cmdBuf->optDef[OptNo_index].fieldValue);
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);
	//if(tmpResult == NULL)
		//tmpResult = Reconnect(tmpSql, "localhost", "OMC_PUB");
	//等待另外的命令执行完毕
	if (tmpResult != NULL && mysql_num_rows(tmpResult) > 0) {
		mysql_free_result(tmpResult);
		//Please wait this command finished 
		sprintf(OutputBuf, "%s\n\r", ERR_0252);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	mysql_free_result(tmpResult);

	if (CmdId > 50000) {
		//sprintf(tmpSql, "DROP TABLE %s", CommandTable);
		sprintf(tmpSql, "TRUNCATE TABLE %s", CommandTable);
		CheckDbConnection();
		mysql_getnores(dbConn, tmpSql);
		/*
		sprintf(tmpSql, "CREATE TABLE %s"
				"(commId smallint(5) unsigned NOT NULL auto_increment,"
				"commType tinyint(1) DEFAULT '0' NOT NULL,"
				"dataTypeNo tinyint(4) DEFAULT '0' NOT NULL,"
				"sysTypeNo smallint(5) unsigned DEFAULT '0' NOT NULL,"
				"sysNo smallint(5) unsigned DEFAULT '0' NOT NULL,"
				"subSysNo smallint(5) unsigned DEFAULT '0' NOT NULL,"
				"indexValueList varchar(255) NOT NULL,"
				"fieldNameList text NOT NULL,"
				"paramType tinyint(4) DEFAULT '0' NOT NULL,"
				"commState tinyint(3) unsigned DEFAULT '0' NOT NULL,"
				"totalNum smallint(5) unsigned DEFAULT '0' NOT NULL,"
				"finishNum smallint(5) unsigned DEFAULT '0' NOT NULL,"
				"sendTime datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,"
				"bgnTime datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,"
				"endTime datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,"
				"remark varchar(200) binary NOT NULL,"
				"PRIMARY KEY (commId),"
				"KEY sysTypeNo (sysTypeNo),"
				"KEY sysNo (sysNo),"
				"KEY subSysNo (subSysNo),"
				"KEY bufferKey (indexValueList));", CommandTable);
		CheckDbConnection();
		mysql_getnores(dbConn, tmpSql);
		*/
	}

	switch (CmdTypeNo) {
	case CMD_READ:
		cmdTypeNo = 1;
		break;
	case CMD_MODIFY:
		cmdTypeNo = 2;
		break;
	case CMD_CREATE:
		cmdTypeNo = 3;
		break;
	case CMD_DELETE:
		cmdTypeNo = 4;
		break;
	case CMD_EXPORT:
		cmdTypeNo = 1;
		break;
	case CMD_IMPORT:
		cmdTypeNo = 3;
		break;
	case CMD_RECHARGE:
		cmdTypeNo = 2;
		break;
	default:
#ifdef SMCLI_DEBUG
		printf("%d-", __LINE__);
#endif
		sprintf(OutputBuf, "%s:%d\n\r", ERR_0001, CmdTypeNo);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	//把输入命令插入用户数据命令表
	//2008-09-22, register opr must specil the all fields
	if(strcmp(cmdBuf->objectStr,"registerOpr") == 0)
	{
		sprintf(tmpSql, "INSERT INTO %s	"
				"(commType,dataTypeNo,sysTypeNo,sysNo,subSysNo,indexValueList,"
				"fieldNameList,paramType,commState,sendTime,remark)"
				"VALUES"
				"(\'%d\',\'%d\',\'%d\',\'%d\',\'%d\',\'%s\',\'ALL\',"
				"\'0\',\'1\',CURRENT_TIMESTAMP,\'by smcli\')",
				CommandTable,
				cmdTypeNo,
				tmpDataTypeNo,
				cmdBuf->sysTypeNo,
				cmdBuf->sysNo,
				cmdBuf->subSysNo,
				cmdBuf->optDef[OptNo_index].fieldValue);
	}
	else
	{
		sprintf(tmpSql, "INSERT INTO %s	"
				"(commType,dataTypeNo,sysTypeNo,sysNo,subSysNo,indexValueList,"
				"fieldNameList,paramType,commState,sendTime,remark)"
				"VALUES"
				"(\'%d\',\'%d\',\'%d\',\'%d\',\'%d\',\'%s\',\'%s\',"
				"\'0\',\'1\',CURRENT_TIMESTAMP,\'by smcli\')",
				CommandTable,
				cmdTypeNo,
				tmpDataTypeNo,
				cmdBuf->sysTypeNo,
				cmdBuf->sysNo,
				cmdBuf->subSysNo,
				cmdBuf->optDef[OptNo_index].fieldValue, FieldNameList);
	}
			
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	mysql_getnores(dbConn, tmpSql);

	//get commId
	sprintf(tmpSql, "SELECT commId FROM %s "
			" WHERE sysTypeNo=\'%d\' "
			" AND dataTypeNo=\'%d\' "
			" AND indexValueList=\'%s\'",
			CommandTable,
			cmdBuf->sysTypeNo,
			tmpDataTypeNo, cmdBuf->optDef[OptNo_index].fieldValue);
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
		mysql_free_result(tmpResult);
		return (1);		
	}
	tmpRow = mysql_fetch_row(tmpResult);
	CmdId = atoi(tmpRow[0]);
	mysql_free_result(tmpResult);
#ifdef SMCLI_DEBUG
	printf("CmdId=%d ", CmdId);
#endif
	return (0);
}

/*************************************************
Function:        // scanCmd
Description:     // 扫描用户数据命令表，查看命令的执行进度
Calls:           // mysql_getnores; send;
Called By:       // doCmdConnect; doCmdDisconnect; .....
Table Accessed:  // OMC_PUB.subscriberComm
Table Updated:   // 
Input:           // sock:the sockId of the client;
Output:          // 
Return:          // 0:successful; 1:failed;
Others:          // 
*************************************************/
int scanCmd(int sock)
{
	int count = 0;
	int cmdState = 0;
	char tmpSql[1024];
	int i;
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;
#ifdef SMCLI_DEBUG
	int progressFlag = 0;
#endif

	CheckDbConnection();

	if (CmdId <= 0)
		return (1);

	while (1) {
		sprintf(tmpSql, "SELECT commState,remark "
				" FROM %s WHERE commId=\'%d\'", CommandTable, CmdId);
		tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);
#ifdef SMCLI_DEBUG
		if (count == 0) {
			printf(" \n tmpSql = %s \n", tmpSql);
		}
#endif

		if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
			mysql_free_result(tmpResult);
#ifdef SMCLI_DEBUG
			printf("%s: Cannot find %d 's info\n", ERR_0200, CmdId);
#endif
			return (1);
		}
		tmpRow = mysql_fetch_row(tmpResult);
		cmdState = atoi(tmpRow[0]);
		strcpy(ErrorMsg, tmpRow[1]);
		mysql_free_result(tmpResult);

		//printf("cmdState=%d\n", cmdState);
		//printf("ErrorMsg=%s\n", ErrorMsg);

		switch (cmdState) {
		case nProcFail:
			sprintf(tmpSql, "DELETE FROM %s WHERE commId=\'%d\'",
					CommandTable, CmdId);
			mysql_getnores(dbConn, tmpSql);
#ifdef SMCLI_DEBUG
			printf("%d-", __LINE__);
#endif
			//printf("ErrorMsg=%s\n", ErrorMsg);
			//if (CmdTypeNo == CMD_READ || CmdTypeNo == CMD_DELETE) {
			if (CmdTypeNo == CMD_READ) {
				if (!strcmp(ErrorMsg, "response timeout"))
					sprintf(OutputBuf, "%s\n\r", ERR_0255);
				else
					sprintf(OutputBuf,
							"%s:Cannot get this object value record!\n\r",
							ERR_0200);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}

			for (i = 0; i < strlen(ErrorMsg); i++) {
				if (ErrorMsg[i] == ':')
					break;
			}

			if (i == 1)
				sprintf(OutputBuf, "020%s\n\r", ErrorMsg);
			else if (i == 2)
				sprintf(OutputBuf, "02%s\n\r", ErrorMsg);
			else if (!strcmp(ErrorMsg, "response timeout"))
				sprintf(OutputBuf, "%s\n\r", ERR_0255);
			else
				sprintf(OutputBuf,
						"%s:Cannot get this object value record!\n\r",
						ERR_0200);

			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
#ifdef SMCLI_DEBUG
			printf("\n tmpSql = %s \n", tmpSql);
			if (progressFlag == 1) {
				printf("\n");
			}
#endif
			return (1);
		case nWaitProc:
#ifdef SMCLI_DEBUG
			if (count == 0)
				printf("\n");
			if (count % 2 == 0) {
				printf(".");
				progressFlag = 1;
			}
#endif
			break;
		case nInProc:
#ifdef SMCLI_DEBUG
			if (count == 0)
				printf("\n");
			if (count % 4 == 0) {
				printf(">");
				progressFlag = 1;
			}
#endif
			break;
		case nOutProc:
			sprintf(tmpSql, "DELETE FROM %s WHERE commId=\'%d\'",
					CommandTable, CmdId);
			mysql_getnores(dbConn, tmpSql);

#ifdef SMCLI_DEBUG
			printf("ErrorMsg = %s \n", ErrorMsg);
			printf(" \n tmpSql = %s \n", tmpSql);

			if (progressFlag == 1) {
				printf("\n");
			}
#endif
			//printf("count=%d\n",count);
			return (0);
		default:
			break;
		}						//end of switch
		count++;

		if (count >= 100) {
			sprintf(OutputBuf, "%s\n\r", ERR_0255);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			sprintf(tmpSql, "DELETE FROM %s WHERE commId=\'%d\'",
					CommandTable, CmdId);
			mysql_getnores(dbConn, tmpSql);
#ifdef SMCLI_DEBUG
			if (progressFlag == 1) {
				printf("\n");
			}
#endif
			return (1);
		}

		fflush(NULL);
		usleep(200000);			//sleep 0.2 second
	}							//end of while(1)
}

/*************************************************
Function:        // showCmdBuf
Description:     // 显示八种命令的权限，和命令后面的参数
Calls:           // send
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // thisCmdBuf:命令缓冲区; sock:the sockId of the client;
Output:          // 
Return:          // 
Others:          // 作为调试用的
*************************************************/
void showCmdBuf(CmdBuf * thisCmdBuf, int sock)
{
	int i, cmdTypeNo, optType;

	for (cmdTypeNo = 1; cmdTypeNo <= 8; cmdTypeNo++) {
		sprintf(OutputBuf, "======================\n%s\n\r",
				CmdList[cmdTypeNo - 1]);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		for (optType = 1; optType < 4; optType++) {
			switch (optType) {
			case Op_M:
				sprintf(OutputBuf, "mandtory: ");
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				break;
			case Op_O:
				sprintf(OutputBuf, "optional: ");
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				break;
			case Op_S:
				sprintf(OutputBuf, "subjoin: ");
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				break;
			}

			for (i = 0; i < thisCmdBuf->optDefNum; i++) {
				if (thisCmdBuf->optDef[i].optFlag[cmdTypeNo] == optType) {
					printf("-%s ", thisCmdBuf->optDef[i].optName);
				}
			}
			sprintf(OutputBuf, "\n\r");
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
		}
	}
}

/*************************************************
Function:        // initCmdBuf
Description:     // 初始化命令缓冲区的参数的值
Calls:           // memset
Called By:       // changeDefaultValueProcInput;
Table Accessed:  // 
Table Updated:   // 
Input:           // thisCmdBuf:命令缓冲区
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void initCmdBuf(CmdBuf * thisCmdBuf)
{
	int i;
	//char tableName[32];
	//char privilege[32];
	//int cmdNo;
	//char tmpSql[4096];
	//MYSQL_RES *tmpResult = NULL;
	//MYSQL_ROW tmpRow = NULL;

	for (i = 0; i < thisCmdBuf->optDefNum; i++) {
		thisCmdBuf->optDef[i].optFlag[0] = 0;
		memset(thisCmdBuf->optDef[i].fieldValue, 0,
			   sizeof(thisCmdBuf->optDef[i].fieldValue));
		if(i==OptNo_srvip)
			continue;
		memset(thisCmdBuf->optDef[i].optValue, 0,
			   sizeof(thisCmdBuf->optDef[i].optValue));
	}
/*	
	if (thisCmdBuf == &defCmdBuf[0])
		return;
	for (i = 1; i < CmdBufSize; i++) {
		if (thisCmdBuf == &defCmdBuf[i]) {
			break;
		}
	}

	switch (i) {
	case 1:
		sprintf(tableName, "%s", smcliTable_1);
		break;
	case 2:
		sprintf(tableName, "%s", smcliTable_2);
		break;
	case 3:
		sprintf(tableName, "%s", smcliTable_3);
		break;
	case 4:
		sprintf(tableName, "%s", smcliTable_4);
		break;
	default:
		return;
	}

	if (CmdTypeNo == CMD_DELETE || CmdTypeNo == CMD_CONNECT
		|| CmdTypeNo == CMD_DISCONNECT)
		return;

	if (CmdTypeNo == CMD_READ || CmdTypeNo == CMD_EXPORT) {
		sprintf(privilege, "readPrivilege");
		cmdNo = 1;
	} else if (CmdTypeNo == CMD_MODIFY || CmdTypeNo == CMD_RECHARGE) {
		sprintf(privilege, "writePrivilege");
		cmdNo = 2;
	} else if (CmdTypeNo == CMD_CREATE || CmdTypeNo == CMD_IMPORT) {
		sprintf(privilege, "createPrivilege");
		cmdNo = 3;
	} else
		return;

	sprintf(tmpSql,
			"SELECT optionalName,%s,initFieldValue FROM %s ORDER BY number",
			privilege, tableName);

#ifdef SMCLI_DEBUG
	printf("tmpSql= %s\n", tmpSql);
#endif
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
		mysql_free_result(tmpResult);
		return;
	}
	i = 0;
	while ((tmpRow = mysql_fetch_row(tmpResult))) {
		strcpy(thisCmdBuf->optDef[i + 9].optName, tmpRow[0]);
		thisCmdBuf->optDef[i + 9].optFlag[cmdNo] = atoi(tmpRow[1]);
		strcpy(thisCmdBuf->optDef[i + 9].initFieldValue, tmpRow[2]);
		i++;
	}
	mysql_free_result(tmpResult);

	sprintf(tmpSql, "SELECT %s FROM %s ORDER BY number", privilege,
			tableName);

#ifdef SMCLI_DEBUG
	printf("tmpSql= %s\n", tmpSql);
#endif
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
		mysql_free_result(tmpResult);
		return;
	}

	i = 0;
	while ((tmpRow = mysql_fetch_row(tmpResult))) {
		thisCmdBuf->optDef[i + 9].optFlag[cmdNo] = atoi(tmpRow[0]);
		i++;
	}
	mysql_free_result(tmpResult);

	if (CmdTypeNo == CMD_RECHARGE && thisCmdBuf == &defCmdBuf[2]) {
		for (i = 42; i < 47; i++) {
			thisCmdBuf->optDef[i].optFlag[9] =
				thisCmdBuf->optDef[i].optFlag[2];
			thisCmdBuf->optDef[i].optFlag[2] = 9;
		}
	}*/
	
	return;
}

/*************************************************
Function:        // doCmdConnect
Description:     // 执行connect到设备服务器的操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // OMC_PUB.sysInfo;
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdConnect(int sock, int loop)
{
	char tmpSql[1024];
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;
	int i = 0;
	int connect[2];
	
	CheckDbConnection();

	if (cmdBuf->optDef[OptNo_srvip].optFlag[0] > 0
		&& strlen(cmdBuf->optDef[OptNo_srvip].optValue) > 0) {
		sprintf(tmpSql,
				"SELECT sysNo,subSysNo,ip FROM %s WHERE ip=\'%s\' AND sysTypeNo =\'%d\'",
				sysInfoTable, cmdBuf->optDef[OptNo_srvip].optValue,
				cmdBuf->sysTypeNo);
	} else {
		sprintf(tmpSql, "SELECT baseStat FROM %s WHERE sysTypeNo =\'%d\' ",
				sysInfoTable, cmdBuf->sysTypeNo);

		tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);
		//if(tmpResult == NULL)
			//tmpResult=Reconnect(tmpSql, "localhost", "OMC_PUB");
		if (mysql_num_rows(tmpResult) > 1) {
			tmpRow = mysql_fetch_row(tmpResult);
			connect[0] = atoi(tmpRow[0]);
			tmpRow = mysql_fetch_row(tmpResult);
			if (tmpRow != NULL)
				connect[1] = atoi(tmpRow[0]);

			if (connect[0] == connect[1])
				sprintf(tmpSql,
						"SELECT sysNo,subSysNo,ip FROM %s WHERE sysTypeNo =\'%d\' AND sysNo=\'0\'",
						sysInfoTable, cmdBuf->sysTypeNo);
			else
				sprintf(tmpSql,
						"SELECT sysNo,subSysNo,ip FROM %s WHERE sysTypeNo =\'%d\' ORDER BY baseStat DESC",
						sysInfoTable, cmdBuf->sysTypeNo);
		} else if (mysql_num_rows(tmpResult) == 1) {
			sprintf(tmpSql,
					"SELECT sysNo,subSysNo,ip FROM %s WHERE sysTypeNo =\'%d\'",
					sysInfoTable, cmdBuf->sysTypeNo);
		} else
			sprintf(OutputBuf, "%s\n\r", ERR_0256);
	}

	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
#ifdef SMCLI_DEBUG
		printf("tmpSql= %s\n", tmpSql);
		printf("%d-", __LINE__);
#endif
		mysql_free_result(tmpResult);
		sprintf(OutputBuf, "%s\n\r", ERR_0256);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	tmpRow = mysql_fetch_row(tmpResult);
	for (i = 0; i < CmdBufSize; i++) {
		if (strcmp(cmdBuf->serverStr, defCmdBuf[i].serverStr) == 0) {
			defCmdBuf[i].sysNo = atoi(tmpRow[0]);
			defCmdBuf[i].subSysNo = atoi(tmpRow[1]);
			sprintf(defCmdBuf[i].optDef[OptNo_ipaddress].optValue, "%s",
					tmpRow[2]);
			sprintf(defCmdBuf[i].optDef[OptNo_srvip].optValue, "%s",
					tmpRow[2]);
			if (strcmp(cmdBuf->serverStr, "vms") == 0) {
				sprintf(tmpSql,
						"SELECT subsDataTable,tmpDataTable FROM %s WHERE sysTypeNo =\'%d\' AND sysNo=\'%d\'",
						sysSubsConfTable, cmdBuf->sysTypeNo,
						cmdBuf->sysNo);
				tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

				if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
					mysql_free_result(tmpResult);
					sprintf(OutputBuf, "%s\n\r", ERR_0256);
					OutputLen = strlen(OutputBuf);
					send(sock, OutputBuf, OutputLen, 0);
					return (1);
				}
				tmpRow = mysql_fetch_row(tmpResult);
				sprintf(defCmdBuf[i].srcTable, "%s", tmpRow[0]);
				sprintf(defCmdBuf[i].tmpTable, "%s", tmpRow[1]);
			}
		}
	}
	mysql_free_result(tmpResult);

	if (strcmp
		(cmdBuf->optDef[OptNo_passwd].optValue,
		 cmdBuf->optDef[OptNo_passwd].initFieldValue) != 0) {
#ifdef SMCLI_DEBUG
		printf("%d-", __LINE__);
#endif
		sprintf(OutputBuf, "%s\n\r", ERR_0257);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	if (getServerStat(cmdBuf->optDef[OptNo_ipaddress].optValue) != 0) {
		sprintf(OutputBuf, "%s %s\n\r", ERR_0260, cmdBuf->serverStr);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}


	for (i = 0; i < CmdBufSize; i++) {
		if (strcmp(cmdBuf->serverStr, defCmdBuf[i].serverStr) == 0) {
			port_status[loop].isConnected[i] = 1;
			strcpy(port_status[loop].ip[i],
				   cmdBuf->optDef[OptNo_ipaddress].optValue);
			port_status[loop].sysNo[i] = cmdBuf->sysNo;
			port_status[loop].subSysNo[i] = cmdBuf->subSysNo;
			strcpy(port_status[loop].serverStr[i], cmdBuf->serverStr);
		}
	}

	sprintf(OutputBuf, "%s:Connected ip = %s\n\r", ERR_0000,
			cmdBuf->optDef[OptNo_ipaddress].optValue);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // doCmdRead
Description:     // 执行read操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdRead(unsigned char exportFlag, int sock, int loop)
{
	int i = 0;
	int j = 0;
	char tmpStr[256];
	char tmpSql[4096];
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;
	char tmpBuf[8192];
	
	CheckDbConnection();
	
	//把一个关键参数的值从输入输出格式转换成数据库格式
	if (exValueOptToField(OptNo_index) == 1) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
				cmdBuf->optDef[OptNo_index].optName,
				cmdBuf->optDef[OptNo_index].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	sprintf(FieldNameList, "ALL");
	//把命令发送到用户数据命令表里
	if (sendCmd(sock, loop) == 0) {
#ifdef SMCLI_DEBUG
		printf("Send command ok \n");
#endif
		//获得命令执行结果
		if (scanCmd(sock) == 0) {
			memset(FieldNameList, 0, sizeof(FieldNameList));
			//构造SQL语句
			for (i = 0; i < cmdBuf->optDefNum; i++) {
				if (strlen(cmdBuf->optDef[i].fieldName) > 0) {
					sprintf(tmpStr, " %s,", cmdBuf->optDef[i].fieldName);
					strcat(FieldNameList, tmpStr);
				}
			}

			i = strlen(FieldNameList);
			FieldNameList[i - 1] = '\0';	//delete the lastest ','
			if ((cmdBuf->sysTypeNo == 330)
				&&
				(!strcmp
				 (cmdBuf->optDef[OptNo_index].fieldName, "inter_msisdn")))
				{sprintf(tmpSql,
						"SELECT %s FROM %s " "WHERE %s LIKE \'91%sE%%\'",
						FieldNameList, cmdBuf->srcTable,
						cmdBuf->optDef[OptNo_index].fieldName,
						cmdBuf->optDef[OptNo_index].fieldValue);
				//writeDebug("sql:%s",tmpSql);
					}
			else
				sprintf(tmpSql, "SELECT %s FROM %s "
						"WHERE %s=\'%s\'",
						FieldNameList,
						cmdBuf->srcTable,
						cmdBuf->optDef[OptNo_index].fieldName,
						cmdBuf->optDef[OptNo_index].fieldValue);
#ifdef SMCLI_DEBUG
			printf("tmpSql=%s\n", tmpSql);
#endif
			tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);



			//数据库里没有记录
			if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
				sprintf(OutputBuf,
						"%s:Cannot get this object value record!\n\r",
						ERR_0200);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				mysql_free_result(tmpResult);
				return (1);
			} else {
				//获取数据库里记录的值
				tmpRow = mysql_fetch_row(tmpResult);
				j = 0;
				for (i = 0; i < cmdBuf->optDefNum; i++) {
					//writeDebug("i=%d fieldName's strlen:%d",i,strlen(cmdBuf->optDef[i].fieldName));
					if (strlen(cmdBuf->optDef[i].fieldName) > 0 && tmpRow[j] != NULL) {
						strcpy(cmdBuf->optDef[i].fieldValue, tmpRow[j]);
						//exchange fieldValue for optValue
						//writeDebug("tmpRow[j]=%s,privilege=%d,cmdBuf->optDef[i].optFlag[CMD_READ]=%d,port_status[loop].privilege-cmdBuf->optDef[i].optFlag[CMD_READ]=%d",tmpRow[j],port_status[loop].privilege,cmdBuf->optDef[i].optFlag[CMD_READ],port_status[loop].privilege-cmdBuf->optDef[i].optFlag[CMD_READ]);
						if (cmdBuf->optDef[i].optFlag[CMD_READ] <=
							port_status[loop].privilege) {
							if (1 != ModifyFlag) {
								exValueFieldToOpt(i);
							}
#ifdef SMCLI_DEBUG
							printf("%s, %s <- %s \n",
								   cmdBuf->optDef[i].optName,
								   cmdBuf->optDef[i].optValue,
								   cmdBuf->optDef[i].fieldValue);
#endif
						}
						j++;

					}
				}
				mysql_free_result(tmpResult);
			}
			//display
			if (1 != ModifyFlag) {
				if (exportFlag != 0) {
					return (0);
				}

				sprintf(tmpBuf, "%s", cmdBuf->objectStr);
				for (i = 0; i < cmdBuf->optDefNum; i++) {
					if (cmdBuf->optDef[i].optFlag[CMD_READ] <=
						port_status[loop].privilege) {
						sprintf(tmpStr, " -%s %s",
								cmdBuf->optDef[i].optName,
								cmdBuf->optDef[i].optValue);
						strcat(tmpBuf, tmpStr);
					}
				}
				//把结果输出到客户端
				sprintf(tmpStr, "\n\r%s\n\r", ERR_0000);
				strcat(tmpBuf, tmpStr);
				//writeDebug("tmpBuf=%s",tmpBuf);
				OutputLen = strlen(tmpBuf);
				send(sock, tmpBuf, OutputLen, 0);
			}
		} else {
#ifdef SMCLI_DEBUG
			printf("%d-", __LINE__);
			printf("%s:when scan command\n\r", ERR_0200);
#endif
			return (1);
		}
	} else {
#ifdef SMCLI_DEBUG
		printf("%d-", __LINE__);
		printf("%s:when send command \n", ERR_0200);
#endif
		return (1);
	}
	sprintf(OutputBuf, "%s", ERR_0000);
	return (0);
}

/*************************************************
Function:        // doCmdModify
Description:     // 执行modify操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdModify(int sock, int loop)
{
	int i = 0;
	char tmpSql[4096];
	char tmpStr[512];
	char where[256];
	
	CheckDbConnection();
	
	memset(FieldNameList, 0, sizeof(FieldNameList));

	sprintf(tmpSql, "UPDATE %s SET ", cmdBuf->tmpTable);
	//把命令中要修改的参数的值转换为数据库的格式
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0
			&& cmdBuf->optDef[i].optFlag[0] > 0 && i != OptNo_index) {
			if (exValueOptToField(i) == 1) {
				sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
						cmdBuf->optDef[i].optName,
						cmdBuf->optDef[i].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
		}
	}
	
	//构造更新记录的sql
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0
			&& cmdBuf->optDef[i].optFlag[0] > 0 && i != OptNo_index) {
			sprintf(tmpStr, " %s =\'%s\',", cmdBuf->optDef[i].fieldName,
					cmdBuf->optDef[i].fieldValue);
			if (!strstr(FieldNameList, cmdBuf->optDef[i].fieldName)) {
				strcat(tmpSql, tmpStr);
				strcat(FieldNameList, cmdBuf->optDef[i].fieldName);
				strcat(FieldNameList, ",");
			}
		}
	}

	//printf("\n tmpSql=%s \n", tmpSql);
	//return (0);
	//没有输入要更新的参数
	if (strlen(FieldNameList) < 2) {
		sprintf(OutputBuf, "%s:Cannot find fields!\n\r", ERR_0002);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	i = strlen(tmpSql);
	tmpSql[i - 1] = '\0';		//delete the lastest ','
	i = strlen(FieldNameList);
	FieldNameList[i - 1] = '\0';

	if (exValueOptToField(OptNo_index) == 1) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
				cmdBuf->optDef[OptNo_index].optName,
				cmdBuf->optDef[OptNo_index].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}
	if ((cmdBuf->sysTypeNo == 330)
		&&
		(!strcmp(cmdBuf->optDef[OptNo_index].fieldName, "inter_msisdn")))
		sprintf(where, " WHERE %s LIKE \'91%sE%%\'",
				cmdBuf->optDef[OptNo_index].fieldName,
				cmdBuf->optDef[OptNo_index].fieldValue);
	else
		sprintf(where, " WHERE %s =\'%s\'",
				cmdBuf->optDef[OptNo_index].fieldName,
				cmdBuf->optDef[OptNo_index].fieldValue);

	strcat(tmpSql, where);
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	
	//2008-09-22, update the registerOpr record in the DB
	if(strcmp(cmdBuf->serverStr,"pps") ==0 && strcmp(cmdBuf->objectStr,"registerOpr") == 0)
	{
		char updateRegOpr[4096];
		//first,delete the record with the imei
		sprintf(updateRegOpr,"delete from %s where imei='%s' ",cmdBuf->tmpTable,cmdBuf->optDef[8].optValue);
		mysql_getnores(dbConn, updateRegOpr);
		sprintf(updateRegOpr,"delete from %s where imei='%s' ",cmdBuf->srcTable,cmdBuf->optDef[8].optValue);
		mysql_getnores(dbConn, updateRegOpr);
		
		//then,insert the record with the imei
		sprintf(updateRegOpr,"insert into %s (imei,ppCardPasswd) values('%s','%s');",cmdBuf->tmpTable,cmdBuf->optDef[8].optValue,cmdBuf->optDef[9].optValue);
		mysql_getnores(dbConn, updateRegOpr);
		sprintf(updateRegOpr,"insert into %s (imei,ppCardPasswd) values('%s','%s');",cmdBuf->srcTable,cmdBuf->optDef[8].optValue,cmdBuf->optDef[9].optValue);
		mysql_getnores(dbConn, updateRegOpr);
	}
	else
	{	
		mysql_getnores(dbConn, tmpSql);
	}
	
	//把命令发送到用户数据命令表里
	if (sendCmd(sock, loop) != 0) {
		return (1);
	}

	//获取命令执行的结果
	if (scanCmd(sock) != 0) {
		return (1);
	}
	
	//2008-09-22, output the response of the register opr
	if(strcmp(cmdBuf->serverStr,"pps") ==0 && strcmp(cmdBuf->objectStr,"registerOpr") == 0)
	{
		char updateRegOpr[4096];
		char tmpstrs[256];
		MYSQL_RES *tmpResult = NULL;
		MYSQL_ROW tmpRow = NULL;
		
		sprintf(updateRegOpr,"select * from %s where imei='%s' ",cmdBuf->srcTable,cmdBuf->optDef[8].optValue);
		tmpResult = (MYSQL_RES *) mysql_getres(dbConn, updateRegOpr);
		if(tmpResult == NULL || mysql_num_rows(tmpResult) == 0) 
		{
			sprintf(OutputBuf,"Register Opr Error!\n\r");
		}
		else
		{
			tmpRow = mysql_fetch_row(tmpResult);
			
			sprintf(OutputBuf,"IMEI\t%s\n\rPasswd\t%s\n\rResult\t%s\n\r",
				tmpRow[0],tmpRow[1],tmpRow[2]);
			
			if(tmpRow[3]!=NULL && strlen(tmpRow[3])>0)
			{	
				sprintf(tmpstrs,"MSISDN\t%s\n\r",tmpRow[3]);
				strcat(OutputBuf,tmpstrs);
			}
			if(tmpRow[4]!=NULL && strlen(tmpRow[4])>0)
			{	
				sprintf(tmpstrs,"PIN\t%s\n\r",tmpRow[4]);
				strcat(OutputBuf,tmpstrs);
			}
			if(tmpRow[5]!=NULL && strlen(tmpRow[5])>0)
			{	
				sprintf(tmpstrs,"Balance\t%d\n\r",atoi(tmpRow[5]));
				strcat(OutputBuf,tmpstrs);
			}
			if(tmpRow[6]!=NULL && strlen(tmpRow[6])>0)
			{	
				sprintf(tmpstrs,"Expiry\t%s\n\r",tmpRow[6]);
				strcat(OutputBuf,tmpstrs);
			}
			if(tmpRow[7]!=NULL && strlen(tmpRow[7])>0)
			{	
				sprintf(tmpstrs,"Cause\t%s\n\r",tmpRow[7]);
				strcat(OutputBuf,tmpstrs);
			}
		}
		mysql_free_result(tmpResult);
		
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
	}

	//成功执行命令
	sprintf(OutputBuf, "%s \n\r", ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // doCmdCreate
Description:     // 执行create操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdCreate(unsigned char importFlag, int sock, int loop)
{
	int i = 0;
	char tmpSql[4096];
	char tmpStr[512];

	CheckDbConnection();
	
	memset(FieldNameList, 0, sizeof(FieldNameList));

	sprintf(tmpSql, "REPLACE %s SET ", cmdBuf->tmpTable);
	//把参数值都设为默认值
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		//if (cmdBuf->optDef[i].optFlag[0] > 0) {
		//if (cmdBuf->optDef[i].optFlag[3] < 9) {
		strcpy(cmdBuf->optDef[i].fieldValue,
			   cmdBuf->optDef[i].initFieldValue);
		//}
	}


	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0) {
			if (cmdBuf->optDef[i].optFlag[0] > 0) {
				if (exValueOptToField(i) == 1) {
					sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
							cmdBuf->optDef[i].optName,
							cmdBuf->optDef[i].optValue);
					OutputLen = strlen(OutputBuf);
					send(sock, OutputBuf, OutputLen, 0);
					//writeDebug("5:%s,i:%d,optValue:%s",OutputBuf,i,cmdBuf->optDef[i].optValue);
					return (1);
				}
			}
		}
	}
	//构造sql语句
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0) {
			//if (cmdBuf->optDef[i].optFlag[0] > 0) {
			//if (cmdBuf->optDef[i].optFlag[3] < 9) {
			sprintf(tmpStr, " %s =\'%s\',",
					cmdBuf->optDef[i].fieldName,
					cmdBuf->optDef[i].fieldValue);
			if (!strstr(FieldNameList, cmdBuf->optDef[i].fieldName)) {
				strcat(tmpSql, tmpStr);
				strcat(FieldNameList, cmdBuf->optDef[i].fieldName);
				strcat(FieldNameList, ",");
			}
			//}
		}
	}
	i = strlen(tmpSql);
	tmpSql[i - 1] = '\0';		//delete the lastest ','
	i = strlen(FieldNameList);
	FieldNameList[i - 1] = '\0';
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	mysql_getnores(dbConn, tmpSql);

	if (sendCmd(sock, loop) != 0) {
		return (1);
	}
	if (scanCmd(sock) != 0) {
		return (1);
	}
	if (importFlag > 0) {
		return (0);
	}
	
	//创建命令执行成功
	sprintf(OutputBuf, "%s\n\r", ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // doCmdDelete
Description:     // 执行delete操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdDelete(int sock, int loop)
{
	int i = 0;
	char tmpSql[4096];
	
	CheckDbConnection();
	
	memset(FieldNameList, 0, sizeof(FieldNameList));

	//权限不够，未能删除
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0
			&& cmdBuf->optDef[i].optFlag[0] > 0
			&& cmdBuf->optDef[i].optFlag[CMD_DELETE] <=
			port_status[loop].privilege) {
			if (exValueOptToField(i) == 1) {
				sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
						cmdBuf->optDef[i].optName,
						cmdBuf->optDef[i].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
			strcpy(FieldNameList, cmdBuf->optDef[i].fieldName);
		}
	}

	//发送命令到用户数据命令表
	if (sendCmd(sock, loop) != 0) {
		return (1);
	}

	//检查命令的执行状态
	if (scanCmd(sock) != 0) {
		return (1);
	}

	if ((cmdBuf->sysTypeNo == 330)
		&&
		(!strcmp(cmdBuf->optDef[OptNo_index].fieldName, "inter_msisdn")))
		sprintf(tmpSql, "Delete FROM %s WHERE %s LIKE \'91%sE%%\'",
				cmdBuf->tmpTable, cmdBuf->optDef[OptNo_index].fieldName,
				cmdBuf->optDef[OptNo_index].fieldValue);
	else
		sprintf(tmpSql, "Delete FROM %s WHERE %s=\'%s\'", cmdBuf->tmpTable,
				cmdBuf->optDef[OptNo_index].fieldName,
				cmdBuf->optDef[OptNo_index].fieldValue);
	mysql_getnores(dbConn, tmpSql);

	if ((cmdBuf->sysTypeNo == 330)
		&&
		(!strcmp(cmdBuf->optDef[OptNo_index].fieldName, "inter_msisdn")))
		sprintf(tmpSql, "Delete FROM %s WHERE %s LIKE \'91%sE%%\'",
				cmdBuf->srcTable, cmdBuf->optDef[OptNo_index].fieldName,
				cmdBuf->optDef[OptNo_index].fieldValue);
	else
		sprintf(tmpSql, "Delete FROM %s WHERE %s=\'%s\'", cmdBuf->srcTable,
				cmdBuf->optDef[OptNo_index].fieldName,
				cmdBuf->optDef[OptNo_index].fieldValue);
	mysql_getnores(dbConn, tmpSql);

	sprintf(OutputBuf, "%s\n\r", ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // doCmdExport
Description:     // 执行export操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdExport(int sock, int loop)
{
	long int i = 0;
	int j;
	//long int len;
	long int maxNum = 10;
	char insSql[256];
	//char tmpBuf[256];
	char tmpSql[1024];
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;
	
	CheckDbConnection();

	port_status[loop].expFile = NULL;
	port_status[loop].exportedNum = 0;
	port_status[loop].exportNum = 0;

	//sprintf(insSql, "INSERT INTO %s (number,loop,exportIndex) VALUES ",
	//      smcliIndexTable);
	//writeDebug("cmdBuf->optDef[OptNo_max].optFlag[0]:%d,cmdBuf->optDef[OptNo_max].optValue:%s",cmdBuf->optDef[OptNo_max].optFlag[0],cmdBuf->optDef[OptNo_max].optValue);
	if (cmdBuf->optDef[OptNo_max].optFlag[0] > 0 &&
		strlen(cmdBuf->optDef[OptNo_max].optValue) > 0) {
		if (strcmp(cmdBuf->optDef[OptNo_max].optValue, "all") != 0) {
			if (strlen(cmdBuf->optDef[OptNo_max].optValue) > 6) {
				sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
						cmdBuf->optDef[OptNo_max].optName,
						cmdBuf->optDef[OptNo_max].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
			for (i = 0; i < strlen(cmdBuf->optDef[OptNo_max].optValue);
				 i++) {
				if (isdigit(cmdBuf->optDef[OptNo_max].optValue[i]) <= 0) {
					sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
							cmdBuf->optDef[OptNo_max].optName,
							cmdBuf->optDef[OptNo_max].optValue);
					OutputLen = strlen(OutputBuf);
					send(sock, OutputBuf, OutputLen, 0);
					return (1);
				}
			}
			maxNum = atol(cmdBuf->optDef[OptNo_max].optValue);
		}
	}
	//writeDebug("cmdBuf->optDef[OptNo_max].optValue:%s",cmdBuf->optDef[OptNo_max].optValue);
	i = 0;
	if (strcmp(cmdBuf->optDef[OptNo_max].optValue, "all") == 0) {
		//try to find -query 's value
		if (cmdBuf->optDef[OptNo_query].optFlag[0] > 0 &&
			strlen(cmdBuf->optDef[OptNo_query].optValue) > 0) {
			sprintf(tmpSql,
					"SELECT %s FROM %s WHERE %s ORDER BY %s",
					cmdBuf->optDef[OptNo_index].fieldName,
					cmdBuf->srcTable, ExportQueryStr,
					cmdBuf->optDef[OptNo_index].fieldName);
		} else {
			sprintf(tmpSql, "SELECT %s FROM %s ORDER BY %s",
					cmdBuf->optDef[OptNo_index].fieldName,
					cmdBuf->srcTable,
					cmdBuf->optDef[OptNo_index].fieldName);
		}
	} else {
		//try to find -query 's value
		if (cmdBuf->optDef[OptNo_query].optFlag[0] > 0 &&
			strlen(cmdBuf->optDef[OptNo_query].optValue) > 0) {
			sprintf(tmpSql,
					"SELECT %s FROM %s WHERE %s ORDER BY %s LIMIT 0,%ld",
					cmdBuf->optDef[OptNo_index].fieldName,
					cmdBuf->srcTable, ExportQueryStr,
					cmdBuf->optDef[OptNo_index].fieldName, maxNum);
		} else {
			sprintf(tmpSql, "SELECT %s FROM %s ORDER BY %s LIMIT 0,%ld",
					cmdBuf->optDef[OptNo_index].fieldName,
					cmdBuf->srcTable,
					cmdBuf->optDef[OptNo_index].fieldName, maxNum);

		}
	}

	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

#ifdef SMCLI_DEBUG
	printf("tmpSql= %s\n", tmpSql);
#endif

	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
		mysql_free_result(tmpResult);
		sprintf(OutputBuf, "%s:Cannot get this object value record!\n\r",
				ERR_0200);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
#ifdef SMCLI_DEBUG
		printf("%d-", __LINE__);
#endif
		return (1);
	}

	while ((tmpRow = mysql_fetch_row(tmpResult))) {
		sprintf(insSql,
				"INSERT INTO %s (number,newloop,exportIndex) VALUES (\'%ld\',\'%d\',\'%s\')",
				smcliIndexTable, i, loop, tmpRow[0]);
		mysql_getnores(dbConn, insSql);
		i++;
	}

	port_status[loop].exportMaxNum = i - 1;

	mysql_free_result(tmpResult);

	//try to find -expfile 's value
	if (cmdBuf->optDef[OptNo_expfile].optFlag[0] > 0 &&
		strlen(cmdBuf->optDef[OptNo_expfile].optValue) > 0) {
		//open file
		port_status[loop].expFile =
			fopen(cmdBuf->optDef[OptNo_expfile].optValue, "w");
		if (port_status[loop].expFile == NULL) {
			perror("fopen");
			sprintf(OutputBuf, "%s:%s\n\r", ERR_0258,
					cmdBuf->optDef[OptNo_expfile].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
	}

	for (j = 0; j < CmdBufSize; j++) {
		if (cmdBuf == &defCmdBuf[j]) {
			port_status[loop].cmdBufNum = j;
			break;
		}
	}
	port_status[loop].fieldNameFlag =
		cmdBuf->optDef[OptNo_fields].optFlag[0];
	strcpy(port_status[loop].fieldNameList, FieldNameList);
	strcpy(port_status[loop].exportFieldsStr, ExportFieldsStr);
	port_status[loop].expDoingFlag = 1;
	return (0);
}

/*************************************************
Function:        // doCmdExport
Description:     // 执行export操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doingCmdExport(int sock, int loop)
{
	int i = 0;
	char tmpStr[256];
	char tmpSql[1024];
	char tmpBuf[8192];
	char selSql[1024];
	MYSQL_RES *selResult = NULL;
	MYSQL_ROW selRow = NULL;
	long l_time;
	struct tm *t;
	
	CheckDbConnection();
	
	CmdTypeNo = CMD_EXPORT;
	cmdBuf = &defCmdBuf[port_status[loop].cmdBufNum];
	cmdBuf->optDef[OptNo_index].optFlag[0] = 1;
	cmdBuf->optDef[OptNo_fields].optFlag[0] =
		port_status[loop].fieldNameFlag;
	strcpy(FieldNameList, port_status[loop].fieldNameList);
	strcpy(ExportFieldsStr, port_status[loop].exportFieldsStr);

	sprintf(selSql,
			"SELECT exportIndex,number From %s WHERE number>=\'%ld\' AND newloop='\%d\' ORDER BY number LIMIT 0,10",
			smcliIndexTable, port_status[loop].exportNum, loop);
	selResult = (MYSQL_RES *) mysql_getres(dbConn, selSql);

#ifdef SMCLI_DEBUG
	printf("selSql= %s\n", selSql);
#endif

	if (selResult == NULL || mysql_num_rows(selResult) == 0) {
		mysql_free_result(selResult);
		sprintf(OutputBuf, "%s:Cannot get this object value record!\n\r",
				ERR_0200);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
#ifdef SMCLI_DEBUG
		printf("%d-", __LINE__);
#endif
		return (1);
	}

	if (port_status[loop].expFile != NULL) {
		while ((selRow = mysql_fetch_row(selResult))) {
			port_status[loop].exportNum++;
			if (atol(selRow[1]) == port_status[loop].exportMaxNum)
				port_status[loop].expDoingFlag = 0;
			sprintf(cmdBuf->optDef[OptNo_index].fieldValue, "%s",
					selRow[0]);
			exValueFieldToOpt(OptNo_index);
			if (doCmdRead(1, sock, loop) == 0) {
				fputs(cmdBuf->objectStr, port_status[loop].expFile);
				for (i = 0; i < cmdBuf->optDefNum; i++) {
					if (cmdBuf->optDef[i].optFlag[CMD_READ] <=
						port_status[loop].privilege) {
						if (cmdBuf->optDef[OptNo_fields].optFlag[0] > 0) {
							sprintf(tmpStr, "%s ",
									cmdBuf->optDef[i].optName);
							if (strstr
								(port_status[loop].exportFieldsStr,
								 tmpStr) == 0) {
								continue;
							}
						}
						sprintf(tmpStr, " -%s %s",
								cmdBuf->optDef[i].optName,
								cmdBuf->optDef[i].optValue);
						fputs(tmpStr, port_status[loop].expFile);
					}
				}
				fputs("\n", port_status[loop].expFile);
				sprintf(OutputBuf, "Export %s=%s ok\n\r",
						cmdBuf->optDef[OptNo_index].optName,
						cmdBuf->optDef[OptNo_index].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				port_status[loop].exportedNum++;
			} else {
				sprintf(OutputBuf, "Export %s=%s failed\n\r",
						cmdBuf->optDef[OptNo_index].optName,
						cmdBuf->optDef[OptNo_index].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
			}
		}
		if (port_status[loop].expDoingFlag == 0) {
			fclose(port_status[loop].expFile);
			sprintf(OutputBuf, "%s:Exported %ld %s(s) in %s\n\r",
					ERR_0000, port_status[loop].exportedNum,
					cmdBuf->objectStr,
					cmdBuf->optDef[OptNo_expfile].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
		}
	} else {
		while ((selRow = mysql_fetch_row(selResult))) {
			port_status[loop].exportNum++;
			if (atol(selRow[1]) == port_status[loop].exportMaxNum)
				port_status[loop].expDoingFlag = 0;
			sprintf(cmdBuf->optDef[OptNo_index].fieldValue, "%s",
					selRow[0]);
			exValueFieldToOpt(OptNo_index);
			if (doCmdRead(1, sock, loop) == 0) {
				sprintf(tmpBuf, "%s", cmdBuf->objectStr);
				for (i = 0; i < cmdBuf->optDefNum; i++) {
					if (cmdBuf->optDef[i].optFlag[CMD_READ] <=
						port_status[loop].privilege) {
						if (cmdBuf->optDef[OptNo_fields].optFlag[0] > 0) {
							sprintf(tmpStr, "%s ",
									cmdBuf->optDef[i].optName);
							if (strstr
								(port_status[loop].exportFieldsStr,
								 tmpStr) == 0) {
								continue;
							}
						}
						sprintf(tmpStr, " -%s %s",
								cmdBuf->optDef[i].optName,
								cmdBuf->optDef[i].optValue);
						strcat(tmpBuf, tmpStr);
					}
				}
				sprintf(tmpStr, "\n\r");
				strcat(tmpBuf, tmpStr);
				OutputLen = strlen(tmpBuf);
				send(sock, tmpBuf, OutputLen, 0);
				port_status[loop].exportedNum++;
			} else {
				sprintf(OutputBuf, "Export %s=%s failed\n\r",
						cmdBuf->optDef[OptNo_index].optName,
						cmdBuf->optDef[OptNo_index].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
			}
		}
		if (port_status[loop].expDoingFlag == 0) {
			sprintf(OutputBuf, "%s:Exported %ld %s(s)\n\r", ERR_0000,
					port_status[loop].exportedNum, cmdBuf->objectStr);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
		}
	}
	mysql_free_result(selResult);
	if (port_status[loop].expDoingFlag == 0) {
		sprintf(tmpSql, "DELETE FROM %s WHERE newloop='\%d\'",
				smcliIndexTable, loop);
		mysql_getnores(dbConn, tmpSql);
		l_time = time(NULL);
		t = localtime(&l_time);
		sprintf(tmpSql, "INSERT INTO %s "
				"(operTypeNo,operNo,remark,userName,datetime)"
				"VALUES"
				"(\'0\',\'0\',\'Command:%s,Result:%s\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
				sysOperLogTable, port_status[loop].tmpInputBuf,
				OutputBuf, port_status[loop].username,
				t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
				t->tm_hour, t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
		printf("\n tmpSql=%s \n", tmpSql);
#endif
		mysql_getnores(dbConn, tmpSql);
		usleep(delayTime);
		sprintf(OutputBuf, "%s", "CLI>");
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		port_status[loop].time = time(NULL);
	}
	return (0);
}

/*************************************************
Function:        // doCmdImport
Description:     // 执行import操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdImport(char *inputBuf, int sock, int loop)
{
	int i;
	char tmpStr[128];
	
	CheckDbConnection();

	port_status[loop].impFile = NULL;
	port_status[loop].impLogFile = NULL;
	port_status[loop].importNum = 0;
	port_status[loop].importedNum = 0;

	//open the export file
	if (cmdBuf->optDef[OptNo_impfile].optFlag[0] > 0 &&
		strlen(cmdBuf->optDef[OptNo_impfile].optValue) > 0) {
		//open import file
		port_status[loop].impFile =
			fopen(cmdBuf->optDef[OptNo_impfile].optValue, "r");
		if (port_status[loop].impFile == NULL) {
			//perror("fopen");
			sprintf(OutputBuf, "%s:%s\n\r", ERR_0258,
					cmdBuf->optDef[OptNo_impfile].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
		//open import log file
		sprintf(tmpStr, "%s.implog",
				cmdBuf->optDef[OptNo_impfile].optValue);
		port_status[loop].impLogFile = fopen(tmpStr, "w");
		if (port_status[loop].impLogFile == NULL) {
			perror("fopen");
			sprintf(OutputBuf, "%s:%s\n\r", ERR_0258, tmpStr);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
	}

	for (i = 0; i < CmdBufSize; i++) {
		if (cmdBuf == &defCmdBuf[i]) {
			port_status[loop].cmdBufNum = i;
			break;
		}
	}
	port_status[loop].impDoingFlag = 1;
	return (0);
}

/*************************************************
Function:        // doCmdImport
Description:     // 执行import操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doingCmdImport(char *inputBuf, int sock, int loop)
{
	int i;
	int optNo;
	long int m, n;
	char tmpStr[128];
	char tmpSql[1024];
	long l_time;
	struct tm *t;
	
	CheckDbConnection();

	CmdTypeNo = CMD_IMPORT;
	cmdBuf = &defCmdBuf[port_status[loop].cmdBufNum];
	m = port_status[loop].importNum;
	n = port_status[loop].importNum + 10;

	//get one line and fill to inputBuf and exchange to cmdBuf
	for (; m < n; m++, port_status[loop].importNum++) {
		memset(inputBuf, 0, InputBufSize);
		memset(FieldNameList, 0, sizeof(FieldNameList));
		if (fgets(inputBuf, InputBufSize, port_status[loop].impFile) ==
			NULL) {
			fclose(port_status[loop].impFile);
			fclose(port_status[loop].impLogFile);
			sprintf(OutputBuf,
					"%s:Total imported %ld %s(s).Import log is in %s.implog\n\r",
					ERR_0000, port_status[loop].importedNum,
					cmdBuf->objectStr,
					cmdBuf->optDef[OptNo_impfile].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			l_time = time(NULL);
			t = localtime(&l_time);
			sprintf(tmpSql, "INSERT INTO %s "
					"(operTypeNo,operNo,remark,userName,datetime)"
					"VALUES"
					"(\'0\',\'0\',\'Command:%s,Result:%s\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
					sysOperLogTable, port_status[loop].tmpInputBuf,
					OutputBuf, port_status[loop].username,
					t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
					t->tm_hour, t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
			printf("\n tmpSql=%s \n", tmpSql);
#endif
			mysql_getnores(dbConn, tmpSql);
			usleep(delayTime);
			sprintf(OutputBuf, "%s", "\rCLI>");
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			port_status[loop].time = time(NULL);
			port_status[loop].impDoingFlag = 0;
			break;
		}
#ifdef SMCLI_DEBUG
		printf("%s \n", inputBuf);
#endif
		if (inputBuf[0] == '#') {
			continue;
		}
		i = strlen(inputBuf);
		if (inputBuf[i - 1] == '\n')
			inputBuf[i - 1] = '\0';
		//init all optFlage[0]
		for (optNo = 0; optNo < cmdBuf->optDefNum; optNo++) {
			if (strlen(cmdBuf->optDef[optNo].fieldName) > 0) {
				cmdBuf->optDef[optNo].optFlag[0] = 0;
			}
		}

		CmdTypeNo = CMD_CREATE;
		if (procInput(inputBuf, 1, sock, loop) != 0) {
			sprintf(OutputBuf, "\rImport %s=%s failed\n\r",
					cmdBuf->optDef[OptNo_index].optName,
					cmdBuf->optDef[OptNo_index].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			fputs(OutputBuf, port_status[loop].impLogFile);
			fputs("\n", port_status[loop].impLogFile);
			CmdTypeNo = CMD_IMPORT;
			continue;
		}
		CmdTypeNo = CMD_IMPORT;

		if (doCmdCreate(1, sock, loop) == 0) {
			sprintf(tmpStr, "\rImport %s=%s ok\n\r",
					cmdBuf->optDef[OptNo_index].optName,
					cmdBuf->optDef[OptNo_index].optValue);
			port_status[loop].importedNum++;
		} else {
			sprintf(tmpStr, "\rImport %s=%s failed\n\r",
					cmdBuf->optDef[OptNo_index].optName,
					cmdBuf->optDef[OptNo_index].optValue);
		}
		sprintf(OutputBuf, "%s", tmpStr);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		fputs(tmpStr, port_status[loop].impLogFile);
		fputs("\n", port_status[loop].impLogFile);
	}
	return (0);
}

/*************************************************
Function:        // doCmdDisconnect
Description:     // 执行disconnect操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdDisconnect(int sock, int loop)
{
	int i = 0;
	int j = 0;
	int findFlag = 0;
	
	CheckDbConnection();

	for (i = 1; i < CmdBufSize; i++)
		defCmdBuf[i].isConnected = port_status[loop].isConnected[i];

	for (i = 1; i < CmdBufSize; i++) {
		if (strcmp(cmdBuf->serverStr, defCmdBuf[i].serverStr) == 0) {
			if (defCmdBuf[i].isConnected > 0) {
				defCmdBuf[i].isConnected = 0;
				port_status[loop].isConnected[i] = 0;
				findFlag = 1;
				j = i;
			}
		}
	}

	if (findFlag) {
		sprintf(OutputBuf, "%s:Disconnected from %s\n\r", ERR_0000,
				port_status[loop].ip[j]);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
	} else {
		sprintf(OutputBuf, "%s:No server has been connected yet.\n\r",
				ERR_0000);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
	}
	return (0);
}

/*************************************************
Function:        // doCmdRecharge
Description:     // 执行recharge操作
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdRecharge(int sock, int loop)
{
	int i, tmpValue;
	char tmpSql[4096];
	char tmpStr[512];
	char tmpStr1[512];
	char where[256];
	char outField[1024];
	char tmpOutField[256];
	long l_time;
	struct tm *t;
	
	int balance_pos=-1;
	int mo_vday_pos=-1;
	int mt_vday_pos=-1;
	int credit_pos=-1;
	int mo_expiration_date_pos=-1;
	int mt_expiration_date_pos=-1;
	int promotion_balance_pos=-1;
	int promotion_credit_pos=-1;
	int promotion_date_pos=-1;
	int promotion_vday_pos=-1;

	CheckDbConnection();
	
	l_time = time(NULL);
	t = localtime(&l_time);		//init t

	memset(FieldNameList, 0, sizeof(FieldNameList));
	
	
	for(i=0;i<cmdBuf->optDefNum;i++)
	{
		if(strcmp(cmdBuf->optDef[i].fieldName,"balance") == 0)
			balance_pos=i;
		else if(strcmp(cmdBuf->optDef[i].fieldName,"mo_expiration_date") == 0)
			mo_expiration_date_pos=i;
		else if(strcmp(cmdBuf->optDef[i].fieldName,"mt_expiration_date") == 0)
			mt_expiration_date_pos=i;
		else if(strcmp(cmdBuf->optDef[i].optName,"mo_vday") == 0)
			mo_vday_pos=i;
		else if(strcmp(cmdBuf->optDef[i].optName,"mt_vday") == 0)
			mt_vday_pos=i;
		else if(strcmp(cmdBuf->optDef[i].optName,"credit") == 0)
			credit_pos=i;
		else if(strcmp(cmdBuf->optDef[i].optName,"promotion_balance") == 0)
			promotion_balance_pos=i;
		else if(strcmp(cmdBuf->optDef[i].optName,"promotion_credit") == 0)
			promotion_credit_pos=i;
		else if(strcmp(cmdBuf->optDef[i].optName,"promotion_date") == 0)
			promotion_date_pos=i;
		else if(strcmp(cmdBuf->optDef[i].optName,"promotion_vday") == 0)
			promotion_vday_pos=i;
	}
	
	if(credit_pos == -1 || 
		balance_pos == -1 || 
		mo_vday_pos == -1 || 
		mt_vday_pos == -1 || 
		mo_expiration_date_pos == -1 || 
		mt_expiration_date_pos == -1 ||
		promotion_balance_pos == -1 ||
		promotion_credit_pos == -1 ||
		promotion_date_pos == -1 ||
		promotion_vday_pos == -1
	)
	{
		sprintf(OutputBuf, "%s:configuration error\n\r",ERR_0010);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	if (atoi(cmdBuf->optDef[11].fieldValue) > 2) {
		sprintf(OutputBuf, "%s:status is %s!\n\r", ERR_0259,
				cmdBuf->optDef[11].fieldValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}
	
	sprintf(tmpSql, "UPDATE %s SET ", cmdBuf->tmpTable);
	sprintf(outField, "-msisdn %s", cmdBuf->optDef[OptNo_index].optValue);

	if(strlen(cmdBuf->optDef[mo_vday_pos].optValue) > 0)
	{
		if(opt_date(cmdBuf->optDef[mo_expiration_date_pos].fieldValue,cmdBuf->optDef[mo_vday_pos].optValue,tmpStr) == NULL)
		{
			sprintf(OutputBuf, "%s:time value %s invalid\n\r", ERR_0203,cmdBuf->optDef[mo_vday_pos].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
		else
		{
			sprintf(tmpStr1,"%s = \'%s\',",cmdBuf->optDef[mo_expiration_date_pos].fieldName,tmpStr);
			strcat(tmpSql, tmpStr1);
			strcat(FieldNameList,cmdBuf->optDef[mo_expiration_date_pos].fieldName);
			strcat(FieldNameList,",");
			sprintf(tmpOutField," -%s %s",cmdBuf->optDef[mo_expiration_date_pos].optName,tmpStr);
			strcat(outField, tmpOutField);
		}
	}

	if(strlen(cmdBuf->optDef[mt_vday_pos].optValue) > 0)
	{
		if(opt_date(cmdBuf->optDef[mt_expiration_date_pos].fieldValue,cmdBuf->optDef[mt_vday_pos].optValue,tmpStr) == NULL)
		{
			sprintf(OutputBuf, "%s:time value %s invalid\n\r", ERR_0203,cmdBuf->optDef[mt_vday_pos].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
		else
		{
			sprintf(tmpStr1,"%s = \'%s\',",cmdBuf->optDef[mt_expiration_date_pos].fieldName,tmpStr);
			strcat(tmpSql, tmpStr1);
			strcat(FieldNameList,cmdBuf->optDef[mt_expiration_date_pos].fieldName);
			strcat(FieldNameList,",");
			sprintf(tmpOutField," -%s %s",cmdBuf->optDef[mt_expiration_date_pos].optName,tmpStr);
			strcat(outField, tmpOutField);
		}
	}

	if(strlen(cmdBuf->optDef[promotion_vday_pos].optValue) > 0)
	{
		if(opt_date(cmdBuf->optDef[promotion_date_pos].fieldValue,cmdBuf->optDef[promotion_vday_pos].optValue,tmpStr) == NULL)
		{
			sprintf(OutputBuf,"%s:time value %s invalid\n\r", ERR_0203,cmdBuf->optDef[promotion_vday_pos].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
		else
		{
			sprintf(tmpStr1,"%s = \'%s\',",cmdBuf->optDef[promotion_date_pos].fieldName,tmpStr);
			strcat(tmpSql, tmpStr1);
			strcat(FieldNameList,cmdBuf->optDef[promotion_date_pos].fieldName);
			strcat(FieldNameList,",");
			sprintf(tmpOutField," -%s %s",cmdBuf->optDef[promotion_date_pos].optName,tmpStr);
			strcat(outField, tmpOutField);
		}
	}

	if(cmdBuf->optDef[credit_pos].optValue[0] == '~')
	{
		tmpValue=atol(cmdBuf->optDef[balance_pos].fieldValue) - atol(&cmdBuf->optDef[credit_pos].optValue[1]);
	}
	else
	{
		tmpValue=atol(cmdBuf->optDef[balance_pos].fieldValue) + atol(cmdBuf->optDef[credit_pos].optValue);
	}
	sprintf(tmpStr,"%s = \'%d\',",cmdBuf->optDef[balance_pos].fieldName,tmpValue);
	strcat(tmpSql, tmpStr);
	if(tmpValue < 0)
	{
		sprintf(tmpOutField," %s ~%d",cmdBuf->optDef[balance_pos].optName,-tmpValue);
	}
	else
	{
		sprintf(tmpOutField," %s %d",cmdBuf->optDef[balance_pos].optName,tmpValue);
	}
	strcat(outField, tmpOutField);
	strcat(FieldNameList,cmdBuf->optDef[balance_pos].fieldName);
	strcat(FieldNameList,",");
	
	if(cmdBuf->optDef[promotion_credit_pos].optValue[0] == '~')
	{
		tmpValue=atol(cmdBuf->optDef[promotion_balance_pos].fieldValue) - atol(&cmdBuf->optDef[promotion_credit_pos].optValue[1]);
	}
	else
	{
		tmpValue=atol(cmdBuf->optDef[promotion_balance_pos].fieldValue) + atol(cmdBuf->optDef[promotion_credit_pos].optValue);
	}
	sprintf(tmpStr,"%s = \'%d\'",cmdBuf->optDef[promotion_balance_pos].fieldName,tmpValue);
	strcat(tmpSql, tmpStr);
	if(tmpValue < 0)
	{
		sprintf(tmpOutField," %s ~%d",cmdBuf->optDef[promotion_balance_pos].optName,-tmpValue);
	}
	else
	{
		sprintf(tmpOutField," %s %d",cmdBuf->optDef[promotion_balance_pos].optName,tmpValue);
	}
	strcat(outField, tmpOutField);
	strcat(FieldNameList,cmdBuf->optDef[promotion_balance_pos].fieldName);
	
	if (strlen(FieldNameList) < 2) {
		sprintf(OutputBuf, "%s:Cannot find fields!\n\r", ERR_0002);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	if (exValueOptToField(OptNo_index) == 1) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
				cmdBuf->optDef[OptNo_index].optName,
				cmdBuf->optDef[OptNo_index].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}
	sprintf(where, " WHERE %s =\'%s\'",
			cmdBuf->optDef[OptNo_index].fieldName,
			cmdBuf->optDef[OptNo_index].fieldValue);
	strcat(tmpSql, where);
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	mysql_getnores(dbConn, tmpSql);

	if (sendCmd(sock, loop) != 0) {
		return (1);
	}

	if (scanCmd(sock) != 0) {
		return (1);
	}

	sprintf(OutputBuf, "ppsuser %s\n\r%s\n\r", outField, ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // procAccount
Description:     // 处理account对象
Calls:           // mysql_num_rows; mysql_free_result; send;
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int procAccount(int sock, int loop)
{
	char tmpSql[1024];
	char *tmpAddr;
	long l_time;
	struct tm *t;
	
	CheckDbConnection();

	if (strcmp(port_status[loop].username, "accountManager") == 0)
		port_status[loop].privilege = 4;
	switch (CmdTypeNo) {
	case CMD_READ:
		doCmdReadAccount(0, sock, loop);
		break;
	case CMD_MODIFY:
		doCmdModifyAccount(sock, loop);
		break;
	case CMD_CREATE:
		doCmdCreateAccount(sock, loop);
		break;
	case CMD_DELETE:
		doCmdDeleteAccount(sock, loop);
		break;
	case CMD_EXPORT:
		doCmdExportAccount(sock, loop);
		break;
	case CMD_ALIVE:
		doCmdAlive(sock);
		break;
	case CMD_HELP:
		doCmdHelp(sock);
		break;
	default:
		sprintf(OutputBuf, "%s:%d\n\r", ERR_0001, CmdTypeNo);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
	}
	if ((tmpAddr =
		 strstr(port_status[loop].tmpInputBuf, "-password")) != 0) {
		tmpAddr = tmpAddr + 10;
		while ((*(tmpAddr + 1) != '-') && (*tmpAddr != '\0')) {
			*tmpAddr = '*';
			tmpAddr++;
		}
	}





	l_time = time(NULL);
	t = localtime(&l_time);
	sprintf(tmpSql, "INSERT INTO %s	"
			"(operTypeNo,operNo,remark,userName,datetime)"
			"VALUES"
			"(\'0\',\'0\',\'Command:%s,Result:%s\',\'smcli:%s\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
			sysOperLogTable, port_status[loop].tmpInputBuf, OutputBuf,
			port_status[loop].username, t->tm_year + 1900,
			t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	mysql_getnores(dbConn, tmpSql);
	usleep(delayTime);
	sprintf(OutputBuf, "%s", "CLI>");
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	port_status[loop].time = time(NULL);
	if (strcmp(port_status[loop].username, "accountManager") == 0)
		port_status[loop].privilege = 3;
	return 0;
}

/*************************************************
Function:        // doCmdReadAccount
Description:     // 执行read account操作
Calls:           // 
Called By:       // procAccount
Table Accessed:  // 
Table Updated:   // 
Input:           // exportFlag:是否export; sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdReadAccount(unsigned char exportFlag, int sock, int loop)
{
	int i = 0;
	int j = 0;
	char tmpStr[512];
	char tmpSql[1024];
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;
	char tmpBuf[1024];
	
	CheckDbConnection();

	if (exValueOptToField(OptNo_index) == 1) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
				cmdBuf->optDef[OptNo_index].optName,
				cmdBuf->optDef[OptNo_index].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}
	memset(FieldNameList, 0, sizeof(FieldNameList));
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0) {
			sprintf(tmpStr, " %s,", cmdBuf->optDef[i].fieldName);
			strcat(FieldNameList, tmpStr);
		}
	}
	i = strlen(FieldNameList);
	FieldNameList[i - 1] = '\0';	//delete the lastest ','

	sprintf(tmpSql, "SELECT %s FROM %s "
			"WHERE %s=\'%s\'",
			FieldNameList,
			cmdBuf->srcTable,
			cmdBuf->optDef[OptNo_index].fieldName,
			cmdBuf->optDef[OptNo_index].fieldValue);
#ifdef SMCLI_DEBUG
	printf("tmpSql=%s\n", tmpSql);
#endif
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
		sprintf(OutputBuf, "%s:Cannot get this object value record!\n\r",
				ERR_0200);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		mysql_free_result(tmpResult);
		return (1);
	} else {
		//get record's value and fill to fieldValue
		j = 0;
		tmpRow = mysql_fetch_row(tmpResult);
		for (i = 0; i < cmdBuf->optDefNum; i++) {
			if (strlen(cmdBuf->optDef[i].fieldName) > 0) {
				sprintf(cmdBuf->optDef[i].fieldValue, "%s", tmpRow[j]);
				//exchange fieldValue for optValue
				exValueFieldToOpt(i);
				//writeDebug("i=%d",i);

#ifdef SMCLI_DEBUG
				printf("%s, %s <- %s \n", cmdBuf->optDef[i].optName,
					   cmdBuf->optDef[i].optValue,
					   cmdBuf->optDef[i].fieldValue);
#endif
				j++;
			}
		}
		mysql_free_result(tmpResult);
		if (exportFlag == 0) {
			if (port_status[loop].privilege <=
				atoi(cmdBuf->optDef[OptNo_privilege].fieldValue)) {
				sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0012,
						cmdBuf->optDef[OptNo_index].optName,
						cmdBuf->optDef[OptNo_index].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
		} else {
			if (port_status[loop].privilege <=
				atoi(cmdBuf->optDef[OptNo_privilege].fieldValue)) {
				return (2);
			}
		}

		//display
		if (exportFlag != 0) {
			return (0);
		}
		sprintf(tmpBuf, "%s", cmdBuf->objectStr);
		for (i = 0; i < cmdBuf->optDefNum; i++) {
			if ((cmdBuf->optDef[i].optFlag[CMD_READ] <=
				 port_status[loop].privilege) && (i != OptNo_password)) {
				sprintf(tmpStr, " -%s %s", cmdBuf->optDef[i].optName,
						cmdBuf->optDef[i].optValue);
				strcat(tmpBuf, tmpStr);
			}
		}
		sprintf(tmpStr, "\n\r%s\n\r", ERR_0000);
		strcat(tmpBuf, tmpStr);
		//writeDebug("tmpBuf=%s",tmpBuf);

		OutputLen = strlen(tmpBuf);
		send(sock, tmpBuf, OutputLen, 0);
		return (0);
	}
}

/*************************************************
Function:        // doCmdModifyAccount
Description:     // 执行modify account操作
Calls:           // 
Called By:       // procAccount
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdModifyAccount(int sock, int loop)
{
	int i = 0;
	char tmpSql[1024];
	char tmpStr[512];
	char where[256];
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;
	
	CheckDbConnection();

	//把输入的account_name参数的值从输入输出格式转换成数据库格式
	if (exValueOptToField(OptNo_index) == 1) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
				cmdBuf->optDef[OptNo_index].optName,
				cmdBuf->optDef[OptNo_index].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}
	
	//获得被修改帐户的权限
	sprintf(tmpSql, "SELECT privilege FROM %s "
			"WHERE %s=\'%s\'",
			cmdBuf->srcTable,
			cmdBuf->optDef[OptNo_index].fieldName,
			cmdBuf->optDef[OptNo_index].fieldValue);
#ifdef SMCLI_DEBUG
	printf("tmpSql=%s\n", tmpSql);
#endif
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

	//数据库中不存在被修改的用户
	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
		sprintf(OutputBuf, "%s:Cannot get this object value record!\n\r",
				ERR_0200);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		mysql_free_result(tmpResult);
		return (1);
	} else {
		//get record's value and fill to fieldValue
		tmpRow = mysql_fetch_row(tmpResult);
		//被修改的帐户的权限比修改帐户的权限大
		if (port_status[loop].privilege <= atoi(tmpRow[0])) {
			sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0012,
					cmdBuf->optDef[OptNo_index].optName,
					cmdBuf->optDef[OptNo_index].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			mysql_free_result(tmpResult);
			return (1);
		}
		mysql_free_result(tmpResult);
	}

	//帐户修改者要修改被修改帐户者的权限
	if (cmdBuf->optDef[OptNo_privilege].optFlag[0] > 0) {
		//权限值是两位数，非法权限
		if (strlen(cmdBuf->optDef[OptNo_privilege].optValue) > 1) {
			sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0010,
					cmdBuf->optDef[OptNo_privilege].optName,
					cmdBuf->optDef[OptNo_privilege].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}

		//权限值不在0和9之内，非法权限
		if ((cmdBuf->optDef[OptNo_privilege].optValue[0] < '0')
			|| (cmdBuf->optDef[OptNo_privilege].optValue[0] > '9')) {
			sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0010,
					cmdBuf->optDef[OptNo_privilege].optName,
					cmdBuf->optDef[OptNo_privilege].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}

		//非法权限值
		if (exValueOptToField(OptNo_privilege) == 1) {
			sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
					cmdBuf->optDef[OptNo_privilege].optName,
					cmdBuf->optDef[OptNo_privilege].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
		
		//修改帐户者的权限小于最后要修改的权限值
		if (port_status[loop].privilege <=
			atoi(cmdBuf->optDef[OptNo_privilege].fieldValue)) {
			sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0012,
					cmdBuf->optDef[OptNo_index].optName,
					cmdBuf->optDef[OptNo_index].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			return (1);
		}
	}

	memset(FieldNameList, 0, sizeof(FieldNameList));
	sprintf(tmpSql, "UPDATE %s SET ", cmdBuf->srcTable);
	//对命令中输入的参数值转换成数据库格式的值
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0
			&& cmdBuf->optDef[i].optFlag[0] > 0 && i != OptNo_index) {
			if (exValueOptToField(i) == 1) {
				sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
						cmdBuf->optDef[i].optName,
						cmdBuf->optDef[i].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
		}
	}

	//构造命令所携带的所有参数的sql语句，以便更新数据库
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0
			&& cmdBuf->optDef[i].optFlag[0] > 0 && i != OptNo_index) {
			if (i == OptNo_password)
				sprintf(tmpStr, " %s = password(\'%s\'),",
						cmdBuf->optDef[i].fieldName,
						cmdBuf->optDef[i].fieldValue);
			else
				sprintf(tmpStr, " %s =\'%s\',",
						cmdBuf->optDef[i].fieldName,
						cmdBuf->optDef[i].fieldValue);
			if (!strstr(FieldNameList, cmdBuf->optDef[i].fieldName)) {
				strcat(tmpSql, tmpStr);
				strcat(FieldNameList, cmdBuf->optDef[i].fieldName);
				strcat(FieldNameList, ",");
			}
		}
	}

	//没有指定修改的参数
	if (strlen(FieldNameList) < 2) {
		sprintf(OutputBuf, "%s:Cannot find fields!\n\r", ERR_0002);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	//删除最后一个逗号
	i = strlen(tmpSql);
	tmpSql[i - 1] = '\0';		
	i = strlen(FieldNameList);
	FieldNameList[i - 1] = '\0';

	//构造语句条件
	sprintf(where, " WHERE %s =\'%s\'",
			cmdBuf->optDef[OptNo_index].fieldName,
			cmdBuf->optDef[OptNo_index].fieldValue);
	strcat(tmpSql, where);
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	mysql_getnores(dbConn, tmpSql);

	//成功执行命令
	sprintf(OutputBuf, "%s \n\r", ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // doCmdCreateAccount
Description:     // 执行create account操作
Calls:           // 
Called By:       // procAccount
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdCreateAccount(int sock, int loop)
{
	int i = 0;
	char tmpSql[1024];
	char tmpStr[512];
	
	CheckDbConnection();
	
	//被创建帐户的权限值是两位数，非法权限
	if (strlen(cmdBuf->optDef[OptNo_privilege].optValue) > 1) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0010,
				cmdBuf->optDef[OptNo_privilege].optName,
				cmdBuf->optDef[OptNo_privilege].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	//被创建帐户的权限值不在0和9之间，非法权限
	if ((cmdBuf->optDef[OptNo_privilege].optValue[0] < '0')
		|| (cmdBuf->optDef[OptNo_privilege].optValue[0] > '9')) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0010,
				cmdBuf->optDef[OptNo_privilege].optName,
				cmdBuf->optDef[OptNo_privilege].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}
	
	//创建帐户者的权限比被创建帐户者的权限小
	if (port_status[loop].privilege <=
		atoi(cmdBuf->optDef[OptNo_privilege].optValue)) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0012,
				cmdBuf->optDef[OptNo_index].optName,
				cmdBuf->optDef[OptNo_index].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	//把命令的每个参数值转换成数据库存储的形式
	sprintf(tmpSql, "REPLACE %s SET ", cmdBuf->srcTable);
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0) {
			if (cmdBuf->optDef[i].optFlag[0] > 0) {
				if (exValueOptToField(i) == 1) {
					sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
							cmdBuf->optDef[i].optName,
							cmdBuf->optDef[i].optValue);
					OutputLen = strlen(OutputBuf);
					send(sock, OutputBuf, OutputLen, 0);
					return (1);
				}
			}
		}
	}
	
	//构造创建帐户的SQL语句
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strlen(cmdBuf->optDef[i].fieldName) > 0) {
			if (cmdBuf->optDef[i].optFlag[0] > 0) {
				if (i == OptNo_password)
					sprintf(tmpStr, " %s =password(\'%s\'),",
							cmdBuf->optDef[i].fieldName,
							cmdBuf->optDef[i].fieldValue);
				else
					sprintf(tmpStr, " %s =\'%s\',",
							cmdBuf->optDef[i].fieldName,
							cmdBuf->optDef[i].fieldValue);
				strcat(tmpSql, tmpStr);
			}
		}
	}

	i = strlen(tmpSql);
	tmpSql[i - 1] = '\0';		//delete the lastest ','
#ifdef SMCLI_DEBUG
	printf("\n tmpSql=%s \n", tmpSql);
#endif
	mysql_getnores(dbConn, tmpSql);
	
	//成功创建帐户执行命令
	sprintf(OutputBuf, "%s\n\r", ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // doCmdDeleteAccount
Description:     // 执行delete account操作
Calls:           // 
Called By:       // procAccount
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdDeleteAccount(int sock, int loop)
{
	char tmpSql[1024];
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;

	CheckDbConnection();
	//把命令中的参数的值转换成数据库存储的格式
	if (exValueOptToField(OptNo_index) == 1) {
		sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
				cmdBuf->optDef[OptNo_index].optName,
				cmdBuf->optDef[OptNo_index].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		return (1);
	}

	//获取被删除帐户的权限
	sprintf(tmpSql, "SELECT privilege FROM %s "
			"WHERE %s=\'%s\'",
			cmdBuf->srcTable,
			cmdBuf->optDef[OptNo_index].fieldName,
			cmdBuf->optDef[OptNo_index].fieldValue);
#ifdef SMCLI_DEBUG
	printf("tmpSql=%s\n", tmpSql);
#endif
	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

	//被删除的帐户不存在
	if (tmpResult == NULL || mysql_num_rows(tmpResult) == 0) {
		sprintf(OutputBuf, "%s:Cannot get this object value record!\n\r",
				ERR_0200);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
		mysql_free_result(tmpResult);
		return (1);
	} else {
		//get record's value and fill to fieldValue
		tmpRow = mysql_fetch_row(tmpResult);
		//被删除帐户的权限大于操作帐户者的权限
		if (port_status[loop].privilege <= atoi(tmpRow[0])) {
			sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0012,
					cmdBuf->optDef[OptNo_index].optName,
					cmdBuf->optDef[OptNo_index].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			mysql_free_result(tmpResult);
			return (1);
		}
	}
	
	//删除帐户
	sprintf(tmpSql, "Delete FROM %s WHERE %s=\'%s\'", cmdBuf->srcTable,
			cmdBuf->optDef[OptNo_index].fieldName,
			cmdBuf->optDef[OptNo_index].fieldValue);
	mysql_getnores(dbConn, tmpSql);

	//成功执行删除帐户的命令
	sprintf(OutputBuf, "%s\n\r", ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // doCmdExportAccount
Description:     // 执行export account的操作
Calls:           // 
Called By:       // procAccount
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client; loop:the index of the port_status;
Output:          // 
Return:          // 0:successful; >0:failed;
Others:          // 
*************************************************/
int doCmdExportAccount(int sock, int loop)
{
	int i = 0;
	int j = 0;
	int exportedNum = 0;
	int maxNum;
	int result;
	char tmpStr[128];
	char tmpSql[1024];
	char tmpBuf[1024];
	MYSQL_RES *tmpResult = NULL;
	MYSQL_ROW tmpRow = NULL;
	FILE *expFile = NULL;
	
	CheckDbConnection();

	//如果命令里有带query参数，并且值不为空
	if (cmdBuf->optDef[OptNo_query].optFlag[0] > 0
		&& strlen(cmdBuf->optDef[OptNo_query].optValue) > 0) {
		sprintf(tmpSql, "SELECT %s FROM %s WHERE %s ORDER BY %s",
				cmdBuf->optDef[OptNo_index].fieldName,
				cmdBuf->srcTable, ExportQueryStr,
				cmdBuf->optDef[OptNo_index].fieldName);
	} 
	//如果没有query参数，则查询数据库就不带条件限制
	else {
		sprintf(tmpSql, "SELECT %s FROM %s ORDER BY %s",
				cmdBuf->optDef[OptNo_index].fieldName,
				cmdBuf->srcTable, cmdBuf->optDef[OptNo_index].fieldName);
	}


	tmpResult = (MYSQL_RES *) mysql_getres(dbConn, tmpSql);

#ifdef SMCLI_DEBUG
	printf("tmpSql= %s\n\r", tmpSql);
#endif

	//数据库没有任何记录
	if (tmpResult == NULL || (maxNum = mysql_num_rows(tmpResult)) == 0) {
		mysql_free_result(tmpResult);
		sprintf(OutputBuf, "%s:Cannot get this object value record!\n\r",
				ERR_0200);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
#ifdef SMCLI_DEBUG
		printf("%d-", __LINE__);
#endif
		return (1);
	}

	//如果命令里有参数max，并且值不为空
	if (cmdBuf->optDef[OptNo_max].optFlag[0] > 0
		&& strlen(cmdBuf->optDef[OptNo_max].optValue) > 0) {
		if (strcmp(cmdBuf->optDef[OptNo_max].optValue, "all") != 0)
			if (strlen(cmdBuf->optDef[OptNo_max].optValue) > 6) {
				sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
						cmdBuf->optDef[OptNo_max].optName,
						cmdBuf->optDef[OptNo_max].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
		//判断max参数的值是否合法	
		for (i = 0; i < strlen(cmdBuf->optDef[OptNo_max].optValue); i++) {
			if (isdigit(cmdBuf->optDef[OptNo_max].optValue[i]) <= 0) {
				sprintf(OutputBuf, "%s:%s %s\n\r", ERR_0203,
						cmdBuf->optDef[OptNo_max].optName,
						cmdBuf->optDef[OptNo_max].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				return (1);
			}
		}
		//获取max参数的值
		maxNum = atoi(cmdBuf->optDef[OptNo_max].optValue);
	} else
		maxNum = 10;


	
	cmdBuf->optDef[OptNo_index].optFlag[0] = 1;
	//如果有expfile参数并且值不为空的话
	if (cmdBuf->optDef[OptNo_expfile].optFlag[0] > 0 &&
		strlen(cmdBuf->optDef[OptNo_expfile].optValue) > 0) {
		//打开指定的导出文件
		expFile = fopen(cmdBuf->optDef[OptNo_expfile].optValue, "w");
		if (expFile == NULL) {
			perror("fopen");
			sprintf(OutputBuf, "%s:%s\n\r", ERR_0258,
					cmdBuf->optDef[OptNo_expfile].optValue);
			OutputLen = strlen(OutputBuf);
			send(sock, OutputBuf, OutputLen, 0);
			mysql_free_result(tmpResult);
			return (1);
		}
		//在数据库里获取指定个数的记录
		while ((tmpRow = mysql_fetch_row(tmpResult)) && j < maxNum) {
			strcpy(cmdBuf->optDef[OptNo_index].fieldValue, tmpRow[0]);
			exValueFieldToOpt(OptNo_index);
			result = doCmdReadAccount(1, sock, loop);
			if (result == 2)
				continue;
			else if (result == 0) {
				//把每一条记录写进指定的文件
				fputs(cmdBuf->objectStr, expFile);
				for (i = 0; i < cmdBuf->optDefNum; i++) {
					if (cmdBuf->optDef[i].optFlag[CMD_READ] <=
						port_status[loop].privilege) {
						if (cmdBuf->optDef[OptNo_fields].optFlag[0] > 0) {
							sprintf(tmpStr, "%s ",
									cmdBuf->optDef[i].optName);
							if (strstr(ExportFieldsStr, tmpStr) == 0) {
								continue;
							}
						}
						sprintf(tmpStr, " -%s %s",
								cmdBuf->optDef[i].optName,
								cmdBuf->optDef[i].optValue);
						fputs(tmpStr, expFile);
					}
				}
				fputs("\n", expFile);
				//在客户端输出提示信息
				sprintf(OutputBuf, "Export %s=%s ok\n\r",
						cmdBuf->optDef[OptNo_index].optName,
						cmdBuf->optDef[OptNo_index].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				exportedNum++;
				j++;
			} else {
				sprintf(OutputBuf, "Export %s=%s failed\n\r",
						cmdBuf->optDef[OptNo_index].optName,
						cmdBuf->optDef[OptNo_index].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				j++;
			}
		}
		fclose(expFile);
		sprintf(OutputBuf, "%s:Exported %d %s(s) in %s \n\r", ERR_0000,
				exportedNum, cmdBuf->objectStr,
				cmdBuf->optDef[OptNo_expfile].optValue);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
	}
	//如果未指定导出文件，则把记录直接输出到客户端上 
	else {
		while ((tmpRow = mysql_fetch_row(tmpResult)) && j < maxNum) {
			strcpy(cmdBuf->optDef[OptNo_index].fieldValue, tmpRow[0]);
			exValueFieldToOpt(OptNo_index);
			result = doCmdReadAccount(1, sock, loop);
			if (result == 2)
				continue;
			else if (result == 0) {
				sprintf(OutputBuf, "%s", cmdBuf->objectStr);
				for (i = 0; i < cmdBuf->optDefNum; i++) {
					if (cmdBuf->optDef[i].optFlag[CMD_READ] <=
						port_status[loop].privilege) {
						if (cmdBuf->optDef[OptNo_fields].optFlag[0] > 0) {
							sprintf(tmpStr, "%s ",
									cmdBuf->optDef[i].optName);
							if (strstr(ExportFieldsStr, tmpStr) == 0) {
								continue;
							}
						}
						sprintf(tmpBuf, " -%s %s",
								cmdBuf->optDef[i].optName,
								cmdBuf->optDef[i].optValue);
						strcat(OutputBuf, tmpBuf);
					}
				}
				strcat(OutputBuf, "\n\r");
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				exportedNum++;
				j++;
			} else {
				sprintf(OutputBuf, "Export %s=%s failed\n\r",
						cmdBuf->optDef[OptNo_index].optName,
						cmdBuf->optDef[OptNo_index].optValue);
				OutputLen = strlen(OutputBuf);
				send(sock, OutputBuf, OutputLen, 0);
				j++;
			}
		}
		sprintf(OutputBuf, "%s:Exported %d %s(s) \n\r", ERR_0000,
				exportedNum, cmdBuf->objectStr);
		OutputLen = strlen(OutputBuf);
		send(sock, OutputBuf, OutputLen, 0);
	}
	mysql_free_result(tmpResult);
	return (0);
}

/*************************************************
Function:        // doCmdAlive
Description:     // 执行Alive操作
Calls:           // send
Called By:       // ReceiveTCP
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client
Output:          // 
Return:          // 
Others:          // 
*************************************************/
int doCmdAlive(int sock)
{
	sprintf(OutputBuf, "%s\n\r", ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // doCmdHelp
Description:     // 执行help命令
Calls:           // send
Called By:       // ReceiveTCP
Table Accessed:  // 
Table Updated:   // 
Input:           // sock:the sockId of the client
Output:          // 
Return:          // 
Others:          // 
*************************************************/
int doCmdHelp(int sock)
{
	sprintf(OutputBuf,
			"-----------------------------------help-----------------------------------------\n\r"
			"connect			---- Connect to server(HLR/PPS/VMS/MNP/OPPS/iPALIM)\n\r"
			"Usage: connect [type(hlr/pps/mnp/opps/ipalim)] -passwd value\n\r"
			"       connect [type(hlr/pps/vms/mnp/opps/ipalim)] -srvip ipaddress -passwd value\n\r"
			"Example: connect hlr -passwd 123456\n\r"
			"         connect hlr -srvip 172.18.98.1 -passwd 123456\n\r"
			"disconnect		---- Disconnect to server(HLR/PPS/VMS/MNP/OPPS/iPALIM)\n\r"
			"Usage: disconnect [type(hlr/pps/vms/mnp/opps/ipalim)]\n\r"
			"Example: disconnect hlr\n\r"
			"read			---- read a subscriber from server\n\r"
			"Usage: read object[type(account/subscriber/ppsuser/ppscard/vmsSubscriber/mnpSubscriber/oppsSubscriber/ipalimSubscriber)] -keyName(account_name/imsi/msisdn/cardno/msisdn/msisdn) keyValue\n\r"
			"Example: read subscriber -imsi 460022157127001\n\r"
			"modify			---- modify a subscriber to server\n\r"
			"Usage: modify object[type(account/subscriber/ppsuser/ppscard/vmsSubscriber/ppsParam/mnpSubscriber/oppsSubscriber/registerOpr/ipalimSubscriber)] -keyName(account_name/imsi/msisdn/cardno/msisdn//msisdn ) keyValue -fieldName fieldValue\n\r"
			"Example: modify subscriber -imsi 460022157127001 -nam gprs\n\r"
			"Example: modify registerOpr -imei 448954827510160 -cardPasswd 0000007600000000\n\r"			
			"create			---- Create a subscriber to server\n\r"
			"Usage: create object[type(account/subscriber/ppsuser/vmsSubscriber/ppsesme/mnpSubscriber/oppsSubscriber/ipalimSubscriber)] -keyName(account_name/imsi/msisdn/msisdn/no/msisdn) keyValue -fieldname fieldValue\n\r"
			"Example: create subscriber -imsi 460022157127001 -msisdn 8675557127001 \n\r"
			"delete			---- Delete a subscriber\n\r"
			"Usage: delete object[type(account/subscriber/ppsuser/vmsSubscriber/mnpSubscriber/oppsSubscriber/ipalimSubscriber)] -keyName(account_name/imsi/msisdn/msisdn/msisdn) keyValue\n\r"
			"Example: delete subscriber -imsi 460022157127001\n\r"
			"export			---- Export subscribers from server\n\r"
			"Usage: export object[type(account/subscriber/ppsuser/vmsSubscriber/mnpSubscriber/oppsSubscriber/ipalimSubscriber)] -query \"query value\" -fields \"fieldname\" -expfile expfilename\n\r"
			"Example: export subscriber -query \"imsi is 460022157127001\" -fields \"nam baoc_p\" -expfile /tmp/baseTestHlr\n\r"
			"import			---- Import subscribers to server\n\r"
			"Usage: import object[type(subscriber/ppsuser/vmsSubscriber/mnpSubscriber/oppsSubscriber/ipalimSubscriber)] -impfile expfilename\n\r"
			"Example: import subscriber  -impfile /tmp/baseTestHlr.import\n\r"
			"recharge		---- Recharge subscribers to server\n\r"
			"Usage: recharge object[type(ppsuser)] -fieldname fielaValue\n\r"
			"Example: recharge ppsuser -msisdn 86755900000 -credit 500 -promotion_credit 400 -mo_vday 010101 -mt_vday 010202 -promotion_vday 010303\n\r"
			"?Alive			---- keep alive \n\r"
			"Usage: ?Alive \n\r"
			"Example: ?Alive\n\r"
			"help			---- display help \n\r"
			"Usage: help \n\r"
			"Example: help\n\r"
			"exit			---- Exit\n\r"
			"Usage: exit\n\r"
			"Example: exit\n\r"
			"--------------------------------------------------------------------------------\n\r");
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	sprintf(OutputBuf, "\n\r%s\n\r", ERR_0000);
	OutputLen = strlen(OutputBuf);
	send(sock, OutputBuf, OutputLen, 0);
	return (0);
}

/*************************************************
Function:        // changeDefaultValue
Description:     // 
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void changeDefaultValue()
{
	int i;
	FILE *defautValueFile = NULL;
	char tmpSql[2048];
	long l_time;
	struct tm *t;
	
	CheckDbConnection();

	//open the smcli defaultValue file
	defautValueFile = fopen(SMCLI_DEFAULT_VALUE_FILE, "r");
	//如果没有这个文件，则在操作记录表里插一条记录
	if (defautValueFile == NULL) {
		l_time = time(NULL);
		t = localtime(&l_time);
		sprintf(tmpSql, "INSERT INTO %s	"
				"(operTypeNo,operNo,remark,userName,datetime)"
				"VALUES"
				"(\'0\',\'0\',\'There are no smcli default value file or open the file failed\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
				sysOperLogTable, t->tm_year + 1900,
				t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min,
				t->tm_sec);
#ifdef SMCLI_DEBUG
		printf("\n tmpSql=%s \n", tmpSql);
#endif
		mysql_getnores(dbConn, tmpSql);
		return;
	}

	memset(InputBuf, 0, InputBufSize);
	while (fgets(InputBuf, InputBufSize, defautValueFile) != NULL) {
#ifdef SMCLI_DEBUG
		printf("%s \n", InputBuf);
#endif
		if (InputBuf[0] == '#') {
			continue;
		}

		i = strlen(InputBuf);
		if (InputBuf[i - 1] == '\n')
			InputBuf[i - 1] = '\0';

		changeDefaultValueProcInput(InputBuf);
	}

	fclose(defautValueFile);
	return;
}

/*************************************************
Function:        // changeDefaultValueProcInput
Description:     // 
Calls:           // 
Called By:       // changeDefaultValue
Table Accessed:  // 
Table Updated:   // 
Input:           // 
Output:          // 
Return:          // 
Others:          // 
*************************************************/
void changeDefaultValueProcInput(char *inputBuf)
{
	int i = 0;
	int j = 0;
	int k = 0;
	int optNo;
	char *paramPart = NULL;
	char *onePart = NULL;
	char tmpSql[2048];
	long l_time;
	struct tm *t;
	
	CheckDbConnection();
	
	while ((paramPart = strsep(&(inputBuf), "-"))) {
		if (strlen(paramPart) < 2) {
			l_time = time(NULL);
			t = localtime(&l_time);
			sprintf(tmpSql, "INSERT INTO %s	"
					"(operTypeNo,operNo,remark,userName,datetime)"
					"VALUES"
					"(\'0\',\'0\',\'Unknown line:%s\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
					sysOperLogTable, inputBuf, t->tm_year + 1900,
					t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min,
					t->tm_sec);
#ifdef SMCLI_DEBUG
			printf("\n tmpSql=%s \n", tmpSql);
#endif
			mysql_getnores(dbConn, tmpSql);
			break;
		}

		switch (i) {
		case 0:				//command and object
			if (paramPart != NULL) {
				k = strlen(paramPart);
				while (' ' == *(paramPart + k - 1)) {
					k = k - 1;
					if (k == 0)
						break;
				}
				*(paramPart + k) = '\0';
			}
			if (paramPart != NULL) {
				onePart = paramPart;
				//object string like "subscriber" or "ppsuser" ...
				for (j = 0; j < CmdBufSize; j++) {
					if (strcmp(onePart, defCmdBuf[j].objectStr) == 0) {
						cmdBuf = &defCmdBuf[j];
						initCmdBuf(cmdBuf);
						for (optNo = 9; optNo < cmdBuf->optDefNum; optNo++)
							strcpy(cmdBuf->optDef[optNo].fieldValue,
								   cmdBuf->optDef[optNo].initFieldValue);
						break;
					}
				}
				if (j == CmdBufSize) {
					l_time = time(NULL);
					t = localtime(&l_time);
					sprintf(tmpSql, "INSERT INTO %s	"
							"(operTypeNo,operNo,remark,userName,datetime)"
							"VALUES"
							"(\'0\',\'0\',\'Unknown object:%s\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
							sysOperLogTable, onePart, t->tm_year + 1900,
							t->tm_mon + 1, t->tm_mday, t->tm_hour,
							t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
					printf("\n tmpSql=%s \n", tmpSql);
#endif
					mysql_getnores(dbConn, tmpSql);
					break;
				}
			} else {
				l_time = time(NULL);
				t = localtime(&l_time);
				sprintf(tmpSql, "INSERT INTO %s	"
						"(operTypeNo,operNo,remark,userName,datetime)"
						"VALUES"
						"(\'0\',\'0\',\'Object is NULL:%s\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
						sysOperLogTable, inputBuf, t->tm_year + 1900,
						t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min,
						t->tm_sec);
#ifdef SMCLI_DEBUG
				printf("\n tmpSql=%s \n", tmpSql);
#endif
				mysql_getnores(dbConn, tmpSql);
				break;
			}
			break;
		default:				//parameters name and value
			//parameter name
			if ((onePart = strsep(&(paramPart), " "))) {
				//try find from cmdBuf(command define array)
				for (optNo = 9; optNo < cmdBuf->optDefNum; optNo++) {
					if (strcmp(onePart, cmdBuf->optDef[optNo].optName) ==
						0) {
						//check option define
						break;
					}
				}
				//cannot find
				if (optNo == cmdBuf->optDefNum) {
					l_time = time(NULL);
					t = localtime(&l_time);
					sprintf(tmpSql, "INSERT INTO %s	"
							"(operTypeNo,operNo,remark,userName,datetime)"
							"VALUES"
							"(\'0\',\'0\',\'Unknown parameter:%s\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
							sysOperLogTable, onePart, t->tm_year + 1900,
							t->tm_mon + 1, t->tm_mday, t->tm_hour,
							t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
					printf("\n tmpSql=%s \n", tmpSql);
#endif
					mysql_getnores(dbConn, tmpSql);
					break;
				}
			} else {
				l_time = time(NULL);
				t = localtime(&l_time);
				sprintf(tmpSql, "INSERT INTO %s	"
						"(operTypeNo,operNo,remark,userName,datetime)"
						"VALUES"
						"(\'0\',\'0\',\'Invalid syntax:%s\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
						sysOperLogTable, onePart, t->tm_year + 1900,
						t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min,
						t->tm_sec);
#ifdef SMCLI_DEBUG
				printf("\n tmpSql=%s \n", tmpSql);
#endif
				mysql_getnores(dbConn, tmpSql);
				break;
			}

			//parameter value
			//if ((onePart = strsep(&(paramPart), " "))) {
			if (paramPart != NULL) {
				k = strlen(paramPart);
				while (' ' == *(paramPart + k - 1)) {
					k = k - 1;
					if (k == 0)
						break;
				}
				*(paramPart + k) = '\0';
			}

			if (paramPart != NULL) {
				onePart = paramPart;
				if (strlen(onePart) >=
					sizeof(cmdBuf->optDef[optNo].optValue)) {
					l_time = time(NULL);
					t = localtime(&l_time);
					sprintf(tmpSql, "INSERT INTO %s	"
							"(operTypeNo,operNo,remark,userName,datetime)"
							"VALUES"
							"(\'0\',\'0\',\'Invalid syntax:%s\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
							sysOperLogTable, onePart, t->tm_year + 1900,
							t->tm_mon + 1, t->tm_mday, t->tm_hour,
							t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
					printf("\n tmpSql=%s \n", tmpSql);
#endif
					mysql_getnores(dbConn, tmpSql);
					break;
				}
				sprintf(cmdBuf->optDef[optNo].optValue, "%s", onePart);
			} else {
				l_time = time(NULL);
				t = localtime(&l_time);
				sprintf(tmpSql, "INSERT INTO %s	"
						"(operTypeNo,operNo,remark,userName,datetime)"
						"VALUES"
						"(\'0\',\'0\',\'Invalid syntax:%s\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
						sysOperLogTable, cmdBuf->optDef[optNo].optName,
						t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
						t->tm_hour, t->tm_min, t->tm_sec);
#ifdef SMCLI_DEBUG
				printf("\n tmpSql=%s \n", tmpSql);
#endif
				mysql_getnores(dbConn, tmpSql);
				break;
			}

			if (exValueOptToField(optNo) == 1) {
				l_time = time(NULL);
				t = localtime(&l_time);
				sprintf(tmpSql, "INSERT INTO %s	"
						"(operTypeNo,operNo,remark,userName,datetime)"
						"VALUES"
						"(\'0\',\'0\',\'Error field value:%s %s\',\'smcli init default value\',\'%04d-%02d-%02d %02d:%02d:%02d\')",
						sysOperLogTable, cmdBuf->optDef[optNo].optName,
						cmdBuf->optDef[optNo].optValue, t->tm_year + 1900,
						t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min,
						t->tm_sec);
#ifdef SMCLI_DEBUG
				printf("\n tmpSql=%s \n", tmpSql);
#endif
				mysql_getnores(dbConn, tmpSql);
				break;
			}
			break;
		}						//end of switch
		i++;
	}							//end of while

	for (optNo = 9; optNo < cmdBuf->optDefNum; optNo++)
		strcpy(cmdBuf->optDef[optNo].initFieldValue,
			   cmdBuf->optDef[optNo].fieldValue);
	return;
}

/*************************************************
Function:        // getOptNoByName
Description:     // 根据参数的名称返回参数的索引
Calls:           // strcmp
Called By:       // procInput
Table Accessed:  // 
Table Updated:   // 
Input:           // optName:参数名称
Output:          // 
Return:          // 参数的索引
Others:          // 
*************************************************/
int getOptNoByName(char *optName)
{
	int i = 0;
	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (strcmp(optName, cmdBuf->optDef[i].optName) == 0) {
			return (i);
		}
	}
	return (-1);
}

/*************************************************
Function:        // setBitValue
Description:     // 
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // hexStr; byteOffset; bitOffset; bitValue;
Output:          // 
Return:          // 
Others:          // 
*************************************************/
int setBitValue(char *hexStr, int byteOffset, int bitOffset, unsigned char bitValue)
{
	unsigned char tmpByte = 0;
	char tmpStr[2];
	unsigned char flaseArr[8] =
		{ 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F };
	unsigned char tureArr[8] =
		{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };

	if (strlen(hexStr) < byteOffset * 2) {
		//error
		return (1);
	}
	//ASCII to BCD  
	omc_AsciiToRbcd(&tmpByte, hexStr + byteOffset * 2, 2);

	//Set bit value
	if (bitValue) {				//enable
		tmpByte = tmpByte | tureArr[bitOffset];
	} else {					//disable
		tmpByte = tmpByte & flaseArr[bitOffset];
	}
	omc_RbcdToAscii(tmpStr, &tmpByte, 2);

	memcpy(hexStr + byteOffset * 2, tmpStr, 2);
	return (0);
}

/*************************************************
Function:        // getBitValue
Description:     // 
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // hexStr; byteOffset; bitOffset; bitValue
Output:          // 
Return:          // 
Others:          // 此函数已废弃
*************************************************/
int getBitValue(char *hexStr, int byteOffset, int bitOffset, unsigned char *bitValue)
{
	unsigned char tmpByte = 0;

	omc_AsciiToRbcd(&tmpByte, hexStr + byteOffset * 2, 2);
//  printf("tmpByte=%c\n", tmpByte);
	*bitValue = (tmpByte >> bitOffset) & 0x01;
//  printf("bitValue=%s\n", bitValue);
	return (0);
}

/*************************************************
Function:        // fieldSync
Description:     // 
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // optNo
Output:          // 
Return:          // 
Others:          // 此函数已废弃
*************************************************/
void fieldSync(int optNo)
{
	int i = 0;
	if (strlen(cmdBuf->optDef[optNo].optValue) == 0) {
		return;
	}

	for (i = 0; i < cmdBuf->optDefNum; i++) {
		if (i != optNo
			&& strcmp(cmdBuf->optDef[optNo].fieldName,
					  cmdBuf->optDef[i].fieldName) == 0) {
			strcpy(cmdBuf->optDef[i].fieldValue,
				   cmdBuf->optDef[optNo].fieldValue);
		}
	}
}

/*************************************************
Function:        // hex2dec
Description:     // 把十六进制的字符串转化为十进制的字符串
Calls:           // 
Called By:       // 
Table Accessed:  // 
Table Updated:   // 
Input:           // hexStr:十六进制字符串; decStr:十进制字符串;
Output:          // 
Return:          // 
Others:          // 此函数已废弃
*************************************************/
int hex2dec(char *hexStr, char *decStr)
{
	int len;
	int i;
	double result = 0;

	len = strlen(hexStr);
	for (i = 0; i < len; i++) {
		if (hexStr[i] == '0')
			result = result;
		else if (hexStr[i] == '1')
			result = result + ldexp(1, ((len - 1 - i) * 4));
		else if (hexStr[i] == '2')
			result = result + ldexp(2, ((len - 1 - i) * 4));
		else if (hexStr[i] == '3')
			result = result + ldexp(3, ((len - 1 - i) * 4));
		else if (hexStr[i] == '4')
			result = result + ldexp(4, ((len - 1 - i) * 4));
		else if (hexStr[i] == '5')
			result = result + ldexp(5, ((len - 1 - i) * 4));
		else if (hexStr[i] == '6')
			result = result + ldexp(6, ((len - 1 - i) * 4));
		else if (hexStr[i] == '7')
			result = result + ldexp(7, ((len - 1 - i) * 4));
		else if (hexStr[i] == '8')
			result = result + ldexp(8, ((len - 1 - i) * 4));
		else if (hexStr[i] == '9')
			result = result + ldexp(9, ((len - 1 - i) * 4));
		else if (hexStr[i] == 'A')
			result = result + ldexp(10, ((len - 1 - i) * 4));
		else if (hexStr[i] == 'B')
			result = result + ldexp(11, ((len - 1 - i) * 4));
		else if (hexStr[i] == 'C')
			result = result + ldexp(12, ((len - 1 - i) * 4));
		else if (hexStr[i] == 'D')
			result = result + ldexp(13, ((len - 1 - i) * 4));
		else if (hexStr[i] == 'E')
			result = result + ldexp(14, ((len - 1 - i) * 4));
		else if (hexStr[i] == 'F')
			result = result + ldexp(15, ((len - 1 - i) * 4));
		else
			break;
	}
	sprintf(decStr, "%.0f", result);
	return (1);
}

/*************************************************
Function:        // getServerStat
Description:     // 获取指定IP地址服务器的状态
Calls:           // pclose; popen;
Called By:       // doCmdConnect;
Table Accessed:  // 
Table Updated:   // 
Input:           // ip:指定的IP地址;
Output:          // 
Return:          // 1:error; 0:ok;
Others:          // 
*************************************************/
//return 1:error, 0:ok
int getServerStat(char *ip)
{
	char sysCommStr[100];
	FILE *fp = NULL;
	char buff[1024], inputStr[10];
	int n, packetNum;

	sprintf(sysCommStr, "ping -U -c 2 %s|grep -c %s", ip, ip);
	//printf("sysCommStr=%s\n",sysCommStr);
	if ((fp = popen(sysCommStr, "r")) == NULL) {
		return (1);
	}
	if (fgets(buff, sizeof(buff), fp) == NULL) {
		pclose(fp);
		return (1);
	}
	pclose(fp);
	n = sscanf(buff, "%s", inputStr);
	if (n > 0) {
		packetNum = atol(inputStr);
		if (packetNum == 4) {
			return (0);
		}
	}
	return (1);
}

int InitDefCmdBuf()
{
	unsigned int i, j, k;
	unsigned int CmdDefSize, OptDefSize;
	MYSQL *tmpdbConn;
	MYSQL_RES *CmdDefResult = NULL;
	MYSQL_ROW CmdDefRow = NULL;
	MYSQL_RES *OptDefResult = NULL;
	MYSQL_ROW OptDefRow = NULL;
	char tmpSQL[200] = "\0";

	tmpdbConn = mysql_conn("localhost", "SMCLI");
	if (tmpdbConn == NULL)
		return (-1);

	sprintf(tmpSQL, "SELECT * FROM sysCmdDef ORDER BY keyId");
	CmdDefResult = (MYSQL_RES *) mysql_getres(tmpdbConn, tmpSQL);
	if (CmdDefResult != NULL)
		CmdDefSize = mysql_num_rows(CmdDefResult);
	else
		return (-2);

	if (CmdDefSize == 0) {
		mysql_free_result(CmdDefResult);
		return (-2);
	} else if (CmdDefSize > CmdBufSize) {
		printf
			("Warning!The number of configed system is larger than the SMCLI support.\n");
		CmdDefSize = CmdBufSize;
	}

	for (i = 0; i < CmdDefSize; i++) {
		CmdDefRow = mysql_fetch_row(CmdDefResult);
		//tmpRow[0] is keyId, ignored
		defCmdBuf[i].isConnected = atoi(CmdDefRow[1]);
		strncpy(defCmdBuf[i].serverStr, CmdDefRow[2],
				sizeof(defCmdBuf[i].serverStr));
		strncpy(defCmdBuf[i].objectStr, CmdDefRow[3],
				sizeof(defCmdBuf[i].objectStr));
		strncpy(defCmdBuf[i].ip, CmdDefRow[4], sizeof(defCmdBuf[i].ip));
		defCmdBuf[i].sysTypeNo = atoi(CmdDefRow[5]);
		defCmdBuf[i].sysNo = atoi(CmdDefRow[6]);
		defCmdBuf[i].subSysNo = atoi(CmdDefRow[7]);
		defCmdBuf[i].dataTypeNo = atoi(CmdDefRow[8]);
		strncpy(defCmdBuf[i].srcTable, CmdDefRow[9],
				sizeof(defCmdBuf[i].srcTable));
		strncpy(defCmdBuf[i].tmpTable, CmdDefRow[10],
				sizeof(defCmdBuf[i].tmpTable));
		strncpy(defCmdBuf[i].paramStr, CmdDefRow[11],
				sizeof(defCmdBuf[i].paramStr));
		strncpy(defCmdBuf[i].paramTable, CmdDefRow[12],
				sizeof(defCmdBuf[i].paramTable));
		strncpy(defCmdBuf[i].cmdFlag, CmdDefRow[13],
				sizeof(defCmdBuf[i].cmdFlag));
		for (k = 0; k < MaxCmdTypeNum; k++) {
			if (defCmdBuf[i].cmdFlag[k] != 0)
				defCmdBuf[i].cmdFlag[k] -= 0x30;
		}

		sprintf(tmpSQL, "SELECT * FROM %s ORDER BY keyId",
				defCmdBuf[i].objectStr);
				//writeDebug("%s",tmpSQL);
		OptDefResult = (MYSQL_RES *) mysql_getres(tmpdbConn, tmpSQL);
		if (OptDefResult != NULL)
			OptDefSize = mysql_num_rows(OptDefResult);
		else
			return (-2);
		if (OptDefSize == 0) {
			mysql_free_result(CmdDefResult);
			continue;
		} else if (OptDefSize > MaxOptNum) {
			printf
				("Warning!The number of configed command in %s is larger than the SMCLI supported.\n",
				 defCmdBuf[i].serverStr);
			OptDefSize = MaxOptNum;
		}
		defCmdBuf[i].optDefNum = OptDefSize;
		for (j = 0; j < OptDefSize; j++) {
			OptDefRow = mysql_fetch_row(OptDefResult);
			strncpy((char*)defCmdBuf[i].optDef[j].optFlag, OptDefRow[1],
					MaxCmdTypeNum + 1);
			for (k = 0; k < MaxCmdTypeNum + 1; k++) {
				if (defCmdBuf[i].optDef[j].optFlag[k] != 0)
					defCmdBuf[i].optDef[j].optFlag[k] -= 0x30;
			}
			strncpy(defCmdBuf[i].optDef[j].optName, OptDefRow[2],
					sizeof(defCmdBuf[i].optDef[j].optName));
			defCmdBuf[i].optDef[j].exMode = atoi(OptDefRow[3]);
			strncpy(defCmdBuf[i].optDef[j].fieldName, OptDefRow[4],
					sizeof(defCmdBuf[i].optDef[j].fieldName));	
			strncpy(defCmdBuf[i].optDef[j].initFieldValue, OptDefRow[5],
					sizeof(defCmdBuf[i].optDef[j].initFieldValue));
		}
		mysql_free_result(OptDefResult);
	}

	mysql_free_result(CmdDefResult);
	mysql_close(tmpdbConn);
	return 0;
}

void CheckDbConnection()
{
	if(mysql_ping(dbConn))
	{
		writeDebug("[ERR 2006][CheckDbConnection]:mysql OMC_PUB has gone away,reconnect");
		mysql_close(dbConn);
		dbConn=mysql_conn("localhost","OMC_PUB");
		if(dbConn == NULL)
		{
		  writeDebug("[ERR][CheckDbConnection]:reconnect OMC_PUB");
		}
	}
}

void writeDebug(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/smcli%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);
	}
}

char *opt_date(char *org_date,char *opt_value,char *result_date)
{
        struct tm org_t,*result_t;
        time_t org_time;
        int len;
        int sign;
        unsigned long opt_second;
        
        time_t now_time;
        struct tm *now_t;
        char currtimestr[64];
        
        len=strlen(org_date);
        if(len < 8)
                return NULL;
        
        now_time=time(NULL);
				now_t=localtime(&now_time);
				sprintf(currtimestr,"%04d%02d%02d000000",now_t->tm_year+1900,now_t->tm_mon+1,now_t->tm_mday);
        
        if(strcmp(org_date,currtimestr) < 0)
        {
        	sprintf(org_date,"%s",currtimestr);
        }       
         
        if(opt_value[0] == '~')
        {
                opt_second=atol(&opt_value[1]) * 24 * 3600;
                sign=-1;
        }
        else
        {
                opt_second=atol(opt_value) * 24 * 3600;
                sign=1;
        }
				memset(&org_t,0,sizeof(org_t));
        org_t.tm_year=(org_date[0] - '0')*1000 + (org_date[1] - '0')*100 +(org_date[2] - '0')*10 +(org_date[3] - '0') - 1900;
        if(org_t.tm_year < 0)
                return NULL;
        org_t.tm_mon=(org_date[4] - '0')*10 + (org_date[5] - '0') - 1;
        if(org_t.tm_mon < 0 || org_t.tm_mon > 11)
                return NULL;
        org_t.tm_mday=(org_date[6] - '0')*10 + (org_date[7] - '0');
        if(org_t.tm_mday < 1 || org_t.tm_mday > 31)
                return NULL;

        org_time=mktime(&org_t);
        if(sign == -1)
        {
                if(org_time < opt_second)
                        return NULL;
                org_time-=opt_second;
        }
        else
        {
                org_time+=opt_second;
        }
        result_t=localtime(&org_time);
        sprintf(result_date,"%04d%02d%02d000000",result_t->tm_year+1900,result_t->tm_mon+1,result_t->tm_mday);
        return result_date;

}
