--- libaitcli/src/aitcli.c 2020/09/01 23:17:03 1.16.2.1 +++ libaitcli/src/aitcli.c 2025/12/21 23:21:40 1.21.2.2 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitcli.c,v 1.16.2.1 2020/09/01 23:17:03 misho Exp $ +* $Id: aitcli.c,v 1.21.2.2 2025/12/21 23:21:40 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 - 2020 +Copyright 2004 - 2025 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -87,25 +87,28 @@ 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 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); + ign = write(buf->line_out, buf->line_prompt, buf->line_bol); } - write(buf->line_out, buf->line_buf, len == -1 ? + ign = write(buf->line_out, buf->line_buf, len == -1 ? buf->line_eol - buf->line_bol : len); } } @@ -113,21 +116,25 @@ printfEOL(linebuffer_t * __restrict buf, int len, int static inline void printfCR(linebuffer_t * __restrict buf, int prompt) { + int ign __attribute__((unused)); + if (buf && 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); + 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); } } @@ -138,6 +145,7 @@ 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; @@ -155,10 +163,10 @@ bufCHAR(int idx, void * __restrict cli_buffer) buf->line_buf[buf->line_len - 1] = 0; if (buf->line_prompt) - write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); + 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); } @@ -178,12 +186,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 @@ -404,6 +418,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; @@ -416,7 +431,7 @@ bufComp(int idx, void * __restrict cli_buffer) str_Trim(s); } - i = j = 0; + j = 0; c = NULL; memset(szLine, 0, STRSIZ); if (*s) { @@ -466,7 +481,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); @@ -511,6 +526,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; @@ -518,6 +534,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); } @@ -540,7 +558,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; @@ -549,6 +567,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 ..."); } @@ -958,6 +978,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 @@ -976,9 +1001,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] = {[0 ... STRSIZ - 1] = 0}; + char szPrompt[STRSIZ + 16] = {[0 ... STRSIZ + 15] = 0}; /* init buffer */ cli_buffer = e_malloc(sizeof(linebuffer_t)); @@ -1029,6 +1054,17 @@ cliInit(int fin, int fout, const char *prompt) 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_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"); @@ -1045,8 +1081,8 @@ 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; @@ -1073,191 +1109,242 @@ cliInit(int fin, int fout, const char *prompt) } /* 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; 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; 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; 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; 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; @@ -1267,6 +1354,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 @@ -1474,7 +1599,6 @@ int cliRun(linebuffer_t * __restrict cli_buffer, char *psInput, int prompt) { char *line, *s, *t, **app, *items[MAX_PROMPT_ITEMS]; - register int i; int ret = RETCODE_OK; struct tagCommand *cmd; @@ -1496,14 +1620,11 @@ cliRun(linebuffer_t * __restrict cli_buffer, char *psI (*app = strsep(&s, " \t")); *app ? app++ : app); // 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) { @@ -1538,9 +1659,10 @@ cliLoop(linebuffer_t * __restrict cli_buffer, const ch { char *line; int ret = RETCODE_OK; + 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; @@ -1558,8 +1680,12 @@ cliLoop(linebuffer_t * __restrict cli_buffer, const ch 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; }