diff options
Diffstat (limited to 'lib/vty.c')
| -rw-r--r-- | lib/vty.c | 173 |
1 files changed, 96 insertions, 77 deletions
@@ -92,28 +92,23 @@ char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG; static int do_log_commands = 0; -/* VTY standard output function. */ -int -vty_out (struct vty *vty, const char *format, ...) +static int +vty_out_variadic (struct vty *vty, const char *format, va_list args) { - va_list args; int len = 0; int size = 1024; char buf[1024]; char *p = NULL; + va_list cp; if (vty_shell (vty)) - { - va_start (args, format); - vprintf (format, args); - va_end (args); - } + vprintf (format, args); else { /* Try to write to initial buffer. */ - va_start (args, format); + va_copy (cp, args); len = vsnprintf (buf, sizeof(buf), format, args); - va_end (args); + va_end (cp); /* Initial buffer is not enough. */ if (len < 0 || len >= size) @@ -129,9 +124,7 @@ vty_out (struct vty *vty, const char *format, ...) if (! p) return -1; - va_start (args, format); len = vsnprintf (p, size, format, args); - va_end (args); if (len > -1 && len < size) break; @@ -152,6 +145,32 @@ vty_out (struct vty *vty, const char *format, ...) return len; } +/* VTY standard output function. */ +int +vty_out (struct vty *vty, const char *format, ...) +{ + int len; + va_list args; + + va_start (args, format); + len = vty_out_variadic (vty, format, args); + va_end (args); + + return len; +} + +int +vty_outln (struct vty *vty, const char *format, ...) +{ + int len; + va_list args; + + va_start (args, format); + len = vty_out_variadic (vty, format, args); + va_end (args); + + return len + vty_out (vty, "%s", VTYNL); +} static int vty_log_out (struct vty *vty, const char *level, const char *proto_str, @@ -244,12 +263,12 @@ vty_hello (struct vty *vty) for (s = buf + strlen (buf); (s > buf) && isspace ((int)*(s - 1)); s--); *s = '\0'; - vty_out (vty, "%s%s", buf, VTY_NEWLINE); + vty_outln (vty, "%s", buf); } fclose (f); } else - vty_out (vty, "MOTD file not found%s", VTY_NEWLINE); + vty_outln (vty, "MOTD file not found"); } else if (host.motd) vty_out (vty, "%s", host.motd); @@ -382,14 +401,14 @@ vty_auth (struct vty *vty, char *buf) { if (vty->node == AUTH_NODE) { - vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE); + vty_outln (vty, "%% Bad passwords, too many failures!"); vty->status = VTY_CLOSE; } else { /* AUTH_ENABLE_NODE */ vty->fail = 0; - vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE); + vty_outln (vty, "%% Bad enable passwords, too many failures!"); vty->status = VTY_CLOSE; } } @@ -474,16 +493,16 @@ vty_command (struct vty *vty, char *buf) { case CMD_WARNING: if (vty->type == VTY_FILE) - vty_out (vty, "Warning...%s", VTY_NEWLINE); + vty_outln (vty, "Warning..."); break; case CMD_ERR_AMBIGUOUS: - vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE); + vty_outln (vty, "%% Ambiguous command."); break; case CMD_ERR_NO_MATCH: - vty_out (vty, "%% [%s] Unknown command: %s%s", protocolname, buf, VTY_NEWLINE); + vty_outln (vty, "%% [%s] Unknown command: %s", protocolname, buf); break; case CMD_ERR_INCOMPLETE: - vty_out (vty, "%% Command incomplete.%s", VTY_NEWLINE); + vty_outln (vty, "%% Command incomplete."); break; } cmd_free_strvec (vline); @@ -711,7 +730,7 @@ vty_backward_word (struct vty *vty) static void vty_down_level (struct vty *vty) { - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); cmd_exit (vty); vty_prompt (vty); vty->cp = 0; @@ -721,7 +740,7 @@ vty_down_level (struct vty *vty) static void vty_end_config (struct vty *vty) { - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); switch (vty->node) { @@ -926,16 +945,16 @@ vty_complete_command (struct vty *vty) cmd_free_strvec (vline); - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); switch (ret) { case CMD_ERR_AMBIGUOUS: - vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE); + vty_outln (vty, "%% Ambiguous command."); vty_prompt (vty); vty_redraw_line (vty); break; case CMD_ERR_NO_MATCH: - /* vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE); */ + /* vty_out (vty, "%% There is no matched command.%s", VTYNL); */ vty_prompt (vty); vty_redraw_line (vty); break; @@ -943,7 +962,7 @@ vty_complete_command (struct vty *vty) if (!matched[0]) { /* 2016-11-28 equinox -- need to debug, SEGV here */ - vty_out (vty, "%% CLI BUG: FULL_MATCH with NULL str%s", VTY_NEWLINE); + vty_outln (vty, "%% CLI BUG: FULL_MATCH with NULL str"); vty_prompt (vty); vty_redraw_line (vty); break; @@ -966,11 +985,11 @@ vty_complete_command (struct vty *vty) for (i = 0; matched[i] != NULL; i++) { if (i != 0 && ((i % 6) == 0)) - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); vty_out (vty, "%-10s ", matched[i]); XFREE (MTYPE_COMPLETION, matched[i]); } - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); vty_prompt (vty); vty_redraw_line (vty); @@ -998,7 +1017,7 @@ vty_describe_fold (struct vty *vty, int cmd_width, if (desc_width <= 0) { - vty_out (vty, " %-*s %s%s", cmd_width, cmd, token->desc, VTY_NEWLINE); + vty_outln (vty, " %-*s %s", cmd_width, cmd, token->desc); return; } @@ -1015,12 +1034,12 @@ vty_describe_fold (struct vty *vty, int cmd_width, strncpy (buf, p, pos); buf[pos] = '\0'; - vty_out (vty, " %-*s %s%s", cmd_width, cmd, buf, VTY_NEWLINE); + vty_outln (vty, " %-*s %s", cmd_width, cmd, buf); cmd = ""; } - vty_out (vty, " %-*s %s%s", cmd_width, cmd, p, VTY_NEWLINE); + vty_outln (vty, " %-*s %s", cmd_width, cmd, p); XFREE (MTYPE_TMP, buf); } @@ -1049,17 +1068,17 @@ vty_describe_command (struct vty *vty) describe = cmd_describe_command (vline, vty, &ret); - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); /* Ambiguous error. */ switch (ret) { case CMD_ERR_AMBIGUOUS: - vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE); + vty_outln (vty, "%% Ambiguous command."); goto out; break; case CMD_ERR_NO_MATCH: - vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE); + vty_outln (vty, "%% There is no matched command."); goto out; break; } @@ -1097,13 +1116,12 @@ vty_describe_command (struct vty *vty) } if (!token->desc) - vty_out (vty, " %-s%s", - token->text, - VTY_NEWLINE); + vty_outln (vty, " %-s", + token->text); else if (desc_width >= strlen (token->desc)) - vty_out (vty, " %-*s %s%s", width, + vty_outln (vty, " %-*s %s", width, token->text, - token->desc, VTY_NEWLINE); + token->desc); else vty_describe_fold (vty, width, desc_width, token); @@ -1123,27 +1141,26 @@ vty_describe_command (struct vty *vty) vty_out(vty, " %s", item); XFREE(MTYPE_COMPLETION, item); } - vty_out(vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); } vector_free(varcomps); } #if 0 vty_out (vty, " %-*s %s%s", width desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd, - desc->str ? desc->str : "", VTY_NEWLINE); + desc->str ? desc->str : "", VTYNL); #endif /* 0 */ } if ((token = token_cr)) { if (!token->desc) - vty_out (vty, " %-s%s", - token->text, - VTY_NEWLINE); + vty_outln (vty, " %-s", + token->text); else if (desc_width >= strlen (token->desc)) - vty_out (vty, " %-*s %s%s", width, + vty_outln (vty, " %-*s %s", width, token->text, - token->desc, VTY_NEWLINE); + token->desc); else vty_describe_fold (vty, width, desc_width, token); } @@ -1169,7 +1186,7 @@ vty_stop_input (struct vty *vty) { vty->cp = vty->length = 0; vty_clear_buf (vty); - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); switch (vty->node) { @@ -1280,20 +1297,20 @@ vty_telnet_option (struct vty *vty, unsigned char *buf, int nbytes) vty_out (vty, "SE "); break; case TELOPT_ECHO: - vty_out (vty, "TELOPT_ECHO %s", VTY_NEWLINE); + vty_outln (vty, "TELOPT_ECHO "); break; case TELOPT_SGA: - vty_out (vty, "TELOPT_SGA %s", VTY_NEWLINE); + vty_outln (vty, "TELOPT_SGA "); break; case TELOPT_NAWS: - vty_out (vty, "TELOPT_NAWS %s", VTY_NEWLINE); + vty_outln (vty, "TELOPT_NAWS "); break; default: vty_out (vty, "%x ", buf[i]); break; } } - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); #endif /* TELNET_OPTION_DEBUG */ @@ -1330,9 +1347,9 @@ vty_telnet_option (struct vty *vty, unsigned char *buf, int nbytes) vty->width = ((vty->sb_buf[1] << 8)|vty->sb_buf[2]); vty->height = ((vty->sb_buf[3] << 8)|vty->sb_buf[4]); #ifdef TELNET_OPTION_DEBUG - vty_out(vty, "TELNET NAWS window size negotiation completed: " - "width %d, height %d%s", - vty->width, vty->height, VTY_NEWLINE); + vty_outln (vty, "TELNET NAWS window size negotiation completed: " + "width %d, height %d", + vty->width, vty->height); #endif } break; @@ -1589,7 +1606,7 @@ vty_read (struct thread *thread) break; case '\n': case '\r': - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, VTYNL); vty_execute (vty); break; case '\t': @@ -1748,7 +1765,7 @@ vty_create (int vty_sock, union sockunion *su) /* Vty is not available if password isn't set. */ if (host.password == NULL && host.password_encrypt == NULL) { - vty_out (vty, "Vty password is not set.%s", VTY_NEWLINE); + vty_outln (vty, "Vty password is not set."); vty->status = VTY_CLOSE; vty_close (vty); return NULL; @@ -1758,7 +1775,8 @@ vty_create (int vty_sock, union sockunion *su) /* Say hello to the world. */ vty_hello (vty); if (! no_password_check) - vty_out (vty, "%sUser Access Verification%s%s", VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + vty_outln (vty, "%sUser Access Verification%s", VTYNL, + VTYNL); /* Setting up terminal. */ vty_will_echo (vty); @@ -2175,7 +2193,7 @@ vtysh_read (struct thread *thread) /* Clear command line buffer. */ vty->cp = vty->length = 0; vty_clear_buf (vty); - vty_out (vty, "%% Command is too long.%s", VTY_NEWLINE); + vty_outln (vty, "%% Command is too long."); } else { @@ -2212,7 +2230,10 @@ vtysh_read (struct thread *thread) } } - vty_event (VTYSH_READ, sock, vty); + if (vty->status == VTY_CLOSE) + vty_close (vty); + else + vty_event (VTYSH_READ, sock, vty); return 0; } @@ -2315,7 +2336,7 @@ vty_timeout (struct thread *thread) /* Clear buffer*/ buffer_reset (vty->obuf); - vty_out (vty, "%sVty connection is timed out.%s", VTY_NEWLINE, VTY_NEWLINE); + vty_outln (vty, "%sVty connection is timed out.", VTYNL); /* Close connection. */ vty->status = VTY_CLOSE; @@ -2698,7 +2719,7 @@ DEFUN_NOSH (config_who, if ((v = vector_slot (vtyvec, i)) != NULL) vty_out (vty, "%svty[%d] connected from %s.%s", v->config ? "*" : " ", - i, v->address, VTY_NEWLINE); + i, v->address, VTYNL); return CMD_SUCCESS; } @@ -2796,8 +2817,7 @@ DEFUN (no_vty_access_class, const char *accesslist = (argc == 3) ? argv[idx_word]->arg : NULL; if (! vty_accesslist_name || (argc == 3 && strcmp(vty_accesslist_name, accesslist))) { - vty_out (vty, "Access-class is not currently applied to vty%s", - VTY_NEWLINE); + vty_outln (vty,"Access-class is not currently applied to vty"); return CMD_WARNING; } @@ -2840,8 +2860,7 @@ DEFUN (no_vty_ipv6_access_class, if (! vty_ipv6_accesslist_name || (argc == 4 && strcmp(vty_ipv6_accesslist_name, accesslist))) { - vty_out (vty, "IPv6 access-class is not currently applied to vty%s", - VTY_NEWLINE); + vty_outln (vty,"IPv6 access-class is not currently applied to vty"); return CMD_WARNING; } @@ -2942,7 +2961,7 @@ DEFUN_NOSH (show_history, } if (vty->hist[index] != NULL) - vty_out (vty, " %s%s", vty->hist[index], VTY_NEWLINE); + vty_out (vty, " %s%s", vty->hist[index], VTYNL); index++; } @@ -2965,30 +2984,30 @@ DEFUN (log_commands, static int vty_config_write (struct vty *vty) { - vty_out (vty, "line vty%s", VTY_NEWLINE); + vty_outln (vty, "line vty"); if (vty_accesslist_name) - vty_out (vty, " access-class %s%s", - vty_accesslist_name, VTY_NEWLINE); + vty_outln (vty, " access-class %s", + vty_accesslist_name); if (vty_ipv6_accesslist_name) - vty_out (vty, " ipv6 access-class %s%s", - vty_ipv6_accesslist_name, VTY_NEWLINE); + vty_outln (vty, " ipv6 access-class %s", + vty_ipv6_accesslist_name); /* exec-timeout */ if (vty_timeout_val != VTY_TIMEOUT_DEFAULT) - vty_out (vty, " exec-timeout %ld %ld%s", + vty_outln (vty, " exec-timeout %ld %ld", vty_timeout_val / 60, - vty_timeout_val % 60, VTY_NEWLINE); + vty_timeout_val % 60); /* login */ if (no_password_check) - vty_out (vty, " no login%s", VTY_NEWLINE); + vty_outln (vty, " no login"); if (do_log_commands) - vty_out (vty, "log commands%s", VTY_NEWLINE); + vty_outln (vty, "log commands"); - vty_out (vty, "!%s", VTY_NEWLINE); + vty_outln (vty, "!"); return CMD_SUCCESS; } |
