📄 parser.c
字号:
//////////////////////////////////////////////////////////////////////////////////// Copyright(c) 2001 Intrinsyc Software Inc. All rights reserved.//// Module name://// parser.c//// Description://// Handles the parsing, and execution of, incoming text commands.//// Author://// Mike Kirkland//// Created://// October 2001//////////////////////////////////////////////////////////////////////////////////#include <parser.h>#include <config.h>#include <serial.h>#include <platform.h>#include <flash_i128.h>#include <c_main.h>#include <string.h>#include <cedecode.h>#include <string.h>#include <cebootme.h>#include <tftp.h>#include <params.h>#include <util.h>#include <ethernet.h>#include <memtest.h>#include <uudecode.h>#include <bootp.h>#include <help.h>#include <net.h>#include <dhcp.h>#include <zeroconf.h>#include <os.h>#include <messages.h>#include <checksum.h>#include <timer.h>#include <xmodem.h>#include <icmp.h>#include <fis.h>#include <eeprom.h>#include <nvconfig.h>#include <idle.h>#include <cpu.h>int boot_parse(char const * arg);int bootme_parse(char const * arg);int bootmem_parse(char const * arg);int jump_parse(char const * arg);int copy_parse(char const * arg);int createfis_parse(char const * arg);int decode_parse(char const * arg);int download_parse(char const *arg);int eeclear_parse(char const * arg);int eedump_parse(char const * arg);int eraseflash_parse(char const * arg);int exec_parse(char const *);int flash_parse(char const *arg);int flashloader_parse(char const *arg);int flashverify_parse(char const * arg);int getbyte_parse(char const * arg);int getword_parse(char const * arg);int getdword_parse(char const * arg);int help_parse(char const * arg);int info_parse(char const * arg);int memtest_parse(char const * arg);int ping_parse(char const * arg);int updatece_parse(char const * arg);int reboot_parse(char const * arg);int runce_parse(char const * arg);int setbyte_parse(char const * arg);int setword_parse(char const * arg);int setdword_parse(char const * arg);int set_parse(char const *arg);int set_ip_parse(char const *arg);int set_mac_parse(char const *arg);int set_server_parse(char const *arg);int set_speed_parse(char const *arg);int set_mask_parse(char const *arg);int set_gw_parse(char const *arg);int crc_parse(char const *arg);command_def command_set[] ={ // command function_name min. # parameters { "boot", boot_parse, 0 }, { "bootme", bootme_parse, 0 }, { "bootmem", bootmem_parse, 2 }, { "copy", copy_parse, 3 }, { "crc", crc_parse, 2 }, { "createfis", createfis_parse, 1 }, { "decode", decode_parse, 0 }, { "download", download_parse, 2 }, #ifdef TAGGED_EEPROM { "eeclear", eeclear_parse, 0 }, { "eedump", eedump_parse, 0 }, #endif // TAGGED_EEPROM { "eraseflash", eraseflash_parse, 1 }, { "exec", exec_parse, 1 }, { "flash", flash_parse, 3 }, { "flashloader", flashloader_parse, 3 }, { "flashverify", flashverify_parse, 3 }, { "getbyte", getbyte_parse, 1 }, { "getword", getword_parse, 1 }, { "getdword", getdword_parse, 1 }, { "help", help_parse, 0 }, { "info", info_parse, 0 }, { "jump", jump_parse, 1 }, { "memtest", memtest_parse, 2 }, { "ping", ping_parse, 1 }, { "reboot", reboot_parse, 0 }, { "runce", runce_parse, 0 }, { "setbyte", setbyte_parse, 2 }, { "setword", setword_parse, 2 }, { "setdword", setdword_parse, 2 }, { "set", set_parse, 0 }, { "set gw", set_gw_parse, 1 }, { "set ip", set_ip_parse, 1 }, { "set mac", set_mac_parse, 1 }, { "set mask", set_mask_parse, 1 }, { "set server", set_server_parse, 1 }, { "set speed", set_speed_parse, 2 }, { "updatece", updatece_parse, 0 },};////////////////////////////////////////////////////////////////////////////////// list_commands// PURPOSE: List all the commands known to the parser// PARAMS: None.// RETURNS: None.////////////////////////////////////////////////////////////////////////////////voidlist_commands(void){ int i;#define COMMANDS_PER_LINE 7 for(i = 0; i < countof(command_set); ++i) { if ((i % COMMANDS_PER_LINE) == 0) { if (i) { /* End of line */ itc_printf(",\r\n"); } } else { itc_printf(", "); } itc_printf("%s",command_set[i].command); } itc_printf("\r\n");}////////////////////////////////////////////////////////////////////////////////// get_token_count// PURPOSE: Returns the number of tokens in a given string.// PARAMS: (IN) char *arg - string to count.// RETURNS: Number of tokens in arg.////////////////////////////////////////////////////////////////////////////////static intget_token_count(char const *arg){ int retval = 0; while(*arg != '\0') { arg = next_token(arg); retval++; } return retval;}////////////////////////////////////////////////////////////////////////////////// parse_command// PURPOSE: Parses the command and passes its arguments on to the appropriate// handler function.// PARAMS: (IN) char *commandline - command to parse.// RETURNS: mode - the current mode. Currently partition or default.////////////////////////////////////////////////////////////////////////////////modeparse_command(char const *commandline, mode cur_mode){ int i = 0; while (*commandline && *commandline <= ' ') commandline++; //skip leading whitespace if(!*commandline || *commandline == '#') { return cur_mode; } for(i = countof(command_set); i >= 0; i--) { if(cmpstr(commandline, command_set[i].command)) { if((get_token_count(commandline) - 1) >= command_set[i].min_args) { //Call the function pointer in the appropriate command_def, and //return the current mode on success, or mode_error on failure. char const *args = commandline + itc_strlen(command_set[i].command); while (*args && *args <= ' ') args++; //skip whitespace after command name return ((command_set[i].parse_func) (args) ? cur_mode : mode_error); } else { error_print(PARSE_MIN_ARGS_ERROR); return mode_error; } } } error_print(PARSE_NO_COMMAND_ERROR); return mode_error;}////////////////////////////////////////////////////////////////////////////////// parse and execute a script// PURPOSE: Parses a script in memory.// PARAMS: (IN) char *curline - script to parse terminated by '\0'.// RETURNS: mode - the current mode, currently partition or default.////////////////////////////////////////////////////////////////////////////////modeparse_script(char const *script){ mode curmode = mode_default; char const *curpos = script; unsigned len; char cmdbuf[256]; //holds only one line at a time while (*script) { while (*curpos && *curpos != '\r' && *curpos != '\n') { curpos++; } len = curpos - script; if (len >= sizeof(cmdbuf)) { itc_printf("Script line too long!\r\n"); return mode_error; } itc_strlcpy(cmdbuf, script, len+1); //copy script line to RAM // A script that was loaded into memory might not have 0 at the end, // and we don't know where the script ends. To avoid interpreting // garbage, allow script to be terminated via 'exit'. if( itc_strcmp( cmdbuf, "exit")) break; //quick way to exit script itc_printf("IBoot: %s\r\n", cmdbuf); curmode = parse_command(cmdbuf, curmode); if (curmode == mode_error) { break; } // skip over Unix (or DOS) line break if (curpos[0] == '\r' && curpos[1] == '\n') { curpos++; } if (*curpos) { curpos++; } script = curpos; } return curmode;}////////////////////////////////////////////////////////////////////////////////// get_number_parse// PURPOSE: Parses an address an address or other 32 bit hexadecimal number.// PARAMS: (IN) char *arg - string to parse.// (OUT) u8 **address - address parsed.// RETURNS: 0 on failure, address of next token in arg on success. If there are// no more tokens, return value will point to the strings null.////////////////////////////////////////////////////////////////////////////////static char const*get_number_parse(char const *arg, u32 *address){ int offset; if(*arg == '0' && *(arg + 1) == 'x') { arg += 2; offset = atou32(arg, (u32 *)address); } else offset = atoi(arg, (int *)address); return (offset ? next_token(arg + offset) : (char *)offset);}////////////////////////////////////////////////////////////////////////////////// get_filename_parse// PURPOSE: Parses out a filename from a string.// PARAMS: (IN) char *arg - argument(s) to the download command.// (OUT) char *buf - buffer to hold file name// (IN) int size - size of buffer// RETURNS: 0 on failure, address of next token in arg on success. If there are// no more tokens, return value will point to the strings null.////////////////////////////////////////////////////////////////////////////////static char const*get_filename_parse(char const *arg, char *buf, int size){ int i = 0; while(*arg != ' ' && *arg != 0 && i < size) { if (*arg == '\\' && *(arg+1)) { // skip over backslash and take next char unconditionally ++arg; } *buf++ = *arg++; i++; } *buf = 0; return (i ? next_token(arg) : (char *)0);}////////////////////////////////////////////////////////////////////////////////// download_parse:// PURPOSE: Parses a download command and executes appropriate download method.// PARAMS: (IN) char *arg - argument(s) to the download command.// RETURNS: 1 for success, 0 for failure.////////////////////////////////////////////////////////////////////////////////intdownload_parse(char const *arg){ enum { unknown, tftp, tftpd, serial, raw, xmodem } dl_type; char *dest = 0; char filename[MAX_FILENAME_SIZE]; u32 ip = 0; int len; if(cmpstr(arg, "tftp")) { dl_type = tftp; } else if(cmpstr(arg, "tftpd")) { dl_type = tftpd; } else if(cmpstr(arg, "serial")) { dl_type = serial; } else if(cmpstr(arg, "raw")) { dl_type = raw; } else if(cmpstr(arg, "xmodem")) { dl_type = xmodem; } else { dl_type = unknown; } arg = next_token(arg); if(dl_type == tftp) { // Parse IP address if specified, otherwise use default server if (*arg == ':') { if((ip = atoip(arg+1))) { status.siaddr = ip; arg = next_token(arg); } else { error_print(PARSE_INVALID_IP_ERROR); return 0; } } if (status.siaddr == 0) { error_print(PARSE_INVALID_IP_ERROR); return 0; } if(!(get_filename_parse(arg, filename, sizeof(filename)))) { error_print(PARSE_INVALID_ARG_ERROR); return 0; } arg = next_token(arg); } if(!(get_number_parse(arg, (u32 *)&dest))) { error_print(PARSE_INVALID_ARG_ERROR); return 0; } arg = next_token(arg); if((u32)dest < PLATFORM_MEMORY_BASE || (u32)dest > PLATFORM_MEMORY_MAX) { error_print(PARSE_RANGE_ERROR); return 0; } switch(dl_type) { case raw: { if(!(get_number_parse(arg, (u32 *)&len))) { error_print(PARSE_INVALID_ARG_ERROR); return 0; } if (!raw_input_serial(dest, len, 3600*100)) { itc_printf("Timeout in serial transfer\r\n"); return 0; } break; } case serial: { len = uudecode(dest); break; } case xmodem: { itc_printf("Start upload procedure using Xmodem-CRC Protocol.\r\n"); itc_printf("(Press ESC to cancel.)\r\n"); if (Xrecv(dest, (u32 *)&len)) { itc_printf("Error in XMODEM transfer\r\n"); return 0; } break; } case tftpd: { if(status.ciaddr == 0) { u32 temp; message_print(PARSE_DHCP_MESSAGE); if(!init_dhcp(&status.ciaddr, &temp, &status.giaddr, &status.smask)) { error_print(DHCP_TIMEOUT_ERROR); return 0; } } do cebootme(); while((len = tftplisten(dest)) < 0) ; break; } case tftp: { if(status.ciaddr == 0) { u32 temp; message_print(PARSE_DHCP_MESSAGE); if(!init_dhcp(&status.ciaddr, &temp, &status.giaddr, &status.smask)) { error_print(DHCP_TIMEOUT_ERROR); return 0; } } if((len = tftpget((char *)filename, dest)) < 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -