#include #include #define MAX_BUF 256 #define MAX_ARG 128 #define NONE 0 #define COMMAND 1 #define SYNTAX 2 #define IOERR 3 #define DSKFULL 4 #define CMDFULL 5 #define NOFILE 6 #define MEMFULL 7 #define IGFMT 8 #define ARIGN 9 #define FSCHK 2 static char prompt[16], echo_flag; static char cmd_buf[MAX_BUF], *cmd_argv[MAX_ARG]; typedef struct { unsigned int (*function)(int, char**); char command[12]; unsigned char min, max, opt; } function_table; static function_table table[] = { {0,"dump", 2, 3, NONE}, {0,"setdata", 3, 4, NONE}, {0,"dir", 1, 2, NONE}, {0,"zeromem", 3, 3, NONE}, {0,"ifconfig", 1, 4, NONE}, {0,"gateway", 2, 2, NONE}, {0,"ping", 2, 2, NONE}, {0,"echo", 2, 2, NONE}, {0,"del", 2, 2, NONE}, {0,"ssid", 3, 3, NONE}, {0,"wipm", 3, 3, NONE}, {0,"tftp", 3, 3, NONE}, {0,"type", 2, 2, NONE}, {0,"pwd", 1, 1, NONE}, {0,"cd", 2, 2, NONE}, {0,"mount", 2, 2, NONE}, {0,"eject", 2, 2, NONE}, {0,"format", 2, 2, NONE}, {0,"copy", 3, 3, NONE}, {0,"dns", 2, 2, NONE}, {0,"", 1, MAX_ARG, NONE} }; static unsigned int read_line(int fd, char* buffer, char** argv) { unsigned int i, argc, n; char* ptr, c; ptr = buffer; for(;;) { if((unsigned int)ptr >= (unsigned int)(buffer + MAX_BUF)) ptr = &buffer[MAX_BUF - 1]; do { n = read(fd, &c, 1); if(fd != 0 && n == 0) return -1; } while(n == 0); *ptr = c; if(*ptr >= 0x80) continue; if(*ptr == '\n') break; if(*ptr == '\r') break; if(*ptr == 0x7f) *ptr = 8; if(*ptr == 8) { if((unsigned int)ptr > (unsigned int)buffer) { if(echo_flag) putchar(*ptr); ptr--; } } else { if(echo_flag) putchar(*ptr); ptr++; } } *ptr = 0; if(buffer[0] == 0) return 0; ptr = buffer; i = argc = 0; argv[argc++] = &(buffer[i]); while(buffer[i] != 0) { if(buffer[i] == ' ') { buffer[i] = 0; if(argc >= (MAX_ARG - 1)) break; argv[argc++] = &(buffer[i + 1]); } i++; } argv[argc] = 0; return argc; } static void err_message(unsigned int id) { static const char message[10][20] = { "Command not found.", "Syntax error.", "Disk I/O error.", "Disk is full.", "Buffer is full.", "File not found.", "Memory is full.", "Ignore file format.", "Arignment error.", "Unknown error." }; unsigned int i; i = (id > 9) ? 9 : id - 1; printf("ERROR[%s]\r", message[i]); } static unsigned int dump(int argc, char** argv) { unsigned int i, n, num; volatile unsigned int w; char *pb; short *pw; sscanf(argv[argc - 1], "%x", &num); n = num + 16 * 8; while(num < n) { printf("%08x : ", num); if(argc == 3 && argv[1][0] == 'w') { if(num & 1) return ARIGN; pw = (short*)num; for(i = 0;i < 8;i++) { if(i == 4) printf(" "); printf("%04x", (unsigned int)(*pw++) & 0xffff); } } else { pb = (char*)num; for(i = 0;i < 16;i++) { if(i == 8) printf(" "); printf("%02x", (unsigned int)(*pb++) & 0xff); } } putchar('\r'); num += 16; } return NONE; } static unsigned int execution(int argc, char** argv) { int pid, waitflag; waitflag = 1; if(argv[argc - 1][0] == '&' && argv[argc - 1][1] == 0) { waitflag = 0; argv[--argc] = 0; } pid = exec(argc, argv); if(pid == -1) return NOFILE; if(waitflag == 1) wait(pid); return NONE; } static unsigned int set_data(int argc, char** argv) { int i, num, data; char *addrchar; short *addrword; sscanf(argv[argc - 2], "%x", &data); addrchar = (char*)data; if(argc == 4 && argv[1][0] == 'w' && data & 1) return ARIGN; addrword = (short*)data; sscanf(argv[argc - 1], "%x", &num); if(addrchar == (char*)-1 || num == -1) return SYNTAX; if(argc == 4 && argv[1][0] == 'w') addrword[0] = num; else addrchar[0] = num; printf(" updated.\r"); return NONE; } static unsigned int clear_memory(int argc, char** argv) { int num, data; char* addr; sscanf(argv[1], "%x", &data); addr = (char*)data; sscanf(argv[2], "%x", &num); if(addr == (char*)-1 || num == -1) return SYNTAX; bzero(addr, num); printf(" cleared.\r"); return NONE; } static unsigned int dir(int argc, char** argv) { int size, fd; DirEnt ent; fd = SetDirent((argc == 1) ? "" : argv[1], &ent); if(fd == -1) return NOFILE; while(NextRecord(fd, &ent) == 0) { if(ent.attr & 0x10) { printf("[%-10s]\r", ent.name); } else { printf("%-10s\t%5d[char]\r", ent.name, ent.length); } } close(fd); return NONE; } static unsigned int remove(int argc, char** argv) { if(DeleteFile(argv[1]) == -1) return NOFILE; return NONE; } static unsigned int ssid(int argc, char** argv) { int fd, ret; fd = open(argv[1], -1); if(fd == -1) return IOERR; ret = ioctl(fd, (int)argv[2], WI_SETSSID); close(fd); return (ret == -1) ? IOERR : NONE; } static unsigned int wi_pm(int argc, char** argv) { int flag, fd, ret; if(argv[2][0] != 'o') return SYNTAX; switch(argv[2][1]) { case 'n': flag = 1; break; case 'f': flag = 0; break; default: return SYNTAX; } fd = open(argv[1], -1); if(fd == -1) return IOERR; ret = ioctl(fd, flag, WI_PMGTON); close(fd); return (ret == -1) ? IOERR : NONE; } static void if_info(unsigned int num) { int i, ip, mask, n, ret; char buf[6]; ret = get_ipinfo(num, &ip, &mask, buf); if(ret == -1) return; printf("net%d\tIP Address:", num); for(i = 0;i < 4;i++) { n = (ip >> ((3 - i) * 8)) & 0xff; printf("%d.", n); } printf(" Netmask:"); for(i = 0;i < 4;i++) { n = (mask >> ((3 - i) * 8)) & 0xff; printf("%d.", n); } printf(" MAC:"); for(i = 0;i < 5;i++) printf("%02x:", (unsigned int)buf[i] & 0xff); printf("%02x\r\r", (unsigned int)buf[i] & 0xff); } unsigned int strtoip(char *ptr, int *error) { int i, j, s; unsigned int ip, n; *error = 0; ip = 0; s = 0; for(i = 0;i < 4;i++) { n = 0; for(j = 0;j < 3;j++) { if(!isdigit(ptr[s])) { *error = -1; return 0; } n = n * 10; n += ptr[s++] - '0'; if(ptr[s] == '.' || (ptr[s] <= ' ' && i == 3)) { break; } } s++; ip <<= 8; ip += n; } return ip; } static unsigned int if_config(int argc, char** argv) { int i, ip, mask, n, ret, net; if(argc == 2) return SYNTAX; if(argc == 1) { for(i = 0;i < 4;i++) if_info(i); return NONE; } if(memcmp(argv[2], "down", 4) == 0) { sscanf(argv[1], "%d", &net); n = ifdown(net); if(n == -1) return IOERR; return NONE; } ip = strtoip(argv[2], &ret); if(ret == -1) return SYNTAX; if(argc == 4) { mask = strtoip(argv[3], &ret); if(ret == -1) return SYNTAX; } else { mask = IPADDR(255,255,255,0); } n = ifconfig(argv[1], ip, mask); if(n == -1) return IOERR; if_info(n); return NONE; } static unsigned int gateway(int argc, char** argv) { int ip, ret; ip = strtoip(argv[1], &ret); if(ret == -1) return SYNTAX; set_gateway(ip); return NONE; } static unsigned int set_dns(int argc, char** argv) { int ip, ret; ip = strtoip(argv[1], &ret); if(ret == -1) return SYNTAX; dns_server(ip); return NONE; } static void tftp_message() { putchar('.'); } static unsigned int tftp(int argc, char** argv) { int ip, ret; char *name; ip = strtoip(argv[1], &ret); if(ret == -1) { ip = gethostbyname(argv[1]); ret = (ip == 0) ? -1 : 0; } if(ret == -1) { ip = strtoip(argv[2], &ret); if(ret == -1) { ip = gethostbyname(argv[2]); ret = (ip == 0) ? -1 : 0; } if(ret == -1) return SYNTAX; name = strrchr(argv[1], '/'); if(name == 0) name = argv[1]; if(tftp_load(ip, name, tftp_message) == -1) return IOERR; } else { name = strrchr(argv[2], '/'); if(name == 0) name = argv[2]; if(tftp_save(ip, name, tftp_message) == -1) return IOERR; } return NONE; } static unsigned int _ping(int argc, char** argv) { int i, ret; unsigned int ip; ip = strtoip(argv[1], &ret); if(ret == -1) { ip = gethostbyname(argv[1]); if(ip == 0) return SYNTAX; } printf("Pinging %s", argv[1]); if(ret == -1) { printf("(%d.", ip >> 24); printf("%d.", (ip >> 16) & 0xff); printf("%d.", (ip >> 8) & 0xff); printf("%d)", ip & 0xff); } printf(" of data.\r"); for(i = 0;i < 4;i++) { ret = ping(ip, 32); if(ret == -1) { printf("Request timed out.\r"); } else { printf("Reply from %s:\r", argv[1]); sleep(1000); } } return NONE; } static unsigned int echo(int argc, char** argv) { if(strcmp(argv[1], "off") == 0) echo_flag = 0; else if(strcmp(argv[1], "on") == 0) echo_flag = 1; else return SYNTAX; return NONE; } static unsigned int type(int argc, char** argv) { int fd, n; char c; fd = open(argv[1], OptRead); if(fd == -1) return IOERR; n = read(fd, &c, 1); while(n > 0) { if(c != '\n') putchar(c); n = read(fd, &c, 1); } close(fd); return NONE; } static unsigned int copy(int argc, char** argv) { int fdin, fdout, n; char buf[64]; fdin = open(argv[1], OptRead); if(fdin == -1) return IOERR; fdout = open(argv[2], OptWrite); if(fdout == -1) { close(fdin); return IOERR; } do { n = read(fdin, buf, 64); write(fdout, buf, n); } while(n == 64); close(fdin); close(fdout); return NONE; } static unsigned int pwd(int argc, char** argv) { printf("[%s]\r", cwd()); return NONE; } static unsigned int _cd(int argc, char** argv) { if(cd(argv[1]) == -1) return NOFILE; return NONE; } static unsigned int _mount(int argc, char** argv) { if(mount(argv[1]) == -1) return IOERR; return NONE; } static unsigned int _eject(int argc, char** argv) { if(eject(argv[1]) == -1) return IOERR; return NONE; } static unsigned int _format(int argc, char** argv) { if(format(argv[1]) == -1) return IOERR; return NONE; } static void shell(int fd) { unsigned int ret, i, argc; strcpy(prompt, "\rMES >"); for(;;) { if(fd == 0) printf(prompt); argc = read_line(fd, cmd_buf, cmd_argv); if(fd != 0 && argc == -1) return; if(argc < 1) continue; putchar('\r'); if(argc >= MAX_ARG) { err_message(CMDFULL); continue; } for(i = 0;;i++) { if(strcmp(cmd_argv[0], table[i].command) == 0 || table[i].command[0] == 0) { if(argc >= table[i].min && argc <= table[i].max) { ret = (*(table[i].function))(argc, cmd_argv); if(ret > NONE) err_message(ret); } else { err_message(SYNTAX); } break; } if(table[i].command[0] == 0) break; } } } static void autoexec() { int fd; fd = open("autoexec.bat", OptRead); if(fd == -1) return; shell(fd); close(fd); } int main() { table[0].function = dump; table[1].function = set_data; table[2].function = dir; table[3].function = clear_memory; table[4].function = if_config; table[5].function = gateway; table[6].function = _ping; table[7].function = echo; table[8].function = remove; table[9].function = ssid; table[10].function = wi_pm; table[11].function = tftp; table[12].function = type; table[13].function = pwd; table[14].function = _cd; table[15].function = _mount; table[16].function = _eject; table[17].function = _format; table[18].function = copy; table[19].function = set_dns; table[20].function = execution; echo_flag = 1; printf("Micro Embeded System Ver2.0 Rev0 2005/10/1\r"); autoexec(); shell(0); }