Diff for /libaitcli/src/aitcli.c between versions 1.2.2.12 and 1.5

version 1.2.2.12, 2010/06/07 16:16:12 version 1.5, 2012/07/22 22:37:08
Line 5 Line 5
 * $Author$  * $Author$
 * $Id$  * $Id$
 *  *
*************************************************************************/**************************************************************************
 The ELWIX and AITNET software is distributed under the following
 terms:
 
 All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
 
 Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
         by Michael Pounov <misho@elwix.org>.  All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. All advertising materials mentioning features or use of this software
    must display the following acknowledgement:
 This product includes software developed by Michael Pounov <misho@elwix.org>
 ELWIX - Embedded LightWeight unIX and its contributors.
 4. Neither the name of AITNET nor the names of its contributors
    may be used to endorse or promote products derived from this software
    without specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.
 */
 #include "global.h"  #include "global.h"
 #include "cli.h"  #include "cli.h"
   
Line 374  bufComp(int idx, void * __restrict buffer) Line 411  bufComp(int idx, void * __restrict buffer)
         if (!buffer || idx < 0 || idx > MAX_BINDKEY)          if (!buffer || idx < 0 || idx > MAX_BINDKEY)
                 return RETCODE_ERR;                  return RETCODE_ERR;
   
        str = strdup(buf->line_buf);        str = io_strdup(buf->line_buf);
         if (!str)          if (!str)
                 return RETCODE_ERR;                  return RETCODE_ERR;
         else {          else {
                 s = str;                  s = str;
                io_TrimStr((u_char*) s);                io_TrimStr(s);
         }          }
   
         i = j = 0;          i = j = 0;
Line 391  bufComp(int idx, void * __restrict buffer) Line 428  bufComp(int idx, void * __restrict buffer)
                                 *app ? i++ : i, *app ? app++ : app);                                  *app ? i++ : i, *app ? app++ : app);
   
                 if (i) {                  if (i) {
                        SLIST_FOREACH(cmd, &buf->line_cmds, cmd_next)                        SLIST_FOREACH(cmd, &buf->line_cmds, cmd_next) {
                                 if (cmd->cmd_level == buf->line_level &&                                   if (cmd->cmd_level == buf->line_level && 
                                                 !strncmp(cmd->cmd_name, items[0], strlen(items[0]))) {                                                  !strncmp(cmd->cmd_name, items[0], strlen(items[0]))) {
                                        j++;                                        if (strncmp(cmd->cmd_name, CLI_CMD_SEP, strlen(CLI_CMD_SEP))) {
                                        c = cmd;                                                j++;
                                        strlcat(szLine, " ", STRSIZ);                                                c = cmd;
                                        strlcat(szLine, cmd->cmd_name, STRSIZ);                                                strlcat(szLine, " ", STRSIZ);
                                                 strlcat(szLine, cmd->cmd_name, STRSIZ);
                                         }
                                 }                                  }
                           }
   
                        printf("i=%d j=%d c=%p name=%s comp=%p\n", i, j, c, c->cmd_name, c->cmd_comp);                        if (i > 1 && c) {
                        if (i > 1 && j == 1 && c && c->cmd_comp) {                                /* we are on argument of command and has complition info */
                                /* we are on argument of command and has complition callback */                                j++;    // always must be j > 1 ;) for arguments
                                printf("ima comp!\n");                                strlcpy(szLine, c->cmd_info, STRSIZ);
                                goto endcomp; 
                         }                          }
                 } else {                  } else {
                         /* we have valid char but i == 0, this case is illegal */                          /* we have valid char but i == 0, this case is illegal */
Line 415  bufComp(int idx, void * __restrict buffer) Line 454  bufComp(int idx, void * __restrict buffer)
                 /* we on 0 position of prompt, show commands for this level */                  /* we on 0 position of prompt, show commands for this level */
                 SLIST_FOREACH(cmd, &buf->line_cmds, cmd_next) {                  SLIST_FOREACH(cmd, &buf->line_cmds, cmd_next) {
                         if (cmd->cmd_level == buf->line_level)                          if (cmd->cmd_level == buf->line_level)
                                j++;                                if (strncmp(cmd->cmd_name, CLI_CMD_SEP, strlen(CLI_CMD_SEP))) {
                                c = cmd;                                        j++;
                                strlcat(szLine, " ", STRSIZ);                                        c = cmd;
                                strlcat(szLine, cmd->cmd_name, STRSIZ);                                        strlcat(szLine, " ", STRSIZ);
                                         strlcat(szLine, cmd->cmd_name, STRSIZ);
                                 }
                 }                  }
         }          }
   
Line 427  bufComp(int idx, void * __restrict buffer) Line 468  bufComp(int idx, void * __restrict buffer)
                 printfNL(buf, 0);                  printfNL(buf, 0);
                 write(buf->line_out, szLine, strlen(szLine));                  write(buf->line_out, szLine, strlen(szLine));
                 printfNL(buf, 1);                  printfNL(buf, 1);
                   printfEOL(buf, buf->line_len - 1, 1);
                   printfEOL(buf, -1, 1);
         }          }
         if (j == 1 && c) {          if (j == 1 && c) {
                 clrscrEOL(buf);                  clrscrEOL(buf);
Line 445  bufComp(int idx, void * __restrict buffer) Line 488  bufComp(int idx, void * __restrict buffer)
         }          }
   
 endcomp:  endcomp:
        free(str);        io_free(str);
         return ret;          return ret;
 }  }
   
Line 458  bufHelp(int idx, void * __restrict buffer) Line 501  bufHelp(int idx, void * __restrict buffer)
                 return RETCODE_ERR;                  return RETCODE_ERR;
   
         cli_Cmd_Help(buf, -1, NULL);          cli_Cmd_Help(buf, -1, NULL);
        printfCR(buf, 1);
         printfEOL(buf, buf->line_len - 1, 1);
         printfEOL(buf, -1, 1);
         return RETCODE_OK;          return RETCODE_OK;
 }  }
   
Line 492  cli_Printf(linebuffer_t * __restrict buffer, char *fmt Line 537  cli_Printf(linebuffer_t * __restrict buffer, char *fmt
 }  }
   
 /*  /*
    * cli_PrintHelp() Print help screen
    * @buffer = CLI buffer
    * return: none
   */
   inline void
   cli_PrintHelp(linebuffer_t * __restrict buffer)
   {
           if (buffer) {
                   bufHelp(0, buffer);
                   clrscrEOL(buffer);
           } else
                   cli_SetErr(EINVAL, "Error:: invalid input parameters ...");
   }
   
   
   /*
  * cli_BindKey() Bind function to key   * cli_BindKey() Bind function to key
  * @key = key structure   * @key = key structure
  * @buffer = CLI buffer   * @buffer = CLI buffer
Line 526  cli_BindKey(bindkey_t * __restrict key, linebuffer_t * Line 587  cli_BindKey(bindkey_t * __restrict key, linebuffer_t *
  * @funcCmd = Callback function when user call command   * @funcCmd = Callback function when user call command
  * @csInfo = Inline information for command   * @csInfo = Inline information for command
  * @csHelp = Help line when call help   * @csHelp = Help line when call help
  * @anComp = Completion array terminated with NULL element, -1 complete commands, NULL nothing  
  * return: RETCODE_ERR error, RETCODE_OK ok   * return: RETCODE_ERR error, RETCODE_OK ok
 */  */
 int  int
 cli_addCommand(linebuffer_t * __restrict buffer, const char *csCmd, int cliLevel, cmd_func_t funcCmd,   cli_addCommand(linebuffer_t * __restrict buffer, const char *csCmd, int cliLevel, cmd_func_t funcCmd, 
                const char *csInfo, const char *csHelp, const char **anComp)                const char *csInfo, const char *csHelp)
 {  {
         struct tagCommand *cmd;          struct tagCommand *cmd;
   
        if (!buffer || !csCmd || !funcCmd) {        if (!buffer || !csCmd) {
                 cli_SetErr(EINVAL, "Error:: invalid input parameters ...");                  cli_SetErr(EINVAL, "Error:: invalid input parameters ...");
                 return RETCODE_ERR;                  return RETCODE_ERR;
         }          }
   
        cmd = malloc(sizeof(struct tagCommand));        cmd = io_malloc(sizeof(struct tagCommand));
         if (!cmd) {          if (!cmd) {
                 LOGERR;                  LOGERR;
                 return RETCODE_ERR;                  return RETCODE_ERR;
Line 549  cli_addCommand(linebuffer_t * __restrict buffer, const Line 609  cli_addCommand(linebuffer_t * __restrict buffer, const
   
         cmd->cmd_level = cliLevel;          cmd->cmd_level = cliLevel;
         cmd->cmd_func = funcCmd;          cmd->cmd_func = funcCmd;
         cmd->cmd_comp = (char**) anComp;  
         cmd->cmd_len = strlcpy(cmd->cmd_name, csCmd, STRSIZ);          cmd->cmd_len = strlcpy(cmd->cmd_name, csCmd, STRSIZ);
         if (csInfo)          if (csInfo)
                 strlcpy(cmd->cmd_info, csInfo, STRSIZ);                  strlcpy(cmd->cmd_info, csInfo, STRSIZ);
Line 581  cli_delCommand(linebuffer_t * __restrict buffer, const Line 640  cli_delCommand(linebuffer_t * __restrict buffer, const
                 if (cmd->cmd_level == cliLevel && !strcmp(cmd->cmd_name, csCmd)) {                  if (cmd->cmd_level == cliLevel && !strcmp(cmd->cmd_name, csCmd)) {
                         ret = 1;                          ret = 1;
                         SLIST_REMOVE(&buffer->line_cmds, cmd, tagCommand, cmd_next);                          SLIST_REMOVE(&buffer->line_cmds, cmd, tagCommand, cmd_next);
                        free(cmd);                        io_free(cmd);
                         break;                          break;
                 }                  }
   
Line 596  cli_delCommand(linebuffer_t * __restrict buffer, const Line 655  cli_delCommand(linebuffer_t * __restrict buffer, const
  * @funcCmd = Callback function when user call command   * @funcCmd = Callback function when user call command
  * @csInfo = Inline information for command   * @csInfo = Inline information for command
  * @csHelp = Help line when call help   * @csHelp = Help line when call help
  * @anComp = Completion array terminated with NULL element, -1 complete commands, NULL nothing,  
  *              update only if funcCmd is not NULL  
  * return: RETCODE_ERR error, RETCODE_OK ok   * return: RETCODE_ERR error, RETCODE_OK ok
 */  */
 int  int
 cli_updCommand(linebuffer_t * __restrict buffer, const char *csCmd, int cliLevel, cmd_func_t funcCmd,   cli_updCommand(linebuffer_t * __restrict buffer, const char *csCmd, int cliLevel, cmd_func_t funcCmd, 
                const char *csInfo, const char *csHelp, const char **anComp)                const char *csInfo, const char *csHelp)
 {  {
         struct tagCommand *cmd;          struct tagCommand *cmd;
         int ret = RETCODE_OK;          int ret = RETCODE_OK;
Line 616  cli_updCommand(linebuffer_t * __restrict buffer, const Line 673  cli_updCommand(linebuffer_t * __restrict buffer, const
                 if (cmd->cmd_level == cliLevel && !strcmp(cmd->cmd_name, csCmd)) {                  if (cmd->cmd_level == cliLevel && !strcmp(cmd->cmd_name, csCmd)) {
                         ret = 1;                          ret = 1;
   
                        if (funcCmd) {                        if (funcCmd)
                                 cmd->cmd_func = funcCmd;                                  cmd->cmd_func = funcCmd;
                                 cmd->cmd_comp = (char**) anComp;  
                         }  
                         if (csInfo)                          if (csInfo)
                                 strlcpy(cmd->cmd_info, csInfo, STRSIZ);                                  strlcpy(cmd->cmd_info, csInfo, STRSIZ);
                         if (csHelp)                          if (csHelp)
Line 648  cli_addHistory(linebuffer_t * __restrict buffer, const Line 703  cli_addHistory(linebuffer_t * __restrict buffer, const
                 return RETCODE_ERR;                  return RETCODE_ERR;
         }          }
   
        if (!(h = malloc(sizeof(struct tagHistory)))) {        if (!(h = io_malloc(sizeof(struct tagHistory)))) {
                 LOGERR;                  LOGERR;
                 return RETCODE_ERR;                  return RETCODE_ERR;
         } else          } else
Line 656  cli_addHistory(linebuffer_t * __restrict buffer, const Line 711  cli_addHistory(linebuffer_t * __restrict buffer, const
   
         if (str) {          if (str) {
                 if (!*str) {                  if (!*str) {
                        free(h);                        io_free(h);
                         return RETCODE_OK;                          return RETCODE_OK;
                 }                  }
   
                 h->hist_len = strlcpy(h->hist_line, str, BUFSIZ);                  h->hist_len = strlcpy(h->hist_line, str, BUFSIZ);
         } else {          } else {
                 if (!*buffer->line_buf || buffer->line_len < 2) {                  if (!*buffer->line_buf || buffer->line_len < 2) {
                        free(h);                        io_free(h);
                         return RETCODE_OK;                          return RETCODE_OK;
                 }                  }
   
                 memcpy(h->hist_line, buffer->line_buf, (h->hist_len = buffer->line_len));                  memcpy(h->hist_line, buffer->line_buf, (h->hist_len = buffer->line_len));
                io_TrimStr((u_char*) h->hist_line);                io_TrimStr(h->hist_line);
                 h->hist_len = strlen(h->hist_line);                  h->hist_len = strlen(h->hist_line);
         }          }
   
Line 752  cli_loadHistory(linebuffer_t * __restrict buffer, cons Line 807  cli_loadHistory(linebuffer_t * __restrict buffer, cons
                 if (!*buf || *buf == '#')                  if (!*buf || *buf == '#')
                         continue;                          continue;
                 else                  else
                        io_TrimStr((u_char*) buf);                        io_TrimStr(buf);
   
                if (!(h = malloc(sizeof(struct tagHistory)))) {                if (!(h = io_malloc(sizeof(struct tagHistory)))) {
                         LOGERR;                          LOGERR;
                         fclose(f);                          fclose(f);
                         return RETCODE_ERR;                          return RETCODE_ERR;
Line 794  cli_freeLine(linebuffer_t * __restrict buffer) Line 849  cli_freeLine(linebuffer_t * __restrict buffer)
   
         if (buffer) {          if (buffer) {
                 if (buffer->line_buf)                  if (buffer->line_buf)
                        free(buffer->line_buf);                        io_free(buffer->line_buf);
   
                buffer->line_buf = malloc(BUFSIZ);                buffer->line_buf = io_malloc(BUFSIZ);
                 if (buffer->line_buf) {                  if (buffer->line_buf) {
                         memset(buffer->line_buf, 0, BUFSIZ);                          memset(buffer->line_buf, 0, BUFSIZ);
                         buffer->line_eol = buffer->line_bol;                          buffer->line_eol = buffer->line_bol;
Line 822  cli_setPrompt(linebuffer_t * __restrict buffer, const  Line 877  cli_setPrompt(linebuffer_t * __restrict buffer, const 
 {  {
         if (buffer) {          if (buffer) {
                 if (buffer->line_prompt) {                  if (buffer->line_prompt) {
                        free(buffer->line_prompt);                        io_free(buffer->line_prompt);
                         buffer->line_prompt = NULL;                          buffer->line_prompt = NULL;
                         buffer->line_bol = 0;                          buffer->line_bol = 0;
                 }                  }
   
                 if (prompt) {                  if (prompt) {
                        buffer->line_prompt = strdup(prompt);                        buffer->line_prompt = io_strdup(prompt);
                         if (buffer->line_prompt) {                          if (buffer->line_prompt) {
                                 buffer->line_bol = strlen(buffer->line_prompt);                                  buffer->line_bol = strlen(buffer->line_prompt);
                                 buffer->line_eol = buffer->line_bol;                                  buffer->line_eol = buffer->line_bol;
Line 855  cliEnd(linebuffer_t * __restrict buffer) Line 910  cliEnd(linebuffer_t * __restrict buffer)
         if (buffer) {          if (buffer) {
                 while ((c = SLIST_FIRST(&buffer->line_cmds))) {                  while ((c = SLIST_FIRST(&buffer->line_cmds))) {
                         SLIST_REMOVE_HEAD(&buffer->line_cmds, cmd_next);                          SLIST_REMOVE_HEAD(&buffer->line_cmds, cmd_next);
                        free(c);                        io_free(c);
                 }                  }
                 while ((h = TAILQ_FIRST(&buffer->line_history))) {                  while ((h = TAILQ_FIRST(&buffer->line_history))) {
                         TAILQ_REMOVE(&buffer->line_history, h, hist_next);                          TAILQ_REMOVE(&buffer->line_history, h, hist_next);
                        free(h);                        io_free(h);
                 }                  }
   
                 if (buffer->line_prompt)                  if (buffer->line_prompt)
                        free(buffer->line_prompt);                        io_free(buffer->line_prompt);
   
                 if (buffer->line_keys)                  if (buffer->line_keys)
                        free(buffer->line_keys);                        io_free(buffer->line_keys);
                 if (buffer->line_buf)                  if (buffer->line_buf)
                        free(buffer->line_buf);                        io_free(buffer->line_buf);
   
                free(buffer);                io_free(buffer);
                 buffer = NULL;                  buffer = NULL;
         } else          } else
                 cli_SetErr(EINVAL, "Error:: invalid input parameters ...");                  cli_SetErr(EINVAL, "Error:: invalid input parameters ...");
Line 889  cliInit(int fin, int fout, const char *prompt) Line 944  cliInit(int fin, int fout, const char *prompt)
         linebuffer_t *buffer;          linebuffer_t *buffer;
         bindkey_t *keys;          bindkey_t *keys;
         register int i;          register int i;
         struct termios t;  
   
         memset(&t, 0, sizeof t);  
         /* init buffer */          /* init buffer */
        buffer = malloc(sizeof (linebuffer_t));        buffer = io_malloc(sizeof(linebuffer_t));
         if (!buffer) {          if (!buffer) {
                 LOGERR;                  LOGERR;
                 return NULL;                  return NULL;
Line 907  cliInit(int fin, int fout, const char *prompt) Line 960  cliInit(int fin, int fout, const char *prompt)
                 SLIST_INIT(&buffer->line_cmds);                  SLIST_INIT(&buffer->line_cmds);
   
                 if (prompt) {                  if (prompt) {
                        buffer->line_prompt = strdup(prompt);                        buffer->line_prompt = io_strdup(prompt);
                         if (!buffer->line_prompt) {                          if (!buffer->line_prompt) {
                                 LOGERR;                                  LOGERR;
                                free(buffer);                                io_free(buffer);
                                 return NULL;                                  return NULL;
                         } else                          } else
                                 buffer->line_eol = buffer->line_bol = strlen(buffer->line_prompt);                                  buffer->line_eol = buffer->line_bol = strlen(buffer->line_prompt);
                 }                  }
         }          }
        buffer->line_buf = malloc(BUFSIZ);        buffer->line_buf = io_malloc(BUFSIZ);
         if (!buffer->line_buf) {          if (!buffer->line_buf) {
                 LOGERR;                  LOGERR;
                 if (buffer->line_prompt)                  if (buffer->line_prompt)
                        free(buffer->line_prompt);                        io_free(buffer->line_prompt);
                free(buffer);                io_free(buffer);
                 return NULL;                  return NULL;
         } else {          } else {
                 memset(buffer->line_buf, 0, BUFSIZ);                  memset(buffer->line_buf, 0, BUFSIZ);
                 buffer->line_len = 1 + buffer->line_eol;                  buffer->line_len = 1 + buffer->line_eol;
         }          }
        keys = calloc(MAX_BINDKEY + 1, sizeof(bindkey_t));        keys = io_calloc(MAX_BINDKEY + 1, sizeof(bindkey_t));
         if (!keys) {          if (!keys) {
                 LOGERR;                  LOGERR;
                 if (buffer->line_prompt)                  if (buffer->line_prompt)
                        free(buffer->line_prompt);                        io_free(buffer->line_prompt);
                free(buffer->line_buf);                io_free(buffer->line_buf);
                free(buffer);                io_free(buffer);
                 return NULL;                  return NULL;
         } else          } else
                 memset(keys, 0, sizeof(bindkey_t) * (MAX_BINDKEY + 1));                  memset(keys, 0, sizeof(bindkey_t) * (MAX_BINDKEY + 1));
   
         /* add helper functions */          /* add helper functions */
        cli_addCommand(buffer, "exit", 0, cli_Cmd_Exit, "exit <cr>", "Exit from console", NULL);        cli_addCommand(buffer, "exit", 0, cli_Cmd_Exit, "exit <cr>", "Exit from console");
        cli_addCommand(buffer, "help", 0, cli_Cmd_Help, "help [command] <cr>", "Help screen"        cli_addCommand(buffer, "help", 0, cli_Cmd_Help, "help [command] <cr>", "Help screen");
                        (const char**) -1);        cli_addCommand(buffer, "-------", 0, NULL, "-------------------------", NULL);
   
         /* fill key bindings */          /* fill key bindings */
         // ascii chars & ctrl+chars          // ascii chars & ctrl+chars
Line 1131  cliInit(int fin, int fout, const char *prompt) Line 1184  cliInit(int fin, int fout, const char *prompt)
         memcpy(keys[i].key_ch, K_F12, keys[i].key_len);          memcpy(keys[i].key_ch, K_F12, keys[i].key_len);
         i++;          i++;
   
           buffer->line_keys = keys;
           return buffer;
   }
   
   /*
    * cliInitLine() Init CLI input line terminal
    * @buffer = CLI buffer
    * return: none
   */
   int
   cliInitLine(linebuffer_t * __restrict buffer)
   {
           struct termios t;
   
           memset(&t, 0, sizeof t);
         tcgetattr(buffer->line_in, &t);          tcgetattr(buffer->line_in, &t);
         t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOCTL | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT);          t.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO | ECHOCTL | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT);
         t.c_iflag |= IGNBRK;          t.c_iflag |= IGNBRK;
         t.c_cc[VMIN] = 1;          t.c_cc[VMIN] = 1;
         t.c_cc[VTIME] = 0;          t.c_cc[VTIME] = 0;
        tcsetattr(buffer->line_in, TCSANOW, &t);        return tcsetattr(buffer->line_in, TCSANOW, &t);
 
        buffer->line_keys = keys; 
        return buffer; 
 }  }
   
 /*  /*
  * cliReadLine() Read line from opened CLI session   * cliReadLine() Read line from opened CLI session
  * @buffer = CLI buffer   * @buffer = CLI buffer
 * return: NULL if error or !=NULL readed line, must be free after use! * return: NULL if error or !=NULL readed line, must be io_free after use!
 */  */
 char *  char *
 cliReadLine(linebuffer_t * __restrict buffer)  cliReadLine(linebuffer_t * __restrict buffer)
Line 1179  cliReadLine(linebuffer_t * __restrict buffer) Line 1244  cliReadLine(linebuffer_t * __restrict buffer)
                 }                  }
                 if (!readLen) {                  if (!readLen) {
                         if (buffer->line_buf)                          if (buffer->line_buf)
                                str = strdup(buffer->line_buf);                                str = io_strdup(buffer->line_buf);
                         else                          else
                                 cli_SetErr(EPIPE, "Error:: unknown state ...");                                  cli_SetErr(EPIPE, "Error:: unknown state ...");
                         return str;                          return str;
Line 1211  recheck: Line 1276  recheck:
         }          }
   
         if (code != RETCODE_ERR && code != RETCODE_EOF && buffer->line_buf)          if (code != RETCODE_ERR && code != RETCODE_EOF && buffer->line_buf)
                str = strdup(buffer->line_buf);                str = io_strdup(buffer->line_buf);
         return str;          return str;
 }  }
   
Line 1221  recheck: Line 1286  recheck:
  * @buffer = CLI buffer   * @buffer = CLI buffer
  * @csHistFile = History file name   * @csHistFile = History file name
  * @sock = client socket   * @sock = client socket
  * @term = stdin termios  
  * @win = window size of tty  
  * return: RETCODE_ERR error, RETCODE_OK ok   * return: RETCODE_ERR error, RETCODE_OK ok
 */  */
 int  int
cliNetLoop(linebuffer_t * __restrict buffer, const char *csHistFile, int sockcliNetLoop(linebuffer_t * __restrict buffer, const char *csHistFile, int sock)
                struct termios *term, struct winsize *win) 
 {  {
         u_char buf[BUFSIZ];          u_char buf[BUFSIZ];
        int pty, r, s, alen, attrlen, flg, ret = 0;        int pid, stat, pty, r, s, alen, flg, attrlen = 0, ret = 0;
         fd_set fds;          fd_set fds;
         struct timeval tv = { DEFAULT_SOCK_TIMEOUT, 0 };          struct timeval tv = { DEFAULT_SOCK_TIMEOUT, 0 };
         struct telnetAttrs *a, Attr[10];          struct telnetAttrs *a, Attr[10];
   
        switch (forkpty(&pty, NULL, term, win)) {        switch ((pid = forkpty(&pty, NULL, NULL, NULL))) {
                 case -1:                  case -1:
                         LOGERR;                          LOGERR;
                         return -1;                          return -1;
                 case 0:                  case 0:
                        close(sock);                        if (!buffer) {
 
                        if (buffer) { 
                                ret = cliLoop(buffer, csHistFile) < 0 ? 1 : 0; 
                                cliEnd(buffer); 
                        } else 
                                 cli_SetErr(EINVAL, "Error:: invalid input parameters ...");                                  cli_SetErr(EINVAL, "Error:: invalid input parameters ...");
                                   return -1;
                           } else
                                   close(sock);
   
                        /* spawn Shell mode */                        ret = cliLoop(buffer, csHistFile) < 0 ? 1 : 0;
                        /*                        cliEnd(buffer);
                        execl("/bin/tcsh", "tcsh", NULL); 
                        */ 
   
                        _exit(ret);                        exit(ret);
                 default:                  default:
                        /* spawn Shell mode */                        cli_telnet_SetCmd(Attr + 0, DO, TELOPT_TTYPE);
                        telnet_SetCmd(Attr + 0, DO, TELOPT_TTYPE);                        cli_telnet_SetCmd(Attr + 1, WILL, TELOPT_ECHO);
                        telnet_SetCmd(Attr + 1, WILL, TELOPT_ECHO);                        cli_telnet_Set_SubOpt(Attr + 2, TELOPT_LFLOW, LFLOW_OFF, NULL, 0);
                        telnet_Set_SubOpt(Attr + 2, TELOPT_LFLOW, LFLOW_OFF, NULL, 0);                        cli_telnet_Set_SubOpt(Attr + 3, TELOPT_LFLOW, LFLOW_RESTART_XON, NULL, 0);
                        telnet_Set_SubOpt(Attr + 3, TELOPT_LFLOW, LFLOW_RESTART_XON, NULL, 0);                        cli_telnet_SetCmd(Attr + 4, DO, TELOPT_LINEMODE);
                        telnet_SetCmd(Attr + 4, DO, TELOPT_LINEMODE);                        if ((ret = cli_telnetSend(sock, Attr, 5, NULL, 0, 0)) == -1)
                        if ((ret = telnetSend(sock, Attr, 5, NULL, 0, 0)) == -1) { 
                                cli_Errno = telnet_GetErrno(); 
                                strlcpy(cli_Error, telnet_GetError(), STRSIZ); 
                                 return -1;                                  return -1;
                        } else                        else
                                 flg = 0;                                  flg = 0;
   
                         while (42) {                          while (42) {
                                   if (waitpid(pid, &stat, WNOHANG))
                                           break;
   
                                 FD_ZERO(&fds);                                  FD_ZERO(&fds);
                                 FD_SET(sock, &fds);                                  FD_SET(sock, &fds);
                                 FD_SET(pty, &fds);                                  FD_SET(pty, &fds);
Line 1282  cliNetLoop(linebuffer_t * __restrict buffer, const cha Line 1340  cliNetLoop(linebuffer_t * __restrict buffer, const cha
                                 r = FD_ISSET(sock, &fds) ? sock : pty;                                  r = FD_ISSET(sock, &fds) ? sock : pty;
                                 s = FD_ISSET(sock, &fds) ? pty : sock;                                  s = FD_ISSET(sock, &fds) ? pty : sock;
   
                                if ((ret = telnetRecv(r, &a, &alen, buf, BUFSIZ)) < 0) {                                if (FD_ISSET(sock, &fds)) {
                                         memset(buf, 0, BUFSIZ);
                                         if ((ret = cli_telnetRecv(sock, &a, &alen, buf, BUFSIZ)) < 0) {
                                                 if (a)
                                                         io_free(a);
 
                                                 if (-2 == ret)
                                                         continue;
                                                 // EOF
                                                 if (-3 == ret)
                                                         shutdown(sock, SHUT_RD);
                                                 break;
                                         }
                                         attrlen = 0;
                                         if (1 == flg && alen) {
                                                 cli_telnet_SetCmd(&Attr[attrlen++], DONT, TELOPT_SGA);
                                                 cli_telnet_SetCmd(&Attr[attrlen++], DO, TELOPT_ECHO);
                                         }
                                         if (2 == flg && alen) {
                                                 cli_telnet_SetCmd(&Attr[attrlen++], WILL, TELOPT_ECHO);
                                                 cli_telnet_Set_SubOpt(&Attr[attrlen++], TELOPT_LFLOW, 
                                                                 LFLOW_OFF, NULL, 0);
                                                 cli_telnet_Set_SubOpt(&Attr[attrlen++], TELOPT_LFLOW, 
                                                                 LFLOW_RESTART_XON, NULL, 0);
                                                 cli_telnet_SetCmd(&Attr[attrlen++], DONT, TELOPT_LINEMODE);
                                         }
                                         if (a)                                          if (a)
                                                free(a);                                                io_free(a);
   
                                        if (-2 == ret)                                        if ((ret = write(pty, buf, ret)) == -1) {
                                                continue;                                                LOGERR;
                                        // EOF                                                break;
                                        if (-3 == ret) 
                                                shutdown(r, SHUT_RD); 
                                        else { 
                                                cli_Errno = telnet_GetErrno(); 
                                                strlcpy(cli_Error, telnet_GetError(), STRSIZ); 
                                         }                                          }
                                         break;  
                                 }                                  }
                                 attrlen = 0;  
                                 if (1 == flg && alen) {  
                                         telnet_SetCmd(&Attr[attrlen++], DONT, TELOPT_SGA);  
                                         telnet_SetCmd(&Attr[attrlen++], DO, TELOPT_ECHO);  
                                 }  
                                 if (2 == flg && alen) {  
                                         telnet_SetCmd(&Attr[attrlen++], WILL, TELOPT_ECHO);  
                                         telnet_Set_SubOpt(&Attr[attrlen++], TELOPT_LFLOW,   
                                                         LFLOW_OFF, NULL, 0);  
                                         telnet_Set_SubOpt(&Attr[attrlen++], TELOPT_LFLOW,   
                                                         LFLOW_RESTART_XON, NULL, 0);  
                                         telnet_SetCmd(&Attr[attrlen++], DONT, TELOPT_LINEMODE);  
                                 }  
                                 if (a)  
                                         free(a);  
   
                                if ((ret = telnetSend(s, Attr, pty == s ? 0 : attrlen, buf, ret, 0)) == -1) {                                if (FD_ISSET(pty, &fds)) {
                                        cli_Errno = telnet_GetErrno();                                        memset(buf, 0, BUFSIZ);
                                        strlcpy(cli_Error, telnet_GetError(), STRSIZ);                                        if ((ret = read(pty, buf, BUFSIZ)) == -1) {
                                        break;                                                LOGERR;
                                } else                                                break;
                                        flg++;                                        }
 
                                         if ((ret = cli_telnetSend(sock, Attr, pty == s ? 0 : attrlen, 
                                                                         buf, ret, 0)) == -1)
                                                 break;
                                         else
                                                 flg++;
                                 }
                         }                          }
   
                         close(pty);                          close(pty);
Line 1341  cliLoop(linebuffer_t * __restrict buffer, const char * Line 1410  cliLoop(linebuffer_t * __restrict buffer, const char *
         int ret = RETCODE_OK;          int ret = RETCODE_OK;
         struct tagCommand *cmd;          struct tagCommand *cmd;
   
         /*  
   
         char **cli_stdCompletion(const char *text, int start, int end)  
         {  
                 register int i;  
                 char **matches = NULL;  
   
                 char *cmdCompGet(const char *text, int state)  
                 {  
                         int len = strlen(text);  
   
                         for (i = state; cmdList[i].cmd_name; i++) {  
                                 if (strncmp(cmdList[i].cmd_name, "---", 3) &&   
                                                 !strncmp(cmdList[i].cmd_name, text, len))  
                                         return strdup(cmdList[i].cmd_name);  
                         }  
   
                         return NULL;  
                 }  
   
                 if (!start)  
                         matches = rl_completion_matches(text, cmdCompGet);  
                 else  
                         for (i = 0; cmdList[i].cmd_name; i++) {  
                                 if (!cmdList[i].cmd_comp)  
                                         continue;  
                                 if (!strncmp(rl_line_buffer, cmdList[i].cmd_name, strlen(cmdList[i].cmd_name)))  
                                         matches = rl_completion_matches(text, cmdList[i].cmd_comp);  
                         }  
   
                 return matches;  
         }  
   
   
         */  
   
         /* --- main body of CLI --- */          /* --- main body of CLI --- */
           cliInitLine(buffer);
   
         if (cli_loadHistory(buffer, csHistFile) == RETCODE_ERR)          if (cli_loadHistory(buffer, csHistFile) == RETCODE_ERR)
                 return RETCODE_ERR;                  return RETCODE_ERR;
Line 1390  cliLoop(linebuffer_t * __restrict buffer, const char * Line 1424  cliLoop(linebuffer_t * __restrict buffer, const char *
                 } else                  } else
                         cli_addHistory(buffer, NULL);                          cli_addHistory(buffer, NULL);
                 // clear whitespaces                  // clear whitespaces
                for (s = line; isspace(*s); s++);                for (s = line; isspace((int) *s); s++);
                 if (*s) {                  if (*s) {
                        for (t = s + strlen(s) - 1; t > s && isspace(*t); t--);                        for (t = s + strlen(s) - 1; t > s && isspace((int) *t); t--);
                         *++t = 0;                          *++t = 0;
                 }                  }
   
Line 1414  cliLoop(linebuffer_t * __restrict buffer, const char * Line 1448  cliLoop(linebuffer_t * __restrict buffer, const char *
                                 cli_Printf(buffer, "\nCommand '%s' not found!\n", items[0]);                                  cli_Printf(buffer, "\nCommand '%s' not found!\n", items[0]);
                                 ret = -1;                                  ret = -1;
                         } else                          } else
                                ret = cmd->cmd_func(buffer, i, items);                                if (cmd->cmd_func) {
                                         cli_Printf(buffer, "\n");
                                         ret = cmd->cmd_func(buffer, i, items);
                                 } else {
                                         clrscrEOL(buffer);
                                         printfCR(buffer, 1);
                                 }
                 }                  }
   
                 cli_freeLine(buffer);                  cli_freeLine(buffer);
                 cli_resetHistory(buffer);                  cli_resetHistory(buffer);
                free(line);                io_free(line);
         } while (ret < 1);          } while (ret < 1);
   
         cli_saveHistory(buffer, csHistFile, HISTORY_LINES);          cli_saveHistory(buffer, csHistFile, HISTORY_LINES);

Removed from v.1.2.2.12  
changed lines
  Added in v.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>