#include "ihe.h" #include "core.h" static int cmd_loop = 1; extern cmd_table_t tab[]; #define CMK_KEYMAP1(KEY) (in_buf[0]==(KEY)&&(ret_read==1)) #define CMD_IN_BUF_SIZE 32 typedef struct cmd_in_buf_t { char buf[CMD_IN_BUF_SIZE+2];//enought space to put "'\n',NULL" int cur_sz; } cmd_in_buf_t; int cmd_buf_clean( cmd_in_buf_t *buf ); /* type == 1, usual printable chars type == 2, print in hex */ int cmd_buf_print( cmd_in_buf_t *buf, int type ); int cmd_buf_add( cmd_in_buf_t *buf, char *ch, int size ); int cmd_buf_rem1( cmd_in_buf_t *buf ); int cmd_buf_full( cmd_in_buf_t *buf ); int cmd_buf_clean( cmd_in_buf_t *buf ) { memset( buf, 0, sizeof(cmd_in_buf_t)); return 0; } int cmd_buf_print( cmd_in_buf_t *buf, int type ) { int i; //printf("sz:%d\n",buf->cur_sz); for (i=0;(icur_sz ) { if (type == 1) { if (isprint(buf->buf[i])) { printf("%c",(char)(buf->buf[i]&0xff)); } else { printf("."); } } else if (type == 2) { printf("%02x ", (unsigned char)(buf->buf[i]&0xff) ); } } else { printf(" "); } } fflush(stdout); return 0; } int term_set_std_mode( term_screen *ts ) { int ret = 0; if ( tcgetattr( ts->ifd, &ts->orig_i ) == -1 ) { ERROR("Cannot get input terminal attributes\n"); goto exit_error; } ts->raw_i = ts->orig_i; /* modify the original mode */ /* input modes: no break, no CR to NL, no parity check, no strip char, * no start/stop output control. */ //ts->raw_i.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); ts->raw_i.c_iflag = IUTF8|ICRNL; /* output modes - disable post raw */ //ts->raw_i.c_oflag &= ~(OPOST); ts->raw_i.c_oflag = OPOST|ONLCR; /* control modes - set 8 bit chars */ //ts->raw_i.c_cflag |= (CS8); ts->raw_i.c_cflag = CS8|CREAD; /* local modes - choing off, canonical off, no extended functions, * no signal chars (^Z,^C) */ //ts->raw_i.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); //if ICANNON ignore ESC char //ts->raw_i.c_lflag = ISIG|ECHO; ts->raw_i.c_lflag = ISIG; /* control chars - set return condition: min number of bytes and timer. * We want read to return every single byte, without timeout. */ ts->raw_i.c_cc[VMIN] = 1; ts->raw_i.c_cc[VTIME] = 0; /* 1 byte, no timer */ /* put terminal in raw mode after flushing */ if (tcsetattr( ts->ifd, TCSAFLUSH, &ts->raw_i) < 0) { ERROR("Cannot set new terminal input attribures\n"); goto exit_error; } return ret; exit_error: errno = ENOTTY; return -1; } int custom_term_echo( char *keybuf ) { if (isprint(keybuf[0])) { write(1,keybuf,1); } if (keybuf[0]=='\n') { write(1,"\r\n",2); } return 0; } int cmd_tab_autocomplete( char *in_buf ) { cmd_arg_t *args; cmd_tok_t tl, *ptr = &tl, *iter = NULL; struct cmd_acq_t *iter_sugg = NULL; memset( &tl, 0, sizeof( cmd_tok_t )); int i; //printf("[%s]\n", in_buf); if ( parse_cmd( ptr, in_buf) == -1) { printf("Cmd problems\n"); return -1; } iter = ptr->next; args = cmd_arg_create( iter ); for (i=0; iargc; i++) { printf("ARG:%d TYPE:%d %s\n", i, args->type[i], args->argv[i]); } //printf("Unkn command\n"); //if command not found offer auto complete options if (args->argc > 0) { //printf("asd\n"); struct cmd_acq_head_t *ac = cmd_acq(tab,args->argv[0]); if (ac != NULL) { printf("\n>"); //printf("Did you mean "); SLIST_FOREACH(iter_sugg,ac,next_sugg) { printf("%s ", iter_sugg->suggestion); } printf("\n"); } cmd_acq_free( ac ); } cmd_tok_destroy( ptr->next ); ptr->next = NULL; cmd_arg_destroy( args ); return 0; } int cmd_buf_add( cmd_in_buf_t *buf, char *ch, int size ) { int i,j; /* for (i=0;icur_sz; for ( j=0; jbuf[i+j] = ch[j]; buf->cur_sz = i+j+1; //printf("%d\n", buf->cur_sz ); //printf("\n"); } } return 0; } int cmd_buf_rem1( cmd_in_buf_t *buf ) { int ret = -1; if ( buf->cur_sz > 0 ) { buf->cur_sz -= 1; ret = 0; } return ret; } int cmd_buf_full( cmd_in_buf_t *buf ) { int ret = 0; if ( buf->cur_sz == (CMD_IN_BUF_SIZE-1) ) { return 1; } return ret; } /* GLOBAL VARIABLES */ file_t *g_file = NULL; buf_t *g_buf = NULL; int g_flags = FD_RW; int c_version( cmd_arg_t *arg ) { int argc = arg->argc; if ( argc != 0 ) { printf("Command should not have arguments mister\n"); return -1; } printf("Version 0.0.2\n"); return 0; } int c_arg( cmd_arg_t *arg ) { int i; int argc = arg->argc; char **argv = arg->argv; for (i=0;iargc; int th = -1; if ( argc > 0 ) { printf("No arguments needed\n"); return -1; } th = term_cur_get_r(); if (th == -1) { printf("Cannot get current term height\n"); return -1; } printf("%d\n",th); */ return 0; } int c_tw( cmd_arg_t *arg ) { /* int argc = arg->argc; int tw = -1; if ( argc > 0 ) { printf("No arguments needed\n"); return -1; } tw = term_cur_get_c(); if (tw == -1) { printf("Cannot get current term width\n"); return -1; } printf("%d\n",tw); */ return 0; } /* CMD COMMANDS */ cmd_table_t tab[] = { {"version", c_version }, {"arg", c_arg }, //{"quit", c_quit}, {"help", c_help}, {"?", c_help}, {"open", c_open}, {"close", c_close}, {"info", c_info}, {"seek", c_seek}, {"pos", c_pos}, {"size", c_size}, {"blk", c_blk}, {"read", c_read}, {"dump", c_dump}, {"dumpx", c_dumpx}, {"dumps", c_dumps}, {"write", c_write}, {"writes", c_writes}, {"resize", c_resize}, {"flags", c_flags}, {"manifesto", c_manifesto}, {"ls", c_ls}, {"pwd", c_pwd}, {"cd", c_cd}, //{"th", c_th}, //{"tw", c_tw}, {NULL, NULL } }; int main( int argc, char **argv ) { const int sz_buf = 1024; uint8_t in_buf[sz_buf]; int ret_read; int new_c=0, new_r=0, old_r=0, old_c=0; cmd_arg_t *args; cmd_tok_t tl, *ptr = &tl, *iter = NULL; memset( &tl, 0, sizeof( cmd_tok_t )); //preapre global stuff g_file = file_init(); //init basic buffer g_buf = buf_init(); buf_size( g_buf, DEFAULT_BLK_SIZE ); buf_zero( g_buf ); struct term_screen ts; memset( &ts, 0, sizeof(ts) ); cmd_in_buf_t cmd_in; cmd_buf_clean( &cmd_in ); if ( term_init( &ts ) == -1 ) printf("Some err when init\n"); //term_set_raw_mode( &ts ); term_set_std_mode( &ts ); term_clr_scr( &ts ); new_c = term_get_maxcol( &ts ); new_r = term_get_maxrow( &ts ); old_r = new_r; old_c = new_c; term_cur_set_c( &ts, 0); term_cur_set_r( &ts, old_r); write(1,"$",1); while ( cmd_loop ) { //write(1,"$",1); ret_read = read(2, in_buf, sz_buf ); if (ret_read < 0) { printf("Cannot read\n"); continue; } in_buf[ret_read] = 0; //custom echoing service to ignore some special chars like TAB custom_term_echo( (char *)in_buf ); //printf("(%d)%s\n",ret_read,in_buf); if ( (isprint(in_buf[0])) && (in_buf[0]!='?') && (in_buf[0]!='\t')) { //printf("asd %d\n", ret_read); cmd_buf_add( &cmd_in, (char *)in_buf, ret_read ); } //auto complete advice if (CMK_KEYMAP1(9)) { if ( cmd_in.cur_sz == 0 ) { continue; } //cmd_buf_print( &cmd_in, 2 ); cmd_in.buf[cmd_in.cur_sz] = '\n'; cmd_in.buf[cmd_in.cur_sz+1] = 0; cmd_tab_autocomplete( cmd_in.buf ); //cmd_buf_print( &cmd_in, 2 ); write(1,"$",1); cmd_buf_print( &cmd_in, 1 ); term_cur_set_c( &ts, cmd_in.cur_sz+2 ); continue; } /* if (CMK_KEYMAP1('?')) { cmd_buf_print( &cmd_in, 1 ); } */ if (CMK_KEYMAP1(8)) { cmd_buf_rem1( &cmd_in ); term_cur_set_c( &ts, 0); write(1,"$",1); cmd_buf_print( &cmd_in, 1 ); term_cur_set_c( &ts, cmd_in.cur_sz+2 ); continue; } if (CMK_KEYMAP1(27)) { cmd_buf_print( &cmd_in, 1 ); break; } //exec cmd if (CMK_KEYMAP1('\n')) { int i; cmd_in.buf[cmd_in.cur_sz] = '\n'; cmd_in.buf[cmd_in.cur_sz+1] = 0; if ( parse_cmd( ptr, cmd_in.buf) == -1) { continue; } iter = ptr->next; args = cmd_arg_create( iter ); cmd_tok_destroy( ptr->next ); ptr->next = NULL; /* for (i=0; iargc; i++) { printf("ARG:%d TYPE:%d %s\n", i, args->type[i], args->argv[i]); } */ if (cmd_exec(tab, args) != 0) { printf("!Unknown command\n"); } cmd_arg_destroy( args ); cmd_buf_clean( &cmd_in ); write(1,"$",1); } } term_clr_scr( &ts ); term_set_orig_mode( &ts ); return 0; }