CmdParser是用于分解和分析命令输入的,说是一个Parser,实际很简单,就是将命令分解,然后将分解出来的命令字串跟已经'regist'的命令字串进行一一的比较,找到就返回注册命令的指针,并传入相应的参数(这部分代码在TelnetServer中);找不到就执行默认的UnknownCmdProc。
#ifndef __CCCMD_H__
#define __CCCMD_H__

#include "CCDataType.h"


extern int cc_TelnetServer_ClientWriteText(SOCKET s, const char* text);


extern int cc_CmdParser_Parser(struct _cc_telnet_clientdata* client, struct _cc_cmddata** cmd, int* argc, char argv[][CC_SIZE_CMD]);
extern int cc_CmdParser_UnknownCmd(struct _cc_telnet_clientdata* client, const char* cmd);

extern int cc_RegCmd(const char* cmd, const char*help, const _cc_cmdcallback callback);
extern int cc_RegDefaultCmds();

extern int cc_CmdOutput(struct _cc_telnet_clientdata* client, const char* fmt,
);

extern int cc_cmd_exit(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD]);
extern int cc_cmd_help(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD]);
extern int cc_cmd_list(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD]);
extern int cc_cmd_version(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD]);


#endif


#include <stdarg.h>

#include "CCCmd.h"

int cc_CmdParser_Search(const char* str, struct _cc_cmddata** cmd)


{
struct _cc_cmddata* c = cc_Global.cmd.cmd;
while(c != NULL)

{
if(strcmp(c->cmd, str) == 0)

{
(*cmd) = c;
return 0;
}
c = c->next;
}
return -1;
}

int cc_CmdParser_Parser(struct _cc_telnet_clientdata* client, struct _cc_cmddata** cmd, int* argc, char argv[][CC_SIZE_CMD])


{
char str[CC_SIZE_CMD];
char* token = NULL;
char* sep = ",";

memset(str, 0, sizeof(str));
strncpy(str, client->buf, client->recv - 2);
token = strtok(str, sep);
if(token == NULL)
return -1;
if(cc_CmdParser_Search(token, cmd) != 0)

{
cc_CmdParser_UnknownCmd(client, token);
return -1;
}
(*argc) = 0;
token = strtok(NULL, sep);
while(token != NULL)

{
strncpy(&argv[(*argc)], token, CC_SIZE_CMD);
++ (*argc);
token = strtok(NULL, sep);
}

return 0;
}

int cc_CmdParser_UnknownCmd(struct _cc_telnet_clientdata* client, const char* cmd)


{
cc_CmdOutput(client, "Unknown command - %s\r\n", cmd);

return 0;
}

int cc_RegDefaultCmds()


{
cc_RegCmd(".version", "display version info.", cc_cmd_version);
cc_RegCmd(".exit", "exit the connection.", cc_cmd_exit);
cc_RegCmd(".help", "display help info of command.", cc_cmd_help);
cc_RegCmd(".list", "list all connections.", cc_cmd_list);

return 0;
}


int cc_RegCmd(const char* cmd, const char* help, const _cc_cmdcallback callback)


{
struct _cc_cmddata* tmp = NULL;
struct _cc_cmddata* c = (struct _cc_cmddata*)malloc(sizeof(struct _cc_cmddata));
c->callback = callback;
strncpy(c->cmd, cmd, sizeof(c->cmd));
strncpy(c->help, help, sizeof(c->help));
c->next = NULL;

if(cc_Global.cmd.cmd == NULL)

{
cc_Global.cmd.cmd = c;
}
else

{
tmp = cc_Global.cmd.cmd;
while(tmp->next != NULL)

{
tmp = tmp->next;
}
tmp->next = c;
}

return 0;
}

int cc_CmdOutput(struct _cc_telnet_clientdata* client, const char* fmt,
)


{
char buf[CC_SIZE_CMD];
int len = -1;
va_list args;

memset(buf, 0, sizeof(buf));
va_start(args, fmt);
len = vsprintf(buf, fmt, args);
va_end(args);
return cc_TelnetServer_ClientWrite(client->sock, buf, len);

// len = sprintf(buf, fmt, __VA_ARGS__);
}


/**//* ----------------------------- */
int cc_cmd_exit(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD])


{
cc_CmdOutput(client, "bye.\r\n");
return -1;
}

int cc_cmd_help(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD])


{
struct _cc_cmddata* tmp = cc_Global.cmd.cmd;
while(tmp != NULL)

{
if(argc > 0)

{
if(strncmp(tmp->cmd, argv[0], sizeof(tmp->cmd)) == 0)

{
cc_CmdOutput(client, "%s : %s\r\n", tmp->cmd, tmp->help);

return 0;
}
}
else

{
cc_CmdOutput(client, "%s : %s\r\n", tmp->cmd, tmp->help);
}
tmp = tmp->next;
}
return 0;
}

int cc_cmd_list(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD])


{
struct _cc_telnet_clientdata* tmp = cc_Global.telnet.client;

while(tmp != NULL)

{
cc_CmdOutput(client, "conn %d : %s:%d in %s", tmp->index, tmp->ip, tmp->port, asctime(gmtime(&tmp->updated)));
tmp = tmp->next;
}
cc_CmdOutput(client, "\r\n");
return 0;
}

int cc_cmd_version(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD])


{
cc_CmdOutput(client, "CmdChannel library v0.0.0.2 by Jie.(codejie@gmail.com).\r\n");
return 0;
}