|
|
| version 1.2.2.13, 2010/06/07 23:38:39 | version 1.3.2.2, 2011/05/29 22:42:39 |
|---|---|
| Line 391 bufComp(int idx, void * __restrict buffer) | Line 391 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); | |
| } | |
| } | } |
| } | |
| if (i > 1 && c) { | if (i > 1 && c) { |
| /* we are on argument of command and has complition info */ | /* we are on argument of command and has complition info */ |
| Line 414 bufComp(int idx, void * __restrict buffer) | Line 417 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 495 cli_Printf(linebuffer_t * __restrict buffer, char *fmt | Line 500 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 537 cli_addCommand(linebuffer_t * __restrict buffer, const | Line 558 cli_addCommand(linebuffer_t * __restrict buffer, const |
| { | { |
| 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; |
| } | } |
| Line 886 cliInit(int fin, int fout, const char *prompt) | Line 907 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 = malloc(sizeof(linebuffer_t)); |
| if (!buffer) { | if (!buffer) { |
| LOGERR; | LOGERR; |
| return NULL; | return NULL; |
| Line 938 cliInit(int fin, int fout, const char *prompt) | Line 957 cliInit(int fin, int fout, const char *prompt) |
| /* add helper functions */ | /* add helper functions */ |
| cli_addCommand(buffer, "exit", 0, cli_Cmd_Exit, "exit <cr>", "Exit from console"); | 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"); |
| cli_addCommand(buffer, "-------", 0, NULL, "-------------------------", NULL); | |
| /* fill key bindings */ | /* fill key bindings */ |
| // ascii chars & ctrl+chars | // ascii chars & ctrl+chars |
| Line 1127 cliInit(int fin, int fout, const char *prompt) | Line 1147 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; | |
| } | } |
| /* | /* |
| Line 1217 recheck: | Line 1249 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 sock, | cliNetLoop(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 1278 cliNetLoop(linebuffer_t * __restrict buffer, const cha | Line 1303 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) | |
| 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); | 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 1338 cliLoop(linebuffer_t * __restrict buffer, const char * | Line 1374 cliLoop(linebuffer_t * __restrict buffer, const char * |
| struct tagCommand *cmd; | struct tagCommand *cmd; |
| /* --- 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 1350 cliLoop(linebuffer_t * __restrict buffer, const char * | Line 1387 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 1374 cliLoop(linebuffer_t * __restrict buffer, const char * | Line 1411 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); |