2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* Virtual terminal [aka TeletYpe] interface routine.
|
|
|
|
* Copyright (C) 1997, 98 Kunihiro Ishiguro
|
|
|
|
*
|
|
|
|
* This file is part of GNU Zebra.
|
|
|
|
*
|
|
|
|
* GNU Zebra is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
* later version.
|
|
|
|
*
|
|
|
|
* GNU Zebra is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with GNU Zebra; see the file COPYING. If not, write to the Free
|
|
|
|
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
2016-09-20 01:46:51 +02:00
|
|
|
* 02111-1307, USA.
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "linklist.h"
|
2003-06-15 03:28:29 +02:00
|
|
|
#include "thread.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "buffer.h"
|
2004-03-16 15:38:36 +01:00
|
|
|
#include <lib/version.h>
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "command.h"
|
|
|
|
#include "sockunion.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "log.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "filter.h"
|
2003-06-15 03:28:29 +02:00
|
|
|
#include "vty.h"
|
2003-06-04 15:59:38 +02:00
|
|
|
#include "privs.h"
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
#include "network.h"
|
|
|
|
|
|
|
|
#include <arpa/telnet.h>
|
2015-05-05 11:04:46 +02:00
|
|
|
#include <termios.h>
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-29 05:48:31 +02:00
|
|
|
DEFINE_MTYPE_STATIC(LIB, VTY, "VTY")
|
|
|
|
DEFINE_MTYPE_STATIC(LIB, VTY_OUT_BUF, "VTY output buffer")
|
|
|
|
DEFINE_MTYPE_STATIC(LIB, VTY_HIST, "VTY history")
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Vty events */
|
2016-09-20 01:46:51 +02:00
|
|
|
enum event
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
VTY_SERV,
|
|
|
|
VTY_READ,
|
|
|
|
VTY_WRITE,
|
|
|
|
VTY_TIMEOUT_RESET,
|
|
|
|
#ifdef VTYSH
|
|
|
|
VTYSH_SERV,
|
2004-11-04 20:26:16 +01:00
|
|
|
VTYSH_READ,
|
|
|
|
VTYSH_WRITE
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif /* VTYSH */
|
|
|
|
};
|
|
|
|
|
|
|
|
static void vty_event (enum event, int, struct vty *);
|
|
|
|
|
|
|
|
/* Extern host structure from command.c */
|
|
|
|
extern struct host host;
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Vector which store each vty structure. */
|
|
|
|
static vector vtyvec;
|
|
|
|
|
|
|
|
/* Vty timeout value. */
|
|
|
|
static unsigned long vty_timeout_val = VTY_TIMEOUT_DEFAULT;
|
|
|
|
|
|
|
|
/* Vty access-class command */
|
|
|
|
static char *vty_accesslist_name = NULL;
|
|
|
|
|
|
|
|
/* Vty access-calss for IPv6. */
|
|
|
|
static char *vty_ipv6_accesslist_name = NULL;
|
|
|
|
|
|
|
|
/* VTY server thread. */
|
2013-02-27 14:47:23 +01:00
|
|
|
static vector Vvty_serv_thread;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Current directory. */
|
|
|
|
char *vty_cwd = NULL;
|
|
|
|
|
|
|
|
/* Configure lock. */
|
|
|
|
static int vty_config;
|
2016-09-27 16:53:25 +02:00
|
|
|
static int vty_config_is_lockless = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Login password check. */
|
|
|
|
static int no_password_check = 0;
|
|
|
|
|
|
|
|
/* Integrated configuration file path */
|
|
|
|
char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG;
|
|
|
|
|
2016-05-17 18:19:51 +02:00
|
|
|
static int do_log_commands = 0;
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* VTY standard output function. */
|
|
|
|
int
|
|
|
|
vty_out (struct vty *vty, const char *format, ...)
|
|
|
|
{
|
|
|
|
va_list args;
|
|
|
|
int len = 0;
|
|
|
|
int size = 1024;
|
|
|
|
char buf[1024];
|
|
|
|
char *p = NULL;
|
|
|
|
|
|
|
|
if (vty_shell (vty))
|
2004-11-23 18:35:08 +01:00
|
|
|
{
|
|
|
|
va_start (args, format);
|
|
|
|
vprintf (format, args);
|
|
|
|
va_end (args);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Try to write to initial buffer. */
|
2004-11-23 18:35:08 +01:00
|
|
|
va_start (args, format);
|
2016-01-12 19:41:49 +01:00
|
|
|
len = vsnprintf (buf, sizeof(buf), format, args);
|
2004-11-23 18:35:08 +01:00
|
|
|
va_end (args);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Initial buffer is not enough. */
|
|
|
|
if (len < 0 || len >= size)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (len > -1)
|
|
|
|
size = len + 1;
|
|
|
|
else
|
|
|
|
size = size * 2;
|
|
|
|
|
|
|
|
p = XREALLOC (MTYPE_VTY_OUT_BUF, p, size);
|
|
|
|
if (! p)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
va_start (args, format);
|
|
|
|
len = vsnprintf (p, size, format, args);
|
|
|
|
va_end (args);
|
|
|
|
|
|
|
|
if (len > -1 && len < size)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* When initial buffer is enough to store all output. */
|
|
|
|
if (! p)
|
2016-09-20 01:46:51 +02:00
|
|
|
p = buf;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Pointer p must point out buffer. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
buffer_put (vty->obuf, (u_char *) p, len);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* If p is not different with buf, it is allocated buffer. */
|
|
|
|
if (p != buf)
|
2016-09-20 01:46:51 +02:00
|
|
|
XFREE (MTYPE_VTY_OUT_BUF, p);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2004-11-23 18:35:08 +01:00
|
|
|
static int
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
vty_log_out (struct vty *vty, const char *level, const char *proto_str,
|
2016-09-20 01:46:51 +02:00
|
|
|
const char *format, struct timestamp_control *ctl, va_list va)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
int ret;
|
2002-12-13 21:15:29 +01:00
|
|
|
int len;
|
|
|
|
char buf[1024];
|
2006-07-03 22:58:29 +02:00
|
|
|
|
2007-04-29 00:14:10 +02:00
|
|
|
if (!ctl->already_rendered)
|
|
|
|
{
|
|
|
|
ctl->len = quagga_timestamp(ctl->precision, ctl->buf, sizeof(ctl->buf));
|
|
|
|
ctl->already_rendered = 1;
|
|
|
|
}
|
|
|
|
if (ctl->len+1 >= sizeof(buf))
|
|
|
|
return -1;
|
|
|
|
memcpy(buf, ctl->buf, len = ctl->len);
|
|
|
|
buf[len++] = ' ';
|
|
|
|
buf[len] = '\0';
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
if (level)
|
2006-07-03 22:58:29 +02:00
|
|
|
ret = snprintf(buf+len, sizeof(buf)-len, "%s: %s: ", level, proto_str);
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
else
|
2006-07-03 22:58:29 +02:00
|
|
|
ret = snprintf(buf+len, sizeof(buf)-len, "%s: ", proto_str);
|
|
|
|
if ((ret < 0) || ((size_t)(len += ret) >= sizeof(buf)))
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
if (((ret = vsnprintf(buf+len, sizeof(buf)-len, format, va)) < 0) ||
|
|
|
|
((size_t)((len += ret)+2) > sizeof(buf)))
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
buf[len++] = '\r';
|
|
|
|
buf[len++] = '\n';
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2013-05-30 16:31:49 +02:00
|
|
|
if (write(vty->wfd, buf, len) < 0)
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
{
|
|
|
|
if (ERRNO_IO_RETRY(errno))
|
2016-09-20 01:46:51 +02:00
|
|
|
/* Kernel buffer is full, probably too much debugging output, so just
|
|
|
|
drop the data and ignore. */
|
|
|
|
return -1;
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
/* Fatal I/O error. */
|
2006-07-10 20:09:42 +02:00
|
|
|
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
zlog_warn("%s: write failed to vty client fd %d, closing: %s",
|
2016-09-20 01:46:51 +02:00
|
|
|
__func__, vty->fd, safe_strerror(errno));
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
buffer_reset(vty->obuf);
|
2006-07-11 02:06:49 +02:00
|
|
|
/* cannot call vty_close, because a parent routine may still try
|
|
|
|
to access the vty struct */
|
|
|
|
vty->status = VTY_CLOSE;
|
|
|
|
shutdown(vty->fd, SHUT_RDWR);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Output current time to the vty. */
|
|
|
|
void
|
|
|
|
vty_time_print (struct vty *vty, int cr)
|
|
|
|
{
|
2016-04-07 21:43:43 +02:00
|
|
|
char buf[QUAGGA_TIMESTAMP_LEN];
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2007-04-29 00:14:10 +02:00
|
|
|
if (quagga_timestamp(0, buf, sizeof(buf)) == 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2007-04-29 00:14:10 +02:00
|
|
|
zlog (NULL, LOG_INFO, "quagga_timestamp error");
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (cr)
|
|
|
|
vty_out (vty, "%s\n", buf);
|
|
|
|
else
|
|
|
|
vty_out (vty, "%s ", buf);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Say hello to vty interface. */
|
|
|
|
void
|
|
|
|
vty_hello (struct vty *vty)
|
|
|
|
{
|
2005-03-08 11:43:43 +01:00
|
|
|
if (host.motdfile)
|
|
|
|
{
|
|
|
|
FILE *f;
|
|
|
|
char buf[4096];
|
2005-03-08 17:00:12 +01:00
|
|
|
|
2005-03-08 11:43:43 +01:00
|
|
|
f = fopen (host.motdfile, "r");
|
|
|
|
if (f)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
while (fgets (buf, sizeof (buf), f))
|
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
/* work backwards to ignore trailling isspace() */
|
|
|
|
for (s = buf + strlen (buf); (s > buf) && isspace ((int)*(s - 1));
|
|
|
|
s--);
|
|
|
|
*s = '\0';
|
|
|
|
vty_out (vty, "%s%s", buf, VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
fclose (f);
|
|
|
|
}
|
2005-03-08 11:43:43 +01:00
|
|
|
else
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, "MOTD file not found%s", VTY_NEWLINE);
|
2005-03-08 11:43:43 +01:00
|
|
|
}
|
|
|
|
else if (host.motd)
|
2010-08-01 15:24:35 +02:00
|
|
|
vty_out (vty, "%s", host.motd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Put out prompt and wait input from user. */
|
|
|
|
static void
|
|
|
|
vty_prompt (struct vty *vty)
|
|
|
|
{
|
|
|
|
struct utsname names;
|
|
|
|
const char*hostname;
|
|
|
|
|
|
|
|
if (vty->type == VTY_TERM)
|
|
|
|
{
|
|
|
|
hostname = host.name;
|
|
|
|
if (!hostname)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
uname (&names);
|
|
|
|
hostname = names.nodename;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out (vty, cmd_prompt (vty->node), hostname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Send WILL TELOPT_ECHO to remote server. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_will_echo (struct vty *vty)
|
|
|
|
{
|
2004-06-11 13:27:03 +02:00
|
|
|
unsigned char cmd[] = { IAC, WILL, TELOPT_ECHO, '\0' };
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out (vty, "%s", cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make suppress Go-Ahead telnet option. */
|
|
|
|
static void
|
|
|
|
vty_will_suppress_go_ahead (struct vty *vty)
|
|
|
|
{
|
2004-06-11 13:27:03 +02:00
|
|
|
unsigned char cmd[] = { IAC, WILL, TELOPT_SGA, '\0' };
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out (vty, "%s", cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make don't use linemode over telnet. */
|
|
|
|
static void
|
|
|
|
vty_dont_linemode (struct vty *vty)
|
|
|
|
{
|
2004-06-11 13:27:03 +02:00
|
|
|
unsigned char cmd[] = { IAC, DONT, TELOPT_LINEMODE, '\0' };
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out (vty, "%s", cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use window size. */
|
|
|
|
static void
|
|
|
|
vty_do_window_size (struct vty *vty)
|
|
|
|
{
|
2004-06-11 13:27:03 +02:00
|
|
|
unsigned char cmd[] = { IAC, DO, TELOPT_NAWS, '\0' };
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out (vty, "%s", cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0 /* Currently not used. */
|
|
|
|
/* Make don't use lflow vty interface. */
|
|
|
|
static void
|
|
|
|
vty_dont_lflow_ahead (struct vty *vty)
|
|
|
|
{
|
2004-06-11 13:27:03 +02:00
|
|
|
unsigned char cmd[] = { IAC, DONT, TELOPT_LFLOW, '\0' };
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out (vty, "%s", cmd);
|
|
|
|
}
|
|
|
|
#endif /* 0 */
|
|
|
|
|
|
|
|
/* Allocate new vty struct. */
|
|
|
|
struct vty *
|
|
|
|
vty_new ()
|
|
|
|
{
|
|
|
|
struct vty *new = XCALLOC (MTYPE_VTY, sizeof (struct vty));
|
|
|
|
|
2016-09-20 01:46:51 +02:00
|
|
|
new->obuf = buffer_new(0); /* Use default buffer size. */
|
2002-12-13 21:15:29 +01:00
|
|
|
new->buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ);
|
2015-07-28 05:30:22 +02:00
|
|
|
new->error_buf = XCALLOC (MTYPE_VTY, VTY_BUFSIZ);
|
2002-12-13 21:15:29 +01:00
|
|
|
new->max = VTY_BUFSIZ;
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Authentication of vty */
|
|
|
|
static void
|
|
|
|
vty_auth (struct vty *vty, char *buf)
|
|
|
|
{
|
|
|
|
char *passwd = NULL;
|
|
|
|
enum node_type next_node = 0;
|
|
|
|
int fail;
|
|
|
|
char *crypt (const char *, const char *);
|
|
|
|
|
|
|
|
switch (vty->node)
|
|
|
|
{
|
|
|
|
case AUTH_NODE:
|
|
|
|
if (host.encrypt)
|
2016-09-20 01:46:51 +02:00
|
|
|
passwd = host.password_encrypt;
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-09-20 01:46:51 +02:00
|
|
|
passwd = host.password;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (host.advanced)
|
2016-09-20 01:46:51 +02:00
|
|
|
next_node = host.enable ? VIEW_NODE : ENABLE_NODE;
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-09-20 01:46:51 +02:00
|
|
|
next_node = VIEW_NODE;
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case AUTH_ENABLE_NODE:
|
|
|
|
if (host.encrypt)
|
2016-09-20 01:46:51 +02:00
|
|
|
passwd = host.enable_encrypt;
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-09-20 01:46:51 +02:00
|
|
|
passwd = host.enable;
|
2002-12-13 21:15:29 +01:00
|
|
|
next_node = ENABLE_NODE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (passwd)
|
|
|
|
{
|
|
|
|
if (host.encrypt)
|
2016-09-20 01:46:51 +02:00
|
|
|
fail = strcmp (crypt(buf, passwd), passwd);
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-09-20 01:46:51 +02:00
|
|
|
fail = strcmp (buf, passwd);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
fail = 1;
|
|
|
|
|
|
|
|
if (! fail)
|
|
|
|
{
|
|
|
|
vty->fail = 0;
|
2016-09-20 01:46:51 +02:00
|
|
|
vty->node = next_node; /* Success ! */
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vty->fail++;
|
|
|
|
if (vty->fail >= 3)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
if (vty->node == AUTH_NODE)
|
|
|
|
{
|
|
|
|
vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE);
|
|
|
|
vty->status = VTY_CLOSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* AUTH_ENABLE_NODE */
|
|
|
|
vty->fail = 0;
|
|
|
|
vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE);
|
2016-03-11 20:27:11 +01:00
|
|
|
vty->status = VTY_CLOSE;
|
2016-09-20 01:46:51 +02:00
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Command execution over the vty interface. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_command (struct vty *vty, char *buf)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
vector vline;
|
2005-09-29 13:25:50 +02:00
|
|
|
const char *protocolname;
|
2016-05-17 18:19:51 +02:00
|
|
|
char *cp = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-01-12 19:41:49 +01:00
|
|
|
/*
|
|
|
|
* Log non empty command lines
|
|
|
|
*/
|
2016-05-17 18:19:51 +02:00
|
|
|
if (do_log_commands)
|
|
|
|
cp = buf;
|
2016-01-12 19:41:49 +01:00
|
|
|
if (cp != NULL)
|
|
|
|
{
|
|
|
|
/* Skip white spaces. */
|
|
|
|
while (isspace ((int) *cp) && *cp != '\0')
|
|
|
|
cp++;
|
|
|
|
}
|
|
|
|
if (cp != NULL && *cp != '\0')
|
|
|
|
{
|
|
|
|
unsigned i;
|
2016-09-20 01:46:51 +02:00
|
|
|
char vty_str[VTY_BUFSIZ];
|
2016-01-12 19:41:49 +01:00
|
|
|
char prompt_str[VTY_BUFSIZ];
|
|
|
|
|
|
|
|
/* format the base vty info */
|
|
|
|
snprintf(vty_str, sizeof(vty_str), "vty[??]@%s", vty->address);
|
|
|
|
if (vty)
|
|
|
|
for (i = 0; i < vector_active (vtyvec); i++)
|
|
|
|
if (vty == vector_slot (vtyvec, i))
|
|
|
|
{
|
|
|
|
snprintf(vty_str, sizeof(vty_str), "vty[%d]@%s",
|
|
|
|
i, vty->address);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* format the prompt */
|
|
|
|
snprintf(prompt_str, sizeof(prompt_str), cmd_prompt (vty->node), vty_str);
|
|
|
|
|
|
|
|
/* now log the command */
|
2016-05-17 18:19:51 +02:00
|
|
|
zlog(NULL, LOG_ERR, "%s%s", prompt_str, buf);
|
2016-01-12 19:41:49 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Split readline string up into the vector */
|
|
|
|
vline = cmd_make_strvec (buf);
|
|
|
|
|
|
|
|
if (vline == NULL)
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
|
2005-04-16 19:11:24 +02:00
|
|
|
#ifdef CONSUMED_TIME_CHECK
|
|
|
|
{
|
|
|
|
RUSAGE_T before;
|
|
|
|
RUSAGE_T after;
|
2005-04-27 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
Add wall-clock timing statistics to 'show thread cpu' output.
* thread.h: Define struct rusage_t to contain wall-clock time
and cpu time. Change GETRUSAGE macro to collect both pieces
of data. Make appropriate changes to struct cpu_thread_history
to track CPU time and real time. Change proto for
thread_consumed_time to return real and cpu time elapsed.
And declare a new global variable 'struct timeval recent_time'.
* thread.c (struct timeval recent_time): New global timestamp variable.
(timeval_adjust): If timeout is negative, set to 0 (not 10
microseconds). And remove upper bound of 1,000,000 seconds, since
this does not seem to make any sense (and it breaks
funcname_thread_add_timer_timeval).
(timeval_cmp): Should return long, not int.
(vty_out_cpu_thread_history): Show CPU time and real time.
(cpu_record_hash_print): Calculate totals for CPU and real time.
(cpu_record_print): Change 'show thread cpu' title to show CPU and
real time.
(thread_timer_remain_second): Put current time in global recent_time.
(funcname_thread_add_timer_timeval): Fix assert. Replace 2-case
switch assignment with a ternary expression. Use global recent_time
variable. Fix use of timeval_adjust (previously, the value was not
actually being adjusted).
(thread_cancel): Add missing "break" statement in case
THREAD_BACKGROUND.
(thread_timer_wait): Use global recent_time value instead of calling
gettimeofday. And there's no need to check for negative timeouts,
since timeval_subtract already sets these to zero.
(thread_timer_process): Timers are sorted, so bail out once we
encounter a timer that has not yet popped. And remove some
extraneous asserts.
(thread_fetch): Do not process foreground timers before calling
select. Instead, add them to the ready list just after the select.
Also, no need to maintain a count of the number of ready threads,
since we don't care how many there are, just whether there's
one at the head of the ready list (which is easily checked).
Stick current time in global variable recent_time to reduce
the number of calls to gettimeofday. Tighten logic for
calculating the select timeout.
(thread_consumed_time): Now returns real time and puts the elapsed
cpu time in an additional argument.
(thread_should_yield): Use real (wall-clock) time to decide whether
to yield.
(thread_call): Maintain CPU and real time statistics.
* vty.c (vty_command): For slow commands, show real and cpu time.
2005-04-28 03:31:13 +02:00
|
|
|
unsigned long realtime, cputime;
|
2005-04-16 19:11:24 +02:00
|
|
|
|
|
|
|
GETRUSAGE(&before);
|
|
|
|
#endif /* CONSUMED_TIME_CHECK */
|
|
|
|
|
2005-01-17 00:31:54 +01:00
|
|
|
ret = cmd_execute_command (vline, vty, NULL, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-09-29 13:25:50 +02:00
|
|
|
/* Get the name of the protocol if any */
|
|
|
|
if (zlog_default)
|
|
|
|
protocolname = zlog_proto_names[zlog_default->protocol];
|
|
|
|
else
|
|
|
|
protocolname = zlog_proto_names[ZLOG_NONE];
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2005-04-16 19:11:24 +02:00
|
|
|
#ifdef CONSUMED_TIME_CHECK
|
|
|
|
GETRUSAGE(&after);
|
2005-04-27 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
Add wall-clock timing statistics to 'show thread cpu' output.
* thread.h: Define struct rusage_t to contain wall-clock time
and cpu time. Change GETRUSAGE macro to collect both pieces
of data. Make appropriate changes to struct cpu_thread_history
to track CPU time and real time. Change proto for
thread_consumed_time to return real and cpu time elapsed.
And declare a new global variable 'struct timeval recent_time'.
* thread.c (struct timeval recent_time): New global timestamp variable.
(timeval_adjust): If timeout is negative, set to 0 (not 10
microseconds). And remove upper bound of 1,000,000 seconds, since
this does not seem to make any sense (and it breaks
funcname_thread_add_timer_timeval).
(timeval_cmp): Should return long, not int.
(vty_out_cpu_thread_history): Show CPU time and real time.
(cpu_record_hash_print): Calculate totals for CPU and real time.
(cpu_record_print): Change 'show thread cpu' title to show CPU and
real time.
(thread_timer_remain_second): Put current time in global recent_time.
(funcname_thread_add_timer_timeval): Fix assert. Replace 2-case
switch assignment with a ternary expression. Use global recent_time
variable. Fix use of timeval_adjust (previously, the value was not
actually being adjusted).
(thread_cancel): Add missing "break" statement in case
THREAD_BACKGROUND.
(thread_timer_wait): Use global recent_time value instead of calling
gettimeofday. And there's no need to check for negative timeouts,
since timeval_subtract already sets these to zero.
(thread_timer_process): Timers are sorted, so bail out once we
encounter a timer that has not yet popped. And remove some
extraneous asserts.
(thread_fetch): Do not process foreground timers before calling
select. Instead, add them to the ready list just after the select.
Also, no need to maintain a count of the number of ready threads,
since we don't care how many there are, just whether there's
one at the head of the ready list (which is easily checked).
Stick current time in global variable recent_time to reduce
the number of calls to gettimeofday. Tighten logic for
calculating the select timeout.
(thread_consumed_time): Now returns real time and puts the elapsed
cpu time in an additional argument.
(thread_should_yield): Use real (wall-clock) time to decide whether
to yield.
(thread_call): Maintain CPU and real time statistics.
* vty.c (vty_command): For slow commands, show real and cpu time.
2005-04-28 03:31:13 +02:00
|
|
|
if ((realtime = thread_consumed_time(&after, &before, &cputime)) >
|
2016-09-20 01:46:51 +02:00
|
|
|
CONSUMED_TIME_CHECK)
|
2005-04-16 19:11:24 +02:00
|
|
|
/* Warn about CPU hog that must be fixed. */
|
2005-04-27 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
Add wall-clock timing statistics to 'show thread cpu' output.
* thread.h: Define struct rusage_t to contain wall-clock time
and cpu time. Change GETRUSAGE macro to collect both pieces
of data. Make appropriate changes to struct cpu_thread_history
to track CPU time and real time. Change proto for
thread_consumed_time to return real and cpu time elapsed.
And declare a new global variable 'struct timeval recent_time'.
* thread.c (struct timeval recent_time): New global timestamp variable.
(timeval_adjust): If timeout is negative, set to 0 (not 10
microseconds). And remove upper bound of 1,000,000 seconds, since
this does not seem to make any sense (and it breaks
funcname_thread_add_timer_timeval).
(timeval_cmp): Should return long, not int.
(vty_out_cpu_thread_history): Show CPU time and real time.
(cpu_record_hash_print): Calculate totals for CPU and real time.
(cpu_record_print): Change 'show thread cpu' title to show CPU and
real time.
(thread_timer_remain_second): Put current time in global recent_time.
(funcname_thread_add_timer_timeval): Fix assert. Replace 2-case
switch assignment with a ternary expression. Use global recent_time
variable. Fix use of timeval_adjust (previously, the value was not
actually being adjusted).
(thread_cancel): Add missing "break" statement in case
THREAD_BACKGROUND.
(thread_timer_wait): Use global recent_time value instead of calling
gettimeofday. And there's no need to check for negative timeouts,
since timeval_subtract already sets these to zero.
(thread_timer_process): Timers are sorted, so bail out once we
encounter a timer that has not yet popped. And remove some
extraneous asserts.
(thread_fetch): Do not process foreground timers before calling
select. Instead, add them to the ready list just after the select.
Also, no need to maintain a count of the number of ready threads,
since we don't care how many there are, just whether there's
one at the head of the ready list (which is easily checked).
Stick current time in global variable recent_time to reduce
the number of calls to gettimeofday. Tighten logic for
calculating the select timeout.
(thread_consumed_time): Now returns real time and puts the elapsed
cpu time in an additional argument.
(thread_should_yield): Use real (wall-clock) time to decide whether
to yield.
(thread_call): Maintain CPU and real time statistics.
* vty.c (vty_command): For slow commands, show real and cpu time.
2005-04-28 03:31:13 +02:00
|
|
|
zlog_warn("SLOW COMMAND: command took %lums (cpu time %lums): %s",
|
2016-09-20 01:46:51 +02:00
|
|
|
realtime/1000, cputime/1000, buf);
|
2005-04-16 19:11:24 +02:00
|
|
|
}
|
|
|
|
#endif /* CONSUMED_TIME_CHECK */
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret != CMD_SUCCESS)
|
|
|
|
switch (ret)
|
|
|
|
{
|
|
|
|
case CMD_WARNING:
|
2016-09-20 01:46:51 +02:00
|
|
|
if (vty->type == VTY_FILE)
|
|
|
|
vty_out (vty, "Warning...%s", VTY_NEWLINE);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case CMD_ERR_AMBIGUOUS:
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case CMD_ERR_NO_MATCH:
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, "%% [%s] Unknown command: %s%s", protocolname, buf, VTY_NEWLINE);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case CMD_ERR_INCOMPLETE:
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, "%% Command incomplete.%s", VTY_NEWLINE);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
cmd_free_strvec (vline);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static const char telnet_backward_char = 0x08;
|
|
|
|
static const char telnet_space_char = ' ';
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Basic function to write buffer to vty. */
|
|
|
|
static void
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
vty_write (struct vty *vty, const char *buf, size_t nbytes)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if ((vty->node == AUTH_NODE) || (vty->node == AUTH_ENABLE_NODE))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Should we do buffering here ? And make vty_flush (vty) ? */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
buffer_put (vty->obuf, buf, nbytes);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Basic function to insert character into vty. */
|
|
|
|
static void
|
|
|
|
vty_self_insert (struct vty *vty, char c)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int length;
|
|
|
|
|
2017-01-18 07:09:26 +01:00
|
|
|
if (vty->length + 1 >= VTY_BUFSIZ)
|
2017-01-11 00:33:50 +01:00
|
|
|
return;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
length = vty->length - vty->cp;
|
|
|
|
memmove (&vty->buf[vty->cp + 1], &vty->buf[vty->cp], length);
|
|
|
|
vty->buf[vty->cp] = c;
|
|
|
|
|
|
|
|
vty_write (vty, &vty->buf[vty->cp], length + 1);
|
|
|
|
for (i = 0; i < length; i++)
|
|
|
|
vty_write (vty, &telnet_backward_char, 1);
|
|
|
|
|
|
|
|
vty->cp++;
|
|
|
|
vty->length++;
|
2017-01-18 07:09:26 +01:00
|
|
|
|
|
|
|
vty->buf[vty->length] = '\0';
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Self insert character 'c' in overwrite mode. */
|
|
|
|
static void
|
|
|
|
vty_self_insert_overwrite (struct vty *vty, char c)
|
|
|
|
{
|
2017-01-11 00:33:50 +01:00
|
|
|
if (vty->cp == vty->length)
|
|
|
|
{
|
|
|
|
vty_self_insert (vty, c);
|
|
|
|
return;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-01-11 00:33:50 +01:00
|
|
|
vty->buf[vty->cp++] = c;
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_write (vty, &c, 1);
|
|
|
|
}
|
|
|
|
|
2017-01-11 00:33:50 +01:00
|
|
|
/**
|
|
|
|
* Insert a string into vty->buf at the current cursor position.
|
|
|
|
*
|
|
|
|
* If the resultant string would be larger than VTY_BUFSIZ it is
|
|
|
|
* truncated to fit.
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
static void
|
|
|
|
vty_insert_word_overwrite (struct vty *vty, char *str)
|
|
|
|
{
|
2017-01-18 07:09:26 +01:00
|
|
|
if (vty->cp == VTY_BUFSIZ)
|
|
|
|
return;
|
|
|
|
|
|
|
|
size_t nwrite = MIN ((int) strlen (str), VTY_BUFSIZ - vty->cp - 1);
|
|
|
|
memcpy (&vty->buf[vty->cp], str, nwrite);
|
2017-01-11 00:33:50 +01:00
|
|
|
vty->cp += nwrite;
|
2017-01-18 07:09:26 +01:00
|
|
|
vty->length = MAX (vty->cp, vty->length);
|
|
|
|
vty->buf[vty->length] = '\0';
|
|
|
|
vty_write (vty, str, nwrite);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Forward character. */
|
|
|
|
static void
|
|
|
|
vty_forward_char (struct vty *vty)
|
|
|
|
{
|
|
|
|
if (vty->cp < vty->length)
|
|
|
|
{
|
|
|
|
vty_write (vty, &vty->buf[vty->cp], 1);
|
|
|
|
vty->cp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Backward character. */
|
|
|
|
static void
|
|
|
|
vty_backward_char (struct vty *vty)
|
|
|
|
{
|
|
|
|
if (vty->cp > 0)
|
|
|
|
{
|
|
|
|
vty->cp--;
|
|
|
|
vty_write (vty, &telnet_backward_char, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move to the beginning of the line. */
|
|
|
|
static void
|
|
|
|
vty_beginning_of_line (struct vty *vty)
|
|
|
|
{
|
|
|
|
while (vty->cp)
|
|
|
|
vty_backward_char (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move to the end of the line. */
|
|
|
|
static void
|
|
|
|
vty_end_of_line (struct vty *vty)
|
|
|
|
{
|
|
|
|
while (vty->cp < vty->length)
|
|
|
|
vty_forward_char (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void vty_kill_line_from_beginning (struct vty *);
|
|
|
|
static void vty_redraw_line (struct vty *);
|
|
|
|
|
|
|
|
/* Print command line history. This function is called from
|
|
|
|
vty_next_line and vty_previous_line. */
|
|
|
|
static void
|
|
|
|
vty_history_print (struct vty *vty)
|
|
|
|
{
|
|
|
|
int length;
|
|
|
|
|
|
|
|
vty_kill_line_from_beginning (vty);
|
|
|
|
|
|
|
|
/* Get previous line from history buffer */
|
|
|
|
length = strlen (vty->hist[vty->hp]);
|
|
|
|
memcpy (vty->buf, vty->hist[vty->hp], length);
|
|
|
|
vty->cp = vty->length = length;
|
2017-01-18 07:09:26 +01:00
|
|
|
vty->buf[vty->length] = '\0';
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Redraw current line */
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Show next command line history. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_next_line (struct vty *vty)
|
|
|
|
{
|
|
|
|
int try_index;
|
|
|
|
|
|
|
|
if (vty->hp == vty->hindex)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Try is there history exist or not. */
|
|
|
|
try_index = vty->hp;
|
|
|
|
if (try_index == (VTY_MAXHIST - 1))
|
|
|
|
try_index = 0;
|
|
|
|
else
|
|
|
|
try_index++;
|
|
|
|
|
|
|
|
/* If there is not history return. */
|
|
|
|
if (vty->hist[try_index] == NULL)
|
|
|
|
return;
|
|
|
|
else
|
|
|
|
vty->hp = try_index;
|
|
|
|
|
|
|
|
vty_history_print (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Show previous command line history. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_previous_line (struct vty *vty)
|
|
|
|
{
|
|
|
|
int try_index;
|
|
|
|
|
|
|
|
try_index = vty->hp;
|
|
|
|
if (try_index == 0)
|
|
|
|
try_index = VTY_MAXHIST - 1;
|
|
|
|
else
|
|
|
|
try_index--;
|
|
|
|
|
|
|
|
if (vty->hist[try_index] == NULL)
|
|
|
|
return;
|
|
|
|
else
|
|
|
|
vty->hp = try_index;
|
|
|
|
|
|
|
|
vty_history_print (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* This function redraw all of the command line character. */
|
|
|
|
static void
|
|
|
|
vty_redraw_line (struct vty *vty)
|
|
|
|
{
|
|
|
|
vty_write (vty, vty->buf, vty->length);
|
|
|
|
vty->cp = vty->length;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Forward word. */
|
|
|
|
static void
|
|
|
|
vty_forward_word (struct vty *vty)
|
|
|
|
{
|
|
|
|
while (vty->cp != vty->length && vty->buf[vty->cp] != ' ')
|
|
|
|
vty_forward_char (vty);
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
while (vty->cp != vty->length && vty->buf[vty->cp] == ' ')
|
|
|
|
vty_forward_char (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Backward word without skipping training space. */
|
|
|
|
static void
|
|
|
|
vty_backward_pure_word (struct vty *vty)
|
|
|
|
{
|
|
|
|
while (vty->cp > 0 && vty->buf[vty->cp - 1] != ' ')
|
|
|
|
vty_backward_char (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Backward word. */
|
|
|
|
static void
|
|
|
|
vty_backward_word (struct vty *vty)
|
|
|
|
{
|
|
|
|
while (vty->cp > 0 && vty->buf[vty->cp - 1] == ' ')
|
|
|
|
vty_backward_char (vty);
|
|
|
|
|
|
|
|
while (vty->cp > 0 && vty->buf[vty->cp - 1] != ' ')
|
|
|
|
vty_backward_char (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* When '^D' is typed at the beginning of the line we move to the down
|
|
|
|
level. */
|
|
|
|
static void
|
|
|
|
vty_down_level (struct vty *vty)
|
|
|
|
{
|
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
2016-11-16 07:00:52 +01:00
|
|
|
cmd_exit (vty);
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_prompt (vty);
|
|
|
|
vty->cp = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* When '^Z' is received from vty, move down to the enable mode. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_end_config (struct vty *vty)
|
|
|
|
{
|
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
switch (vty->node)
|
|
|
|
{
|
|
|
|
case VIEW_NODE:
|
|
|
|
case ENABLE_NODE:
|
|
|
|
/* Nothing to do. */
|
|
|
|
break;
|
|
|
|
case CONFIG_NODE:
|
|
|
|
case INTERFACE_NODE:
|
|
|
|
case ZEBRA_NODE:
|
|
|
|
case RIP_NODE:
|
|
|
|
case RIPNG_NODE:
|
|
|
|
case BGP_NODE:
|
|
|
|
case BGP_VPNV4_NODE:
|
2016-06-07 04:29:05 +02:00
|
|
|
case BGP_VPNV6_NODE:
|
2016-01-12 19:42:04 +01:00
|
|
|
case BGP_ENCAP_NODE:
|
|
|
|
case BGP_ENCAPV6_NODE:
|
2017-01-12 14:30:17 +01:00
|
|
|
case BGP_VRF_POLICY_NODE:
|
bgpd: add L3/L2VPN Virtual Network Control feature
This feature adds an L3 & L2 VPN application that makes use of the VPN
and Encap SAFIs. This code is currently used to support IETF NVO3 style
operation. In NVO3 terminology it provides the Network Virtualization
Authority (NVA) and the ability to import/export IP prefixes and MAC
addresses from Network Virtualization Edges (NVEs). The code supports
per-NVE tables.
The NVE-NVA protocol used to communicate routing and Ethernet / Layer 2
(L2) forwarding information between NVAs and NVEs is referred to as the
Remote Forwarder Protocol (RFP). OpenFlow is an example RFP. For
general background on NVO3 and RFP concepts see [1]. For information on
Openflow see [2].
RFPs are integrated with BGP via the RF API contained in the new "rfapi"
BGP sub-directory. Currently, only a simple example RFP is included in
Quagga. Developers may use this example as a starting point to integrate
Quagga with an RFP of their choosing, e.g., OpenFlow. The RFAPI code
also supports the ability import/export of routing information between
VNC and customer edge routers (CEs) operating within a virtual
network. Import/export may take place between BGP views or to the
default zebera VRF.
BGP, with IP VPNs and Tunnel Encapsulation, is used to distribute VPN
information between NVAs. BGP based IP VPN support is defined in
RFC4364, BGP/MPLS IP Virtual Private Networks (VPNs), and RFC4659,
BGP-MPLS IP Virtual Private Network (VPN) Extension for IPv6 VPN . Use
of both the Encapsulation Subsequent Address Family Identifier (SAFI)
and the Tunnel Encapsulation Attribute, RFC5512, The BGP Encapsulation
Subsequent Address Family Identifier (SAFI) and the BGP Tunnel
Encapsulation Attribute, are supported. MAC address distribution does
not follow any standard BGB encoding, although it was inspired by the
early IETF EVPN concepts.
The feature is conditionally compiled and disabled by default.
Use the --enable-bgp-vnc configure option to enable.
The majority of this code was authored by G. Paul Ziemba
<paulz@labn.net>.
[1] http://tools.ietf.org/html/draft-ietf-nvo3-nve-nva-cp-req
[2] https://www.opennetworking.org/sdn-resources/technical-library
Now includes changes needed to merge with cmaster-next.
2016-05-07 20:18:56 +02:00
|
|
|
case BGP_VNC_DEFAULTS_NODE:
|
|
|
|
case BGP_VNC_NVE_GROUP_NODE:
|
|
|
|
case BGP_VNC_L2_GROUP_NODE:
|
2002-12-13 21:15:29 +01:00
|
|
|
case BGP_IPV4_NODE:
|
|
|
|
case BGP_IPV4M_NODE:
|
|
|
|
case BGP_IPV6_NODE:
|
2005-08-23 00:39:56 +02:00
|
|
|
case BGP_IPV6M_NODE:
|
2017-01-04 15:45:54 +01:00
|
|
|
case BGP_EVPN_NODE:
|
2002-12-13 21:15:29 +01:00
|
|
|
case RMAP_NODE:
|
|
|
|
case OSPF_NODE:
|
|
|
|
case OSPF6_NODE:
|
2016-03-01 19:31:28 +01:00
|
|
|
case LDP_NODE:
|
|
|
|
case LDP_IPV4_NODE:
|
|
|
|
case LDP_IPV6_NODE:
|
|
|
|
case LDP_IPV4_IFACE_NODE:
|
|
|
|
case LDP_IPV6_IFACE_NODE:
|
|
|
|
case LDP_L2VPN_NODE:
|
|
|
|
case LDP_PSEUDOWIRE_NODE:
|
2003-12-23 09:56:18 +01:00
|
|
|
case ISIS_NODE:
|
2002-12-13 21:15:29 +01:00
|
|
|
case KEYCHAIN_NODE:
|
|
|
|
case KEYCHAIN_KEY_NODE:
|
|
|
|
case MASC_NODE:
|
2015-02-04 07:01:14 +01:00
|
|
|
case PIM_NODE:
|
2002-12-13 21:15:29 +01:00
|
|
|
case VTY_NODE:
|
|
|
|
vty_config_unlock (vty);
|
|
|
|
vty->node = ENABLE_NODE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Unknown node, we have to ignore it. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_prompt (vty);
|
|
|
|
vty->cp = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete a charcter at the current point. */
|
|
|
|
static void
|
|
|
|
vty_delete_char (struct vty *vty)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
if (vty->length == 0)
|
|
|
|
{
|
|
|
|
vty_down_level (vty);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vty->cp == vty->length)
|
2016-09-20 01:46:51 +02:00
|
|
|
return; /* completion need here? */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
size = vty->length - vty->cp;
|
|
|
|
|
|
|
|
vty->length--;
|
|
|
|
memmove (&vty->buf[vty->cp], &vty->buf[vty->cp + 1], size - 1);
|
|
|
|
vty->buf[vty->length] = '\0';
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2008-08-13 18:27:38 +02:00
|
|
|
if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
|
|
|
|
return;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty_write (vty, &vty->buf[vty->cp], size - 1);
|
|
|
|
vty_write (vty, &telnet_space_char, 1);
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++)
|
|
|
|
vty_write (vty, &telnet_backward_char, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete a character before the point. */
|
|
|
|
static void
|
|
|
|
vty_delete_backward_char (struct vty *vty)
|
|
|
|
{
|
|
|
|
if (vty->cp == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vty_backward_char (vty);
|
|
|
|
vty_delete_char (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Kill rest of line from current point. */
|
|
|
|
static void
|
|
|
|
vty_kill_line (struct vty *vty)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int size;
|
|
|
|
|
|
|
|
size = vty->length - vty->cp;
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (size == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (i = 0; i < size; i++)
|
|
|
|
vty_write (vty, &telnet_space_char, 1);
|
|
|
|
for (i = 0; i < size; i++)
|
|
|
|
vty_write (vty, &telnet_backward_char, 1);
|
|
|
|
|
|
|
|
memset (&vty->buf[vty->cp], 0, size);
|
|
|
|
vty->length = vty->cp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Kill line from the beginning. */
|
|
|
|
static void
|
|
|
|
vty_kill_line_from_beginning (struct vty *vty)
|
|
|
|
{
|
|
|
|
vty_beginning_of_line (vty);
|
|
|
|
vty_kill_line (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete a word before the point. */
|
|
|
|
static void
|
|
|
|
vty_forward_kill_word (struct vty *vty)
|
|
|
|
{
|
|
|
|
while (vty->cp != vty->length && vty->buf[vty->cp] == ' ')
|
|
|
|
vty_delete_char (vty);
|
|
|
|
while (vty->cp != vty->length && vty->buf[vty->cp] != ' ')
|
|
|
|
vty_delete_char (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Delete a word before the point. */
|
|
|
|
static void
|
|
|
|
vty_backward_kill_word (struct vty *vty)
|
|
|
|
{
|
|
|
|
while (vty->cp > 0 && vty->buf[vty->cp - 1] == ' ')
|
|
|
|
vty_delete_backward_char (vty);
|
|
|
|
while (vty->cp > 0 && vty->buf[vty->cp - 1] != ' ')
|
|
|
|
vty_delete_backward_char (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Transpose chars before or at the point. */
|
|
|
|
static void
|
|
|
|
vty_transpose_chars (struct vty *vty)
|
|
|
|
{
|
|
|
|
char c1, c2;
|
|
|
|
|
|
|
|
/* If length is short or point is near by the beginning of line then
|
|
|
|
return. */
|
|
|
|
if (vty->length < 2 || vty->cp < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* In case of point is located at the end of the line. */
|
|
|
|
if (vty->cp == vty->length)
|
|
|
|
{
|
|
|
|
c1 = vty->buf[vty->cp - 1];
|
|
|
|
c2 = vty->buf[vty->cp - 2];
|
|
|
|
|
|
|
|
vty_backward_char (vty);
|
|
|
|
vty_backward_char (vty);
|
|
|
|
vty_self_insert_overwrite (vty, c1);
|
|
|
|
vty_self_insert_overwrite (vty, c2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
c1 = vty->buf[vty->cp];
|
|
|
|
c2 = vty->buf[vty->cp - 1];
|
|
|
|
|
|
|
|
vty_backward_char (vty);
|
|
|
|
vty_self_insert_overwrite (vty, c1);
|
|
|
|
vty_self_insert_overwrite (vty, c2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do completion at vty interface. */
|
|
|
|
static void
|
|
|
|
vty_complete_command (struct vty *vty)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int ret;
|
|
|
|
char **matched = NULL;
|
|
|
|
vector vline;
|
|
|
|
|
|
|
|
if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
vline = cmd_make_strvec (vty->buf);
|
|
|
|
if (vline == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* In case of 'help \t'. */
|
|
|
|
if (isspace ((int) vty->buf[vty->length - 1]))
|
2016-05-15 19:33:15 +02:00
|
|
|
vector_set (vline, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-10-29 06:43:04 +02:00
|
|
|
matched = cmd_complete_command (vline, vty, &ret);
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
cmd_free_strvec (vline);
|
|
|
|
|
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
|
|
|
switch (ret)
|
|
|
|
{
|
|
|
|
case CMD_ERR_AMBIGUOUS:
|
|
|
|
vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
|
|
|
|
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_prompt (vty);
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
break;
|
|
|
|
case CMD_COMPLETE_FULL_MATCH:
|
2016-11-28 18:41:34 +01:00
|
|
|
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_prompt (vty);
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
break;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_prompt (vty);
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
vty_backward_pure_word (vty);
|
|
|
|
vty_insert_word_overwrite (vty, matched[0]);
|
|
|
|
vty_self_insert (vty, ' ');
|
|
|
|
XFREE (MTYPE_TMP, matched[0]);
|
|
|
|
break;
|
|
|
|
case CMD_COMPLETE_MATCH:
|
|
|
|
vty_prompt (vty);
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
vty_backward_pure_word (vty);
|
|
|
|
vty_insert_word_overwrite (vty, matched[0]);
|
|
|
|
XFREE (MTYPE_TMP, matched[0]);
|
|
|
|
break;
|
|
|
|
case CMD_COMPLETE_LIST_MATCH:
|
|
|
|
for (i = 0; matched[i] != NULL; i++)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
if (i != 0 && ((i % 6) == 0))
|
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
|
|
|
vty_out (vty, "%-10s ", matched[i]);
|
|
|
|
XFREE (MTYPE_TMP, matched[i]);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
vty_prompt (vty);
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
break;
|
|
|
|
case CMD_ERR_NOTHING_TODO:
|
|
|
|
vty_prompt (vty);
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (matched)
|
2017-01-26 21:57:24 +01:00
|
|
|
XFREE (MTYPE_TMP, matched);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_describe_fold (struct vty *vty, int cmd_width,
|
2016-09-20 01:46:51 +02:00
|
|
|
unsigned int desc_width, struct cmd_token *token)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-10-05 23:01:23 +02:00
|
|
|
char *buf;
|
|
|
|
const char *cmd, *p;
|
2002-12-13 21:15:29 +01:00
|
|
|
int pos;
|
|
|
|
|
2016-09-22 22:17:48 +02:00
|
|
|
cmd = token->text;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (desc_width <= 0)
|
|
|
|
{
|
2013-09-30 14:27:51 +02:00
|
|
|
vty_out (vty, " %-*s %s%s", cmd_width, cmd, token->desc, VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-09-30 14:27:51 +02:00
|
|
|
buf = XCALLOC (MTYPE_TMP, strlen (token->desc) + 1);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2013-09-30 14:27:51 +02:00
|
|
|
for (p = token->desc; strlen (p) > desc_width; p += pos + 1)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
for (pos = desc_width; pos > 0; pos--)
|
|
|
|
if (*(p + pos) == ' ')
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (pos == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
strncpy (buf, p, pos);
|
|
|
|
buf[pos] = '\0';
|
|
|
|
vty_out (vty, " %-*s %s%s", cmd_width, cmd, buf, VTY_NEWLINE);
|
|
|
|
|
|
|
|
cmd = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_out (vty, " %-*s %s%s", cmd_width, cmd, p, VTY_NEWLINE);
|
|
|
|
|
|
|
|
XFREE (MTYPE_TMP, buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Describe matched command function. */
|
|
|
|
static void
|
|
|
|
vty_describe_command (struct vty *vty)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
vector vline;
|
|
|
|
vector describe;
|
2004-10-05 23:01:23 +02:00
|
|
|
unsigned int i, width, desc_width;
|
2013-09-30 14:27:51 +02:00
|
|
|
struct cmd_token *token, *token_cr = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vline = cmd_make_strvec (vty->buf);
|
|
|
|
|
|
|
|
/* In case of '> ?'. */
|
|
|
|
if (vline == NULL)
|
|
|
|
{
|
|
|
|
vline = vector_init (1);
|
2016-05-15 19:33:15 +02:00
|
|
|
vector_set (vline, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2016-09-20 01:46:51 +02:00
|
|
|
else
|
2002-12-13 21:15:29 +01:00
|
|
|
if (isspace ((int) vty->buf[vty->length - 1]))
|
2016-05-15 19:33:15 +02:00
|
|
|
vector_set (vline, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
describe = cmd_describe_command (vline, vty, &ret);
|
|
|
|
|
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
/* Ambiguous error. */
|
|
|
|
switch (ret)
|
|
|
|
{
|
|
|
|
case CMD_ERR_AMBIGUOUS:
|
|
|
|
vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
|
2006-05-13 01:22:01 +02:00
|
|
|
goto out;
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case CMD_ERR_NO_MATCH:
|
|
|
|
vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE);
|
2006-05-13 01:22:01 +02:00
|
|
|
goto out;
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
2016-09-20 01:46:51 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Get width of command string. */
|
|
|
|
width = 0;
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (describe); i++)
|
2013-09-30 14:27:51 +02:00
|
|
|
if ((token = vector_slot (describe, i)) != NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-20 01:46:51 +02:00
|
|
|
unsigned int len;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-20 01:46:51 +02:00
|
|
|
if (token->text[0] == '\0')
|
|
|
|
continue;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-20 01:46:51 +02:00
|
|
|
len = strlen (token->text);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-20 01:46:51 +02:00
|
|
|
if (width < len)
|
|
|
|
width = len;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Get width of description string. */
|
|
|
|
desc_width = vty->width - (width + 6);
|
|
|
|
|
|
|
|
/* Print out description. */
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (describe); i++)
|
2013-09-30 14:27:51 +02:00
|
|
|
if ((token = vector_slot (describe, i)) != NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-20 01:46:51 +02:00
|
|
|
if (token->text[0] == '\0')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (strcmp (token->text, CMD_CR_TEXT) == 0)
|
|
|
|
{
|
|
|
|
token_cr = token;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!token->desc)
|
|
|
|
vty_out (vty, " %-s%s",
|
|
|
|
token->text,
|
|
|
|
VTY_NEWLINE);
|
|
|
|
else if (desc_width >= strlen (token->desc))
|
|
|
|
vty_out (vty, " %-*s %s%s", width,
|
|
|
|
token->text,
|
|
|
|
token->desc, VTY_NEWLINE);
|
|
|
|
else
|
|
|
|
vty_describe_fold (vty, width, desc_width, token);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#if 0
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, " %-*s %s%s", width
|
|
|
|
desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
|
|
|
|
desc->str ? desc->str : "", VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif /* 0 */
|
|
|
|
}
|
|
|
|
|
2013-09-30 14:27:51 +02:00
|
|
|
if ((token = token_cr))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2013-09-30 14:27:51 +02:00
|
|
|
if (!token->desc)
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, " %-s%s",
|
|
|
|
token->text,
|
|
|
|
VTY_NEWLINE);
|
2013-09-30 14:27:51 +02:00
|
|
|
else if (desc_width >= strlen (token->desc))
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, " %-*s %s%s", width,
|
|
|
|
token->text,
|
|
|
|
token->desc, VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_describe_fold (vty, width, desc_width, token);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2006-05-13 01:22:01 +02:00
|
|
|
out:
|
2002-12-13 21:15:29 +01:00
|
|
|
cmd_free_strvec (vline);
|
2006-05-15 12:56:46 +02:00
|
|
|
if (describe)
|
|
|
|
vector_free (describe);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty_prompt (vty);
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
}
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_clear_buf (struct vty *vty)
|
|
|
|
{
|
|
|
|
memset (vty->buf, 0, vty->max);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ^C stop current input and do not add command line to the history. */
|
|
|
|
static void
|
|
|
|
vty_stop_input (struct vty *vty)
|
|
|
|
{
|
|
|
|
vty->cp = vty->length = 0;
|
|
|
|
vty_clear_buf (vty);
|
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
switch (vty->node)
|
|
|
|
{
|
|
|
|
case VIEW_NODE:
|
|
|
|
case ENABLE_NODE:
|
|
|
|
/* Nothing to do. */
|
|
|
|
break;
|
|
|
|
case CONFIG_NODE:
|
|
|
|
case INTERFACE_NODE:
|
|
|
|
case ZEBRA_NODE:
|
|
|
|
case RIP_NODE:
|
|
|
|
case RIPNG_NODE:
|
|
|
|
case BGP_NODE:
|
|
|
|
case RMAP_NODE:
|
|
|
|
case OSPF_NODE:
|
|
|
|
case OSPF6_NODE:
|
2016-03-01 19:31:28 +01:00
|
|
|
case LDP_NODE:
|
|
|
|
case LDP_IPV4_NODE:
|
|
|
|
case LDP_IPV6_NODE:
|
|
|
|
case LDP_IPV4_IFACE_NODE:
|
|
|
|
case LDP_IPV6_IFACE_NODE:
|
|
|
|
case LDP_L2VPN_NODE:
|
|
|
|
case LDP_PSEUDOWIRE_NODE:
|
2003-12-23 09:56:18 +01:00
|
|
|
case ISIS_NODE:
|
2002-12-13 21:15:29 +01:00
|
|
|
case KEYCHAIN_NODE:
|
|
|
|
case KEYCHAIN_KEY_NODE:
|
|
|
|
case MASC_NODE:
|
2015-02-04 07:01:14 +01:00
|
|
|
case PIM_NODE:
|
2002-12-13 21:15:29 +01:00
|
|
|
case VTY_NODE:
|
|
|
|
vty_config_unlock (vty);
|
|
|
|
vty->node = ENABLE_NODE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* Unknown node, we have to ignore it. */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
vty_prompt (vty);
|
|
|
|
|
|
|
|
/* Set history pointer to the latest one. */
|
|
|
|
vty->hp = vty->hindex;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add current command line to the history buffer. */
|
|
|
|
static void
|
|
|
|
vty_hist_add (struct vty *vty)
|
|
|
|
{
|
|
|
|
int index;
|
|
|
|
|
|
|
|
if (vty->length == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
index = vty->hindex ? vty->hindex - 1 : VTY_MAXHIST - 1;
|
|
|
|
|
|
|
|
/* Ignore the same string as previous one. */
|
|
|
|
if (vty->hist[index])
|
|
|
|
if (strcmp (vty->buf, vty->hist[index]) == 0)
|
|
|
|
{
|
|
|
|
vty->hp = vty->hindex;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Insert history entry. */
|
|
|
|
if (vty->hist[vty->hindex])
|
|
|
|
XFREE (MTYPE_VTY_HIST, vty->hist[vty->hindex]);
|
|
|
|
vty->hist[vty->hindex] = XSTRDUP (MTYPE_VTY_HIST, vty->buf);
|
|
|
|
|
|
|
|
/* History index rotation. */
|
|
|
|
vty->hindex++;
|
|
|
|
if (vty->hindex == VTY_MAXHIST)
|
|
|
|
vty->hindex = 0;
|
|
|
|
|
|
|
|
vty->hp = vty->hindex;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* #define TELNET_OPTION_DEBUG */
|
|
|
|
|
|
|
|
/* Get telnet window size. */
|
|
|
|
static int
|
|
|
|
vty_telnet_option (struct vty *vty, unsigned char *buf, int nbytes)
|
|
|
|
{
|
|
|
|
#ifdef TELNET_OPTION_DEBUG
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < nbytes; i++)
|
|
|
|
{
|
|
|
|
switch (buf[i])
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
case IAC:
|
|
|
|
vty_out (vty, "IAC ");
|
|
|
|
break;
|
|
|
|
case WILL:
|
|
|
|
vty_out (vty, "WILL ");
|
|
|
|
break;
|
|
|
|
case WONT:
|
|
|
|
vty_out (vty, "WONT ");
|
|
|
|
break;
|
|
|
|
case DO:
|
|
|
|
vty_out (vty, "DO ");
|
|
|
|
break;
|
|
|
|
case DONT:
|
|
|
|
vty_out (vty, "DONT ");
|
|
|
|
break;
|
|
|
|
case SB:
|
|
|
|
vty_out (vty, "SB ");
|
|
|
|
break;
|
|
|
|
case SE:
|
|
|
|
vty_out (vty, "SE ");
|
|
|
|
break;
|
|
|
|
case TELOPT_ECHO:
|
|
|
|
vty_out (vty, "TELOPT_ECHO %s", VTY_NEWLINE);
|
|
|
|
break;
|
|
|
|
case TELOPT_SGA:
|
|
|
|
vty_out (vty, "TELOPT_SGA %s", VTY_NEWLINE);
|
|
|
|
break;
|
|
|
|
case TELOPT_NAWS:
|
|
|
|
vty_out (vty, "TELOPT_NAWS %s", VTY_NEWLINE);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty_out (vty, "%x ", buf[i]);
|
|
|
|
break;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
#endif /* TELNET_OPTION_DEBUG */
|
|
|
|
|
|
|
|
switch (buf[0])
|
|
|
|
{
|
|
|
|
case SB:
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
vty->sb_len = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
vty->iac_sb_in_progress = 1;
|
|
|
|
return 0;
|
|
|
|
break;
|
2016-09-20 01:46:51 +02:00
|
|
|
case SE:
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-09-20 01:46:51 +02:00
|
|
|
if (!vty->iac_sb_in_progress)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ((vty->sb_len == 0) || (vty->sb_buf[0] == '\0'))
|
|
|
|
{
|
|
|
|
vty->iac_sb_in_progress = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
switch (vty->sb_buf[0])
|
|
|
|
{
|
|
|
|
case TELOPT_NAWS:
|
|
|
|
if (vty->sb_len != TELNET_NAWS_SB_LEN)
|
|
|
|
zlog_warn("RFC 1073 violation detected: telnet NAWS option "
|
|
|
|
"should send %d characters, but we received %lu",
|
|
|
|
TELNET_NAWS_SB_LEN, (u_long)vty->sb_len);
|
|
|
|
else if (sizeof(vty->sb_buf) < TELNET_NAWS_SB_LEN)
|
|
|
|
zlog_err("Bug detected: sizeof(vty->sb_buf) %lu < %d, "
|
|
|
|
"too small to handle the telnet NAWS option",
|
|
|
|
(u_long)sizeof(vty->sb_buf), TELNET_NAWS_SB_LEN);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vty->width = ((vty->sb_buf[1] << 8)|vty->sb_buf[2]);
|
|
|
|
vty->height = ((vty->sb_buf[3] << 8)|vty->sb_buf[4]);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
#ifdef TELNET_OPTION_DEBUG
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out(vty, "TELNET NAWS window size negotiation completed: "
|
|
|
|
"width %d, height %d%s",
|
|
|
|
vty->width, vty->height, VTY_NEWLINE);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
#endif
|
2016-09-20 01:46:51 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
vty->iac_sb_in_progress = 0;
|
|
|
|
return 0;
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Execute current command line. */
|
|
|
|
static int
|
|
|
|
vty_execute (struct vty *vty)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = CMD_SUCCESS;
|
|
|
|
|
|
|
|
switch (vty->node)
|
|
|
|
{
|
|
|
|
case AUTH_NODE:
|
|
|
|
case AUTH_ENABLE_NODE:
|
|
|
|
vty_auth (vty, vty->buf);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = vty_command (vty, vty->buf);
|
|
|
|
if (vty->type == VTY_TERM)
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_hist_add (vty);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear command line buffer. */
|
|
|
|
vty->cp = vty->length = 0;
|
|
|
|
vty_clear_buf (vty);
|
|
|
|
|
2004-11-05 02:25:55 +01:00
|
|
|
if (vty->status != VTY_CLOSE )
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_prompt (vty);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define CONTROL(X) ((X) - '@')
|
|
|
|
#define VTY_NORMAL 0
|
|
|
|
#define VTY_PRE_ESCAPE 1
|
|
|
|
#define VTY_ESCAPE 2
|
|
|
|
|
|
|
|
/* Escape character command map. */
|
|
|
|
static void
|
|
|
|
vty_escape_map (unsigned char c, struct vty *vty)
|
|
|
|
{
|
|
|
|
switch (c)
|
|
|
|
{
|
|
|
|
case ('A'):
|
|
|
|
vty_previous_line (vty);
|
|
|
|
break;
|
|
|
|
case ('B'):
|
|
|
|
vty_next_line (vty);
|
|
|
|
break;
|
|
|
|
case ('C'):
|
|
|
|
vty_forward_char (vty);
|
|
|
|
break;
|
|
|
|
case ('D'):
|
|
|
|
vty_backward_char (vty);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Go back to normal mode. */
|
|
|
|
vty->escape = VTY_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Quit print out to the buffer. */
|
|
|
|
static void
|
|
|
|
vty_buffer_reset (struct vty *vty)
|
|
|
|
{
|
|
|
|
buffer_reset (vty->obuf);
|
|
|
|
vty_prompt (vty);
|
|
|
|
vty_redraw_line (vty);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read data via vty socket. */
|
|
|
|
static int
|
|
|
|
vty_read (struct thread *thread)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int nbytes;
|
|
|
|
unsigned char buf[VTY_READ_BUFSIZ];
|
|
|
|
|
|
|
|
int vty_sock = THREAD_FD (thread);
|
|
|
|
struct vty *vty = THREAD_ARG (thread);
|
|
|
|
vty->t_read = NULL;
|
|
|
|
|
|
|
|
/* Read raw data from socket */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
if ((nbytes = read (vty->fd, buf, VTY_READ_BUFSIZ)) <= 0)
|
|
|
|
{
|
|
|
|
if (nbytes < 0)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
if (ERRNO_IO_RETRY(errno))
|
|
|
|
{
|
|
|
|
vty_event (VTY_READ, vty_sock, vty);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
|
|
|
|
zlog_warn("%s: read error on vty client fd %d, closing: %s",
|
|
|
|
__func__, vty->fd, safe_strerror(errno));
|
2015-05-14 14:24:06 +02:00
|
|
|
buffer_reset(vty->obuf);
|
2016-09-20 01:46:51 +02:00
|
|
|
}
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
vty->status = VTY_CLOSE;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-20 01:46:51 +02:00
|
|
|
for (i = 0; i < nbytes; i++)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if (buf[i] == IAC)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
if (!vty->iac)
|
|
|
|
{
|
|
|
|
vty->iac = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vty->iac = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (vty->iac_sb_in_progress && !vty->iac)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
if (vty->sb_len < sizeof(vty->sb_buf))
|
|
|
|
vty->sb_buf[vty->sb_len] = buf[i];
|
|
|
|
vty->sb_len++;
|
|
|
|
continue;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (vty->iac)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
/* In case of telnet command */
|
|
|
|
int ret = 0;
|
|
|
|
ret = vty_telnet_option (vty, buf + i, nbytes - i);
|
|
|
|
vty->iac = 0;
|
|
|
|
i += ret;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (vty->status == VTY_MORE)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
switch (buf[i])
|
|
|
|
{
|
|
|
|
case CONTROL('C'):
|
|
|
|
case 'q':
|
|
|
|
case 'Q':
|
|
|
|
vty_buffer_reset (vty);
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
#if 0 /* More line does not work for "show ip bgp". */
|
2016-09-20 01:46:51 +02:00
|
|
|
case '\n':
|
|
|
|
case '\r':
|
|
|
|
vty->status = VTY_MORELINE;
|
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif
|
2016-09-20 01:46:51 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Escape character. */
|
|
|
|
if (vty->escape == VTY_ESCAPE)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
vty_escape_map (buf[i], vty);
|
|
|
|
continue;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Pre-escape status. */
|
|
|
|
if (vty->escape == VTY_PRE_ESCAPE)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
switch (buf[i])
|
|
|
|
{
|
|
|
|
case '[':
|
|
|
|
vty->escape = VTY_ESCAPE;
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
vty_backward_word (vty);
|
|
|
|
vty->escape = VTY_NORMAL;
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
vty_forward_word (vty);
|
|
|
|
vty->escape = VTY_NORMAL;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
vty_forward_kill_word (vty);
|
|
|
|
vty->escape = VTY_NORMAL;
|
|
|
|
break;
|
|
|
|
case CONTROL('H'):
|
|
|
|
case 0x7f:
|
|
|
|
vty_backward_kill_word (vty);
|
|
|
|
vty->escape = VTY_NORMAL;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
vty->escape = VTY_NORMAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
switch (buf[i])
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
case CONTROL('A'):
|
|
|
|
vty_beginning_of_line (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('B'):
|
|
|
|
vty_backward_char (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('C'):
|
|
|
|
vty_stop_input (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('D'):
|
|
|
|
vty_delete_char (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('E'):
|
|
|
|
vty_end_of_line (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('F'):
|
|
|
|
vty_forward_char (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('H'):
|
|
|
|
case 0x7f:
|
|
|
|
vty_delete_backward_char (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('K'):
|
|
|
|
vty_kill_line (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('N'):
|
|
|
|
vty_next_line (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('P'):
|
|
|
|
vty_previous_line (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('T'):
|
|
|
|
vty_transpose_chars (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('U'):
|
|
|
|
vty_kill_line_from_beginning (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('W'):
|
|
|
|
vty_backward_kill_word (vty);
|
|
|
|
break;
|
|
|
|
case CONTROL('Z'):
|
|
|
|
vty_end_config (vty);
|
|
|
|
break;
|
|
|
|
case '\n':
|
|
|
|
case '\r':
|
|
|
|
vty_out (vty, "%s", VTY_NEWLINE);
|
|
|
|
vty_execute (vty);
|
|
|
|
break;
|
|
|
|
case '\t':
|
|
|
|
vty_complete_command (vty);
|
|
|
|
break;
|
|
|
|
case '?':
|
|
|
|
if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
|
|
|
|
vty_self_insert (vty, buf[i]);
|
|
|
|
else
|
|
|
|
vty_describe_command (vty);
|
|
|
|
break;
|
|
|
|
case '\033':
|
|
|
|
if (i + 1 < nbytes && buf[i + 1] == '[')
|
|
|
|
{
|
|
|
|
vty->escape = VTY_ESCAPE;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
vty->escape = VTY_PRE_ESCAPE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (buf[i] > 31 && buf[i] < 127)
|
|
|
|
vty_self_insert (vty, buf[i]);
|
|
|
|
break;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Check status. */
|
|
|
|
if (vty->status == VTY_CLOSE)
|
|
|
|
vty_close (vty);
|
|
|
|
else
|
|
|
|
{
|
2013-05-30 16:31:49 +02:00
|
|
|
vty_event (VTY_WRITE, vty->wfd, vty);
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_event (VTY_READ, vty_sock, vty);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Flush buffer to the vty. */
|
|
|
|
static int
|
|
|
|
vty_flush (struct thread *thread)
|
|
|
|
{
|
|
|
|
int erase;
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
buffer_status_t flushrc;
|
2002-12-13 21:15:29 +01:00
|
|
|
int vty_sock = THREAD_FD (thread);
|
|
|
|
struct vty *vty = THREAD_ARG (thread);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
vty->t_write = NULL;
|
|
|
|
|
|
|
|
/* Tempolary disable read thread. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
if ((vty->lines == 0) && vty->t_read)
|
|
|
|
{
|
|
|
|
thread_cancel (vty->t_read);
|
|
|
|
vty->t_read = NULL;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Function execution continue. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
erase = ((vty->status == VTY_MORE || vty->status == VTY_MORELINE));
|
|
|
|
|
|
|
|
/* N.B. if width is 0, that means we don't know the window size. */
|
2016-01-12 19:41:49 +01:00
|
|
|
if ((vty->lines == 0) || (vty->width == 0) || (vty->height == 0))
|
2013-05-30 16:31:49 +02:00
|
|
|
flushrc = buffer_flush_available(vty->obuf, vty_sock);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
else if (vty->status == VTY_MORELINE)
|
2013-05-30 16:31:49 +02:00
|
|
|
flushrc = buffer_flush_window(vty->obuf, vty_sock, vty->width,
|
2016-09-20 01:46:51 +02:00
|
|
|
1, erase, 0);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
else
|
2013-05-30 16:31:49 +02:00
|
|
|
flushrc = buffer_flush_window(vty->obuf, vty_sock, vty->width,
|
2016-09-20 01:46:51 +02:00
|
|
|
vty->lines >= 0 ? vty->lines :
|
|
|
|
vty->height,
|
|
|
|
erase, 0);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
switch (flushrc)
|
|
|
|
{
|
|
|
|
case BUFFER_ERROR:
|
2006-07-10 20:09:42 +02:00
|
|
|
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
zlog_warn("buffer_flush failed on vty client fd %d, closing",
|
2016-09-20 01:46:51 +02:00
|
|
|
vty->fd);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
buffer_reset(vty->obuf);
|
|
|
|
vty_close(vty);
|
|
|
|
return 0;
|
|
|
|
case BUFFER_EMPTY:
|
|
|
|
if (vty->status == VTY_CLOSE)
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_close (vty);
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
vty->status = VTY_NORMAL;
|
|
|
|
if (vty->lines == 0)
|
|
|
|
vty_event (VTY_READ, vty_sock, vty);
|
|
|
|
}
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
break;
|
|
|
|
case BUFFER_PENDING:
|
|
|
|
/* There is more data waiting to be written. */
|
|
|
|
vty->status = VTY_MORE;
|
|
|
|
if (vty->lines == 0)
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_event (VTY_WRITE, vty_sock, vty);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
break;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-05-30 16:33:45 +02:00
|
|
|
/* allocate and initialise vty */
|
|
|
|
static struct vty *
|
|
|
|
vty_new_init (int vty_sock)
|
|
|
|
{
|
|
|
|
struct vty *vty;
|
|
|
|
|
|
|
|
vty = vty_new ();
|
|
|
|
vty->fd = vty_sock;
|
|
|
|
vty->wfd = vty_sock;
|
|
|
|
vty->type = VTY_TERM;
|
|
|
|
vty->node = AUTH_NODE;
|
|
|
|
vty->fail = 0;
|
|
|
|
vty->cp = 0;
|
|
|
|
vty_clear_buf (vty);
|
|
|
|
vty->length = 0;
|
|
|
|
memset (vty->hist, 0, sizeof (vty->hist));
|
|
|
|
vty->hp = 0;
|
|
|
|
vty->hindex = 0;
|
|
|
|
vector_set_index (vtyvec, vty_sock, vty);
|
|
|
|
vty->status = VTY_NORMAL;
|
|
|
|
vty->lines = -1;
|
|
|
|
vty->iac = 0;
|
|
|
|
vty->iac_sb_in_progress = 0;
|
|
|
|
vty->sb_len = 0;
|
|
|
|
|
|
|
|
return vty;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Create new vty structure. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static struct vty *
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_create (int vty_sock, union sockunion *su)
|
|
|
|
{
|
2012-04-10 16:57:23 +02:00
|
|
|
char buf[SU_ADDRSTRLEN];
|
2002-12-13 21:15:29 +01:00
|
|
|
struct vty *vty;
|
|
|
|
|
2012-04-10 16:57:23 +02:00
|
|
|
sockunion2str(su, buf, SU_ADDRSTRLEN);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Allocate new vty structure and set up default values. */
|
2013-05-30 16:33:45 +02:00
|
|
|
vty = vty_new_init (vty_sock);
|
|
|
|
|
|
|
|
/* configurable parameters not part of basic init */
|
|
|
|
vty->v_timeout = vty_timeout_val;
|
2012-04-10 16:57:23 +02:00
|
|
|
strcpy (vty->address, buf);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (no_password_check)
|
|
|
|
{
|
2016-03-11 20:27:11 +01:00
|
|
|
if (host.advanced)
|
2016-09-20 01:46:51 +02:00
|
|
|
vty->node = ENABLE_NODE;
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2016-09-20 01:46:51 +02:00
|
|
|
vty->node = VIEW_NODE;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
if (host.lines >= 0)
|
|
|
|
vty->lines = host.lines;
|
|
|
|
|
|
|
|
if (! no_password_check)
|
|
|
|
{
|
|
|
|
/* Vty is not available if password isn't set. */
|
|
|
|
if (host.password == NULL && host.password_encrypt == NULL)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
vty_out (vty, "Vty password is not set.%s", VTY_NEWLINE);
|
|
|
|
vty->status = VTY_CLOSE;
|
|
|
|
vty_close (vty);
|
|
|
|
return NULL;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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);
|
|
|
|
|
|
|
|
/* Setting up terminal. */
|
|
|
|
vty_will_echo (vty);
|
|
|
|
vty_will_suppress_go_ahead (vty);
|
|
|
|
|
|
|
|
vty_dont_linemode (vty);
|
|
|
|
vty_do_window_size (vty);
|
|
|
|
/* vty_dont_lflow_ahead (vty); */
|
|
|
|
|
|
|
|
vty_prompt (vty);
|
|
|
|
|
|
|
|
/* Add read/write thread. */
|
|
|
|
vty_event (VTY_WRITE, vty_sock, vty);
|
|
|
|
vty_event (VTY_READ, vty_sock, vty);
|
|
|
|
|
|
|
|
return vty;
|
|
|
|
}
|
|
|
|
|
2013-05-30 16:33:45 +02:00
|
|
|
/* create vty for stdio */
|
2015-05-05 11:04:46 +02:00
|
|
|
static struct termios stdio_orig_termios;
|
|
|
|
static struct vty *stdio_vty = NULL;
|
2015-05-12 21:56:18 +02:00
|
|
|
static void (*stdio_vty_atclose)(void);
|
2015-05-05 11:04:46 +02:00
|
|
|
|
|
|
|
static void
|
|
|
|
vty_stdio_reset (void)
|
|
|
|
{
|
|
|
|
if (stdio_vty)
|
|
|
|
{
|
|
|
|
tcsetattr (0, TCSANOW, &stdio_orig_termios);
|
|
|
|
stdio_vty = NULL;
|
2015-05-12 21:56:18 +02:00
|
|
|
|
|
|
|
if (stdio_vty_atclose)
|
|
|
|
stdio_vty_atclose ();
|
|
|
|
stdio_vty_atclose = NULL;
|
2015-05-05 11:04:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-30 16:33:45 +02:00
|
|
|
struct vty *
|
2015-05-12 21:56:18 +02:00
|
|
|
vty_stdio (void (*atclose)())
|
2013-05-30 16:33:45 +02:00
|
|
|
{
|
|
|
|
struct vty *vty;
|
2015-05-05 11:04:46 +02:00
|
|
|
struct termios termios;
|
2013-05-30 16:33:45 +02:00
|
|
|
|
2015-05-05 11:04:46 +02:00
|
|
|
/* refuse creating two vtys on stdio */
|
|
|
|
if (stdio_vty)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
vty = stdio_vty = vty_new_init (0);
|
2015-05-12 21:56:18 +02:00
|
|
|
stdio_vty_atclose = atclose;
|
2013-05-30 16:33:45 +02:00
|
|
|
vty->wfd = 1;
|
|
|
|
|
|
|
|
/* always have stdio vty in a known _unchangeable_ state, don't want config
|
|
|
|
* to have any effect here to make sure scripting this works as intended */
|
|
|
|
vty->node = ENABLE_NODE;
|
|
|
|
vty->v_timeout = 0;
|
|
|
|
strcpy (vty->address, "console");
|
|
|
|
|
2015-05-05 11:04:46 +02:00
|
|
|
if (!tcgetattr (0, &stdio_orig_termios))
|
|
|
|
{
|
|
|
|
termios = stdio_orig_termios;
|
|
|
|
termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
|
|
|
|
| INLCR | IGNCR | ICRNL | IXON);
|
|
|
|
termios.c_oflag &= ~OPOST;
|
|
|
|
termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
|
|
|
|
termios.c_cflag &= ~(CSIZE | PARENB);
|
|
|
|
termios.c_cflag |= CS8;
|
|
|
|
tcsetattr (0, TCSANOW, &termios);
|
|
|
|
}
|
|
|
|
|
2013-05-30 16:33:45 +02:00
|
|
|
vty_prompt (vty);
|
|
|
|
|
|
|
|
/* Add read/write thread. */
|
|
|
|
vty_event (VTY_WRITE, 1, vty);
|
|
|
|
vty_event (VTY_READ, 0, vty);
|
|
|
|
|
|
|
|
return vty;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Accept connection from the network. */
|
|
|
|
static int
|
|
|
|
vty_accept (struct thread *thread)
|
|
|
|
{
|
|
|
|
int vty_sock;
|
|
|
|
union sockunion su;
|
|
|
|
int ret;
|
|
|
|
unsigned int on;
|
|
|
|
int accept_sock;
|
2015-05-22 12:40:57 +02:00
|
|
|
struct prefix p;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct access_list *acl = NULL;
|
2012-04-10 16:57:23 +02:00
|
|
|
char buf[SU_ADDRSTRLEN];
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
accept_sock = THREAD_FD (thread);
|
|
|
|
|
|
|
|
/* We continue hearing vty socket. */
|
|
|
|
vty_event (VTY_SERV, accept_sock, NULL);
|
|
|
|
|
|
|
|
memset (&su, 0, sizeof (union sockunion));
|
|
|
|
|
|
|
|
/* We can handle IPv4 or IPv6 socket. */
|
|
|
|
vty_sock = sockunion_accept (accept_sock, &su);
|
|
|
|
if (vty_sock < 0)
|
|
|
|
{
|
2004-11-20 03:06:59 +01:00
|
|
|
zlog_warn ("can't accept vty socket : %s", safe_strerror (errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
set_nonblocking(vty_sock);
|
2016-11-08 20:46:05 +01:00
|
|
|
set_cloexec(vty_sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2015-05-22 12:40:57 +02:00
|
|
|
sockunion2hostprefix (&su, &p);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* VTY's accesslist apply. */
|
2015-05-22 12:40:57 +02:00
|
|
|
if (p.family == AF_INET && vty_accesslist_name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if ((acl = access_list_lookup (AFI_IP, vty_accesslist_name)) &&
|
2016-09-20 01:46:51 +02:00
|
|
|
(access_list_apply (acl, &p) == FILTER_DENY))
|
|
|
|
{
|
|
|
|
zlog (NULL, LOG_INFO, "Vty connection refused from %s",
|
|
|
|
sockunion2str (&su, buf, SU_ADDRSTRLEN));
|
|
|
|
close (vty_sock);
|
|
|
|
|
|
|
|
/* continue accepting connections */
|
|
|
|
vty_event (VTY_SERV, accept_sock, NULL);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* VTY's ipv6 accesslist apply. */
|
2015-05-22 12:40:57 +02:00
|
|
|
if (p.family == AF_INET6 && vty_ipv6_accesslist_name)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
if ((acl = access_list_lookup (AFI_IP6, vty_ipv6_accesslist_name)) &&
|
2016-09-20 01:46:51 +02:00
|
|
|
(access_list_apply (acl, &p) == FILTER_DENY))
|
|
|
|
{
|
|
|
|
zlog (NULL, LOG_INFO, "Vty connection refused from %s",
|
|
|
|
sockunion2str (&su, buf, SU_ADDRSTRLEN));
|
|
|
|
close (vty_sock);
|
|
|
|
|
|
|
|
/* continue accepting connections */
|
|
|
|
vty_event (VTY_SERV, accept_sock, NULL);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
on = 1;
|
2016-09-20 01:46:51 +02:00
|
|
|
ret = setsockopt (vty_sock, IPPROTO_TCP, TCP_NODELAY,
|
|
|
|
(char *) &on, sizeof (on));
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret < 0)
|
2016-09-20 01:46:51 +02:00
|
|
|
zlog (NULL, LOG_INFO, "can't set sockopt to vty_sock : %s",
|
|
|
|
safe_strerror (errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2009-12-07 14:41:14 +01:00
|
|
|
zlog (NULL, LOG_INFO, "Vty connection from %s",
|
2016-09-20 01:46:51 +02:00
|
|
|
sockunion2str (&su, buf, SU_ADDRSTRLEN));
|
2009-12-07 14:41:14 +01:00
|
|
|
|
2011-12-18 16:43:40 +01:00
|
|
|
vty_create (vty_sock, &su);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_serv_sock_addrinfo (const char *hostname, unsigned short port)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct addrinfo req;
|
|
|
|
struct addrinfo *ainfo;
|
|
|
|
struct addrinfo *ainfo_save;
|
|
|
|
int sock;
|
|
|
|
char port_str[BUFSIZ];
|
|
|
|
|
|
|
|
memset (&req, 0, sizeof (struct addrinfo));
|
|
|
|
req.ai_flags = AI_PASSIVE;
|
|
|
|
req.ai_family = AF_UNSPEC;
|
|
|
|
req.ai_socktype = SOCK_STREAM;
|
|
|
|
sprintf (port_str, "%d", port);
|
|
|
|
port_str[sizeof (port_str) - 1] = '\0';
|
|
|
|
|
|
|
|
ret = getaddrinfo (hostname, port_str, &req, &ainfo);
|
|
|
|
|
|
|
|
if (ret != 0)
|
|
|
|
{
|
|
|
|
fprintf (stderr, "getaddrinfo failed: %s\n", gai_strerror (ret));
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
ainfo_save = ainfo;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (ainfo->ai_family != AF_INET
|
2016-09-20 01:46:51 +02:00
|
|
|
&& ainfo->ai_family != AF_INET6
|
|
|
|
)
|
|
|
|
continue;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
sock = socket (ainfo->ai_family, ainfo->ai_socktype, ainfo->ai_protocol);
|
|
|
|
if (sock < 0)
|
2016-09-20 01:46:51 +02:00
|
|
|
continue;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2009-10-04 16:21:49 +02:00
|
|
|
sockopt_v6only (ainfo->ai_family, sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
sockopt_reuseaddr (sock);
|
|
|
|
sockopt_reuseport (sock);
|
2016-11-08 20:46:05 +01:00
|
|
|
set_cloexec (sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen);
|
|
|
|
if (ret < 0)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
close (sock); /* Avoid sd leak. */
|
|
|
|
continue;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
ret = listen (sock, 3);
|
2016-09-20 01:46:51 +02:00
|
|
|
if (ret < 0)
|
|
|
|
{
|
|
|
|
close (sock); /* Avoid sd leak. */
|
|
|
|
continue;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty_event (VTY_SERV, sock, NULL);
|
|
|
|
}
|
|
|
|
while ((ainfo = ainfo->ai_next) != NULL);
|
|
|
|
|
|
|
|
freeaddrinfo (ainfo_save);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VTYSH
|
|
|
|
/* For sockaddr_un. */
|
|
|
|
#include <sys/un.h>
|
|
|
|
|
|
|
|
/* VTY shell UNIX domain socket. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
2004-10-07 21:33:46 +02:00
|
|
|
vty_serv_un (const char *path)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
int ret;
|
2004-10-31 03:13:09 +01:00
|
|
|
int sock, len;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct sockaddr_un serv;
|
|
|
|
mode_t old_mask;
|
2003-06-04 15:59:38 +02:00
|
|
|
struct zprivs_ids_t ids;
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* First of all, unlink existing socket */
|
|
|
|
unlink (path);
|
|
|
|
|
|
|
|
/* Set umask */
|
2003-05-23 10:12:36 +02:00
|
|
|
old_mask = umask (0007);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Make UNIX domain socket. */
|
|
|
|
sock = socket (AF_UNIX, SOCK_STREAM, 0);
|
|
|
|
if (sock < 0)
|
|
|
|
{
|
2005-01-30 19:49:28 +01:00
|
|
|
zlog_err("Cannot create unix stream socket: %s", safe_strerror(errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make server socket. */
|
|
|
|
memset (&serv, 0, sizeof (struct sockaddr_un));
|
|
|
|
serv.sun_family = AF_UNIX;
|
2017-02-10 15:04:06 +01:00
|
|
|
strlcpy (serv.sun_path, path, sizeof (serv.sun_path));
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
2002-12-13 21:15:29 +01:00
|
|
|
len = serv.sun_len = SUN_LEN(&serv);
|
|
|
|
#else
|
|
|
|
len = sizeof (serv.sun_family) + strlen (serv.sun_path);
|
[autoconf] bugs 162,303,178: Fix 'present but can not be compiled' warnings
2007-05-09 Paul Jakma <paul.jakma@sun.com>
* configure.ac: sys/conf.h depends on sys/param.h, at least on
FBSD 6.2.
(bug #363) Should check for in_pktinfo for IRDP
2006-05-27 Paul Jakma <paul.jakma@sun.com>
* configure.ac: General cleanup of header and type checks, introducing
an internal define, QUAGGA_INCLUDES, to build up a list of
stuff to include so as to avoid 'present but cant be compiled'
warnings.
Misc additional checks of things missing according to autoscan.
Add LIBM, for bgpd's use of libm, so as to avoid burdening
LIBS, and all the binaries, with libm linkage.
Remove the bad practice of using m4 changequote(), just
quote the []'s in the case statements properly.
This should fix bugs 162, 303 and 178.
* */*.{c,h}: Update all HAVE_* to the standard autoconf namespaced
HAVE_* defines. I.e. HAVE_SA_LEN -> HAVE_STRUCT_SOCKADDR_SA_LEN,
* bgpd/Makefile.am: Add LIBM to bgpd's LDADD, for pow().
2007-05-10 04:38:51 +02:00
|
|
|
#endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-11-08 20:46:05 +01:00
|
|
|
set_cloexec (sock);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
ret = bind (sock, (struct sockaddr *) &serv, len);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2005-01-30 19:49:28 +01:00
|
|
|
zlog_err("Cannot bind path %s: %s", path, safe_strerror(errno));
|
2016-09-20 01:46:51 +02:00
|
|
|
close (sock); /* Avoid sd leak. */
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = listen (sock, 5);
|
|
|
|
if (ret < 0)
|
|
|
|
{
|
2005-01-30 19:49:28 +01:00
|
|
|
zlog_err("listen(fd %d) failed: %s", sock, safe_strerror(errno));
|
2016-09-20 01:46:51 +02:00
|
|
|
close (sock); /* Avoid sd leak. */
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
umask (old_mask);
|
|
|
|
|
2003-06-04 15:59:38 +02:00
|
|
|
zprivs_get_ids(&ids);
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2017-01-20 20:48:45 +01:00
|
|
|
/* Hack: ids.gid_vty is actually a uint, but we stored -1 in it
|
|
|
|
earlier for the case when we don't need to chown the file
|
|
|
|
type casting it here to make a compare */
|
|
|
|
if ((int)ids.gid_vty > 0)
|
2003-06-04 15:59:38 +02:00
|
|
|
{
|
|
|
|
/* set group of socket */
|
|
|
|
if ( chown (path, -1, ids.gid_vty) )
|
|
|
|
{
|
|
|
|
zlog_err ("vty_serv_un: could chown socket, %s",
|
2004-11-20 03:06:59 +01:00
|
|
|
safe_strerror (errno) );
|
2003-06-04 15:59:38 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_event (VTYSH_SERV, sock, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* #define VTYSH_DEBUG 1 */
|
|
|
|
|
|
|
|
static int
|
|
|
|
vtysh_accept (struct thread *thread)
|
|
|
|
{
|
|
|
|
int accept_sock;
|
|
|
|
int sock;
|
|
|
|
int client_len;
|
|
|
|
struct sockaddr_un client;
|
|
|
|
struct vty *vty;
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
accept_sock = THREAD_FD (thread);
|
|
|
|
|
|
|
|
vty_event (VTYSH_SERV, accept_sock, NULL);
|
|
|
|
|
|
|
|
memset (&client, 0, sizeof (struct sockaddr_un));
|
|
|
|
client_len = sizeof (struct sockaddr_un);
|
|
|
|
|
2004-09-26 18:08:11 +02:00
|
|
|
sock = accept (accept_sock, (struct sockaddr *) &client,
|
2016-09-20 01:46:51 +02:00
|
|
|
(socklen_t *) &client_len);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (sock < 0)
|
|
|
|
{
|
2004-11-20 03:06:59 +01:00
|
|
|
zlog_warn ("can't accept vty socket : %s", safe_strerror (errno));
|
2002-12-13 21:15:29 +01:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
if (set_nonblocking(sock) < 0)
|
2004-10-31 03:13:09 +01:00
|
|
|
{
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
zlog_warn ("vtysh_accept: could not set vty socket %d to non-blocking,"
|
|
|
|
" %s, closing", sock, safe_strerror (errno));
|
2004-10-31 03:13:09 +01:00
|
|
|
close (sock);
|
|
|
|
return -1;
|
|
|
|
}
|
2016-11-08 20:46:05 +01:00
|
|
|
set_cloexec(sock);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
#ifdef VTYSH_DEBUG
|
|
|
|
printf ("VTY shell accept\n");
|
|
|
|
#endif /* VTYSH_DEBUG */
|
|
|
|
|
|
|
|
vty = vty_new ();
|
|
|
|
vty->fd = sock;
|
2013-05-30 16:31:49 +02:00
|
|
|
vty->wfd = sock;
|
2002-12-13 21:15:29 +01:00
|
|
|
vty->type = VTY_SHELL_SERV;
|
|
|
|
vty->node = VIEW_NODE;
|
|
|
|
|
|
|
|
vty_event (VTYSH_READ, sock, vty);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static int
|
|
|
|
vtysh_flush(struct vty *vty)
|
|
|
|
{
|
2013-05-30 16:31:49 +02:00
|
|
|
switch (buffer_flush_available(vty->obuf, vty->wfd))
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
{
|
|
|
|
case BUFFER_PENDING:
|
2013-05-30 16:31:49 +02:00
|
|
|
vty_event(VTYSH_WRITE, vty->wfd, vty);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
break;
|
|
|
|
case BUFFER_ERROR:
|
2006-07-10 20:09:42 +02:00
|
|
|
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
zlog_warn("%s: write error to fd %d, closing", __func__, vty->fd);
|
|
|
|
buffer_reset(vty->obuf);
|
|
|
|
vty_close(vty);
|
|
|
|
return -1;
|
|
|
|
break;
|
|
|
|
case BUFFER_EMPTY:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
static int
|
|
|
|
vtysh_read (struct thread *thread)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int sock;
|
|
|
|
int nbytes;
|
|
|
|
struct vty *vty;
|
|
|
|
unsigned char buf[VTY_READ_BUFSIZ];
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
unsigned char *p;
|
2002-12-13 21:15:29 +01:00
|
|
|
u_char header[4] = {0, 0, 0, 0};
|
|
|
|
|
|
|
|
sock = THREAD_FD (thread);
|
|
|
|
vty = THREAD_ARG (thread);
|
|
|
|
vty->t_read = NULL;
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
if ((nbytes = read (sock, buf, VTY_READ_BUFSIZ)) <= 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
if (nbytes < 0)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
if (ERRNO_IO_RETRY(errno))
|
|
|
|
{
|
|
|
|
vty_event (VTYSH_READ, sock, vty);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
vty->monitor = 0; /* disable monitoring to avoid infinite recursion */
|
|
|
|
zlog_warn("%s: read failed on vtysh client fd %d, closing: %s",
|
|
|
|
__func__, sock, safe_strerror(errno));
|
|
|
|
}
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
buffer_reset(vty->obuf);
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_close (vty);
|
|
|
|
#ifdef VTYSH_DEBUG
|
|
|
|
printf ("close vtysh\n");
|
|
|
|
#endif /* VTYSH_DEBUG */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef VTYSH_DEBUG
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
printf ("line: %.*s\n", nbytes, buf);
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif /* VTYSH_DEBUG */
|
|
|
|
|
2017-01-18 07:09:26 +01:00
|
|
|
if (vty->length + nbytes >= VTY_BUFSIZ)
|
2017-01-11 00:33:50 +01:00
|
|
|
{
|
|
|
|
/* Clear command line buffer. */
|
|
|
|
vty->cp = vty->length = 0;
|
|
|
|
vty_clear_buf (vty);
|
|
|
|
vty_out (vty, "%% Command is too long.%s", VTY_NEWLINE);
|
|
|
|
}
|
|
|
|
else
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
{
|
2017-01-11 00:33:50 +01:00
|
|
|
for (p = buf; p < buf+nbytes; p++)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
2017-01-11 00:33:50 +01:00
|
|
|
vty->buf[vty->length++] = *p;
|
|
|
|
if (*p == '\0')
|
|
|
|
{
|
|
|
|
/* Pass this line to parser. */
|
|
|
|
ret = vty_execute (vty);
|
|
|
|
/* Note that vty_execute clears the command buffer and resets
|
|
|
|
vty->length to 0. */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-01-11 00:33:50 +01:00
|
|
|
/* Return result. */
|
2002-12-13 21:15:29 +01:00
|
|
|
#ifdef VTYSH_DEBUG
|
2017-01-11 00:33:50 +01:00
|
|
|
printf ("result: %d\n", ret);
|
|
|
|
printf ("vtysh node: %d\n", vty->node);
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif /* VTYSH_DEBUG */
|
|
|
|
|
2017-01-11 00:33:50 +01:00
|
|
|
/* hack for asynchronous "write integrated"
|
|
|
|
* - other commands in "buf" will be ditched
|
|
|
|
* - input during pending config-write is "unsupported" */
|
|
|
|
if (ret == CMD_SUSPEND)
|
|
|
|
break;
|
2016-11-09 14:15:34 +01:00
|
|
|
|
2017-01-11 00:33:50 +01:00
|
|
|
/* warning: watchquagga hardcodes this result write */
|
|
|
|
header[3] = ret;
|
|
|
|
buffer_put(vty->obuf, header, 4);
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
|
2017-01-11 00:33:50 +01:00
|
|
|
if (!vty->t_write && (vtysh_flush(vty) < 0))
|
|
|
|
/* Try to flush results; exit if a write error occurs. */
|
|
|
|
return 0;
|
|
|
|
}
|
2016-09-20 01:46:51 +02:00
|
|
|
}
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty_event (VTYSH_READ, sock, vty);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2004-11-04 20:26:16 +01:00
|
|
|
|
|
|
|
static int
|
|
|
|
vtysh_write (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct vty *vty = THREAD_ARG (thread);
|
|
|
|
|
|
|
|
vty->t_write = NULL;
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
vtysh_flush(vty);
|
2004-11-10 16:40:09 +01:00
|
|
|
return 0;
|
2004-11-04 20:26:16 +01:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
#endif /* VTYSH */
|
|
|
|
|
|
|
|
/* Determine address family to bind. */
|
|
|
|
void
|
2004-10-07 21:33:46 +02:00
|
|
|
vty_serv_sock (const char *addr, unsigned short port, const char *path)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* If port is set to 0, do not listen on TCP/IP at all! */
|
|
|
|
if (port)
|
2017-01-13 13:57:57 +01:00
|
|
|
vty_serv_sock_addrinfo (addr, port);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#ifdef VTYSH
|
|
|
|
vty_serv_un (path);
|
|
|
|
#endif /* VTYSH */
|
|
|
|
}
|
|
|
|
|
2006-07-11 02:06:49 +02:00
|
|
|
/* Close vty interface. Warning: call this only from functions that
|
|
|
|
will be careful not to access the vty afterwards (since it has
|
|
|
|
now been freed). This is safest from top-level functions (called
|
|
|
|
directly by the thread dispatcher). */
|
2002-12-13 21:15:29 +01:00
|
|
|
void
|
|
|
|
vty_close (struct vty *vty)
|
|
|
|
{
|
|
|
|
int i;
|
2017-02-02 01:49:48 +01:00
|
|
|
bool was_stdio = false;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Cancel threads.*/
|
|
|
|
if (vty->t_read)
|
|
|
|
thread_cancel (vty->t_read);
|
|
|
|
if (vty->t_write)
|
|
|
|
thread_cancel (vty->t_write);
|
|
|
|
if (vty->t_timeout)
|
|
|
|
thread_cancel (vty->t_timeout);
|
|
|
|
|
|
|
|
/* Flush buffer. */
|
2013-05-30 16:31:49 +02:00
|
|
|
buffer_flush_all (vty->obuf, vty->wfd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Free input buffer. */
|
|
|
|
buffer_free (vty->obuf);
|
|
|
|
|
|
|
|
/* Free command history. */
|
|
|
|
for (i = 0; i < VTY_MAXHIST; i++)
|
|
|
|
if (vty->hist[i])
|
|
|
|
XFREE (MTYPE_VTY_HIST, vty->hist[i]);
|
|
|
|
|
|
|
|
/* Unset vector. */
|
|
|
|
vector_unset (vtyvec, vty->fd);
|
|
|
|
|
2017-02-08 16:14:10 +01:00
|
|
|
if (vty->wfd > 0 && vty->type == VTY_FILE)
|
|
|
|
fsync (vty->wfd);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Close socket. */
|
|
|
|
if (vty->fd > 0)
|
2017-02-08 16:14:10 +01:00
|
|
|
{
|
|
|
|
close (vty->fd);
|
|
|
|
if (vty->wfd > 0 && vty->wfd != vty->fd)
|
|
|
|
close (vty->wfd);
|
|
|
|
}
|
2015-05-05 11:04:46 +02:00
|
|
|
else
|
2017-01-26 22:09:37 +01:00
|
|
|
was_stdio = true;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (vty->buf)
|
|
|
|
XFREE (MTYPE_VTY, vty->buf);
|
|
|
|
|
2015-07-28 05:30:22 +02:00
|
|
|
if (vty->error_buf)
|
|
|
|
XFREE (MTYPE_VTY, vty->error_buf);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check configure. */
|
|
|
|
vty_config_unlock (vty);
|
|
|
|
|
|
|
|
/* OK free vty. */
|
|
|
|
XFREE (MTYPE_VTY, vty);
|
2017-01-26 22:09:37 +01:00
|
|
|
|
|
|
|
if (was_stdio)
|
|
|
|
vty_stdio_reset ();
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* When time out occur output message then close connection. */
|
|
|
|
static int
|
|
|
|
vty_timeout (struct thread *thread)
|
|
|
|
{
|
|
|
|
struct vty *vty;
|
|
|
|
|
|
|
|
vty = THREAD_ARG (thread);
|
|
|
|
vty->t_timeout = NULL;
|
|
|
|
vty->v_timeout = 0;
|
|
|
|
|
|
|
|
/* Clear buffer*/
|
|
|
|
buffer_reset (vty->obuf);
|
|
|
|
vty_out (vty, "%sVty connection is timed out.%s", VTY_NEWLINE, VTY_NEWLINE);
|
|
|
|
|
|
|
|
/* Close connection. */
|
|
|
|
vty->status = VTY_CLOSE;
|
|
|
|
vty_close (vty);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read up configuration file from file_name. */
|
|
|
|
static void
|
|
|
|
vty_read_file (FILE *confp)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct vty *vty;
|
2009-07-28 22:36:14 +02:00
|
|
|
unsigned int line_num = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty = vty_new ();
|
2013-05-30 16:31:49 +02:00
|
|
|
vty->wfd = dup(STDERR_FILENO); /* vty_close() will close this */
|
|
|
|
if (vty->wfd < 0)
|
2009-07-28 22:36:14 +02:00
|
|
|
{
|
|
|
|
/* Fine, we couldn't make a new fd. vty_close doesn't close stdout. */
|
2013-05-30 16:31:49 +02:00
|
|
|
vty->wfd = STDOUT_FILENO;
|
2009-07-28 22:36:14 +02:00
|
|
|
}
|
2013-05-30 16:31:49 +02:00
|
|
|
vty->fd = STDIN_FILENO;
|
2009-07-28 22:36:14 +02:00
|
|
|
vty->type = VTY_FILE;
|
2002-12-13 21:15:29 +01:00
|
|
|
vty->node = CONFIG_NODE;
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Execute configuration file */
|
2009-07-28 22:36:14 +02:00
|
|
|
ret = config_from_file (vty, confp, &line_num);
|
|
|
|
|
|
|
|
/* Flush any previous errors before printing messages below */
|
|
|
|
buffer_flush_all (vty->obuf, vty->fd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-09-20 01:46:51 +02:00
|
|
|
if ( !((ret == CMD_SUCCESS) || (ret == CMD_ERR_NOTHING_TODO)) )
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2016-10-06 20:39:31 +02:00
|
|
|
const char *message = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (ret)
|
2003-07-15 14:52:22 +02:00
|
|
|
{
|
|
|
|
case CMD_ERR_AMBIGUOUS:
|
2016-10-06 20:39:31 +02:00
|
|
|
message = "*** Error reading config: Ambiguous command.";
|
2003-07-15 14:52:22 +02:00
|
|
|
break;
|
|
|
|
case CMD_ERR_NO_MATCH:
|
2016-10-06 20:39:31 +02:00
|
|
|
message = "*** Error reading config: There is no such command.";
|
2003-07-15 14:52:22 +02:00
|
|
|
break;
|
|
|
|
}
|
2016-10-06 20:39:31 +02:00
|
|
|
fprintf (stderr, "%s\n", message);
|
|
|
|
zlog_err ("%s", message);
|
|
|
|
fprintf (stderr, "*** Error occurred processing line %u, below:\n%s\n",
|
2016-09-20 01:46:51 +02:00
|
|
|
line_num, vty->error_buf);
|
2016-10-06 20:39:31 +02:00
|
|
|
zlog_err ("*** Error occurred processing line %u, below:\n%s",
|
|
|
|
line_num, vty->error_buf);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
vty_close (vty);
|
|
|
|
}
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static FILE *
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_use_backup_config (char *fullpath)
|
|
|
|
{
|
|
|
|
char *fullpath_sav, *fullpath_tmp;
|
|
|
|
FILE *ret = NULL;
|
|
|
|
int tmp, sav;
|
|
|
|
int c;
|
|
|
|
char buffer[512];
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
fullpath_sav = malloc (strlen (fullpath) + strlen (CONF_BACKUP_EXT) + 1);
|
|
|
|
strcpy (fullpath_sav, fullpath);
|
|
|
|
strcat (fullpath_sav, CONF_BACKUP_EXT);
|
2017-02-10 15:04:40 +01:00
|
|
|
|
|
|
|
sav = open (fullpath_sav, O_RDONLY);
|
|
|
|
if (sav < 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
free (fullpath_sav);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
fullpath_tmp = malloc (strlen (fullpath) + 8);
|
|
|
|
sprintf (fullpath_tmp, "%s.XXXXXX", fullpath);
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Open file to configuration write. */
|
|
|
|
tmp = mkstemp (fullpath_tmp);
|
|
|
|
if (tmp < 0)
|
2017-02-10 15:04:40 +01:00
|
|
|
goto out_close_sav;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-02-10 15:04:40 +01:00
|
|
|
if (fchmod (tmp, CONFIGFILE_MASK) != 0)
|
|
|
|
goto out_close;
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
while((c = read (sav, buffer, 512)) > 0)
|
2015-09-25 01:57:36 +02:00
|
|
|
{
|
|
|
|
if (write (tmp, buffer, c) <= 0)
|
2017-02-10 15:04:40 +01:00
|
|
|
goto out_close;
|
2015-09-25 01:57:36 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
close (sav);
|
|
|
|
close (tmp);
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2017-02-10 15:04:40 +01:00
|
|
|
if (rename (fullpath_tmp, fullpath) == 0)
|
|
|
|
ret = fopen (fullpath, "r");
|
|
|
|
else
|
|
|
|
unlink (fullpath_tmp);
|
|
|
|
|
|
|
|
if (0)
|
2003-12-22 21:15:53 +01:00
|
|
|
{
|
2017-02-10 15:04:40 +01:00
|
|
|
out_close:
|
|
|
|
close (tmp);
|
2003-12-22 21:18:18 +01:00
|
|
|
unlink (fullpath_tmp);
|
2017-02-10 15:04:40 +01:00
|
|
|
out_close_sav:
|
|
|
|
close (sav);
|
2003-12-22 21:15:53 +01:00
|
|
|
}
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
free (fullpath_sav);
|
|
|
|
free (fullpath_tmp);
|
2005-03-07 09:35:39 +01:00
|
|
|
return ret;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Read up configuration file from file_name. */
|
|
|
|
void
|
|
|
|
vty_read_config (char *config_file,
|
2004-06-20 21:54:37 +02:00
|
|
|
char *config_default_dir)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-10-22 04:49:38 +02:00
|
|
|
char cwd[MAXPATHLEN];
|
2002-12-13 21:15:29 +01:00
|
|
|
FILE *confp = NULL;
|
|
|
|
char *fullpath;
|
2005-10-26 07:49:54 +02:00
|
|
|
char *tmp = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* If -f flag specified. */
|
|
|
|
if (config_file != NULL)
|
|
|
|
{
|
|
|
|
if (! IS_DIRECTORY_SEP (config_file[0]))
|
2004-06-20 21:54:37 +02:00
|
|
|
{
|
2015-09-25 01:57:36 +02:00
|
|
|
if (getcwd (cwd, MAXPATHLEN) == NULL)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
fprintf (stderr, "Failure to determine Current Working Directory %d!\n", errno);
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
tmp = XMALLOC (MTYPE_TMP,
|
|
|
|
strlen (cwd) + strlen (config_file) + 2);
|
2005-10-26 07:49:54 +02:00
|
|
|
sprintf (tmp, "%s/%s", cwd, config_file);
|
|
|
|
fullpath = tmp;
|
2004-06-20 21:54:37 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2004-06-20 21:54:37 +02:00
|
|
|
fullpath = config_file;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
confp = fopen (fullpath, "r");
|
|
|
|
|
|
|
|
if (confp == NULL)
|
2004-06-20 21:54:37 +02:00
|
|
|
{
|
2005-04-05 02:45:23 +02:00
|
|
|
fprintf (stderr, "%s: failed to open configuration file %s: %s\n",
|
|
|
|
__func__, fullpath, safe_strerror (errno));
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2004-06-20 21:54:37 +02:00
|
|
|
confp = vty_use_backup_config (fullpath);
|
|
|
|
if (confp)
|
|
|
|
fprintf (stderr, "WARNING: using backup configuration file!\n");
|
|
|
|
else
|
|
|
|
{
|
2016-09-20 01:46:51 +02:00
|
|
|
fprintf (stderr, "can't open configuration file [%s]\n",
|
|
|
|
config_file);
|
2004-06-20 21:54:37 +02:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-05-20 03:29:18 +02:00
|
|
|
|
2015-05-21 01:55:57 +02:00
|
|
|
host_config_set (config_default_dir);
|
2015-05-20 03:29:18 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
#ifdef VTYSH
|
2004-06-20 21:54:37 +02:00
|
|
|
int ret;
|
|
|
|
struct stat conf_stat;
|
|
|
|
|
|
|
|
/* !!!!PLEASE LEAVE!!!!
|
|
|
|
* This is NEEDED for use with vtysh -b, or else you can get
|
|
|
|
* a real configuration food fight with a lot garbage in the
|
|
|
|
* merged configuration file it creates coming from the per
|
|
|
|
* daemon configuration files. This also allows the daemons
|
|
|
|
* to start if there default configuration file is not
|
|
|
|
* present or ignore them, as needed when using vtysh -b to
|
|
|
|
* configure the daemons at boot - MAG
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Stat for vtysh Zebra.conf, if found startup and wait for
|
|
|
|
* boot configuration
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ( strstr(config_default_dir, "vtysh") == NULL)
|
|
|
|
{
|
|
|
|
ret = stat (integrate_default, &conf_stat);
|
|
|
|
if (ret >= 0)
|
2016-09-20 01:46:51 +02:00
|
|
|
goto tmp_free_and_out;
|
2004-06-20 21:54:37 +02:00
|
|
|
}
|
2015-05-20 03:29:18 +02:00
|
|
|
#endif /* VTYSH */
|
2015-05-21 01:55:57 +02:00
|
|
|
confp = fopen (config_default_dir, "r");
|
|
|
|
if (confp == NULL)
|
|
|
|
{
|
|
|
|
fprintf (stderr, "%s: failed to open configuration file %s: %s\n",
|
|
|
|
__func__, config_default_dir, safe_strerror (errno));
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2015-05-21 01:55:57 +02:00
|
|
|
confp = vty_use_backup_config (config_default_dir);
|
|
|
|
if (confp)
|
|
|
|
{
|
|
|
|
fprintf (stderr, "WARNING: using backup configuration file!\n");
|
|
|
|
fullpath = config_default_dir;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fprintf (stderr, "can't open configuration file [%s]\n",
|
2016-09-20 01:46:51 +02:00
|
|
|
config_default_dir);
|
|
|
|
goto tmp_free_and_out;
|
2015-05-21 01:55:57 +02:00
|
|
|
}
|
2016-09-20 01:46:51 +02:00
|
|
|
}
|
2015-05-21 01:55:57 +02:00
|
|
|
else
|
|
|
|
fullpath = config_default_dir;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_read_file (confp);
|
|
|
|
|
|
|
|
fclose (confp);
|
|
|
|
|
|
|
|
host_config_set (fullpath);
|
2016-03-07 20:57:16 +01:00
|
|
|
|
|
|
|
tmp_free_and_out:
|
2005-10-26 07:49:54 +02:00
|
|
|
if (tmp)
|
|
|
|
XFREE (MTYPE_TMP, fullpath);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Small utility function which output log to the VTY. */
|
|
|
|
void
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
vty_log (const char *level, const char *proto_str,
|
2016-09-20 01:46:51 +02:00
|
|
|
const char *format, struct timestamp_control *ctl, va_list va)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2004-10-05 23:01:23 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct vty *vty;
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2006-05-28 10:18:38 +02:00
|
|
|
if (!vtyvec)
|
|
|
|
return;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (vtyvec); i++)
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((vty = vector_slot (vtyvec, i)) != NULL)
|
|
|
|
if (vty->monitor)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
va_list ac;
|
|
|
|
va_copy(ac, va);
|
|
|
|
vty_log_out (vty, level, proto_str, format, ctl, ac);
|
|
|
|
va_end(ac);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
/* Async-signal-safe version of vty_log for fixed strings. */
|
|
|
|
void
|
2015-05-20 03:04:26 +02:00
|
|
|
vty_log_fixed (char *buf, size_t len)
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
{
|
|
|
|
unsigned int i;
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
struct iovec iov[2];
|
2015-05-20 03:04:26 +02:00
|
|
|
char crlf[4] = "\r\n";
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
|
2006-05-28 10:18:38 +02:00
|
|
|
/* vty may not have been initialised */
|
|
|
|
if (!vtyvec)
|
|
|
|
return;
|
2016-09-20 01:46:51 +02:00
|
|
|
|
Fix most compiler warnings in default GCC build.
Fix lots of warnings. Some const and type-pun breaks strict-aliasing
warnings left but much reduced.
* bgp_advertise.h: (struct bgp_advertise_fifo) is functionally identical to
(struct fifo), so just use that. Makes it clearer the beginning of
(struct bgp_advertise) is compatible with with (struct fifo), which seems
to be enough for gcc.
Add a BGP_ADV_FIFO_HEAD macro to contain the right cast to try shut up
type-punning breaks strict aliasing warnings.
* bgp_packet.c: Use BGP_ADV_FIFO_HEAD.
(bgp_route_refresh_receive) fix an interesting logic error in
(!ok || (ret != BLAH)) where ret is only well-defined if ok.
* bgp_vty.c: Peer commands should use bgp_vty_return to set their return.
* jhash.{c,h}: Can take const on * args without adding issues & fix warnings.
* libospf.h: LSA sequence numbers use the unsigned range of values, and
constants need to be set to unsigned, or it causes warnings in ospf6d.
* md5.h: signedness of caddr_t is implementation specific, change to an
explicit (uint_8 *), fix sign/unsigned comparison warnings.
* vty.c: (vty_log_fixed) const on level is well-intentioned, but not going
to fly given iov_base.
* workqueue.c: ALL_LIST_ELEMENTS_RO tests for null pointer, which is always
true for address of static variable. Correct but pointless warning in
this case, but use a 2nd pointer to shut it up.
* ospf6_route.h: Add a comment about the use of (struct prefix) to stuff 2
different 32 bit IDs into in (struct ospf6_route), and the resulting
type-pun strict-alias breakage warnings this causes. Need to use 2
different fields to fix that warning?
general:
* remove unused variables, other than a few cases where they serve a
sufficiently useful documentary purpose (e.g. for code that needs
fixing), or they're required dummies. In those cases, try mark them as
unused.
* Remove dead code that can't be reached.
* Quite a few 'no ...' forms of vty commands take arguments, but do not
check the argument matches the command being negated. E.g., should
'distance X <prefix>' succeed if previously 'distance Y <prefix>' was set?
Or should it be required that the distance match the previously configured
distance for the prefix?
Ultimately, probably better to be strict about this. However, changing
from slack to strict might expose problems in command aliases and tools.
* Fix uninitialised use of variables.
* Fix sign/unsigned comparison warnings by making signedness of types consistent.
* Mark functions as static where their use is restricted to the same compilation
unit.
* Add required headers
* Move constants defined in headers into code.
* remove dead, unused functions that have no debug purpose.
(cherry picked from commit 7aa9dcef80b2ce50ecaa77653d87c8b84e009c49)
Conflicts:
bgpd/bgp_advertise.h
bgpd/bgp_mplsvpn.c
bgpd/bgp_nexthop.c
bgpd/bgp_packet.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
lib/command.c
lib/if.c
lib/jhash.c
lib/workqueue.c
ospf6d/ospf6_lsa.c
ospf6d/ospf6_neighbor.h
ospf6d/ospf6_spf.c
ospf6d/ospf6_top.c
ospfd/ospf_api.c
zebra/router-id.c
zebra/rt_netlink.c
zebra/rt_netlink.h
2014-09-19 15:42:23 +02:00
|
|
|
iov[0].iov_base = buf;
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
iov[0].iov_len = len;
|
2015-05-20 03:04:26 +02:00
|
|
|
iov[1].iov_base = crlf;
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
iov[1].iov_len = 2;
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (vtyvec); i++)
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
{
|
|
|
|
struct vty *vty;
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
if (((vty = vector_slot (vtyvec, i)) != NULL) && vty->monitor)
|
2016-09-20 01:46:51 +02:00
|
|
|
/* N.B. We don't care about the return code, since process is
|
|
|
|
most likely just about to die anyway. */
|
|
|
|
if (writev(vty->wfd, iov, 2) == -1)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Failure to writev: %d\n", errno);
|
|
|
|
exit(-1);
|
|
|
|
}
|
2004-12-07 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* bgp_main.c: (main) The 2nd argument to openzlog has been removed.
* isis_main.c: (main) The 2nd argument to openzlog has been removed.
* ospf6_main.c: (main) The 2nd argument to openzlog has been removed.
Note that stdout logging will no longer be enabled by default when
not running as a daemon.
* ospf_main.c: (main) The 2nd argument to openzlog has been removed.
* rip_main.c: (main) The 2nd argument to openzlog has been removed.
* ripng_main.c: (main) The 2nd argument to openzlog has been removed.
* main.c: (main) The 2nd argument to openzlog has been removed.
So stdout logging will no longer be enabled by default.
* irdp_main.c: (irdp_finish) Reduce severity of shutdown message
from LOG_WARNING to LOG_INFO.
* vtysh.c: Make several functions static instead of global.
Added several commands to support destination-specific logging levels.
(vtysh_completion) This function is unused, so comment it out.
* basic.texi: Document new logging features. Separate basic config
commands from basic VTY commands.
* log.h: Replace struct zlog flags and maskpri fields with maxlvl
array to support individual logging levels for each destination.
Remove the 2nd argument to openzlog since the default logging config
should be standardized inside the library. Replaced the
zlog_set_flag and zlog_reset_flag functions with zlog_set_level.
And zlog_set_file now requires an additional log_level argument.
Declare zlog_proto_names for use inside command.c in the
"show logging" command. Added defines useful for command
construction.
* log.c: (vzlog) Decide where to send the message based on the
individual logging levels configured for each destination.
Remove support for ZLOG_STDERR since it was never actually used.
Support record-priority for terminal monitors.
(zlog_signal,zlog_backtrace_sigsafe) Support destination-specific
logging levels. Remove stderr support (was never used). Added
support for terminal monitor logging.
(_zlog_assert_failed) Increase message severity to LOG_EMERG.
(openzlog) Remove 2nd argument since default config should be
standardized in library. By default, terminal monitoring
is set to debug, and all other logging is disabled.
(zlog_set_flag,zlog_reset_flag) Removed.
(zlog_set_level) New function to replace zlog_set_flag and
zlog_reset_flag. Supports destination-specific logging levels.
(zlog_set_file,zlog_reset_file) Support file-specific logging level.
(zlog_rotate) Log an error message if fopen fails, and support
new file-specific logging level.
* command.h: Change DEFUN_CMD_FUNC_DECL and DEFUN_CMD_FUNC_TEXT so that
command functions will be static instead of global. Remove
declarations for config_exit and config_help. Define new macros
DEFUNSH_ATTR, DEFUNSH_HIDDEN, and DEFUNSH_DEPRECATED so we can
have deprecated commands in vtysh. Similarly, for completeness,
define macros ALIAS_SH, ALIAS_SH_HIDDEN, and ALIAS_SH_DEPRECATED.
Also, fix bug in ALIAS_ATTR macro (didn't matter because it
was never used).
* command.c: Make many functions static instead of global.
(facility_name,facility_match,level_match) New functions
to support enhanced destination-specific logging levels.
(config_write_host) Support new destination-specific logging levels.
(config_logmsg) Added new "logmsg" command to help test logging
system.
(show_logging) Added "show logging" command to show the current
configuration of the logging system.
(config_log_stdout_level) Support explicit stdout logging level.
(no_config_log_stdout) Now takes optional LEVEL arg.
(config_log_monitor,config_log_monitor_level,no_config_log_monitor)
New commands creating new "log monitor" commands to set terminal
monitoring log level.
(config_log_file_level) Support explicit file logging level.
(config_log_syslog_level) Support explicit syslog logging level.
(config_log_facility,no_config_log_facility) Implement new
"log facility" command.
(cmd_init) Add hooks for new commands: "show logging", "logmsg",
"log stdout <level>", "log monitor", "log monitor <level>",
"no log monitor", "log file <filename> <level>",
"no log file <filename> <level>", "log syslog <level>",
"log facility", and "no log facility".
* vty.h: Added a "level" argument to vty_log so it can support
"log record-priority". Declare new function vty_log_fixed for
use in signal handlers.
* vty.c: (vty_log,vty_log_out) Added a "level" argument to support
"log record-priority" for vty terminal monitors.
(vty_down_level) Use config_exit_cmd.func instead of calling
config_exit directly (since command functions will now be static
instead of global).
(vty_log_fixed) New function to send terminal monitor messages
from inside a signal handler.
2004-12-07 16:39:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
int
|
|
|
|
vty_config_lock (struct vty *vty)
|
|
|
|
{
|
2016-09-27 16:53:25 +02:00
|
|
|
if (vty_config_is_lockless)
|
|
|
|
return 1;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (vty_config == 0)
|
|
|
|
{
|
|
|
|
vty->config = 1;
|
|
|
|
vty_config = 1;
|
|
|
|
}
|
|
|
|
return vty->config;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vty_config_unlock (struct vty *vty)
|
|
|
|
{
|
2016-09-27 16:53:25 +02:00
|
|
|
if (vty_config_is_lockless)
|
|
|
|
return 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (vty_config == 1 && vty->config == 1)
|
|
|
|
{
|
|
|
|
vty->config = 0;
|
|
|
|
vty_config = 0;
|
|
|
|
}
|
|
|
|
return vty->config;
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2016-09-27 16:53:25 +02:00
|
|
|
void
|
|
|
|
vty_config_lockless (void)
|
|
|
|
{
|
|
|
|
vty_config_is_lockless = 1;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Master of the threads. */
|
2015-10-13 20:37:15 +02:00
|
|
|
static struct thread_master *vty_master;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
static void
|
|
|
|
vty_event (enum event event, int sock, struct vty *vty)
|
|
|
|
{
|
|
|
|
struct thread *vty_serv_thread;
|
|
|
|
|
|
|
|
switch (event)
|
|
|
|
{
|
|
|
|
case VTY_SERV:
|
2015-10-13 20:37:15 +02:00
|
|
|
vty_serv_thread = thread_add_read (vty_master, vty_accept, vty, sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
vector_set_index (Vvty_serv_thread, sock, vty_serv_thread);
|
|
|
|
break;
|
|
|
|
#ifdef VTYSH
|
|
|
|
case VTYSH_SERV:
|
2015-10-13 20:37:15 +02:00
|
|
|
vty_serv_thread = thread_add_read (vty_master, vtysh_accept, vty, sock);
|
2013-02-27 14:47:23 +01:00
|
|
|
vector_set_index (Vvty_serv_thread, sock, vty_serv_thread);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case VTYSH_READ:
|
2015-10-13 20:37:15 +02:00
|
|
|
vty->t_read = thread_add_read (vty_master, vtysh_read, vty, sock);
|
2004-11-04 20:26:16 +01:00
|
|
|
break;
|
|
|
|
case VTYSH_WRITE:
|
2015-10-13 20:37:15 +02:00
|
|
|
vty->t_write = thread_add_write (vty_master, vtysh_write, vty, sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
#endif /* VTYSH */
|
|
|
|
case VTY_READ:
|
2015-10-13 20:37:15 +02:00
|
|
|
vty->t_read = thread_add_read (vty_master, vty_read, vty, sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Time out treatment. */
|
|
|
|
if (vty->v_timeout)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
if (vty->t_timeout)
|
|
|
|
thread_cancel (vty->t_timeout);
|
|
|
|
vty->t_timeout =
|
|
|
|
thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case VTY_WRITE:
|
|
|
|
if (! vty->t_write)
|
2016-09-20 01:46:51 +02:00
|
|
|
vty->t_write = thread_add_write (vty_master, vty_flush, vty, sock);
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
case VTY_TIMEOUT_RESET:
|
|
|
|
if (vty->t_timeout)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
thread_cancel (vty->t_timeout);
|
|
|
|
vty->t_timeout = NULL;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
if (vty->v_timeout)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
vty->t_timeout =
|
|
|
|
thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
DEFUN (config_who,
|
|
|
|
config_who_cmd,
|
|
|
|
"who",
|
|
|
|
"Display who is on vty\n")
|
|
|
|
{
|
2004-10-05 23:01:23 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct vty *v;
|
|
|
|
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (vtyvec); i++)
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((v = vector_slot (vtyvec, i)) != NULL)
|
|
|
|
vty_out (vty, "%svty[%d] connected from %s.%s",
|
2016-09-20 01:46:51 +02:00
|
|
|
v->config ? "*" : " ",
|
|
|
|
i, v->address, VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Move to vty configuration mode. */
|
|
|
|
DEFUN (line_vty,
|
|
|
|
line_vty_cmd,
|
|
|
|
"line vty",
|
|
|
|
"Configure a terminal line\n"
|
|
|
|
"Virtual terminal\n")
|
|
|
|
{
|
|
|
|
vty->node = VTY_NODE;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set time out value. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static int
|
2004-10-10 Paul Jakma <paul@dishone.st>
* version.h.in: (pid_output*) add const qualifier.
* command.h: Change DEFUN func to take const char *[] rather
than char **, to begin process of fixing compile warnings in lib/.
Nearly all other changes in this commit follow from this change.
* buffer.{c,h}: (buffer_write) pointer-arithmetic is gccism, take
const void * and cast an automatic const char *p to it.
(buffer_putstr) add const
* command.c: (zencrypt) const qualifier
(cmd_execute_command_real) ditto
(cmd_execute_command_strict) ditto
(config_log_file) ditto.
Fix leak of getcwd() returned string.
* memory.{c,h}: Add MTYPE_DISTRIBUTE_IFNAME for struct dist ifname.
* distribute.{c,h}: Update with const qualifier.
(distribute_free) use MTYPE_DISTRIBUTE_IFNAME
(distribute_lookup) Cast to char *, note that it's ok.
(distribute_hash_alloc) use MTYPE_DISTRIBUTE_IFNAME.
(distribute_get) Cast to char *, note that it's ok.
* filter.c: Update with const qualifier.
* if.{c,h}: ditto.
* if_rmap.{c,h}: ditto.
(if_rmap_lookup) Cast to char *, note that it's ok.
(if_rmap_get) ditto.
* log.{c,h}: Update with const qualifier.
* plist.{c,h}: ditto.
* routemap.{c,h}: ditto.
* smux.{c,h}: ditto. Fix some signed/unsigned comparisons.
* sockopt.c: (getsockopt_cmsg_data) add return for error case.
* vty.c: Update with const qualifier.
2004-10-10 13:56:56 +02:00
|
|
|
exec_timeout (struct vty *vty, const char *min_str, const char *sec_str)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
unsigned long timeout = 0;
|
|
|
|
|
|
|
|
/* min_str and sec_str are already checked by parser. So it must be
|
|
|
|
all digit string. */
|
|
|
|
if (min_str)
|
|
|
|
{
|
|
|
|
timeout = strtol (min_str, NULL, 10);
|
|
|
|
timeout *= 60;
|
|
|
|
}
|
|
|
|
if (sec_str)
|
|
|
|
timeout += strtol (sec_str, NULL, 10);
|
|
|
|
|
|
|
|
vty_timeout_val = timeout;
|
|
|
|
vty->v_timeout = timeout;
|
|
|
|
vty_event (VTY_TIMEOUT_RESET, 0, vty);
|
|
|
|
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (exec_timeout_min,
|
|
|
|
exec_timeout_min_cmd,
|
2016-09-22 22:17:48 +02:00
|
|
|
"exec-timeout (0-35791)",
|
2002-12-13 21:15:29 +01:00
|
|
|
"Set timeout value\n"
|
|
|
|
"Timeout value in minutes\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_number = 1;
|
|
|
|
return exec_timeout (vty, argv[idx_number]->arg, NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (exec_timeout_sec,
|
|
|
|
exec_timeout_sec_cmd,
|
2016-09-22 22:17:48 +02:00
|
|
|
"exec-timeout (0-35791) (0-2147483)",
|
2002-12-13 21:15:29 +01:00
|
|
|
"Set the EXEC timeout\n"
|
|
|
|
"Timeout in minutes\n"
|
|
|
|
"Timeout in seconds\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_number = 1;
|
|
|
|
int idx_number_2 = 2;
|
|
|
|
return exec_timeout (vty, argv[idx_number]->arg, argv[idx_number_2]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_exec_timeout,
|
|
|
|
no_exec_timeout_cmd,
|
|
|
|
"no exec-timeout",
|
|
|
|
NO_STR
|
|
|
|
"Set the EXEC timeout\n")
|
|
|
|
{
|
|
|
|
return exec_timeout (vty, NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set vty access class. */
|
|
|
|
DEFUN (vty_access_class,
|
|
|
|
vty_access_class_cmd,
|
|
|
|
"access-class WORD",
|
|
|
|
"Filter connections based on an IP access list\n"
|
|
|
|
"IP access list\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_word = 1;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (vty_accesslist_name)
|
|
|
|
XFREE(MTYPE_VTY, vty_accesslist_name);
|
|
|
|
|
2016-09-23 22:17:29 +02:00
|
|
|
vty_accesslist_name = XSTRDUP(MTYPE_VTY, argv[idx_word]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear vty access class. */
|
|
|
|
DEFUN (no_vty_access_class,
|
|
|
|
no_vty_access_class_cmd,
|
|
|
|
"no access-class [WORD]",
|
|
|
|
NO_STR
|
|
|
|
"Filter connections based on an IP access list\n"
|
|
|
|
"IP access list\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_word = 2;
|
|
|
|
const char *accesslist = (argc == 3) ? argv[idx_word]->arg : NULL;
|
2016-09-29 21:51:56 +02:00
|
|
|
if (! vty_accesslist_name || (argc == 3 && strcmp(vty_accesslist_name, accesslist)))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
vty_out (vty, "Access-class is not currently applied to vty%s",
|
2016-09-20 01:46:51 +02:00
|
|
|
VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
XFREE(MTYPE_VTY, vty_accesslist_name);
|
|
|
|
|
|
|
|
vty_accesslist_name = NULL;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Set vty access class. */
|
|
|
|
DEFUN (vty_ipv6_access_class,
|
|
|
|
vty_ipv6_access_class_cmd,
|
|
|
|
"ipv6 access-class WORD",
|
|
|
|
IPV6_STR
|
|
|
|
"Filter connections based on an IP access list\n"
|
|
|
|
"IPv6 access list\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_word = 2;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (vty_ipv6_accesslist_name)
|
|
|
|
XFREE(MTYPE_VTY, vty_ipv6_accesslist_name);
|
|
|
|
|
2016-09-23 22:17:29 +02:00
|
|
|
vty_ipv6_accesslist_name = XSTRDUP(MTYPE_VTY, argv[idx_word]->arg);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Clear vty access class. */
|
|
|
|
DEFUN (no_vty_ipv6_access_class,
|
|
|
|
no_vty_ipv6_access_class_cmd,
|
|
|
|
"no ipv6 access-class [WORD]",
|
|
|
|
NO_STR
|
|
|
|
IPV6_STR
|
|
|
|
"Filter connections based on an IP access list\n"
|
|
|
|
"IPv6 access list\n")
|
|
|
|
{
|
2016-09-23 22:17:29 +02:00
|
|
|
int idx_word = 3;
|
|
|
|
const char *accesslist = (argc == 4) ? argv[idx_word]->arg : NULL;
|
2016-09-22 22:17:48 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (! vty_ipv6_accesslist_name ||
|
2016-09-29 21:51:56 +02:00
|
|
|
(argc == 4 && strcmp(vty_ipv6_accesslist_name, accesslist)))
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
vty_out (vty, "IPv6 access-class is not currently applied to vty%s",
|
2016-09-20 01:46:51 +02:00
|
|
|
VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
return CMD_WARNING;
|
|
|
|
}
|
|
|
|
|
|
|
|
XFREE(MTYPE_VTY, vty_ipv6_accesslist_name);
|
|
|
|
|
|
|
|
vty_ipv6_accesslist_name = NULL;
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* vty login. */
|
|
|
|
DEFUN (vty_login,
|
|
|
|
vty_login_cmd,
|
|
|
|
"login",
|
|
|
|
"Enable password checking\n")
|
|
|
|
{
|
|
|
|
no_password_check = 0;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_vty_login,
|
|
|
|
no_vty_login_cmd,
|
|
|
|
"no login",
|
|
|
|
NO_STR
|
|
|
|
"Enable password checking\n")
|
|
|
|
{
|
|
|
|
no_password_check = 1;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (service_advanced_vty,
|
|
|
|
service_advanced_vty_cmd,
|
|
|
|
"service advanced-vty",
|
|
|
|
"Set up miscellaneous service\n"
|
|
|
|
"Enable advanced mode vty interface\n")
|
|
|
|
{
|
|
|
|
host.advanced = 1;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (no_service_advanced_vty,
|
|
|
|
no_service_advanced_vty_cmd,
|
|
|
|
"no service advanced-vty",
|
|
|
|
NO_STR
|
|
|
|
"Set up miscellaneous service\n"
|
|
|
|
"Enable advanced mode vty interface\n")
|
|
|
|
{
|
|
|
|
host.advanced = 0;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (terminal_monitor,
|
|
|
|
terminal_monitor_cmd,
|
|
|
|
"terminal monitor",
|
|
|
|
"Set terminal line parameters\n"
|
|
|
|
"Copy debug output to the current terminal line\n")
|
|
|
|
{
|
|
|
|
vty->monitor = 1;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFUN (terminal_no_monitor,
|
|
|
|
terminal_no_monitor_cmd,
|
|
|
|
"terminal no monitor",
|
|
|
|
"Set terminal line parameters\n"
|
|
|
|
NO_STR
|
|
|
|
"Copy debug output to the current terminal line\n")
|
|
|
|
{
|
|
|
|
vty->monitor = 0;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-09-23 22:08:47 +02:00
|
|
|
DEFUN (no_terminal_monitor,
|
2006-01-17 18:42:03 +01:00
|
|
|
no_terminal_monitor_cmd,
|
|
|
|
"no terminal monitor",
|
|
|
|
NO_STR
|
|
|
|
"Set terminal line parameters\n"
|
|
|
|
"Copy debug output to the current terminal line\n")
|
2016-09-23 22:08:47 +02:00
|
|
|
{
|
|
|
|
return terminal_no_monitor (self, vty, argc, argv);
|
|
|
|
}
|
|
|
|
|
2006-01-17 18:42:03 +01:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
DEFUN (show_history,
|
|
|
|
show_history_cmd,
|
|
|
|
"show history",
|
|
|
|
SHOW_STR
|
|
|
|
"Display the session command history\n")
|
|
|
|
{
|
|
|
|
int index;
|
|
|
|
|
|
|
|
for (index = vty->hindex + 1; index != vty->hindex;)
|
|
|
|
{
|
|
|
|
if (index == VTY_MAXHIST)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
index = 0;
|
|
|
|
continue;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (vty->hist[index] != NULL)
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, " %s%s", vty->hist[index], VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2016-05-17 18:19:51 +02:00
|
|
|
/* vty login. */
|
|
|
|
DEFUN (log_commands,
|
|
|
|
log_commands_cmd,
|
|
|
|
"log commands",
|
|
|
|
"Logging control\n"
|
|
|
|
"Log all commands (can't be unset without restart)\n")
|
|
|
|
{
|
|
|
|
do_log_commands = 1;
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Display current configuration. */
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_config_write (struct vty *vty)
|
|
|
|
{
|
|
|
|
vty_out (vty, "line vty%s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
if (vty_accesslist_name)
|
|
|
|
vty_out (vty, " access-class %s%s",
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_accesslist_name, VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (vty_ipv6_accesslist_name)
|
|
|
|
vty_out (vty, " ipv6 access-class %s%s",
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_ipv6_accesslist_name, VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* exec-timeout */
|
|
|
|
if (vty_timeout_val != VTY_TIMEOUT_DEFAULT)
|
2016-09-20 01:46:51 +02:00
|
|
|
vty_out (vty, " exec-timeout %ld %ld%s",
|
|
|
|
vty_timeout_val / 60,
|
|
|
|
vty_timeout_val % 60, VTY_NEWLINE);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* login */
|
|
|
|
if (no_password_check)
|
|
|
|
vty_out (vty, " no login%s", VTY_NEWLINE);
|
2016-05-17 18:19:51 +02:00
|
|
|
|
|
|
|
if (do_log_commands)
|
|
|
|
vty_out (vty, "log commands%s", VTY_NEWLINE);
|
2016-09-20 01:46:51 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
vty_out (vty, "!%s", VTY_NEWLINE);
|
|
|
|
|
|
|
|
return CMD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct cmd_node vty_node =
|
|
|
|
{
|
|
|
|
VTY_NODE,
|
|
|
|
"%s(config-line)# ",
|
2004-10-03 22:11:32 +02:00
|
|
|
1,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Reset all VTY status. */
|
|
|
|
void
|
|
|
|
vty_reset ()
|
|
|
|
{
|
2004-10-05 23:01:23 +02:00
|
|
|
unsigned int i;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct vty *vty;
|
|
|
|
struct thread *vty_serv_thread;
|
|
|
|
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (vtyvec); i++)
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((vty = vector_slot (vtyvec, i)) != NULL)
|
|
|
|
{
|
2016-09-20 01:46:51 +02:00
|
|
|
buffer_reset (vty->obuf);
|
|
|
|
vty->status = VTY_CLOSE;
|
|
|
|
vty_close (vty);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2005-03-14 21:19:01 +01:00
|
|
|
for (i = 0; i < vector_active (Vvty_serv_thread); i++)
|
2002-12-13 21:15:29 +01:00
|
|
|
if ((vty_serv_thread = vector_slot (Vvty_serv_thread, i)) != NULL)
|
|
|
|
{
|
2016-09-20 01:46:51 +02:00
|
|
|
thread_cancel (vty_serv_thread);
|
|
|
|
vector_slot (Vvty_serv_thread, i) = NULL;
|
2002-12-13 21:15:29 +01:00
|
|
|
close (i);
|
|
|
|
}
|
|
|
|
|
|
|
|
vty_timeout_val = VTY_TIMEOUT_DEFAULT;
|
|
|
|
|
|
|
|
if (vty_accesslist_name)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_VTY, vty_accesslist_name);
|
|
|
|
vty_accesslist_name = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vty_ipv6_accesslist_name)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_VTY, vty_ipv6_accesslist_name);
|
|
|
|
vty_ipv6_accesslist_name = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-02-23 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* buffer.h: Make the struct buffer and struct buffer_data structures
private by moving them inside buffer.c. Add comments for all
functions. Rename buffer_write as buffer_put (to be more consistent
with the buffer_putc and buffer_putstr functions). Declare a new
buffer_write function that is used to write data to a file descriptor
and/or add it to the buffer queue. Remove unused function
buffer_flush_vty_all. Create a new enum typedef buffer_status_t
to be used as the return code for all buffer_flush* functions
and buffer_write.
* buffer.c: The struct buffer and struct buffer_data declarations
are now private to this file. In conjunction with that, remove
some unnecessary fields: struct buffer (alloc, unused_head,
unused_tail, length), struct buffer_data (prev).
(buffer_data_new) Removed: functionality incorporated into buffer_add.
(buffer_data_free) Removed: use a macro BUFFER_DATA_FREE instead.
(buffer_new) Use calloc instead of malloc + memset(zero).
Supply an appropriate default size if the specified size is 0.
(buffer_free) Eliminate code duplication by calling buffer_reset to
free the contents of the buffer (and remove unused code related
to unused_head).
(buffer_empty,buffer_putc,buffer_putstr) Aesthetic change (make more
compact).
(buffer_reset) Use macro BUFFER_DATA_FREE. No need to set
alloc and length to 0 (these fields have been removed).
(buffer_add) Fix scope to be static. Call XMALLOC directly instead
of calling removed buffer_data_new function. Simplify the logic
(since it's now a singly-linked list instead of doubly-linked).
(buffer_write) Renamed to buffer_put. Change to void, since return
code of 1 was meaningless. No need to adjust length field, since
it has been removed.
(buffer_putw,buffer_flush,buffer_flush_vty_all,buffer_flush_vty)
Remove unused functions.
(buffer_flush_all) Rewrite using buffer_flush_available to eliminate
a possible failure mode if IOV_MAX is less than the number of buffers
on the queue.
(buffer_flush_window) Incorporate logic from buffer_flush_vty.
Log an error message if there is a writev error.
(buffer_flush_available) Be more paranoid: check for case where
buffer is already empty. Use new ERRNO_IO_RETRY macro, and use
new enum for return codes. Simplify deletion logic (since it's
now a singly-linked list).
(buffer_write) New function for use with non-blocking I/O.
* vty.h: Replace the struct vty sb_buffer field with a fixed-size
(5-character) sb_buf field and an sb_len field, since using
a struct buffer was inappropriate for this task. Add some useful
comments about telnet window size negotiation.
* vty.c: Include <arpa/telnet.h> (no longer included by zebra.h).
Remove VTY_OBUF_SIZE (instead use buffer_new default size).
Make telnet_backward_char and telnet_space_char static const.
(vty_out) Replace buffer_write with buffer_put.
(vty_log_out) Check for I/O errors. If fatal, close the vty session.
Consolidate 3 separate writes into a single write call.
(vty_will_echo,vty_command,vty_next_line,vty_previous_line,
vty_end_config,vty_describe_fold,vty_clear_buf,vty_serv_sock_addrinfo,
vty_serv_sock_family,vty_serv_un,vty_use_backup_config,exec_timeout,
vty_config_write,vty_save_cwd) Fix scope to static.
(vty_new) Let buffer_new use its default buffer size.
(vty_write) Fix signature: 2nd arg should be const char *.
Replaced buffer_write with buffer_put.
(vty_telnet_option) Fix minor bug (window height or width greater than
255 was broken). Use sb_buf and sb_len instead of removed sb_buffer
(which was being used improperly).
(vty_read) On error, use ERRNO_IO_RETRY to decide whether it's fatal.
If the error is fatal, call buffer_reset so vty_close does not attempt
to flush the data. Use new sb_buf and sb_len instead of sb_buffer
to store the SB negotiation string.
(vty_flush) When vty->lines is 0, call buffer_flush_available instead
of buffer_flush_window. Look at the return code from buffer_flush
to detect I/O errors (and in that case, log an error message and
close the vty).
(vty_create) Fix scope to static. Initialize sb_len to 0 instead
of creating sb_buffer.
(vty_accept) Set socket nonblocking.
(vtysh_accept) Use new set_nonblocking function instead of calling
fcntl directly.
(vtysh_flush) New function called from vtysh_read (after command
execution) and from vtysh_write. This flushes the buffer
and reacts appropriately to the return code (by closing the vty
or scheduling further flushes).
(vtysh_read) Check whether error is fatal using ERRNO_IO_RETRY.
If not, just try again later. Otherwise, call buffer_reset before
calling vty_close (to avoid trying to flush the buffer in vty_close).
Fix logic to allow case where a command does not arrive atomically
in a single read call by checking for the terminating NUL char.
(vtysh_write) Use new vtysh_flush helper function.
(vty_close) No need to call buffer_empty, just call buffer_flush_all
in any case (it will check whether the buffer is empty).
Do not free sb_buffer (since it has been removed).
(vty_log_fixed) Use writev instead of write.
* zebra.h: Do not include <arpa/telnet.h>, since this is used only
by lib/vty.c.
2005-02-23 16:12:34 +01:00
|
|
|
static void
|
|
|
|
vty_save_cwd (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2003-10-16 00:09:28 +02:00
|
|
|
char cwd[MAXPATHLEN];
|
2003-10-22 04:49:38 +02:00
|
|
|
char *c;
|
2003-10-16 00:09:28 +02:00
|
|
|
|
2003-10-22 04:49:38 +02:00
|
|
|
c = getcwd (cwd, MAXPATHLEN);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2003-10-22 04:49:38 +02:00
|
|
|
if (!c)
|
2003-10-16 00:09:28 +02:00
|
|
|
{
|
2015-09-25 01:57:36 +02:00
|
|
|
/*
|
|
|
|
* At this point if these go wrong, more than likely
|
|
|
|
* the whole world is coming down around us
|
|
|
|
* Hence not worrying about it too much.
|
|
|
|
*/
|
|
|
|
if (!chdir (SYSCONFDIR))
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
fprintf(stderr, "Failure to chdir to %s, errno: %d\n", SYSCONFDIR, errno);
|
|
|
|
exit(-1);
|
|
|
|
}
|
2015-09-25 01:57:36 +02:00
|
|
|
if (getcwd (cwd, MAXPATHLEN) == NULL)
|
2016-09-20 01:46:51 +02:00
|
|
|
{
|
|
|
|
fprintf(stderr, "Failure to getcwd, errno: %d\n", errno);
|
|
|
|
exit(-1);
|
|
|
|
}
|
2003-10-16 00:09:28 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
vty_cwd = XMALLOC (MTYPE_TMP, strlen (cwd) + 1);
|
|
|
|
strcpy (vty_cwd, cwd);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
|
|
|
vty_get_cwd ()
|
|
|
|
{
|
|
|
|
return vty_cwd;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vty_shell (struct vty *vty)
|
|
|
|
{
|
|
|
|
return vty->type == VTY_SHELL ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
vty_shell_serv (struct vty *vty)
|
|
|
|
{
|
|
|
|
return vty->type == VTY_SHELL_SERV ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
vty_init_vtysh ()
|
|
|
|
{
|
|
|
|
vtyvec = vector_init (VECTOR_MIN_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Install vty's own commands like `who' command. */
|
|
|
|
void
|
2003-06-15 03:28:29 +02:00
|
|
|
vty_init (struct thread_master *master_thread)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
/* For further configuration read, preserve current directory. */
|
|
|
|
vty_save_cwd ();
|
|
|
|
|
|
|
|
vtyvec = vector_init (VECTOR_MIN_SIZE);
|
|
|
|
|
2015-10-13 20:37:15 +02:00
|
|
|
vty_master = master_thread;
|
2003-06-15 03:28:29 +02:00
|
|
|
|
2015-05-05 11:04:46 +02:00
|
|
|
atexit (vty_stdio_reset);
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Initilize server thread vector. */
|
|
|
|
Vvty_serv_thread = vector_init (VECTOR_MIN_SIZE);
|
|
|
|
|
|
|
|
/* Install bgp top node. */
|
|
|
|
install_node (&vty_node, vty_config_write);
|
|
|
|
|
|
|
|
install_element (VIEW_NODE, &config_who_cmd);
|
|
|
|
install_element (VIEW_NODE, &show_history_cmd);
|
|
|
|
install_element (CONFIG_NODE, &line_vty_cmd);
|
|
|
|
install_element (CONFIG_NODE, &service_advanced_vty_cmd);
|
|
|
|
install_element (CONFIG_NODE, &no_service_advanced_vty_cmd);
|
|
|
|
install_element (CONFIG_NODE, &show_history_cmd);
|
2016-05-17 18:19:51 +02:00
|
|
|
install_element (CONFIG_NODE, &log_commands_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
install_element (ENABLE_NODE, &terminal_monitor_cmd);
|
|
|
|
install_element (ENABLE_NODE, &terminal_no_monitor_cmd);
|
2006-01-17 18:42:03 +01:00
|
|
|
install_element (ENABLE_NODE, &no_terminal_monitor_cmd);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
install_default (VTY_NODE);
|
|
|
|
install_element (VTY_NODE, &exec_timeout_min_cmd);
|
|
|
|
install_element (VTY_NODE, &exec_timeout_sec_cmd);
|
|
|
|
install_element (VTY_NODE, &no_exec_timeout_cmd);
|
|
|
|
install_element (VTY_NODE, &vty_access_class_cmd);
|
|
|
|
install_element (VTY_NODE, &no_vty_access_class_cmd);
|
|
|
|
install_element (VTY_NODE, &vty_login_cmd);
|
|
|
|
install_element (VTY_NODE, &no_vty_login_cmd);
|
|
|
|
install_element (VTY_NODE, &vty_ipv6_access_class_cmd);
|
|
|
|
install_element (VTY_NODE, &no_vty_ipv6_access_class_cmd);
|
|
|
|
}
|
[bgpd] Stability fixes including bugs 397, 492
I've spent the last several weeks working on stability fixes to bgpd.
These patches fix all of the numerous crashes, assertion failures, memory
leaks and memory stomping I could find. Valgrind was used extensively.
Added new function bgp_exit() to help catch problems. If "debug bgp" is
configured and bgpd exits with status of 0, statistics on remaining
lib/memory.c allocations are printed to stderr. It is my hope that other
developers will use this to stay on top of memory issues.
Example questionable exit:
bgpd: memstats: Current memory utilization in module LIB:
bgpd: memstats: Link List : 6
bgpd: memstats: Link Node : 5
bgpd: memstats: Hash : 8
bgpd: memstats: Hash Bucket : 2
bgpd: memstats: Hash Index : 8
bgpd: memstats: Work queue : 3
bgpd: memstats: Work queue item : 2
bgpd: memstats: Work queue name string : 3
bgpd: memstats: Current memory utilization in module BGP:
bgpd: memstats: BGP instance : 1
bgpd: memstats: BGP peer : 1
bgpd: memstats: BGP peer hostname : 1
bgpd: memstats: BGP attribute : 1
bgpd: memstats: BGP extra attributes : 1
bgpd: memstats: BGP aspath : 1
bgpd: memstats: BGP aspath str : 1
bgpd: memstats: BGP table : 24
bgpd: memstats: BGP node : 1
bgpd: memstats: BGP route : 1
bgpd: memstats: BGP synchronise : 8
bgpd: memstats: BGP Process queue : 1
bgpd: memstats: BGP node clear queue : 1
bgpd: memstats: NOTE: If configuration exists, utilization may be expected.
Example clean exit:
bgpd: memstats: No remaining tracked memory utilization.
This patch fixes bug #397: "Invalid free in bgp_announce_check()".
This patch fixes bug #492: "SIGBUS in bgpd/bgp_route.c:
bgp_clear_route_node()".
My apologies for not separating out these changes into individual patches.
The complexity of doing so boggled what is left of my brain. I hope this
is all still useful to the community.
This code has been production tested, in non-route-server-client mode, on
a linux 32-bit box and a 64-bit box.
Release/reset functions, used by bgp_exit(), added to:
bgpd/bgp_attr.c,h
bgpd/bgp_community.c,h
bgpd/bgp_dump.c,h
bgpd/bgp_ecommunity.c,h
bgpd/bgp_filter.c,h
bgpd/bgp_nexthop.c,h
bgpd/bgp_route.c,h
lib/routemap.c,h
File by file analysis:
* bgpd/bgp_aspath.c: Prevent re-use of ashash after it is released.
* bgpd/bgp_attr.c: #if removed uncalled cluster_dup().
* bgpd/bgp_clist.c,h: Allow community_list_terminate() to be called from
bgp_exit().
* bgpd/bgp_filter.c: Fix aslist->name use without allocation check, and
also fix memory leak.
* bgpd/bgp_main.c: Created bgp_exit() exit routine. This function frees
allocations made as part of bgpd initialization and, to some extent,
configuration. If "debug bgp" is configured, memory stats are printed
as described above.
* bgpd/bgp_nexthop.c: zclient_new() already allocates stream for
ibuf/obuf, so bgp_scan_init() shouldn't do it too. Also, made it so
zlookup is global so bgp_exit() can use it.
* bgpd/bgp_packet.c: bgp_capability_msg_parse() call to bgp_clear_route()
adjusted to use new BGP_CLEAR_ROUTE_NORMAL flag.
* bgpd/bgp_route.h: Correct reference counter "lock" to be signed.
bgp_clear_route() now accepts a bgp_clear_route_type of either
BGP_CLEAR_ROUTE_NORMAL or BGP_CLEAR_ROUTE_MY_RSCLIENT.
* bgpd/bgp_route.c:
- bgp_process_rsclient(): attr was being zero'ed and then
bgp_attr_extra_free() was being called with it, even though it was
never filled with valid data.
- bgp_process_rsclient(): Make sure rsclient->group is not NULL before
use.
- bgp_processq_del(): Add call to bgp_table_unlock().
- bgp_process(): Add call to bgp_table_lock().
- bgp_update_rsclient(): memset clearing of new_attr not needed since
declarationw with "= { 0 }" does it. memset was already commented
out.
- bgp_update_rsclient(): Fix screwed up misleading indentation.
- bgp_withdraw_rsclient(): Fix screwed up misleading indentation.
- bgp_clear_route_node(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT.
- bgp_clear_node_queue_del(): Add call to bgp_table_unlock() and also
free struct bgp_clear_node_queue used for work item.
- bgp_clear_node_complete(): Do peer_unlock() after BGP_EVENT_ADD() in
case peer is released by peer_unlock() call.
- bgp_clear_route_table(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT. Use
struct bgp_clear_node_queue to supply data to worker. Add call to
bgp_table_lock().
- bgp_clear_route(): Add support for BGP_CLEAR_ROUTE_NORMAL or
BGP_CLEAR_ROUTE_MY_RSCLIENT.
- bgp_clear_route_all(): Use BGP_CLEAR_ROUTE_NORMAL.
Bug 397 fixes:
- bgp_default_originate()
- bgp_announce_table()
* bgpd/bgp_table.h:
- struct bgp_table: Added reference count. Changed type of owner to be
"struct peer *" rather than "void *".
- struct bgp_node: Correct reference counter "lock" to be signed.
* bgpd/bgp_table.c:
- Added bgp_table reference counting.
- bgp_table_free(): Fixed cleanup code. Call peer_unlock() on owner if
set.
- bgp_unlock_node(): Added assertion.
- bgp_node_get(): Added call to bgp_lock_node() to code path that it was
missing from.
* bgpd/bgp_vty.c:
- peer_rsclient_set_vty(): Call peer_lock() as part of peer assignment
to owner. Handle failure gracefully.
- peer_rsclient_unset_vty(): Add call to bgp_clear_route() with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
* bgpd/bgp_zebra.c: Made it so zclient is global so bgp_exit() can use it.
* bgpd/bgpd.c:
- peer_lock(): Allow to be called when status is "Deleted".
- peer_deactivate(): Supply BGP_CLEAR_ROUTE_NORMAL purpose to
bgp_clear_route() call.
- peer_delete(): Common variable listnode pn. Fix bug in which rsclient
was only dealt with if not part of a peer group. Call
bgp_clear_route() for rsclient, if appropriate, and do so with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
- peer_group_get(): Use XSTRDUP() instead of strdup() for conf->host.
- peer_group_bind(): Call bgp_clear_route() for rsclient, and do so with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
- bgp_create(): Use XSTRDUP() instead of strdup() for peer_self->host.
- bgp_delete(): Delete peers before groups, rather than after. And then
rather than deleting rsclients, verify that there are none at this
point.
- bgp_unlock(): Add assertion.
- bgp_free(): Call bgp_table_finish() rather than doing XFREE() itself.
* lib/command.c,h: Compiler warning fixes. Add cmd_terminate(). Fixed
massive leak in install_element() in which cmd_make_descvec() was being
called more than once for the same cmd->strvec/string/doc.
* lib/log.c: Make closezlog() check fp before calling fclose().
* lib/memory.c: Catch when alloc count goes negative by using signed
counts. Correct #endif comment. Add log_memstats_stderr().
* lib/memory.h: Add log_memstats_stderr().
* lib/thread.c: thread->funcname was being accessed in thread_call() after
it had been freed. Rearranged things so that thread_call() frees
funcname. Also made it so thread_master_free() cleans up cpu_record.
* lib/vty.c,h: Use global command_cr. Add vty_terminate().
* lib/zclient.c,h: Re-enable zclient_free().
2009-07-18 07:44:03 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
vty_terminate (void)
|
|
|
|
{
|
|
|
|
if (vty_cwd)
|
|
|
|
XFREE (MTYPE_TMP, vty_cwd);
|
|
|
|
|
|
|
|
if (vtyvec && Vvty_serv_thread)
|
|
|
|
{
|
|
|
|
vty_reset ();
|
|
|
|
vector_free (vtyvec);
|
|
|
|
vector_free (Vvty_serv_thread);
|
|
|
|
}
|
|
|
|
}
|
2016-03-01 19:31:28 +01:00
|
|
|
|
|
|
|
/* Utility functions to get arguments from commands generated
|
|
|
|
by the xml2cli.pl script. */
|
|
|
|
const char *
|
|
|
|
vty_get_arg_value (struct vty_arg *args[], const char *arg)
|
|
|
|
{
|
|
|
|
while (*args)
|
|
|
|
{
|
|
|
|
if (strcmp ((*args)->name, arg) == 0)
|
|
|
|
return (*args)->value;
|
|
|
|
args++;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct vty_arg *
|
|
|
|
vty_get_arg (struct vty_arg *args[], const char *arg)
|
|
|
|
{
|
|
|
|
while (*args)
|
|
|
|
{
|
|
|
|
if (strcmp ((*args)->name, arg) == 0)
|
|
|
|
return *args;
|
|
|
|
args++;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|