--- libaitcli/src/aitcli.c 2013/12/03 20:09:14 1.12.2.1 +++ libaitcli/src/aitcli.c 2025/12/24 00:49:52 1.21.2.7 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitcli.c,v 1.12.2.1 2013/12/03 20:09:14 misho Exp $ +* $Id: aitcli.c,v 1.21.2.7 2025/12/24 00:49:52 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 +Copyright 2004 - 2025 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -84,60 +84,133 @@ cli_SetErr(int eno, char *estr, ...) // ------------------------------------------------------------ static inline void +rewindin(linebuffer_t * __restrict buf, int len) +{ + int ign __attribute__((unused)); + + if (buf) { + if (len == -1) + len = buf->line_posin; + while (len-- > 0) + ign = write(buf->line_out, K_CTRL_H, 1); + } +} + +static inline void +clrscrEOLin(linebuffer_t * __restrict buf) +{ + register int i; + int ign __attribute__((unused)); + + if (buf) { + rewindin(buf, -1); + + for (i = 0; i < buf->line_lenin; i++) + ign = write(buf->line_out, K_SPACE, 1); + } +} + +static inline void clrscrEOL(linebuffer_t * __restrict buf) { register int i; + int ign __attribute__((unused)); if (buf && buf->line_prompt) { - write(buf->line_out, K_CR, 1); + ign = write(buf->line_out, K_CR, 1); for (i = 0; i < buf->line_len; i++) - write(buf->line_out, K_SPACE, 1); + ign = write(buf->line_out, K_SPACE, 1); } } static inline void +printfEOLin(linebuffer_t * __restrict buf) +{ + int ign __attribute__((unused)); + + if (buf) + ign = write(buf->line_out, buf->line_input, buf->line_lenin); +} + +static inline void printfEOL(linebuffer_t * __restrict buf, int len, int prompt) { + int ign __attribute__((unused)); + if (buf) { - if (prompt && buf->line_prompt) { - write(buf->line_out, K_CR, 1); - write(buf->line_out, buf->line_prompt, buf->line_bol); - } + ign = write(buf->line_out, K_CR, 1); - write(buf->line_out, buf->line_buf, len == -1 ? - buf->line_eol - buf->line_bol: len); + if (prompt && buf->line_prompt) + ign = write(buf->line_out, buf->line_prompt, buf->line_bol); + + ign = write(buf->line_out, buf->line_buf, len == -1 ? + buf->line_eol - buf->line_bol : len); } } static inline void printfCR(linebuffer_t * __restrict buf, int prompt) { - if (buf && prompt && buf->line_prompt) { - write(buf->line_out, K_CR, 1); - write(buf->line_out, buf->line_prompt, buf->line_bol); - } + int ign __attribute__((unused)); + + ign = write(buf->line_out, K_CR, 1); + if (buf && prompt && buf->line_prompt) + ign = write(buf->line_out, buf->line_prompt, buf->line_bol); } static inline void printfNL(linebuffer_t * __restrict buf, int prompt) { + int ign __attribute__((unused)); + if (buf) { - write(buf->line_out, K_ENTER, 1); + ign = write(buf->line_out, K_ENTER, 1); if (prompt) if (prompt && buf->line_prompt) - write(buf->line_out, buf->line_prompt, buf->line_bol); + ign = write(buf->line_out, buf->line_prompt, buf->line_bol); } } // ------------------------------------------------------------ static int +bufCHARin(int idx, void * __restrict cli_buffer) +{ + linebuffer_t *buf = cli_buffer; + int pos; + int ign __attribute__((unused)); + + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + pos = buf->line_posin; + + if (buf->line_mode == LINEMODE_INS) + memmove(buf->line_input + pos + buf->line_inkeys[idx].key_len, buf->line_input + pos, + buf->line_lenin - buf->line_posin); + if (buf->line_mode == LINEMODE_INS || buf->line_posin == buf->line_lenin) + buf->line_lenin += buf->line_inkeys[idx].key_len; + buf->line_posin += buf->line_inkeys[idx].key_len; + + memcpy(buf->line_input + pos, buf->line_inkeys[idx].key_ch, buf->line_inkeys[idx].key_len); + buf->line_input[buf->line_lenin] = 0; + + if (buf->line_mode == LINEMODE_INS) { + rewindin(buf, buf->line_posin - buf->line_inkeys[idx].key_len); + printfEOLin(buf); + rewindin(buf, buf->line_lenin - buf->line_posin); + } + return RETCODE_OK; +} + +static int bufCHAR(int idx, void * __restrict cli_buffer) { linebuffer_t *buf = cli_buffer; int pos; + int ign __attribute__((unused)); if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; @@ -154,10 +227,11 @@ bufCHAR(int idx, void * __restrict cli_buffer) memcpy(buf->line_buf + pos, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); buf->line_buf[buf->line_len - 1] = 0; - write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); + if (buf->line_prompt) + ign = write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); if (buf->line_mode == LINEMODE_INS) { - write(buf->line_out, (const u_char*) buf->line_buf + pos + buf->line_keys[idx].key_len, + ign = write(buf->line_out, (const u_char*) buf->line_buf + pos + buf->line_keys[idx].key_len, buf->line_len - buf->line_eol); printfEOL(buf, -1, 1); } @@ -165,6 +239,15 @@ bufCHAR(int idx, void * __restrict cli_buffer) } static int +bufEOLin(int idx, void * __restrict cli_buffer) +{ + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + return RETCODE_EOL; +} + +static int bufEOL(int idx, void * __restrict cli_buffer) { if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) @@ -177,12 +260,18 @@ bufEOL(int idx, void * __restrict cli_buffer) static int bufEOF(int idx, void * __restrict cli_buffer) { + int ret; + /* if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; */ - return RETCODE_EOF; + printfNL(cli_buffer, 0); + ret = cli_Cmd_End(cli_buffer, idx, NULL); + printfCR(cli_buffer, (ret != RETCODE_EOF)); + + return ret; } static int @@ -248,6 +337,20 @@ bufDOWN(int idx, void * __restrict cli_buffer) } static int +bufCLRin(int idx, void * __restrict cli_buffer) +{ + linebuffer_t *buf = cli_buffer; + + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + clrscrEOLin(buf); + rewindin(buf, buf->line_lenin); + cli_freeInput(cli_buffer); + return RETCODE_OK; +} + +static int bufCLR(int idx, void * __restrict cli_buffer) { if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) @@ -261,6 +364,33 @@ bufCLR(int idx, void * __restrict cli_buffer) } static int +bufBSin(int idx, void * __restrict cli_buffer) +{ + linebuffer_t *buf = cli_buffer; + + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + if (buf->line_posin > 0) { + clrscrEOLin(buf); + rewindin(buf, -1); + + buf->line_posin--; + buf->line_lenin--; + memmove(buf->line_input + buf->line_posin, + buf->line_input + buf->line_posin + 1, + buf->line_lenin - buf->line_posin); + buf->line_input[buf->line_lenin] = 0; + + rewindin(buf, buf->line_lenin - buf->line_posin); + printfEOLin(buf); + rewindin(buf, buf->line_lenin - buf->line_posin); + } + + return RETCODE_OK; +} + +static int bufBS(int idx, void * __restrict cli_buffer) { linebuffer_t *buf = cli_buffer; @@ -318,6 +448,20 @@ bufMODE(int idx, void * __restrict cli_buffer) } static int +bufBEGINin(int idx, void * __restrict cli_buffer) +{ + linebuffer_t *buf = cli_buffer; + + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + rewindin(buf, -1); + buf->line_posin ^= buf->line_posin; + + return RETCODE_OK; +} + +static int bufBEGIN(int idx, void * __restrict cli_buffer) { linebuffer_t *buf = cli_buffer; @@ -332,6 +476,21 @@ bufBEGIN(int idx, void * __restrict cli_buffer) } static int +bufENDin(int idx, void * __restrict cli_buffer) +{ + linebuffer_t *buf = cli_buffer; + + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + rewindin(buf, -1); + printfEOLin(buf); + buf->line_posin = buf->line_lenin; + + return RETCODE_OK; +} + +static int bufEND(int idx, void * __restrict cli_buffer) { linebuffer_t *buf = cli_buffer; @@ -346,6 +505,22 @@ bufEND(int idx, void * __restrict cli_buffer) } static int +bufLEFTin(int idx, void * __restrict cli_buffer) +{ + linebuffer_t *buf = cli_buffer; + + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + if (buf->line_posin > 0) { + rewindin(buf, 1); + buf->line_posin--; + } + + return RETCODE_OK; +} + +static int bufLEFT(int idx, void * __restrict cli_buffer) { linebuffer_t *buf = cli_buffer; @@ -360,6 +535,22 @@ bufLEFT(int idx, void * __restrict cli_buffer) } static int +bufRIGHTin(int idx, void * __restrict cli_buffer) +{ + linebuffer_t *buf = cli_buffer; + + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + if (buf->line_posin < buf->line_lenin) { + write(buf->line_out, buf->line_input + buf->line_posin, 1); + buf->line_posin++; + } + + return RETCODE_OK; +} + +static int bufRIGHT(int idx, void * __restrict cli_buffer) { linebuffer_t *buf = cli_buffer; @@ -374,6 +565,31 @@ bufRIGHT(int idx, void * __restrict cli_buffer) } static int +bufDELin(int idx, void * __restrict cli_buffer) +{ + linebuffer_t *buf = cli_buffer; + + if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + if (buf->line_lenin > 0 && buf->line_posin < buf->line_lenin) { + clrscrEOLin(buf); + rewindin(buf, buf->line_lenin); + + buf->line_lenin--; + memmove(buf->line_input + buf->line_posin, + buf->line_input + buf->line_posin + 1, + buf->line_lenin - buf->line_posin); + buf->line_input[buf->line_lenin] = 0; + + printfEOLin(buf); + rewindin(buf, buf->line_lenin - buf->line_posin); + } + + return RETCODE_OK; +} + +static int bufDEL(int idx, void * __restrict cli_buffer) { linebuffer_t *buf = cli_buffer; @@ -381,16 +597,18 @@ bufDEL(int idx, void * __restrict cli_buffer) if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; - clrscrEOL(buf); + if (buf->line_bol < buf->line_eol && buf->line_eol < buf->line_len) { + clrscrEOL(buf); - buf->line_len--; - memmove(buf->line_buf + buf->line_eol - buf->line_bol, - buf->line_buf + buf->line_eol - buf->line_bol + 1, - buf->line_len - buf->line_eol); - buf->line_buf[buf->line_len - 1] = 0; + buf->line_len--; + memmove(buf->line_buf + buf->line_eol - buf->line_bol, + buf->line_buf + buf->line_eol - buf->line_bol + 1, + buf->line_len - buf->line_eol); + buf->line_buf[buf->line_len - 1] = 0; - printfEOL(buf, buf->line_len - 1, 1); - printfEOL(buf, -1, 1); + printfEOL(buf, buf->line_len - 1, 1); + printfEOL(buf, -1, 1); + } return RETCODE_OK; } @@ -403,6 +621,7 @@ bufComp(int idx, void * __restrict cli_buffer) register int i, j; struct tagCommand *cmd, *c; int pos, ret = RETCODE_OK; + int ign __attribute__((unused)); if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; @@ -415,7 +634,7 @@ bufComp(int idx, void * __restrict cli_buffer) str_Trim(s); } - i = j = 0; + j = 0; c = NULL; memset(szLine, 0, STRSIZ); if (*s) { @@ -465,7 +684,7 @@ bufComp(int idx, void * __restrict cli_buffer) /* completion show actions ... */ if (j > 1 && c) { printfNL(buf, 0); - write(buf->line_out, szLine, strlen(szLine)); + ign = write(buf->line_out, szLine, strlen(szLine)); printfNL(buf, 1); printfEOL(buf, buf->line_len - 1, 1); printfEOL(buf, -1, 1); @@ -510,6 +729,7 @@ static int bufEndNode(int idx, void * __restrict cli_buffer) { linebuffer_t *buf = cli_buffer; + char szPrompt[STRSIZ + 16] = {[0 ... STRSIZ + 15] = 0}; if (!cli_buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; @@ -517,6 +737,8 @@ bufEndNode(int idx, void * __restrict cli_buffer) if (buf->line_level > 0) { printfNL(cli_buffer, 0); buf->line_level--; + snprintf(szPrompt, sizeof szPrompt, "%s{%d}> ", buf->line_porigin, buf->line_level); + cli_setPrompt(buf, szPrompt); cli_Printf(buf, "Enter to config level %d\n", buf->line_level); } @@ -539,7 +761,7 @@ cli_Printf(linebuffer_t * __restrict cli_buffer, char FILE *f; if (fmt) { - f = fdopen(cli_buffer->line_out, "a"); + f = fdopen(dup(cli_buffer->line_out), "a"); if (!f) { LOGERR; return; @@ -548,6 +770,8 @@ cli_Printf(linebuffer_t * __restrict cli_buffer, char va_start(lst, fmt); vfprintf(f, fmt, lst); va_end(lst); + + fclose(f); } else cli_SetErr(EINVAL, "Invalid input parameters ..."); } @@ -867,6 +1091,28 @@ cli_resetHistory(linebuffer_t * __restrict cli_buffer) /* + * cli_freeInput() - Clear entire input + * + * @cli_buffer = CLI buffer + * return: RETCODE_ERR error, RETCODE_OK ok +*/ +int +cli_freeInput(linebuffer_t * __restrict cli_buffer) +{ + int code = RETCODE_ERR; + + if (cli_buffer) { + memset(cli_buffer->line_input, 0, BUFSIZ); + cli_buffer->line_posin ^= cli_buffer->line_posin; + cli_buffer->line_lenin ^= cli_buffer->line_lenin; + + code = RETCODE_OK; + } else + cli_SetErr(EINVAL, "Invalid input parameters ..."); + + return code; +} +/* * cli_freeLine() - Clear entire line * * @cli_buffer = CLI buffer @@ -878,18 +1124,11 @@ cli_freeLine(linebuffer_t * __restrict cli_buffer) int code = RETCODE_ERR; if (cli_buffer) { - if (cli_buffer->line_buf) - e_free(cli_buffer->line_buf); + memset(cli_buffer->line_buf, 0, BUFSIZ); + cli_buffer->line_eol = cli_buffer->line_bol; + cli_buffer->line_len = 1 + cli_buffer->line_eol; - cli_buffer->line_buf = e_malloc(BUFSIZ); - if (cli_buffer->line_buf) { - memset(cli_buffer->line_buf, 0, BUFSIZ); - cli_buffer->line_eol = cli_buffer->line_bol; - cli_buffer->line_len = 1 + cli_buffer->line_eol; - - code = RETCODE_OK; - } else - LOGERR; + code = RETCODE_OK; } else cli_SetErr(EINVAL, "Invalid input parameters ..."); @@ -957,6 +1196,11 @@ cliEnd(linebuffer_t * __restrict cli_buffer) if (cli_buffer->line_buf) e_free(cli_buffer->line_buf); + if (cli_buffer->line_inkeys) + e_free(cli_buffer->line_inkeys); + if (cli_buffer->line_input) + e_free(cli_buffer->line_input); + e_free(cli_buffer); cli_buffer = NULL; } else @@ -975,8 +1219,9 @@ linebuffer_t * cliInit(int fin, int fout, const char *prompt) { linebuffer_t *cli_buffer; - bindkey_t *keys; + bindkey_t *keys, *inkeys; register int i; + char szPrompt[STRSIZ + 16] = {[0 ... STRSIZ + 15] = 0}; /* init buffer */ cli_buffer = e_malloc(sizeof(linebuffer_t)); @@ -993,7 +1238,9 @@ cliInit(int fin, int fout, const char *prompt) SLIST_INIT(&cli_buffer->line_cmds); if (prompt) { - cli_buffer->line_prompt = e_strdup(prompt); + strlcpy(cli_buffer->line_porigin, prompt, sizeof cli_buffer->line_porigin); + snprintf(szPrompt, sizeof szPrompt, "%s{%d}> ", cli_buffer->line_porigin, cli_buffer->line_level); + cli_buffer->line_prompt = e_strdup(szPrompt); if (!cli_buffer->line_prompt) { LOGERR; e_free(cli_buffer); @@ -1015,16 +1262,41 @@ cliInit(int fin, int fout, const char *prompt) memset(cli_buffer->line_buf, 0, BUFSIZ); cli_buffer->line_len = 1 + cli_buffer->line_eol; } + cli_buffer->line_input = e_malloc(BUFSIZ); + if (!cli_buffer->line_input) { + LOGERR; + if (cli_buffer->line_prompt) + e_free(cli_buffer->line_prompt); + e_free(cli_buffer->line_buf); + e_free(cli_buffer); + return NULL; + } else { + memset(cli_buffer->line_input, 0, BUFSIZ); + cli_buffer->line_lenin = cli_buffer->line_posin; + } keys = e_calloc(MAX_BINDKEY + 1, sizeof(bindkey_t)); if (!keys) { LOGERR; if (cli_buffer->line_prompt) e_free(cli_buffer->line_prompt); + e_free(cli_buffer->line_input); e_free(cli_buffer->line_buf); e_free(cli_buffer); return NULL; } else memset(keys, 0, sizeof(bindkey_t) * (MAX_BINDKEY + 1)); + inkeys = e_calloc(MAX_BINDKEY + 1, sizeof(bindkey_t)); + if (!inkeys) { + LOGERR; + e_free(keys); + if (cli_buffer->line_prompt) + e_free(cli_buffer->line_prompt); + e_free(cli_buffer->line_input); + e_free(cli_buffer->line_buf); + e_free(cli_buffer); + return NULL; + } else + memset(inkeys, 0, sizeof(bindkey_t) * (MAX_BINDKEY + 1)); /* add helper functions */ cli_addCommand(cli_buffer, "exit", 1, cli_Cmd_Exit, "exit ", "Exit from console"); @@ -1041,219 +1313,291 @@ cliInit(int fin, int fout, const char *prompt) /* fill key bindings */ /* ascii chars & ctrl+chars */ for (i = 0; i < 256; i++) { - *keys[i].key_ch = (u_char) i; - keys[i].key_len = 1; + *keys[i].key_ch = *inkeys[i].key_ch = (u_char) i; + keys[i].key_len = inkeys[i].key_len = 1; if (!i || i == *K_CTRL_D) keys[i].key_func = bufEOF; - if (i == *K_CTRL_M || i == *K_CTRL_J) + if (i == *K_CTRL_M || i == *K_CTRL_J) { keys[i].key_func = bufEOL; - if (cli_buffer->line_prompt && (i == *K_CTRL_H || i == *K_BACKSPACE)) - keys[i].key_func = bufBS; - if (i == *K_CTRL_C) + inkeys[i].key_func = bufEOLin; + } + if (i == *K_CTRL_H || i == *K_BACKSPACE) { + if (cli_buffer->line_prompt) + keys[i].key_func = bufBS; + inkeys[i].key_func = bufBSin; + } + if (i == *K_CTRL_C) { keys[i].key_func = bufCLR; - if (cli_buffer->line_prompt && i == *K_CTRL_A) - keys[i].key_func = bufBEGIN; - if (cli_buffer->line_prompt && i == *K_CTRL_E) - keys[i].key_func = bufEND; + inkeys[i].key_func = bufCLRin; + } + if (i == *K_CTRL_A) { + if (cli_buffer->line_prompt) + keys[i].key_func = bufBEGIN; + inkeys[i].key_func = bufBEGINin; + } + if (i == *K_CTRL_E) { + if (cli_buffer->line_prompt) + keys[i].key_func = bufEND; + inkeys[i].key_func = bufENDin; + } if (cli_buffer->line_prompt && i == *K_TAB) keys[i].key_func = bufComp; if (i == *K_CTRL_Z) keys[i].key_func = bufEndNode; - if (i >= *K_SPACE && i < *K_BACKSPACE) + if (i >= *K_SPACE && i < *K_BACKSPACE) { keys[i].key_func = bufCHAR; - if (i > *K_BACKSPACE && i < 0xff) + inkeys[i].key_func = bufCHARin; + } + if (i > *K_BACKSPACE && i < 0xff) { keys[i].key_func = bufCHAR; + inkeys[i].key_func = bufCHARin; + } if (cli_buffer->line_prompt && i == '?') keys[i].key_func = bufHelp; } /* alt+chars */ for (i = 256; i < 512; i++) { - keys[i].key_ch[0] = 0x1b; - keys[i].key_ch[1] = (u_char) i - 256; - keys[i].key_len = 2; + keys[i].key_ch[0] = inkeys[i].key_ch[0] = 0x1b; + keys[i].key_ch[1] = inkeys[i].key_ch[1] = (u_char) i - 256; + keys[i].key_len = inkeys[i].key_len = 2; } /* 3 bytes */ - keys[i].key_len = sizeof K_F1 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F1 - 1; memcpy(keys[i].key_ch, K_F1, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F1, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F2 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F2 - 1; memcpy(keys[i].key_ch, K_F2, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F2, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F3 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F3 - 1; memcpy(keys[i].key_ch, K_F3, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F3, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F4 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F4 - 1; memcpy(keys[i].key_ch, K_F4, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F4, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F1 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F1 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F1, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F1, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F2 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F2 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F2, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F2, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F3 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F3 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F3, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F3, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F4 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F4 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F4, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F4, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F5 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F5 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F5, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F5, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F6 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F6 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F6, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F6, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F7 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F7 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F7, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F7, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F8 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F8 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F8, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F8, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F9 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F9 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F9, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F9, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F10 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F10 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F10, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F10, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F11 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F11 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F11, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F11, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_SH_F12 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_SH_F12 - 1; memcpy(keys[i].key_ch, K_CTRL_SH_F12, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_SH_F12, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F1 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F1 - 1; memcpy(keys[i].key_ch, K_CTRL_F1, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F1, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F2 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F2 - 1; memcpy(keys[i].key_ch, K_CTRL_F2, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F2, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F3 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F3 - 1; memcpy(keys[i].key_ch, K_CTRL_F3, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F3, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F4 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F4 - 1; memcpy(keys[i].key_ch, K_CTRL_F4, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F4, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F5 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F5 - 1; memcpy(keys[i].key_ch, K_CTRL_F5, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F5, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F6 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F6 - 1; memcpy(keys[i].key_ch, K_CTRL_F6, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F6, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F7 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F7 - 1; memcpy(keys[i].key_ch, K_CTRL_F7, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F7, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F8 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F8 - 1; memcpy(keys[i].key_ch, K_CTRL_F8, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F8, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F9 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F9 - 1; memcpy(keys[i].key_ch, K_CTRL_F9, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F9, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F10 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F10 - 1; memcpy(keys[i].key_ch, K_CTRL_F10, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F10, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F11 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F11 - 1; memcpy(keys[i].key_ch, K_CTRL_F11, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F11, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_CTRL_F12 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_CTRL_F12 - 1; memcpy(keys[i].key_ch, K_CTRL_F12, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_CTRL_F12, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_HOME - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_HOME - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufBEGIN; memcpy(keys[i].key_ch, K_HOME, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_HOME, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_END - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_END - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufEND; memcpy(keys[i].key_ch, K_END, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_END, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_UP - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_UP - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufUP; memcpy(keys[i].key_ch, K_UP, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_UP, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_DOWN - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_DOWN - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufDOWN; memcpy(keys[i].key_ch, K_DOWN, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_DOWN, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_RIGHT - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_RIGHT - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufRIGHT; + inkeys[i].key_func = bufRIGHTin; memcpy(keys[i].key_ch, K_RIGHT, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_RIGHT, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_LEFT - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_LEFT - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufLEFT; + inkeys[i].key_func = bufLEFTin; memcpy(keys[i].key_ch, K_LEFT, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_LEFT, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_BTAB - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_BTAB - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufBTAB; memcpy(keys[i].key_ch, K_BTAB, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_BTAB, inkeys[i].key_len); i++; /* 4 bytes */ - keys[i].key_len = sizeof K_INS - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_INS - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufMODE; + inkeys[i].key_func = bufMODE; memcpy(keys[i].key_ch, K_INS, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_INS, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_DEL - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_DEL - 1; if (cli_buffer->line_prompt) keys[i].key_func = bufDEL; + inkeys[i].key_func = bufDELin; memcpy(keys[i].key_ch, K_DEL, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_DEL, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_PGUP - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_PGUP - 1; memcpy(keys[i].key_ch, K_PGUP, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_PGUP, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_PGDN - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_PGDN - 1; memcpy(keys[i].key_ch, K_PGDN, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_PGDN, inkeys[i].key_len); i++; /* 5 bytes */ - keys[i].key_len = sizeof K_F5 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F5 - 1; memcpy(keys[i].key_ch, K_F5, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F5, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F6 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F6 - 1; memcpy(keys[i].key_ch, K_F6, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F6, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F7 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F7 - 1; memcpy(keys[i].key_ch, K_F7, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F7, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F8 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F8 - 1; memcpy(keys[i].key_ch, K_F8, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F8, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F9 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F9 - 1; memcpy(keys[i].key_ch, K_F9, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F9, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F10 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F10 - 1; memcpy(keys[i].key_ch, K_F10, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F10, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F11 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F11 - 1; memcpy(keys[i].key_ch, K_F11, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F11, inkeys[i].key_len); i++; - keys[i].key_len = sizeof K_F12 - 1; + keys[i].key_len = inkeys[i].key_len = sizeof K_F12 - 1; memcpy(keys[i].key_ch, K_F12, keys[i].key_len); + memcpy(inkeys[i].key_ch, K_F12, inkeys[i].key_len); i++; cli_buffer->line_keys = keys; + cli_buffer->line_inkeys = inkeys; return cli_buffer; } /* - * cliInitLine() - Init CLI input line terminal + * cliSetLine() - Set CLI input line terminal * * @cli_buffer = CLI buffer - * return: none + * @old = Old terminal settings + * return: -1 error or 0 ok */ int -cliInitLine(linebuffer_t * __restrict cli_buffer) +cliSetLine(linebuffer_t * __restrict cli_buffer, struct termios * __restrict old) { struct termios t; memset(&t, 0, sizeof t); tcgetattr(cli_buffer->line_in, &t); + if (old) + memcpy(old, &t, sizeof(struct termios)); t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOCTL | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT); t.c_iflag |= IGNBRK; @@ -1263,6 +1607,44 @@ cliInitLine(linebuffer_t * __restrict cli_buffer) } /* + * cliResetLine() - Reset CLI input line terminal + * + * @cli_buffer = CLI buffer + * @old = Original terminal settings + * return: -1 error or 0 ok +*/ +int +cliResetLine(linebuffer_t * __restrict cli_buffer, struct termios * __restrict orig) +{ + return tcsetattr(cli_buffer->line_in, TCSANOW, orig); +} + +/* + * cliEcho() - Switch echo on or off + * + * @cli_buffer = CLI buffer + * @on = On or off for echo on input handler + * return: -1 error or 0 ok +*/ +int +cliEcho(linebuffer_t * __restrict cli_buffer, int on) +{ + struct termios t; + + if (tcgetattr(cli_buffer->line_in, &t) == -1) { + cli_SetErr(errno, "tcgetattr(%d) - %s", cli_buffer->line_in, strerror(errno)); + return -1; + } + + if (on) + t.c_lflag |= (ECHO); + else + t.c_lflag &= ~(ECHO); + + return tcsetattr(cli_buffer->line_in, TCSANOW, &t); +} + +/* * cliReadLine() - Read line from opened CLI session * * @cli_buffer = CLI buffer @@ -1290,52 +1672,37 @@ cliReadLine(linebuffer_t * __restrict cli_buffer, int printfCR(cli_buffer, 1); while (42) { if ((ret = poll(&fds, 1, timeout)) < 1) { - if (!ret) { + if (!ret) cli_buffer->line_kill = 1; - if (str) { - e_free(str); - str = NULL; - } - } else + else LOGERR; - return str; + return NULL; } memset(buf, 0, sizeof buf); - readLen = read(cli_buffer->line_in, buf, BUFSIZ); - if (readLen == -1) { - LOGERR; - return str; + readLen = read(cli_buffer->line_in, buf, sizeof buf - 1); + if (readLen < 1) { + if (readLen) + LOGERR; + return NULL; } - if (!readLen) { - if (cli_buffer->line_buf) - str = e_strdup(cli_buffer->line_buf); - else - cli_SetErr(EPIPE, "Unknown state ..."); - return str; - } -recheck: - for (code = RETCODE_OK, i = MAX_BINDKEY - 1; i > -1; i--) - if (readLen >= cli_buffer->line_keys[i].key_len && - !memcmp(cli_buffer->line_keys[i].key_ch, buf, - cli_buffer->line_keys[i].key_len)) { - readLen -= cli_buffer->line_keys[i].key_len; - if (readLen) - memmove(buf, buf + cli_buffer->line_keys[i].key_len, readLen); - else - memset(buf, 0, cli_buffer->line_keys[i].key_len); + while (readLen) + for (code = RETCODE_OK, i = MAX_BINDKEY - 1; i > -1; i--) + if (readLen >= cli_buffer->line_keys[i].key_len && + !memcmp(cli_buffer->line_keys[i].key_ch, buf, + cli_buffer->line_keys[i].key_len)) { + readLen -= cli_buffer->line_keys[i].key_len; + if (readLen) + memmove(buf, buf + cli_buffer->line_keys[i].key_len, readLen); + else + memset(buf, 0, cli_buffer->line_keys[i].key_len); - if (cli_buffer->line_keys[i].key_func) - if ((code = cli_buffer->line_keys[i].key_func(i, cli_buffer))) - readLen = 0; + if (cli_buffer->line_keys[i].key_func) + if ((code = cli_buffer->line_keys[i].key_func(i, cli_buffer))) + readLen = 0; + } - if (readLen) - goto recheck; - else - break; - } - if (code) break; } @@ -1345,7 +1712,72 @@ recheck: return str; } +/* + * cliInputLine() - Input line from opened CLI session + * + * @cli_buffer = CLI buffer + * @timeout = Session timeout (-1 infinit) + * return: NULL if error or !=NULL readed line, must be e_free after use! +*/ +char * +cliInputLine(linebuffer_t * __restrict cli_buffer, int timeout) +{ + int code, readLen, ret; + register int i; + struct pollfd fds; + char buf[BUFSIZ], *str = NULL; + if (!cli_buffer) { + cli_SetErr(EINVAL, "Invalid input parameters ..."); + return NULL; + } else if (timeout > 0) + timeout *= 1000; /* convert from sec to ms */ + + memset(&fds, 0, sizeof fds); + fds.fd = cli_buffer->line_in; + fds.events = POLLIN; + + while (42) { + if ((ret = poll(&fds, 1, timeout)) < 1) { + if (ret == -1) + LOGERR; + return NULL; + } + + memset(buf, 0, sizeof buf); + readLen = read(cli_buffer->line_in, buf, sizeof buf - 1); + if (readLen < 1) { + if (readLen) + LOGERR; + return NULL; + } + + while (readLen) + for (code = RETCODE_OK, i = MAX_BINDKEY - 1; i > -1; i--) + if (readLen >= cli_buffer->line_inkeys[i].key_len && + !memcmp(cli_buffer->line_inkeys[i].key_ch, buf, + cli_buffer->line_inkeys[i].key_len)) { + readLen -= cli_buffer->line_inkeys[i].key_len; + if (readLen) + memmove(buf, buf + cli_buffer->line_inkeys[i].key_len, readLen); + else + memset(buf, 0, cli_buffer->line_inkeys[i].key_len); + + if (cli_buffer->line_inkeys[i].key_func) + if ((code = cli_buffer->line_inkeys[i].key_func(i, cli_buffer))) + readLen = 0; + } + + if (code) + break; + } + + if (code != RETCODE_ERR && code != RETCODE_EOF && cli_buffer->line_input) + str = e_strdup(cli_buffer->line_input); + return str; +} + + /* * cliNetLoop() - CLI network main loop binded to socket * @@ -1360,7 +1792,7 @@ cliNetLoop(linebuffer_t * __restrict cli_buffer, const int sock, int timeout) { u_char buf[BUFSIZ]; - int pid, stat, pty, r, s, alen, flg, attrlen = 0, ret = 0; + int pid, stat, pty, s, alen, flg, attrlen = 0, ret = 0; fd_set fds; struct timeval tv = { DEFAULT_SOCK_TIMEOUT, 0 }; struct telnetAttrs *a, Attr[10]; @@ -1405,7 +1837,6 @@ cliNetLoop(linebuffer_t * __restrict cli_buffer, const break; } - r = FD_ISSET(sock, &fds) ? sock : pty; s = FD_ISSET(sock, &fds) ? pty : sock; if (FD_ISSET(sock, &fds)) { @@ -1445,8 +1876,9 @@ cliNetLoop(linebuffer_t * __restrict cli_buffer, const if (FD_ISSET(pty, &fds)) { memset(buf, 0, BUFSIZ); - if ((ret = read(pty, buf, BUFSIZ)) == -1) { - LOGERR; + if ((ret = read(pty, buf, BUFSIZ)) < 1) { + if (ret) + LOGERR; break; } @@ -1465,6 +1897,65 @@ cliNetLoop(linebuffer_t * __restrict cli_buffer, const } /* + * cliRun() - CLI run command line + * + * @cli_buffer = CLI buffer + * @psInput = Input command line + * @prompt = Display prompt after command + * return: RETCODE_ERR error, RETCODE_OK ok +*/ +int +cliRun(linebuffer_t * __restrict cli_buffer, char *psInput, int prompt) +{ + char *line, *s, *t, **app, *items[MAX_PROMPT_ITEMS]; + int ret = RETCODE_OK; + struct tagCommand *cmd; + + if (!psInput) + return RETCODE_ERR; + else + line = psInput; + + // clear whitespaces + for (s = line; isspace((int) *s); s++); + if (*s) { + for (t = s + strlen(s) - 1; t > s && isspace((int) *t); t--); + *++t = 0; + } + + if (*s) { + memset(items, 0, sizeof(char*) * MAX_PROMPT_ITEMS); + for (app = items; app < items + MAX_PROMPT_ITEMS - 1 && + (*app = strsep(&s, " \t")); *app ? app++ : app); + + // exec_cmd ... + SLIST_FOREACH(cmd, &cli_buffer->line_cmds, cmd_next) { + if (!(cmd->cmd_level & (1 << cli_buffer->line_level))) + continue; + if (*items[0] && !strncmp(cmd->cmd_name, items[0], strlen(items[0]))) + break; + } + + if (!cmd) { + cli_Printf(cli_buffer, "%sCommand '%s' not found!\n", + cli_buffer->line_prompt ? "\n" : "", items[0]); + ret = RETCODE_ERR; + } else + if (cmd->cmd_func) { + if (prompt && cli_buffer->line_prompt) + cli_Printf(cli_buffer, "\n"); + ret = cmd->cmd_func(cli_buffer, + cli_buffer->line_level, items); + } else if (prompt) { + clrscrEOL(cli_buffer); + printfCR(cli_buffer, 1); + } + } + + return ret; +} + +/* * cliLoop() - CLI main loop * * @cli_buffer = CLI buffer @@ -1475,13 +1966,12 @@ cliNetLoop(linebuffer_t * __restrict cli_buffer, const int cliLoop(linebuffer_t * __restrict cli_buffer, const char *csHistFile, int timeout) { - char *line, *s, *t, **app, *items[MAX_PROMPT_ITEMS]; - register int i; + char *line; int ret = RETCODE_OK; - struct tagCommand *cmd; + struct termios t; /* --- main body of CLI --- */ - cliInitLine(cli_buffer); + cliSetLine(cli_buffer, &t); if (cli_loadHistory(cli_buffer, csHistFile) == RETCODE_ERR) return RETCODE_ERR; @@ -1493,48 +1983,18 @@ cliLoop(linebuffer_t * __restrict cli_buffer, const ch break; } else cli_addHistory(cli_buffer, NULL); - // clear whitespaces - for (s = line; isspace((int) *s); s++); - if (*s) { - for (t = s + strlen(s) - 1; t > s && isspace((int) *t); t--); - *++t = 0; - } - if (*s) { - memset(items, 0, sizeof(char*) * MAX_PROMPT_ITEMS); - for (app = items; app < items + MAX_PROMPT_ITEMS - 1 && - (*app = strsep(&s, " \t")); *app ? app++ : app); + ret = cliRun(cli_buffer, line, 42); - // exec_cmd ... - i = 0; - SLIST_FOREACH(cmd, &cli_buffer->line_cmds, cmd_next) { - if (!(cmd->cmd_level & (1 << cli_buffer->line_level))) - continue; - if (*items[0] && !strncmp(cmd->cmd_name, items[0], strlen(items[0]))) - break; - else - i++; - } - - if (!cmd) { - cli_Printf(cli_buffer, "\nCommand '%s' not found!\n", items[0]); - ret = -1; - } else - if (cmd->cmd_func) { - cli_Printf(cli_buffer, "\n"); - ret = cmd->cmd_func(cli_buffer, - cli_buffer->line_level, items); - } else { - clrscrEOL(cli_buffer); - printfCR(cli_buffer, 1); - } - } - cli_freeLine(cli_buffer); cli_resetHistory(cli_buffer); e_free(line); - } while (cli_buffer->line_kill || ret < 1); + } while (!cli_buffer->line_kill); cli_saveHistory(cli_buffer, csHistFile, HISTORY_LINES); + + /* --- restore tty --- */ + cliResetLine(cli_buffer, &t); + return ret; }