aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2010-05-19 19:45:32 +0200
committerHarald Welte <laforge@gnumonks.org>2010-05-25 23:40:38 +0200
commit4b037e4117c0c1e02a516c8b3374444f438c70e1 (patch)
treec2c02920c333c33f728b4d3dbe63a45635b1b61b
parent4f1e81543abea8cfb6b55c09e342831863d7a134 (diff)
Migrate VTY code to libosmovty
-rw-r--r--openbsc/configure.in2
-rw-r--r--openbsc/include/Makefile.am2
-rw-r--r--openbsc/include/openbsc/Makefile.am2
-rw-r--r--openbsc/include/openbsc/debug.h3
-rw-r--r--openbsc/include/openbsc/gb_proxy.h2
-rw-r--r--openbsc/include/openbsc/telnet_interface.h40
-rw-r--r--openbsc/include/openbsc/vty.h4
-rw-r--r--openbsc/include/vty/Makefile.am1
-rw-r--r--openbsc/include/vty/buffer.h102
-rw-r--r--openbsc/include/vty/command.h390
-rw-r--r--openbsc/include/vty/vector.h64
-rw-r--r--openbsc/include/vty/vty.h151
-rw-r--r--openbsc/src/Makefile.am11
-rw-r--r--openbsc/src/bsc_hack.c2
-rw-r--r--openbsc/src/bsc_init.c2
-rw-r--r--openbsc/src/bsc_vty.c9
-rw-r--r--openbsc/src/common_vty.c52
-rw-r--r--openbsc/src/gprs/Makefile.am4
-rw-r--r--openbsc/src/gprs/gb_proxy.c2
-rw-r--r--openbsc/src/gprs/gb_proxy_main.c4
-rw-r--r--openbsc/src/gprs/gb_proxy_vty.c4
-rw-r--r--openbsc/src/gprs/gprs_bssgp_vty.c7
-rw-r--r--openbsc/src/gprs/gprs_llc_vty.c4
-rw-r--r--openbsc/src/gprs/gprs_ns_vty.c7
-rw-r--r--openbsc/src/gprs/osmo_sgsn.cfg4
-rw-r--r--openbsc/src/gprs/sgsn_main.c3
-rw-r--r--openbsc/src/gprs/sgsn_vty.c4
-rw-r--r--openbsc/src/logging_vty.c345
-rw-r--r--openbsc/src/mgcp/mgcp_main.c4
-rw-r--r--openbsc/src/mgcp/mgcp_vty.c4
-rw-r--r--openbsc/src/telnet_interface.c203
-rw-r--r--openbsc/src/vty/buffer.c463
-rw-r--r--openbsc/src/vty/command.c3211
-rw-r--r--openbsc/src/vty/utils.c50
-rw-r--r--openbsc/src/vty/vector.c192
-rw-r--r--openbsc/src/vty/vty.c1685
-rw-r--r--openbsc/src/vty_interface_layer3.c6
37 files changed, 97 insertions, 6948 deletions
diff --git a/openbsc/configure.in b/openbsc/configure.in
index 0f4836379..552f4f0c1 100644
--- a/openbsc/configure.in
+++ b/openbsc/configure.in
@@ -23,6 +23,7 @@ AC_SEARCH_LIBS(gtp_new, gtp,
AM_CONDITIONAL(HAVE_LIBGTP, test "x$GPRS_LIBGTP" != "x")
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.6)
+PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.1.6)
dnl checks for header files
AC_HEADER_STDC
@@ -48,7 +49,6 @@ AC_OUTPUT(
openbsc.pc
libsccp.pc
include/openbsc/Makefile
- include/vty/Makefile
include/sccp/Makefile
include/Makefile
src/Makefile
diff --git a/openbsc/include/Makefile.am b/openbsc/include/Makefile.am
index 56b2a338a..a4acc23b2 100644
--- a/openbsc/include/Makefile.am
+++ b/openbsc/include/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = openbsc vty sccp
+SUBDIRS = openbsc sccp
noinst_HEADERS = mISDNif.h compat_af_isdn.h
diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am
index 5abc4ddd0..416e907d1 100644
--- a/openbsc/include/openbsc/Makefile.am
+++ b/openbsc/include/openbsc/Makefile.am
@@ -1,6 +1,6 @@
noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
gsm_subscriber.h gsm_04_11.h debug.h signal.h \
- misdn.h chan_alloc.h telnet_interface.h paging.h \
+ misdn.h chan_alloc.h paging.h \
subchan_demux.h trau_frame.h e1_input.h trau_mux.h \
ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
diff --git a/openbsc/include/openbsc/debug.h b/openbsc/include/openbsc/debug.h
index de1e2e2c6..203aedb83 100644
--- a/openbsc/include/openbsc/debug.h
+++ b/openbsc/include/openbsc/debug.h
@@ -45,9 +45,6 @@ enum {
#define BSC_CTX_NSVC 4
#define BSC_CTX_BVC 5
-#define LOGGING_STR "Configure log message to this terminal\n"
-#define FILTER_STR "Filter log messages\n"
-
/* target */
enum {
diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h
index ed1ac2de2..18ded2295 100644
--- a/openbsc/include/openbsc/gb_proxy.h
+++ b/openbsc/include/openbsc/gb_proxy.h
@@ -6,7 +6,7 @@
#include <osmocore/msgb.h>
#include <openbsc/gprs_ns.h>
-#include <vty/command.h>
+#include <osmocom/vty/command.h>
struct gbproxy_config {
/* parsed from config file */
diff --git a/openbsc/include/openbsc/telnet_interface.h b/openbsc/include/openbsc/telnet_interface.h
deleted file mode 100644
index 5a3e17930..000000000
--- a/openbsc/include/openbsc/telnet_interface.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* minimalistic telnet/network interface it might turn into a wire interface */
-/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * All Rights Reserved
- *
- * This program 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 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#ifndef TELNET_INTERFACE_H
-#define TELNET_INTERFACE_H
-
-#include <osmocore/logging.h>
-#include <osmocore/select.h>
-
-#include <vty/vty.h>
-
-struct telnet_connection {
- struct llist_head entry;
- void *priv;
- struct bsc_fd fd;
- struct vty *vty;
- struct log_target *dbg;
-};
-
-
-int telnet_init(void *tall_ctx, void *priv, int port);
-
-#endif
diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h
index 2adbded0d..26e7d5e4d 100644
--- a/openbsc/include/openbsc/vty.h
+++ b/openbsc/include/openbsc/vty.h
@@ -1,8 +1,8 @@
#ifndef OPENBSC_VTY_H
#define OPENBSC_VTY_H
-#include <vty/vty.h>
-#include <vty/buffer.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/buffer.h>
struct gsm_network;
struct vty;
diff --git a/openbsc/include/vty/Makefile.am b/openbsc/include/vty/Makefile.am
deleted file mode 100644
index 167476630..000000000
--- a/openbsc/include/vty/Makefile.am
+++ /dev/null
@@ -1 +0,0 @@
-noinst_HEADERS = buffer.h command.h vector.h vty.h
diff --git a/openbsc/include/vty/buffer.h b/openbsc/include/vty/buffer.h
deleted file mode 100644
index c9467a91d..000000000
--- a/openbsc/include/vty/buffer.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Buffering to output and input.
- * Copyright (C) 1998 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 02111-1307, USA.
- */
-
-#ifndef _ZEBRA_BUFFER_H
-#define _ZEBRA_BUFFER_H
-
-#include <sys/types.h>
-
-/* Create a new buffer. Memory will be allocated in chunks of the given
- size. If the argument is 0, the library will supply a reasonable
- default size suitable for buffering socket I/O. */
-struct buffer *buffer_new(void *ctx, size_t);
-
-/* Free all data in the buffer. */
-void buffer_reset(struct buffer *);
-
-/* This function first calls buffer_reset to release all buffered data.
- Then it frees the struct buffer itself. */
-void buffer_free(struct buffer *);
-
-/* Add the given data to the end of the buffer. */
-extern void buffer_put(struct buffer *, const void *, size_t);
-/* Add a single character to the end of the buffer. */
-extern void buffer_putc(struct buffer *, u_char);
-/* Add a NUL-terminated string to the end of the buffer. */
-extern void buffer_putstr(struct buffer *, const char *);
-
-/* Combine all accumulated (and unflushed) data inside the buffer into a
- single NUL-terminated string allocated using XMALLOC(MTYPE_TMP). Note
- that this function does not alter the state of the buffer, so the data
- is still inside waiting to be flushed. */
-char *buffer_getstr(struct buffer *);
-
-/* Returns 1 if there is no pending data in the buffer. Otherwise returns 0. */
-int buffer_empty(struct buffer *);
-
-typedef enum {
- /* An I/O error occurred. The buffer should be destroyed and the
- file descriptor should be closed. */
- BUFFER_ERROR = -1,
-
- /* The data was written successfully, and the buffer is now empty
- (there is no pending data waiting to be flushed). */
- BUFFER_EMPTY = 0,
-
- /* There is pending data in the buffer waiting to be flushed. Please
- try flushing the buffer when select indicates that the file descriptor
- is writeable. */
- BUFFER_PENDING = 1
-} buffer_status_t;
-
-/* Try to write this data to the file descriptor. Any data that cannot
- be written immediately is added to the buffer queue. */
-extern buffer_status_t buffer_write(struct buffer *, int fd,
- const void *, size_t);
-
-/* This function attempts to flush some (but perhaps not all) of
- the queued data to the given file descriptor. */
-extern buffer_status_t buffer_flush_available(struct buffer *, int fd);
-
-/* The following 2 functions (buffer_flush_all and buffer_flush_window)
- are for use in lib/vty.c only. They should not be used elsewhere. */
-
-/* Call buffer_flush_available repeatedly until either all data has been
- flushed, or an I/O error has been encountered, or the operation would
- block. */
-extern buffer_status_t buffer_flush_all(struct buffer *, int fd);
-
-/* Attempt to write enough data to the given fd to fill a window of the
- given width and height (and remove the data written from the buffer).
-
- If !no_more, then a message saying " --More-- " is appended.
- If erase is true, then first overwrite the previous " --More-- " message
- with spaces.
-
- Any write error (including EAGAIN or EINTR) will cause this function
- to return -1 (because the logic for handling the erase and more features
- is too complicated to retry the write later).
-*/
-extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width,
- int height, int erase, int no_more);
-
-#endif /* _ZEBRA_BUFFER_H */
diff --git a/openbsc/include/vty/command.h b/openbsc/include/vty/command.h
deleted file mode 100644
index 252a22d5e..000000000
--- a/openbsc/include/vty/command.h
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Zebra configuration command 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 02111-1307, USA.
- */
-
-#ifndef _ZEBRA_COMMAND_H
-#define _ZEBRA_COMMAND_H
-
-#include <stdio.h>
-#include <sys/types.h>
-#include "vector.h"
-#include "vty.h"
-
-/* Host configuration variable */
-struct host {
- /* Host name of this router. */
- char *name;
-
- /* Password for vty interface. */
- char *password;
- char *password_encrypt;
-
- /* Enable password */
- char *enable;
- char *enable_encrypt;
-
- /* System wide terminal lines. */
- int lines;
-
- /* Log filename. */
- char *logfile;
-
- /* config file name of this host */
- char *config;
-
- /* Flags for services */
- int advanced;
- int encrypt;
-
- /* Banner configuration. */
- const char *motd;
- char *motdfile;
-
- const char *prog_name;
- const char *prog_version;
- const char *prog_copyright;
-};
-
-/* There are some command levels which called from command node. */
-enum node_type {
- AUTH_NODE, /* Authentication mode of vty interface. */
- VIEW_NODE, /* View node. Default mode of vty interface. */
- AUTH_ENABLE_NODE, /* Authentication mode for change enable. */
- ENABLE_NODE, /* Enable node. */
- CONFIG_NODE, /* Config node. Default mode of config file. */
- SERVICE_NODE, /* Service node. */
- DEBUG_NODE, /* Debug node. */
-#if 0
- AAA_NODE, /* AAA node. */
- KEYCHAIN_NODE, /* Key-chain node. */
- KEYCHAIN_KEY_NODE, /* Key-chain key node. */
- INTERFACE_NODE, /* Interface mode node. */
- ZEBRA_NODE, /* zebra connection node. */
- TABLE_NODE, /* rtm_table selection node. */
- RIP_NODE, /* RIP protocol mode node. */
- RIPNG_NODE, /* RIPng protocol mode node. */
- BGP_NODE, /* BGP protocol mode which includes BGP4+ */
- BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */
- BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */
- BGP_IPV4M_NODE, /* BGP IPv4 multicast address family. */
- BGP_IPV6_NODE, /* BGP IPv6 address family */
- OSPF_NODE, /* OSPF protocol mode */
- OSPF6_NODE, /* OSPF protocol for IPv6 mode */
- ISIS_NODE, /* ISIS protocol mode */
- MASC_NODE, /* MASC for multicast. */
- IRDP_NODE, /* ICMP Router Discovery Protocol mode. */
- IP_NODE, /* Static ip route node. */
- ACCESS_NODE, /* Access list node. */
- PREFIX_NODE, /* Prefix list node. */
- ACCESS_IPV6_NODE, /* Access list node. */
- PREFIX_IPV6_NODE, /* Prefix list node. */
- AS_LIST_NODE, /* AS list node. */
- COMMUNITY_LIST_NODE, /* Community list node. */
- RMAP_NODE, /* Route map node. */
- SMUX_NODE, /* SNMP configuration node. */
- DUMP_NODE, /* Packet dump node. */
- FORWARDING_NODE, /* IP forwarding node. */
-#endif
- VTY_NODE, /* Vty node. */
-
- GSMNET_NODE,
- BTS_NODE,
- TRX_NODE,
- TS_NODE,
- SUBSCR_NODE,
- MGCP_NODE,
- GBPROXY_NODE,
- SGSN_NODE,
- NS_NODE,
- BSSGP_NODE,
-};
-
-/* Node which has some commands and prompt string and configuration
- function pointer . */
-struct cmd_node {
- /* Node index. */
- enum node_type node;
-
- /* Prompt character at vty interface. */
- const char *prompt;
-
- /* Is this node's configuration goes to vtysh ? */
- int vtysh;
-
- /* Node's configuration write function */
- int (*func) (struct vty *);
-
- /* Vector of this node's command list. */
- vector cmd_vector;
-};
-
-enum {
- CMD_ATTR_DEPRECATED = 1,
- CMD_ATTR_HIDDEN,
-};
-
-/* Structure of command element. */
-struct cmd_element {
- const char *string; /* Command specification by string. */
- int (*func) (struct cmd_element *, struct vty *, int, const char *[]);
- const char *doc; /* Documentation of this command. */
- int daemon; /* Daemon to which this command belong. */
- vector strvec; /* Pointing out each description vector. */
- unsigned int cmdsize; /* Command index count. */
- char *config; /* Configuration string */
- vector subconfig; /* Sub configuration string */
- u_char attr; /* Command attributes */
-};
-
-/* Command description structure. */
-struct desc {
- const char *cmd; /* Command string. */
- const char *str; /* Command's description. */
-};
-
-/* Return value of the commands. */
-#define CMD_SUCCESS 0
-#define CMD_WARNING 1
-#define CMD_ERR_NO_MATCH 2
-#define CMD_ERR_AMBIGUOUS 3
-#define CMD_ERR_INCOMPLETE 4
-#define CMD_ERR_EXEED_ARGC_MAX 5
-#define CMD_ERR_NOTHING_TODO 6
-#define CMD_COMPLETE_FULL_MATCH 7
-#define CMD_COMPLETE_MATCH 8
-#define CMD_COMPLETE_LIST_MATCH 9
-#define CMD_SUCCESS_DAEMON 10
-
-/* Argc max counts. */
-#define CMD_ARGC_MAX 25
-
-/* Turn off these macros when uisng cpp with extract.pl */
-#ifndef VTYSH_EXTRACT_PL
-
-/* helper defines for end-user DEFUN* macros */
-#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
- static struct cmd_element cmdname = \
- { \
- .string = cmdstr, \
- .func = funcname, \
- .doc = helpstr, \
- .attr = attrs, \
- .daemon = dnum, \
- };
-
-/* global (non static) cmd_element */
-#define gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
- struct cmd_element cmdname = \
- { \
- .string = cmdstr, \
- .func = funcname, \
- .doc = helpstr, \
- .attr = attrs, \
- .daemon = dnum, \
- };
-
-#define DEFUN_CMD_FUNC_DECL(funcname) \
- static int funcname (struct cmd_element *, struct vty *, int, const char *[]); \
-
-#define DEFUN_CMD_FUNC_TEXT(funcname) \
- static int funcname \
- (struct cmd_element *self, struct vty *vty, int argc, const char *argv[])
-
-/* DEFUN for vty command interafce. Little bit hacky ;-). */
-#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_FUNC_DECL(funcname) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
- DEFUN_CMD_FUNC_TEXT(funcname)
-
-/* global (non static) cmd_element */
-#define gDEFUN(funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_FUNC_DECL(funcname) \
- gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
- DEFUN_CMD_FUNC_TEXT(funcname)
-
-#define DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
- DEFUN_CMD_FUNC_DECL(funcname) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \
- DEFUN_CMD_FUNC_TEXT(funcname)
-
-#define DEFUN_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
- DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
-
-#define DEFUN_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
- DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED) \
-
-/* DEFUN_NOSH for commands that vtysh should ignore */
-#define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \
- DEFUN(funcname, cmdname, cmdstr, helpstr)
-
-/* DEFSH for vtysh. */
-#define DEFSH(daemon, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, 0, daemon) \
-
-/* DEFUN + DEFSH */
-#define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_FUNC_DECL(funcname) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon) \
- DEFUN_CMD_FUNC_TEXT(funcname)
-
-/* DEFUN + DEFSH with attributes */
-#define DEFUNSH_ATTR(daemon, funcname, cmdname, cmdstr, helpstr, attr) \
- DEFUN_CMD_FUNC_DECL(funcname) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, daemon) \
- DEFUN_CMD_FUNC_TEXT(funcname)
-
-#define DEFUNSH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \
- DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
-
-#define DEFUNSH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \
- DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED)
-
-/* ALIAS macro which define existing command's alias. */
-#define ALIAS(funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
-
-/* global (non static) cmd_element */
-#define gALIAS(funcname, cmdname, cmdstr, helpstr) \
- gDEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
-
-#define ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0)
-
-#define ALIAS_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, 0)
-
-#define ALIAS_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, 0)
-
-#define ALIAS_SH(daemon, funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon)
-
-#define ALIAS_SH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, daemon)
-
-#define ALIAS_SH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \
- DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, daemon)
-
-#endif /* VTYSH_EXTRACT_PL */
-
-/* Some macroes */
-#define CMD_OPTION(S) ((S[0]) == '[')
-#define CMD_VARIABLE(S) (((S[0]) >= 'A' && (S[0]) <= 'Z') || ((S[0]) == '<'))
-#define CMD_VARARG(S) ((S[0]) == '.')
-#define CMD_RANGE(S) ((S[0] == '<'))
-
-#define CMD_IPV4(S) ((strcmp ((S), "A.B.C.D") == 0))
-#define CMD_IPV4_PREFIX(S) ((strcmp ((S), "A.B.C.D/M") == 0))
-#define CMD_IPV6(S) ((strcmp ((S), "X:X::X:X") == 0))
-#define CMD_IPV6_PREFIX(S) ((strcmp ((S), "X:X::X:X/M") == 0))
-
-/* Common descriptions. */
-#define SHOW_STR "Show running system information\n"
-#define IP_STR "IP information\n"
-#define IPV6_STR "IPv6 information\n"
-#define NO_STR "Negate a command or set its defaults\n"
-#define CLEAR_STR "Reset functions\n"
-#define RIP_STR "RIP information\n"
-#define BGP_STR "BGP information\n"
-#define OSPF_STR "OSPF information\n"
-#define NEIGHBOR_STR "Specify neighbor router\n"
-#define DEBUG_STR "Debugging functions (see also 'undebug')\n"
-#define UNDEBUG_STR "Disable debugging functions (see also 'debug')\n"
-#define ROUTER_STR "Enable a routing process\n"
-#define AS_STR "AS number\n"
-#define MBGP_STR "MBGP information\n"
-#define MATCH_STR "Match values from routing table\n"
-#define SET_STR "Set values in destination routing protocol\n"
-#define OUT_STR "Filter outgoing routing updates\n"
-#define IN_STR "Filter incoming routing updates\n"
-#define V4NOTATION_STR "specify by IPv4 address notation(e.g. 0.0.0.0)\n"
-#define OSPF6_NUMBER_STR "Specify by number\n"
-#define INTERFACE_STR "Interface infomation\n"
-#define IFNAME_STR "Interface name(e.g. ep0)\n"
-#define IP6_STR "IPv6 Information\n"
-#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n"
-#define OSPF6_ROUTER_STR "Enable a routing process\n"
-#define OSPF6_INSTANCE_STR "<1-65535> Instance ID\n"
-#define SECONDS_STR "<1-65535> Seconds\n"
-#define ROUTE_STR "Routing Table\n"
-#define PREFIX_LIST_STR "Build a prefix list\n"
-#define OSPF6_DUMP_TYPE_LIST \
-"(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
-#define ISIS_STR "IS-IS information\n"
-#define AREA_TAG_STR "[area tag]\n"
-
-#define CONF_BACKUP_EXT ".sav"
-
-/* IPv4 only machine should not accept IPv6 address for peer's IP
- address. So we replace VTY command string like below. */
-#ifdef HAVE_IPV6
-#define NEIGHBOR_CMD "neighbor (A.B.C.D|X:X::X:X) "
-#define NO_NEIGHBOR_CMD "no neighbor (A.B.C.D|X:X::X:X) "
-#define NEIGHBOR_ADDR_STR "Neighbor address\nIPv6 address\n"
-#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|X:X::X:X|WORD) "
-#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|X:X::X:X|WORD) "
-#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nNeighbor tag\n"
-#else
-#define NEIGHBOR_CMD "neighbor A.B.C.D "
-#define NO_NEIGHBOR_CMD "no neighbor A.B.C.D "
-#define NEIGHBOR_ADDR_STR "Neighbor address\n"
-#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|WORD) "
-#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|WORD) "
-#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor tag\n"
-#endif /* HAVE_IPV6 */
-
-/* Prototypes. */
-void install_node(struct cmd_node *, int (*)(struct vty *));
-void install_default(enum node_type);
-void install_element(enum node_type, struct cmd_element *);
-void install_element_ve(struct cmd_element *cmd);
-void sort_node();
-
-/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated
- string with a space between each element (allocated using
- XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */
-char *argv_concat(const char **argv, int argc, int shift);
-
-vector cmd_make_strvec(const char *);
-void cmd_free_strvec(vector);
-vector cmd_describe_command();
-char **cmd_complete_command();
-const char *cmd_prompt(enum node_type);
-int config_from_file(struct vty *, FILE *);
-enum node_type node_parent(enum node_type);
-int cmd_execute_command(vector, struct vty *, struct cmd_element **, int);
-int cmd_execute_command_strict(vector, struct vty *, struct cmd_element **);
-void config_replace_string(struct cmd_element *, char *, ...);
-void cmd_init(int);
-
-/* Export typical functions. */
-extern struct cmd_element config_exit_cmd;
-extern struct cmd_element config_help_cmd;
-extern struct cmd_element config_list_cmd;
-char *host_config_file();
-void host_config_set(const char *);
-
-/* This is called from main when a daemon is invoked with -v or --version. */
-void print_version(int print_copyright);
-
-extern void *tall_vty_cmd_ctx;
-
-#endif /* _ZEBRA_COMMAND_H */
diff --git a/openbsc/include/vty/vector.h b/openbsc/include/vty/vector.h
deleted file mode 100644
index 22a184d61..000000000
--- a/openbsc/include/vty/vector.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Generic vector interface header.
- * 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
- * 02111-1307, USA.
- */
-
-#ifndef _ZEBRA_VECTOR_H
-#define _ZEBRA_VECTOR_H
-
-/* struct for vector */
-struct _vector {
- unsigned int active; /* number of active slots */
- unsigned int alloced; /* number of allocated slot */
- void **index; /* index to data */
-};
-typedef struct _vector *vector;
-
-#define VECTOR_MIN_SIZE 1
-
-/* (Sometimes) usefull macros. This macro convert index expression to
- array expression. */
-/* Reference slot at given index, caller must ensure slot is active */
-#define vector_slot(V,I) ((V)->index[(I)])
-/* Number of active slots.
- * Note that this differs from vector_count() as it the count returned
- * will include any empty slots
- */
-#define vector_active(V) ((V)->active)
-
-/* Prototypes. */
-vector vector_init(unsigned int size);
-void vector_ensure(vector v, unsigned int num);
-int vector_empty_slot(vector v);
-int vector_set(vector v, void *val);
-int vector_set_index(vector v, unsigned int i, void *val);
-void vector_unset(vector v, unsigned int i);
-unsigned int vector_count(vector v);
-void vector_only_wrapper_free(vector v);
-void vector_only_index_free(void *index);
-void vector_free(vector v);
-vector vector_copy(vector v);
-
-void *vector_lookup(vector, unsigned int);
-void *vector_lookup_ensure(vector, unsigned int);
-
-extern void *tall_vty_vec_ctx;
-
-#endif /* _ZEBRA_VECTOR_H */
diff --git a/openbsc/include/vty/vty.h b/openbsc/include/vty/vty.h
deleted file mode 100644
index f82ada1cc..000000000
--- a/openbsc/include/vty/vty.h
+++ /dev/null
@@ -1,151 +0,0 @@
-#ifndef _VTY_H
-#define _VTY_H
-
-#include <stdio.h>
-#include <stdarg.h>
-
-/* GCC have printf type attribute check. */
-#ifdef __GNUC__
-#define VTY_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
-#else
-#define VTY_PRINTF_ATTRIBUTE(a,b)
-#endif /* __GNUC__ */
-
-/* Does the I/O error indicate that the operation should be retried later? */
-#define ERRNO_IO_RETRY(EN) \
- (((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
-
-/* Vty read buffer size. */
-#define VTY_READ_BUFSIZ 512
-
-#define VTY_BUFSIZ 512
-#define VTY_MAXHIST 20
-
-/* Vty events */
-enum event {
- VTY_SERV,
- VTY_READ,
- VTY_WRITE,
- VTY_CLOSED,
- VTY_TIMEOUT_RESET,
-#ifdef VTYSH
- VTYSH_SERV,
- VTYSH_READ,
- VTYSH_WRITE
-#endif /* VTYSH */
-};
-
-struct vty {
- FILE *file;
-
- /* private data, specified by creator */
- void *priv;
-
- /* File descripter of this vty. */
- int fd;
-
- /* Is this vty connect to file or not */
- enum { VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV } type;
-
- /* Node status of this vty */
- int node;
-
- /* Failure count */
- int fail;
-
- /* Output buffer. */
- struct buffer *obuf;
-
- /* Command input buffer */
- char *buf;
-
- /* Command cursor point */
- int cp;
-
- /* Command length */
- int length;
-
- /* Command max length. */
- int max;
-
- /* Histry of command */
- char *hist[VTY_MAXHIST];
-
- /* History lookup current point */
- int hp;
-
- /* History insert end point */
- int hindex;
-
- /* For current referencing point of interface, route-map,
- access-list etc... */
- void *index;
-
- /* For multiple level index treatment such as key chain and key. */
- void *index_sub;
-
- /* For escape character. */
- unsigned char escape;
-
- /* Current vty status. */
- enum { VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE } status;
-
- /* IAC handling: was the last character received the IAC
- * (interpret-as-command) escape character (and therefore the next
- * character will be the command code)? Refer to Telnet RFC 854. */
- unsigned char iac;
-
- /* IAC SB (option subnegotiation) handling */
- unsigned char iac_sb_in_progress;
- /* At the moment, we care only about the NAWS (window size) negotiation,
- * and that requires just a 5-character buffer (RFC 1073):
- * <NAWS char> <16-bit width> <16-bit height> */
-#define TELNET_NAWS_SB_LEN 5
- unsigned char sb_buf[TELNET_NAWS_SB_LEN];
- /* How many subnegotiation characters have we received? We just drop
- * those that do not fit in the buffer. */
- size_t sb_len;
-
- /* Window width/height. */
- int width;
- int height;
-
- /* Configure lines. */
- int lines;
-
- int monitor;
-
- /* In configure mode. */
- int config;
-};
-
-/* Small macro to determine newline is newline only or linefeed needed. */
-#define VTY_NEWLINE ((vty->type == VTY_TERM) ? "\r\n" : "\n")
-
-static inline char *vty_newline(struct vty *vty)
-{
- return VTY_NEWLINE;
-}
-
-/* Prototypes. */
-void vty_init(const char *name, const char *version, const char *copyright);
-int vty_read_config_file(const char *file_name, void *priv);
-void vty_init_vtysh (void);
-void vty_reset (void);
-struct vty *vty_new (void);
-struct vty *vty_create (int vty_sock, void *priv);
-int vty_out (struct vty *, const char *, ...) VTY_PRINTF_ATTRIBUTE(2, 3);
-int vty_out_newline(struct vty *);
-int vty_read(struct vty *vty);
-//void vty_time_print (struct vty *, int);
-void vty_close (struct vty *);
-char *vty_get_cwd (void);
-void vty_log (const char *level, const char *proto, const char *fmt, va_list);
-int vty_config_lock (struct vty *);
-int vty_config_unlock (struct vty *);
-int vty_shell (struct vty *);
-int vty_shell_serv (struct vty *);
-void vty_hello (struct vty *);
-
-void *tall_vty_ctx;
-#endif
diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am
index 942007199..bd9be8c15 100644
--- a/openbsc/src/Makefile.am
+++ b/openbsc/src/Makefile.am
@@ -1,5 +1,5 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
-AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS)
+AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS)
AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
# build current directory before building gprs
@@ -25,14 +25,13 @@ libmsc_a_SOURCES = gsm_subscriber.c db.c \
token_auth.c rrlp.c gsm_04_80.c ussd.c silent_call.c \
handover_logic.c handover_decision.c meas_rep.c
-libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c \
- telnet_interface.c vty/utils.c common_vty.c \
- logging_vty.c
+libvty_a_SOURCES = common_vty.c
libsccp_a_SOURCES = sccp/sccp.c
bsc_hack_SOURCES = bsc_hack.c bsc_init.c bsc_vty.c vty_interface_layer3.c
-bsc_hack_LDADD = libmsc.a libbsc.a libmsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
+bsc_hack_LDADD = libmsc.a libbsc.a libvty.a libmsc.a \
+ -ldl -ldbi $(LIBCRYPT) $(LIBOSMOVTY_LIBS)
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c debug.c \
rs232.c bts_siemens_bs11.c
@@ -41,4 +40,4 @@ isdnsync_SOURCES = isdnsync.c
bsc_mgcp_SOURCES = mgcp/mgcp_main.c mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c \
debug.c
-bsc_mgcp_LDADD = libvty.a
+bsc_mgcp_LDADD = libvty.a $(LIBOSMOVTY_LIBS)
diff --git a/openbsc/src/bsc_hack.c b/openbsc/src/bsc_hack.c
index fa058aa4c..739d7a542 100644
--- a/openbsc/src/bsc_hack.c
+++ b/openbsc/src/bsc_hack.c
@@ -37,7 +37,7 @@
#include <osmocore/talloc.h>
#include <openbsc/signal.h>
-#include <vty/command.h>
+#include <osmocom/vty/command.h>
#include "../bscconfig.h"
diff --git a/openbsc/src/bsc_init.c b/openbsc/src/bsc_init.c
index 424a26848..fa4d8580e 100644
--- a/openbsc/src/bsc_init.c
+++ b/openbsc/src/bsc_init.c
@@ -27,7 +27,7 @@
#include <openbsc/abis_nm.h>
#include <openbsc/debug.h>
#include <openbsc/misdn.h>
-#include <openbsc/telnet_interface.h>
+#include <osmocom/vty/telnet_interface.h>
#include <openbsc/system_information.h>
#include <openbsc/paging.h>
#include <openbsc/signal.h>
diff --git a/openbsc/src/bsc_vty.c b/openbsc/src/bsc_vty.c
index 5a89af0bf..ad49bd580 100644
--- a/openbsc/src/bsc_vty.c
+++ b/openbsc/src/bsc_vty.c
@@ -22,9 +22,11 @@
#include <unistd.h>
#include <sys/types.h>
-#include <vty/command.h>
-#include <vty/buffer.h>
-#include <vty/vty.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/buffer.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/vty/telnet_interface.h>
#include <arpa/inet.h>
@@ -37,7 +39,6 @@
#include <openbsc/meas_rep.h>
#include <openbsc/db.h>
#include <osmocore/talloc.h>
-#include <openbsc/telnet_interface.h>
#include <openbsc/vty.h>
#include <openbsc/gprs_ns.h>
#include <openbsc/debug.h>
diff --git a/openbsc/src/common_vty.c b/openbsc/src/common_vty.c
index 4f18a74e7..eb0d29e38 100644
--- a/openbsc/src/common_vty.c
+++ b/openbsc/src/common_vty.c
@@ -25,15 +25,59 @@
#include <osmocore/talloc.h>
#include <openbsc/vty.h>
-#include <openbsc/telnet_interface.h>
#include <openbsc/gsm_data.h>
#include <openbsc/debug.h>
+#include <openbsc/gsm_subscriber.h>
-#include <vty/command.h>
-#include <vty/buffer.h>
-#include <vty/vty.h>
+#include <osmocom/vty/telnet_interface.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/buffer.h>
+#include <osmocom/vty/vty.h>
+int bsc_vty_go_parent(struct vty *vty)
+{
+ switch (vty->node) {
+ case GSMNET_NODE:
+ vty->node = CONFIG_NODE;
+ vty->index = NULL;
+ break;
+ case BTS_NODE:
+ vty->node = GSMNET_NODE;
+ {
+ /* set vty->index correctly ! */
+ struct gsm_bts *bts = vty->index;
+ vty->index = bts->network;
+ }
+ break;
+ case TRX_NODE:
+ vty->node = BTS_NODE;
+ {
+ /* set vty->index correctly ! */
+ struct gsm_bts_trx *trx = vty->index;
+ vty->index = trx->bts;
+ }
+ break;
+ case TS_NODE:
+ vty->node = TRX_NODE;
+ {
+ /* set vty->index correctly ! */
+ struct gsm_bts_trx_ts *ts = vty->index;
+ vty->index = ts->trx;
+ }
+ break;
+ case SUBSCR_NODE:
+ vty->node = VIEW_NODE;
+ subscr_put(vty->index);
+ vty->index = NULL;
+ break;
+ default:
+ vty->node = CONFIG_NODE;
+ }
+
+ return vty->node;
+}
+
/* Down vty node level. */
gDEFUN(ournode_exit,
ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
diff --git a/openbsc/src/gprs/Makefile.am b/openbsc/src/gprs/Makefile.am
index 191f6193c..11b2ac934 100644
--- a/openbsc/src/gprs/Makefile.am
+++ b/openbsc/src/gprs/Makefile.am
@@ -1,6 +1,6 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
-AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) -fno-strict-aliasing
-AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
+AM_CFLAGS=-Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS)
+AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS)
noinst_LIBRARIES = libgb.a
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 26c9e4fe9..b6fbac77e 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -567,7 +567,7 @@ int gbprox_signal(unsigned int subsys, unsigned int signal,
}
-#include <vty/command.h>
+#include <osmocom/vty/command.h>
gDEFUN(show_gbproxy, show_gbproxy_cmd, "show gbproxy",
SHOW_STR "Display information about the Gb proxy")
diff --git a/openbsc/src/gprs/gb_proxy_main.c b/openbsc/src/gprs/gb_proxy_main.c
index 71d608609..208ae47ca 100644
--- a/openbsc/src/gprs/gb_proxy_main.c
+++ b/openbsc/src/gprs/gb_proxy_main.c
@@ -42,11 +42,11 @@
#include <openbsc/debug.h>
#include <openbsc/gprs_ns.h>
#include <openbsc/gprs_bssgp.h>
-#include <openbsc/telnet_interface.h>
#include <openbsc/vty.h>
#include <openbsc/gb_proxy.h>
-#include <vty/command.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/telnet_interface.h>
#include "../../bscconfig.h"
diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c
index 738adcfef..7b6d2dab9 100644
--- a/openbsc/src/gprs/gb_proxy_vty.c
+++ b/openbsc/src/gprs/gb_proxy_vty.c
@@ -31,8 +31,8 @@
#include <openbsc/gprs_ns.h>
#include <openbsc/vty.h>
-#include <vty/command.h>
-#include <vty/vty.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/vty.h>
static struct gbproxy_config *g_cfg = NULL;
diff --git a/openbsc/src/gprs/gprs_bssgp_vty.c b/openbsc/src/gprs/gprs_bssgp_vty.c
index 8377c56e8..9da02abb3 100644
--- a/openbsc/src/gprs/gprs_bssgp_vty.c
+++ b/openbsc/src/gprs/gprs_bssgp_vty.c
@@ -37,11 +37,12 @@
#include <openbsc/signal.h>
#include <openbsc/gprs_ns.h>
#include <openbsc/gprs_bssgp.h>
-#include <openbsc/telnet_interface.h>
#include <openbsc/vty.h>
-#include <vty/vty.h>
-#include <vty/command.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/vty/telnet_interface.h>
/* FIXME: this should go to some common file as it is copied
* in vty_interface.c of the BSC */
diff --git a/openbsc/src/gprs/gprs_llc_vty.c b/openbsc/src/gprs/gprs_llc_vty.c
index 510ef64f0..9c7f5568e 100644
--- a/openbsc/src/gprs/gprs_llc_vty.c
+++ b/openbsc/src/gprs/gprs_llc_vty.c
@@ -37,8 +37,8 @@
#include <openbsc/signal.h>
#include <openbsc/gprs_llc.h>
-#include <vty/vty.h>
-#include <vty/command.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/command.h>
struct value_string gprs_llc_state_strs[] = {
{ GPRS_LLS_UNASSIGNED, "TLLI Unassigned" },
diff --git a/openbsc/src/gprs/gprs_ns_vty.c b/openbsc/src/gprs/gprs_ns_vty.c
index 423ac205a..81346c6ef 100644
--- a/openbsc/src/gprs/gprs_ns_vty.c
+++ b/openbsc/src/gprs/gprs_ns_vty.c
@@ -37,11 +37,12 @@
#include <openbsc/signal.h>
#include <openbsc/gprs_ns.h>
#include <openbsc/gprs_bssgp.h>
-#include <openbsc/telnet_interface.h>
#include <openbsc/vty.h>
-#include <vty/vty.h>
-#include <vty/command.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/logging.h>
+#include <osmocom/vty/telnet_interface.h>
static struct gprs_ns_inst *vty_nsi = NULL;
diff --git a/openbsc/src/gprs/osmo_sgsn.cfg b/openbsc/src/gprs/osmo_sgsn.cfg
index d3d4bb2a4..298d2d6f0 100644
--- a/openbsc/src/gprs/osmo_sgsn.cfg
+++ b/openbsc/src/gprs/osmo_sgsn.cfg
@@ -6,10 +6,12 @@ line vty
no login
!
sgsn
- ggsn 0 remote-ip 192.168.100.239
+ ggsn 0 remote-ip 127.0.0.1
ggsn 0 gtp-version 1
ns
+ encapsulation udp local-ip 192.168.100.239
encapsulation udp local-port 23000
+ encapsulation framerelay-gre enabled 1
timer tns-block 3
timer tns-block-retries 3
timer tns-reset 3
diff --git a/openbsc/src/gprs/sgsn_main.c b/openbsc/src/gprs/sgsn_main.c
index 7c5afe55c..4ed498042 100644
--- a/openbsc/src/gprs/sgsn_main.c
+++ b/openbsc/src/gprs/sgsn_main.c
@@ -38,9 +38,10 @@
#include <osmocore/select.h>
#include <osmocore/rate_ctr.h>
+#include <osmocom/vty/telnet_interface.h>
+
#include <openbsc/signal.h>
#include <openbsc/debug.h>
-#include <openbsc/telnet_interface.h>
#include <openbsc/vty.h>
#include <openbsc/sgsn.h>
#include <openbsc/gprs_ns.h>
diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c
index 2532a8840..34dd8c646 100644
--- a/openbsc/src/gprs/sgsn_vty.c
+++ b/openbsc/src/gprs/sgsn_vty.c
@@ -34,8 +34,8 @@
#include <openbsc/gprs_sgsn.h>
#include <openbsc/vty.h>
-#include <vty/command.h>
-#include <vty/vty.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/vty.h>
#include <pdp.h>
diff --git a/openbsc/src/logging_vty.c b/openbsc/src/logging_vty.c
deleted file mode 100644
index 603975ae6..000000000
--- a/openbsc/src/logging_vty.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/* OpenBSC logging helper for the VTY */
-/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
- * (C) 2009-2010 by Holger Hans Peter Freyther
- * All Rights Reserved
- *
- * This program 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 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <osmocore/talloc.h>
-
-#include <openbsc/vty.h>
-#include <openbsc/telnet_interface.h>
-#include <openbsc/gsm_data.h>
-#include <openbsc/debug.h>
-
-#include <vty/command.h>
-#include <vty/buffer.h>
-#include <vty/vty.h>
-
-static void _vty_output(struct log_target *tgt, const char *line)
-{
- struct vty *vty = tgt->tgt_vty.vty;
- vty_out(vty, "%s", line);
- /* This is an ugly hack, but there is no easy way... */
- if (strchr(line, '\n'))
- vty_out(vty, "\r");
-}
-
-struct log_target *log_target_create_vty(struct vty *vty)
-{
- struct log_target *target;
-
- target = log_target_create();
- if (!target)
- return NULL;
-
- target->tgt_vty.vty = vty;
- target->output = _vty_output;
- return target;
-}
-
-DEFUN(enable_logging,
- enable_logging_cmd,
- "logging enable",
- LOGGING_STR
- "Enables logging to this vty\n")
-{
- struct telnet_connection *conn;
-
- conn = (struct telnet_connection *) vty->priv;
- if (conn->dbg) {
- vty_out(vty, "Logging already enabled.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- conn->dbg = log_target_create_vty(vty);
- if (!conn->dbg)
- return CMD_WARNING;
-
- log_add_target(conn->dbg);
- return CMD_SUCCESS;
-}
-
-DEFUN(logging_fltr_all,
- logging_fltr_all_cmd,
- "logging filter all (0|1)",
- LOGGING_STR FILTER_STR
- "Do you want to log all messages?\n"
- "Only print messages matched by other filters\n"
- "Bypass filter and print all messages\n")
-{
- struct telnet_connection *conn;
-
- conn = (struct telnet_connection *) vty->priv;
- if (!conn->dbg) {
- vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- log_set_all_filter(conn->dbg, atoi(argv[0]));
- return CMD_SUCCESS;
-}
-
-DEFUN(logging_use_clr,
- logging_use_clr_cmd,
- "logging color (0|1)",
- LOGGING_STR "Configure color-printing for log messages\n"
- "Don't use color for printing messages\n"
- "Use color for printing messages\n")
-{
- struct telnet_connection *conn;
-
- conn = (struct telnet_connection *) vty->priv;
- if (!conn->dbg) {
- vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- log_set_use_color(conn->dbg, atoi(argv[0]));
- return CMD_SUCCESS;
-}
-
-DEFUN(logging_prnt_timestamp,
- logging_prnt_timestamp_cmd,
- "logging timestamp (0|1)",
- LOGGING_STR "Configure log message timestamping\n"
- "Don't prefix each log message\n"
- "Prefix each log message with current timestamp\n")
-{
- struct telnet_connection *conn;
-
- conn = (struct telnet_connection *) vty->priv;
- if (!conn->dbg) {
- vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- log_set_print_timestamp(conn->dbg, atoi(argv[0]));
- return CMD_SUCCESS;
-}
-
-/* FIXME: those have to be kept in sync with the log levels and categories */
-#define VTY_DEBUG_CATEGORIES "(rll|cc|mm|rr|rsl|nm|sms|pag|mncc|inp|mi|mib|mux|meas|sccp|msc|mgcp|ho|db|ref|gprs|ns|bssgp|llc|sndcp|all)"
-#define CATEGORIES_HELP \
- "A-bis Radio Link Layer (RLL)\n" \
- "Layer3 Call Control (CC)\n" \
- "Layer3 Mobility Management (MM)\n" \
- "Layer3 Radio Resource (RR)\n" \
- "A-bis Radio Signalling Link (RSL)\n" \
- "A-bis Network Management / O&M (NM/OML)\n" \
- "Layer3 Short Messagaging Service (SMS)\n" \
- "Paging Subsystem\n" \
- "MNCC API for Call Control application\n" \
- "A-bis Input Subsystem\n" \
- "A-bis Input Driver for Signalling\n" \
- "A-bis Input Driver for B-Channel (voice data)\n" \
- "A-bis B-Channel / Sub-channel Multiplexer\n" \
- "Radio Measurements\n" \
- "SCCP\n" \
- "Mobile Switching Center\n" \
- "Media Gateway Control Protocol\n" \
- "Hand-over\n" \
- "Database Layer\n" \
- "Reference Counting\n" \
- "GPRS Core\n" \
- "GPRS Network Service (NS)\n" \
- "GPRS BSS Gateway Protocol (BSSGP)\n" \
- "GPRS Logical Link Control Protocol (LLC)\n" \
- "GPRS Sub-Network Dependent Control Protocol (SNDCP)\n" \
- "Global setting for all subsytems\n"
-
-#define VTY_DEBUG_LEVELS "(everything|debug|info|notice|error|fatal)"
-#define LEVELS_HELP \
- "Log simply everything\n" \
- "Log debug messages and higher levels\n" \
- "Log informational messages and higher levels\n" \
- "Log noticable messages and higher levels\n" \
- "Log error messages and higher levels\n" \
- "Log only fatal messages\n"
-DEFUN(logging_level,
- logging_level_cmd,
- "logging level " VTY_DEBUG_CATEGORIES " " VTY_DEBUG_LEVELS,
- LOGGING_STR
- "Set the log level for a specified category\n"
- CATEGORIES_HELP
- LEVELS_HELP)
-{
- struct telnet_connection *conn;
- int category = log_parse_category(argv[0]);
- int level = log_parse_level(argv[1]);
-
- conn = (struct telnet_connection *) vty->priv;
- if (!conn->dbg) {
- vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (level < 0) {
- vty_out(vty, "Invalid level `%s'%s", argv[1], VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Check for special case where we want to set global log level */
- if (!strcmp(argv[0], "all")) {
- log_set_log_level(conn->dbg, level);
- return CMD_SUCCESS;
- }
-
- if (category < 0) {
- vty_out(vty, "Invalid category `%s'%s", argv[0], VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- conn->dbg->categories[category].enabled = 1;
- conn->dbg->categories[category].loglevel = level;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(logging_set_category_mask,
- logging_set_category_mask_cmd,
- "logging set log mask MASK",
- LOGGING_STR
- "Decide which categories to output.\n")
-{
- struct telnet_connection *conn;
-
- conn = (struct telnet_connection *) vty->priv;
- if (!conn->dbg) {
- vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- log_parse_category_mask(conn->dbg, argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(diable_logging,
- disable_logging_cmd,
- "logging disable",
- LOGGING_STR
- "Disables logging to this vty\n")
-{
- struct telnet_connection *conn;
-
- conn = (struct telnet_connection *) vty->priv;
- if (!conn->dbg) {
- vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- log_del_target(conn->dbg);
- talloc_free(conn->dbg);
- conn->dbg = NULL;
- return CMD_SUCCESS;
-}
-
-static void vty_print_logtarget(struct vty *vty, const struct log_info *info,
- const struct log_target *tgt)
-{
- unsigned int i;
-
- vty_out(vty, " Global Loglevel: %s%s",
- log_level_str(tgt->loglevel), VTY_NEWLINE);
- vty_out(vty, " Use color: %s, Print Timestamp: %s%s",
- tgt->use_color ? "On" : "Off",
- tgt->print_timestamp ? "On" : "Off", VTY_NEWLINE);
-
- vty_out(vty, " Log Level specific information:%s", VTY_NEWLINE);
-
- for (i = 0; i < info->num_cat; i++) {
- const struct log_category *cat = &tgt->categories[i];
- vty_out(vty, " %-10s %-10s %-8s %s%s",
- info->cat[i].name+1, log_level_str(cat->loglevel),
- cat->enabled ? "Enabled" : "Disabled",
- info->cat[i].description,
- VTY_NEWLINE);
- }
-}
-
-#define SHOW_LOG_STR "Show current logging configuration\n"
-
-DEFUN(show_logging_vty,
- show_logging_vty_cmd,
- "show logging vty",
- SHOW_STR SHOW_LOG_STR
- "Show current logging configuration for this vty\n")
-{
- struct telnet_connection *conn;
-
- conn = (struct telnet_connection *) vty->priv;
- if (!conn->dbg) {
- vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- vty_print_logtarget(vty, &log_info, conn->dbg);
-
- return CMD_SUCCESS;
-}
-
-gDEFUN(cfg_description, cfg_description_cmd,
- "description .TEXT",
- "Save human-readable decription of the object\n")
-{
- char **dptr = vty->index_sub;
-
- if (!dptr) {
- vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- *dptr = argv_concat(argv, argc, 0);
- if (!dptr)
- return CMD_WARNING;
-
- return CMD_SUCCESS;
-}
-
-gDEFUN(cfg_no_description, cfg_no_description_cmd,
- "no description",
- NO_STR
- "Remove description of the object\n")
-{
- char **dptr = vty->index_sub;
-
- if (!dptr) {
- vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (*dptr) {
- talloc_free(*dptr);
- *dptr = NULL;
- }
-
- return CMD_SUCCESS;
-}
-
-void logging_vty_add_cmds()
-{
- install_element_ve(&enable_logging_cmd);
- install_element_ve(&disable_logging_cmd);
- install_element_ve(&logging_fltr_all_cmd);
- install_element_ve(&logging_use_clr_cmd);
- install_element_ve(&logging_prnt_timestamp_cmd);
- install_element_ve(&logging_set_category_mask_cmd);
- install_element_ve(&logging_level_cmd);
- install_element_ve(&show_logging_vty_cmd);
-}
diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c
index 99391223a..35e7fb1d6 100644
--- a/openbsc/src/mgcp/mgcp_main.c
+++ b/openbsc/src/mgcp/mgcp_main.c
@@ -39,10 +39,10 @@
#include <osmocore/select.h>
#include <openbsc/mgcp.h>
#include <openbsc/mgcp_internal.h>
-#include <openbsc/telnet_interface.h>
+#include <osmocom/vty//telnet_interface.h>
#include <openbsc/vty.h>
-#include <vty/command.h>
+#include <osmocom/vty/command.h>
#include "../../bscconfig.h"
diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c
index 1e76839a3..ea59abf15 100644
--- a/openbsc/src/mgcp/mgcp_vty.c
+++ b/openbsc/src/mgcp/mgcp_vty.c
@@ -31,8 +31,8 @@
#include <openbsc/mgcp_internal.h>
#include <openbsc/vty.h>
-#include <vty/command.h>
-#include <vty/vty.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/vty.h>
#include <string.h>
diff --git a/openbsc/src/telnet_interface.c b/openbsc/src/telnet_interface.c
deleted file mode 100644
index 37e1c25ec..000000000
--- a/openbsc/src/telnet_interface.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/* minimalistic telnet/network interface it might turn into a wire interface */
-/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
- * All Rights Reserved
- *
- * This program 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 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <osmocore/msgb.h>
-#include <osmocore/talloc.h>
-#include <osmocore/logging.h>
-#include <openbsc/telnet_interface.h>
-
-#include <vty/buffer.h>
-
-/* per connection data */
-LLIST_HEAD(active_connections);
-
-static void *tall_telnet_ctx;
-
-/* per network data */
-static int telnet_new_connection(struct bsc_fd *fd, unsigned int what);
-
-static struct bsc_fd server_socket = {
- .when = BSC_FD_READ,
- .cb = telnet_new_connection,
- .priv_nr = 0,
-};
-
-int telnet_init(void *tall_ctx, void *priv, int port)
-{
- struct sockaddr_in sock_addr;
- int fd, rc, on = 1;
-
- tall_telnet_ctx = talloc_named_const(tall_ctx, 1,
- "telnet_connection");
-
- fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
-
- if (fd < 0) {
- LOGP(0, LOGL_ERROR, "Telnet interface socket creation failed\n");
- return fd;
- }
-
- setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-
- memset(&sock_addr, 0, sizeof(sock_addr));
- sock_addr.sin_family = AF_INET;
- sock_addr.sin_port = htons(port);
- sock_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- rc = bind(fd, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
- if (bind < 0) {
- LOGP(0, LOGL_ERROR, "Telnet interface failed to bind\n");
- close(fd);
- return rc;
- }
-
- rc = listen(fd, 0);
- if (rc < 0) {
- LOGP(0, LOGL_ERROR, "Telnet interface failed to listen\n");
- close(fd);
- return rc;
- }
-
- server_socket.data = priv;
- server_socket.fd = fd;
- bsc_register_fd(&server_socket);
-
- return 0;
-}
-
-extern const char *openbsc_copyright;
-
-static void print_welcome(int fd)
-{
- int ret;
- static char *msg =
- "Welcome to the OpenBSC Control interface\n";
-
- ret = write(fd, msg, strlen(msg));
- ret = write(fd, openbsc_copyright, strlen(openbsc_copyright));
-}
-
-int telnet_close_client(struct bsc_fd *fd)
-{
- struct telnet_connection *conn = (struct telnet_connection*)fd->data;
-
- close(fd->fd);
- bsc_unregister_fd(fd);
-
- if (conn->dbg) {
- log_del_target(conn->dbg);
- talloc_free(conn->dbg);
- }
-
- llist_del(&conn->entry);
- talloc_free(conn);
- return 0;
-}
-
-static int client_data(struct bsc_fd *fd, unsigned int what)
-{
- struct telnet_connection *conn = fd->data;
- int rc = 0;
-
- if (what & BSC_FD_READ) {
- conn->fd.when &= ~BSC_FD_READ;
- rc = vty_read(conn->vty);
- }
-
- /* vty might have been closed from vithin vty_read() */
- if (!conn->vty)
- return rc;
-
- if (what & BSC_FD_WRITE) {
- rc = buffer_flush_all(conn->vty->obuf, fd->fd);
- if (rc == BUFFER_EMPTY)
- conn->fd.when &= ~BSC_FD_WRITE;
- }
-
- return rc;
-}
-
-static int telnet_new_connection(struct bsc_fd *fd, unsigned int what)
-{
- struct telnet_connection *connection;
- struct sockaddr_in sockaddr;
- socklen_t len = sizeof(sockaddr);
- int new_connection = accept(fd->fd, (struct sockaddr*)&sockaddr, &len);
-
- if (new_connection < 0) {
- LOGP(0, LOGL_ERROR, "telnet accept failed\n");
- return new_connection;
- }
-
- connection = talloc_zero(tall_telnet_ctx, struct telnet_connection);
- connection->priv = fd->data;
- connection->fd.data = connection;
- connection->fd.fd = new_connection;
- connection->fd.when = BSC_FD_READ;
- connection->fd.cb = client_data;
- bsc_register_fd(&connection->fd);
- llist_add_tail(&connection->entry, &active_connections);
-
- print_welcome(new_connection);
-
- connection->vty = vty_create(new_connection, connection);
- if (!connection->vty) {
- LOGP(0, LOGL_ERROR, "couldn't create VTY\n");
- close(new_connection);
- talloc_free(connection);
- return -1;
- }
-
- return 0;
-}
-
-/* callback from VTY code */
-void vty_event(enum event event, int sock, struct vty *vty)
-{
- struct telnet_connection *connection = vty->priv;
- struct bsc_fd *bfd = &connection->fd;
-
- if (vty->type != VTY_TERM)
- return;
-
- switch (event) {
- case VTY_READ:
- bfd->when |= BSC_FD_READ;
- break;
- case VTY_WRITE:
- bfd->when |= BSC_FD_WRITE;
- break;
- case VTY_CLOSED:
- /* vty layer is about to free() vty */
- connection->vty = NULL;
- telnet_close_client(bfd);
- break;
- default:
- break;
- }
-}
-
diff --git a/openbsc/src/vty/buffer.c b/openbsc/src/vty/buffer.c
deleted file mode 100644
index 0bc1760cc..000000000
--- a/openbsc/src/vty/buffer.c
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Buffering of output and input.
- * Copyright (C) 1998 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 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <stddef.h>
-#include <sys/uio.h>
-
-#include <osmocore/talloc.h>
-#include <vty/buffer.h>
-#include <vty/vty.h>
-
-/* Buffer master. */
-struct buffer {
- /* Data list. */
- struct buffer_data *head;
- struct buffer_data *tail;
-
- /* Size of each buffer_data chunk. */
- size_t size;
-};
-
-/* Data container. */
-struct buffer_data {
- struct buffer_data *next;
-
- /* Location to add new data. */
- size_t cp;
-
- /* Pointer to data not yet flushed. */
- size_t sp;
-
- /* Actual data stream (variable length). */
- unsigned char data[0]; /* real dimension is buffer->size */
-};
-
-/* It should always be true that: 0 <= sp <= cp <= size */
-
-/* Default buffer size (used if none specified). It is rounded up to the
- next page boundery. */
-#define BUFFER_SIZE_DEFAULT 4096
-
-#define BUFFER_DATA_FREE(D) talloc_free((D))
-
-/* Make new buffer. */
-struct buffer *buffer_new(void *ctx, size_t size)
-{
- struct buffer *b;
-
- b = talloc_zero(ctx, struct buffer);
-
- if (size)
- b->size = size;
- else {
- static size_t default_size;
- if (!default_size) {
- long pgsz = sysconf(_SC_PAGESIZE);
- default_size =
- ((((BUFFER_SIZE_DEFAULT - 1) / pgsz) + 1) * pgsz);
- }
- b->size = default_size;
- }
-
- return b;
-}
-
-/* Free buffer. */
-void buffer_free(struct buffer *b)
-{
- buffer_reset(b);
- talloc_free(b);
-}
-
-/* Make string clone. */
-char *buffer_getstr(struct buffer *b)
-{
- size_t totlen = 0;
- struct buffer_data *data;
- char *s;
- char *p;
-
- for (data = b->head; data; data = data->next)
- totlen += data->cp - data->sp;
- if (!(s = _talloc_zero(tall_vty_ctx, (totlen + 1), "buffer_getstr")))
- return NULL;
- p = s;
- for (data = b->head; data; data = data->next) {
- memcpy(p, data->data + data->sp, data->cp - data->sp);
- p += data->cp - data->sp;
- }
- *p = '\0';
- return s;
-}
-
-/* Return 1 if buffer is empty. */
-int buffer_empty(struct buffer *b)
-{
- return (b->head == NULL);
-}
-
-/* Clear and free all allocated data. */
-void buffer_reset(struct buffer *b)
-{
- struct buffer_data *data;
- struct buffer_data *next;
-
- for (data = b->head; data; data = next) {
- next = data->next;
- BUFFER_DATA_FREE(data);
- }
- b->head = b->tail = NULL;
-}
-
-/* Add buffer_data to the end of buffer. */
-static struct buffer_data *buffer_add(struct buffer *b)
-{
- struct buffer_data *d;
-
- d = _talloc_zero(b,
- offsetof(struct buffer_data, data[b->size]),
- "buffer_add");
- if (!d)
- return NULL;
- d->cp = d->sp = 0;
- d->next = NULL;
-
- if (b->tail)
- b->tail->next = d;
- else
- b->head = d;
- b->tail = d;
-
- return d;
-}
-
-/* Write data to buffer. */
-void buffer_put(struct buffer *b, const void *p, size_t size)
-{
- struct buffer_data *data = b->tail;
- const char *ptr = p;
-
- /* We use even last one byte of data buffer. */
- while (size) {
- size_t chunk;
-
- /* If there is no data buffer add it. */
- if (data == NULL || data->cp == b->size)
- data = buffer_add(b);
-
- chunk =
- ((size <=
- (b->size - data->cp)) ? size : (b->size - data->cp));
- memcpy((data->data + data->cp), ptr, chunk);
- size -= chunk;
- ptr += chunk;
- data->cp += chunk;
- }
-}
-
-/* Insert character into the buffer. */
-void buffer_putc(struct buffer *b, u_char c)
-{
- buffer_put(b, &c, 1);
-}
-
-/* Put string to the buffer. */
-void buffer_putstr(struct buffer *b, const char *c)
-{
- buffer_put(b, c, strlen(c));
-}
-
-/* Keep flushing data to the fd until the buffer is empty or an error is
- encountered or the operation would block. */
-buffer_status_t buffer_flush_all(struct buffer *b, int fd)
-{
- buffer_status_t ret;
- struct buffer_data *head;
- size_t head_sp;
-
- if (!b->head)
- return BUFFER_EMPTY;
- head_sp = (head = b->head)->sp;
- /* Flush all data. */
- while ((ret = buffer_flush_available(b, fd)) == BUFFER_PENDING) {
- if ((b->head == head) && (head_sp == head->sp)
- && (errno != EINTR))
- /* No data was flushed, so kernel buffer must be full. */
- return ret;
- head_sp = (head = b->head)->sp;
- }
-
- return ret;
-}
-
-#if 0
-/* Flush enough data to fill a terminal window of the given scene (used only
- by vty telnet interface). */
-buffer_status_t
-buffer_flush_window(struct buffer * b, int fd, int width, int height,
- int erase_flag, int no_more_flag)
-{
- int nbytes;
- int iov_alloc;
- int iov_index;
- struct iovec *iov;
- struct iovec small_iov[3];
- char more[] = " --More-- ";
- char erase[] =
- { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
- };
- struct buffer_data *data;
- int column;
-
- if (!b->head)
- return BUFFER_EMPTY;
-
- if (height < 1) {
- zlog_warn
- ("%s called with non-positive window height %d, forcing to 1",
- __func__, height);
- height = 1;
- } else if (height >= 2)
- height--;
- if (width < 1) {
- zlog_warn
- ("%s called with non-positive window width %d, forcing to 1",
- __func__, width);
- width = 1;
- }
-
- /* For erase and more data add two to b's buffer_data count. */
- if (b->head->next == NULL) {
- iov_alloc = sizeof(small_iov) / sizeof(small_iov[0]);
- iov = small_iov;
- } else {
- iov_alloc = ((height * (width + 2)) / b->size) + 10;
- iov = XMALLOC(MTYPE_TMP, iov_alloc * sizeof(*iov));
- }
- iov_index = 0;
-
- /* Previously print out is performed. */
- if (erase_flag) {
- iov[iov_index].iov_base = erase;
- iov[iov_index].iov_len = sizeof erase;
- iov_index++;
- }
-
- /* Output data. */
- column = 1; /* Column position of next character displayed. */
- for (data = b->head; data && (height > 0); data = data->next) {
- size_t cp;
-
- cp = data->sp;
- while ((cp < data->cp) && (height > 0)) {
- /* Calculate lines remaining and column position after displaying
- this character. */
- if (data->data[cp] == '\r')
- column = 1;
- else if ((data->data[cp] == '\n') || (column == width)) {
- column = 1;
- height--;
- } else
- column++;
- cp++;
- }
- iov[iov_index].iov_base = (char *)(data->data + data->sp);
- iov[iov_index++].iov_len = cp - data->sp;
- data->sp = cp;
-
- if (iov_index == iov_alloc)
- /* This should not ordinarily happen. */
- {
- iov_alloc *= 2;
- if (iov != small_iov) {
- zlog_warn("%s: growing iov array to %d; "
- "width %d, height %d, size %lu",
- __func__, iov_alloc, width, height,
- (u_long) b->size);
- iov =
- XREALLOC(MTYPE_TMP, iov,
- iov_alloc * sizeof(*iov));
- } else {
- /* This should absolutely never occur. */
- zlog_err
- ("%s: corruption detected: iov_small overflowed; "
- "head %p, tail %p, head->next %p",
- __func__, b->head, b->tail, b->head->next);
- iov =
- XMALLOC(MTYPE_TMP,
- iov_alloc * sizeof(*iov));
- memcpy(iov, small_iov, sizeof(small_iov));
- }
- }
- }
-
- /* In case of `more' display need. */
- if (b->tail && (b->tail->sp < b->tail->cp) && !no_more_flag) {
- iov[iov_index].iov_base = more;
- iov[iov_index].iov_len = sizeof more;
- iov_index++;
- }
-#ifdef IOV_MAX
- /* IOV_MAX are normally defined in <sys/uio.h> , Posix.1g.
- example: Solaris2.6 are defined IOV_MAX size at 16. */
- {
- struct iovec *c_iov = iov;
- nbytes = 0; /* Make sure it's initialized. */
-
- while (iov_index > 0) {
- int iov_size;
-
- iov_size =
- ((iov_index > IOV_MAX) ? IOV_MAX : iov_index);
- if ((nbytes = writev(fd, c_iov, iov_size)) < 0) {
- zlog_warn("%s: writev to fd %d failed: %s",
- __func__, fd, safe_strerror(errno));
- break;
- }
-
- /* move pointer io-vector */
- c_iov += iov_size;
- iov_index -= iov_size;
- }
- }
-#else /* IOV_MAX */
- if ((nbytes = writev(fd, iov, iov_index)) < 0)
- zlog_warn("%s: writev to fd %d failed: %s",
- __func__, fd, safe_strerror(errno));
-#endif /* IOV_MAX */
-
- /* Free printed buffer data. */
- while (b->head && (b->head->sp == b->head->cp)) {
- struct buffer_data *del;
- if (!(b->head = (del = b->head)->next))
- b->tail = NULL;
- BUFFER_DATA_FREE(del);
- }
-
- if (iov != small_iov)
- XFREE(MTYPE_TMP, iov);
-
- return (nbytes < 0) ? BUFFER_ERROR :
- (b->head ? BUFFER_PENDING : BUFFER_EMPTY);
-}
-#endif
-
-/* This function (unlike other buffer_flush* functions above) is designed
-to work with non-blocking sockets. It does not attempt to write out
-all of the queued data, just a "big" chunk. It returns 0 if it was
-able to empty out the buffers completely, 1 if more flushing is
-required later, or -1 on a fatal write error. */
-buffer_status_t buffer_flush_available(struct buffer * b, int fd)
-{
-
-/* These are just reasonable values to make sure a significant amount of
-data is written. There's no need to go crazy and try to write it all
-in one shot. */
-#ifdef IOV_MAX
-#define MAX_CHUNKS ((IOV_MAX >= 16) ? 16 : IOV_MAX)
-#else
-#define MAX_CHUNKS 16
-#endif
-#define MAX_FLUSH 131072
-
- struct buffer_data *d;
- size_t written;
- struct iovec iov[MAX_CHUNKS];
- size_t iovcnt = 0;
- size_t nbyte = 0;
-
- for (d = b->head; d && (iovcnt < MAX_CHUNKS) && (nbyte < MAX_FLUSH);
- d = d->next, iovcnt++) {
- iov[iovcnt].iov_base = d->data + d->sp;
- nbyte += (iov[iovcnt].iov_len = d->cp - d->sp);
- }
-
- if (!nbyte)
- /* No data to flush: should we issue a warning message? */
- return BUFFER_EMPTY;
-
- /* only place where written should be sign compared */
- if ((ssize_t) (written = writev(fd, iov, iovcnt)) < 0) {
- if (ERRNO_IO_RETRY(errno))
- /* Calling code should try again later. */
- return BUFFER_PENDING;
- return BUFFER_ERROR;
- }
-
- /* Free printed buffer data. */
- while (written > 0) {
- struct buffer_data *d;
- if (!(d = b->head))
- break;
- if (written < d->cp - d->sp) {
- d->sp += written;
- return BUFFER_PENDING;
- }
-
- written -= (d->cp - d->sp);
- if (!(b->head = d->next))
- b->tail = NULL;
- BUFFER_DATA_FREE(d);
- }
-
- return b->head ? BUFFER_PENDING : BUFFER_EMPTY;
-
-#undef MAX_CHUNKS
-#undef MAX_FLUSH
-}
-
-buffer_status_t
-buffer_write(struct buffer * b, int fd, const void *p, size_t size)
-{
- ssize_t nbytes;
-
-#if 0
- /* Should we attempt to drain any previously buffered data? This could help reduce latency in pushing out the data if we are stuck in a long-running thread that is preventing the main select loop from calling the flush thread... */
-
- if (b->head && (buffer_flush_available(b, fd) == BUFFER_ERROR))
- return BUFFER_ERROR;
-#endif
- if (b->head)
- /* Buffer is not empty, so do not attempt to write the new data. */
- nbytes = 0;
- else if ((nbytes = write(fd, p, size)) < 0) {
- if (ERRNO_IO_RETRY(errno))
- nbytes = 0;
- else
- return BUFFER_ERROR;
- }
- /* Add any remaining data to the buffer. */
- {
- size_t written = nbytes;
- if (written < size)
- buffer_put(b, ((const char *)p) + written,
- size - written);
- }
- return b->head ? BUFFER_PENDING : BUFFER_EMPTY;
-}
diff --git a/openbsc/src/vty/command.c b/openbsc/src/vty/command.c
deleted file mode 100644
index 5be0092a6..000000000
--- a/openbsc/src/vty/command.c
+++ /dev/null
@@ -1,3211 +0,0 @@
-/*
- $Id: command.c,v 1.47 2005/04/25 16:26:42 paul Exp $
-
- Command interpreter routine for virtual terminal [aka TeletYpe]
- Copyright (C) 1997, 98, 99 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 02111-1307, USA. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <errno.h>
-#define _XOPEN_SOURCE
-#include <unistd.h>
-#include <assert.h>
-#include <ctype.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-
-#include <vty/vector.h>
-#include <vty/vty.h>
-#include <vty/command.h>
-
-#include <openbsc/gsm_data.h>
-#include <openbsc/gsm_subscriber.h>
-#include <osmocore/talloc.h>
-
-#define CONFIGFILE_MASK 022
-
-void *tall_vty_cmd_ctx;
-
-/* Command vector which includes some level of command lists. Normally
- each daemon maintains each own cmdvec. */
-vector cmdvec;
-
-/* Host information structure. */
-struct host host;
-
-/* Standard command node structures. */
-struct cmd_node auth_node = {
- AUTH_NODE,
- "Password: ",
-};
-
-struct cmd_node view_node = {
- VIEW_NODE,
- "%s> ",
-};
-
-struct cmd_node auth_enable_node = {
- AUTH_ENABLE_NODE,
- "Password: ",
-};
-
-struct cmd_node enable_node = {
- ENABLE_NODE,
- "%s# ",
-};
-
-struct cmd_node config_node = {
- CONFIG_NODE,
- "%s(config)# ",
- 1
-};
-
-/* Default motd string. */
-const char *default_motd = "";
-
-/* This is called from main when a daemon is invoked with -v or --version. */
-void print_version(int print_copyright)
-{
- printf("%s version %s\n", host.prog_name, host.prog_version);
- if (print_copyright)
- printf("\n%s\n", host.prog_copyright);
-}
-
-/* Utility function to concatenate argv argument into a single string
- with inserting ' ' character between each argument. */
-char *argv_concat(const char **argv, int argc, int shift)
-{
- int i;
- size_t len;
- char *str;
- char *p;
-
- len = 0;
- for (i = shift; i < argc; i++)
- len += strlen(argv[i]) + 1;
- if (!len)
- return NULL;
- p = str = _talloc_zero(tall_vty_cmd_ctx, len, "arvg_concat");
- for (i = shift; i < argc; i++) {
- size_t arglen;
- memcpy(p, argv[i], (arglen = strlen(argv[i])));
- p += arglen;
- *p++ = ' ';
- }
- *(p - 1) = '\0';
- return str;
-}
-
-/* Install top node of command vector. */
-void install_node(struct cmd_node *node, int (*func) (struct vty *))
-{
- vector_set_index(cmdvec, node->node, node);
- node->func = func;
- node->cmd_vector = vector_init(VECTOR_MIN_SIZE);
-}
-
-/* Compare two command's string. Used in sort_node (). */
-static int cmp_node(const void *p, const void *q)
-{
- struct cmd_element *a = *(struct cmd_element **)p;
- struct cmd_element *b = *(struct cmd_element **)q;
-
- return strcmp(a->string, b->string);
-}
-
-static int cmp_desc(const void *p, const void *q)
-{
- struct desc *a = *(struct desc **)p;
- struct desc *b = *(struct desc **)q;
-
- return strcmp(a->cmd, b->cmd);
-}
-
-/* Sort each node's command element according to command string. */
-void sort_node()
-{
- unsigned int i, j;
- struct cmd_node *cnode;
- vector descvec;
- struct cmd_element *cmd_element;
-
- for (i = 0; i < vector_active(cmdvec); i++)
- if ((cnode = vector_slot(cmdvec, i)) != NULL) {
- vector cmd_vector = cnode->cmd_vector;
- qsort(cmd_vector->index, vector_active(cmd_vector),
- sizeof(void *), cmp_node);
-
- for (j = 0; j < vector_active(cmd_vector); j++)
- if ((cmd_element =
- vector_slot(cmd_vector, j)) != NULL
- && vector_active(cmd_element->strvec)) {
- descvec =
- vector_slot(cmd_element->strvec,
- vector_active
- (cmd_element->strvec) -
- 1);
- qsort(descvec->index,
- vector_active(descvec),
- sizeof(void *), cmp_desc);
- }
- }
-}
-
-/* Breaking up string into each command piece. I assume given
- character is separated by a space character. Return value is a
- vector which includes char ** data element. */
-vector cmd_make_strvec(const char *string)
-{
- const char *cp, *start;
- char *token;
- int strlen;
- vector strvec;
-
- if (string == NULL)
- return NULL;
-
- cp = string;
-
- /* Skip white spaces. */
- while (isspace((int)*cp) && *cp != '\0')
- cp++;
-
- /* Return if there is only white spaces */
- if (*cp == '\0')
- return NULL;
-
- if (*cp == '!' || *cp == '#')
- return NULL;
-
- /* Prepare return vector. */
- strvec = vector_init(VECTOR_MIN_SIZE);
-
- /* Copy each command piece and set into vector. */
- while (1) {
- start = cp;
- while (!(isspace((int)*cp) || *cp == '\r' || *cp == '\n') &&
- *cp != '\0')
- cp++;
- strlen = cp - start;
- token = _talloc_zero(tall_vty_cmd_ctx, strlen + 1, "make_strvec");
- memcpy(token, start, strlen);
- *(token + strlen) = '\0';
- vector_set(strvec, token);
-
- while ((isspace((int)*cp) || *cp == '\n' || *cp == '\r') &&
- *cp != '\0')
- cp++;
-
- if (*cp == '\0')
- return strvec;
- }
-}
-
-/* Free allocated string vector. */
-void cmd_free_strvec(vector v)
-{
- unsigned int i;
- char *cp;
-
- if (!v)
- return;
-
- for (i = 0; i < vector_active(v); i++)
- if ((cp = vector_slot(v, i)) != NULL)
- talloc_free(cp);
-
- vector_free(v);
-}
-
-/* Fetch next description. Used in cmd_make_descvec(). */
-static char *cmd_desc_str(const char **string)
-{
- const char *cp, *start;
- char *token;
- int strlen;
-
- cp = *string;
-
- if (cp == NULL)
- return NULL;
-
- /* Skip white spaces. */
- while (isspace((int)*cp) && *cp != '\0')
- cp++;
-
- /* Return if there is only white spaces */
- if (*cp == '\0')
- return NULL;
-
- start = cp;
-
- while (!(*cp == '\r' || *cp == '\n') && *cp != '\0')
- cp++;
-
- strlen = cp - start;
- token = _talloc_zero(tall_vty_cmd_ctx, strlen + 1, "cmd_desc_str");
- memcpy(token, start, strlen);
- *(token + strlen) = '\0';
-
- *string = cp;
-
- return token;
-}
-
-/* New string vector. */
-static vector cmd_make_descvec(const char *string, const char *descstr)
-{
- int multiple = 0;
- const char *sp;
- char *token;
- int len;
- const char *cp;
- const char *dp;
- vector allvec;
- vector strvec = NULL;
- struct desc *desc;
-
- cp = string;
- dp = descstr;
-
- if (cp == NULL)
- return NULL;
-
- allvec = vector_init(VECTOR_MIN_SIZE);
-
- while (1) {
- while (isspace((int)*cp) && *cp != '\0')
- cp++;
-
- if (*cp == '(') {
- multiple = 1;
- cp++;
- }
- if (*cp == ')') {
- multiple = 0;
- cp++;
- }
- if (*cp == '|') {
- if (!multiple) {
- fprintf(stderr, "Command parse error!: %s\n",
- string);
- exit(1);
- }
- cp++;
- }
-
- while (isspace((int)*cp) && *cp != '\0')
- cp++;
-
- if (*cp == '(') {
- multiple = 1;
- cp++;
- }
-
- if (*cp == '\0')
- return allvec;
-
- sp = cp;
-
- while (!
- (isspace((int)*cp) || *cp == '\r' || *cp == '\n'
- || *cp == ')' || *cp == '|') && *cp != '\0')
- cp++;
-
- len = cp - sp;
-
- token = _talloc_zero(tall_vty_cmd_ctx, len + 1, "cmd_make_descvec");
- memcpy(token, sp, len);
- *(token + len) = '\0';
-
- desc = talloc_zero(tall_vty_cmd_ctx, struct desc);
- desc->cmd = token;
- desc->str = cmd_desc_str(&dp);
-
- if (multiple) {
- if (multiple == 1) {
- strvec = vector_init(VECTOR_MIN_SIZE);
- vector_set(allvec, strvec);
- }
- multiple++;
- } else {
- strvec = vector_init(VECTOR_MIN_SIZE);
- vector_set(allvec, strvec);
- }
- vector_set(strvec, desc);
- }
-}
-
-/* Count mandantory string vector size. This is to determine inputed
- command has enough command length. */
-static int cmd_cmdsize(vector strvec)
-{
- unsigned int i;
- int size = 0;
- vector descvec;
- struct desc *desc;
-
- for (i = 0; i < vector_active(strvec); i++)
- if ((descvec = vector_slot(strvec, i)) != NULL) {
- if ((vector_active(descvec)) == 1
- && (desc = vector_slot(descvec, 0)) != NULL) {
- if (desc->cmd == NULL || CMD_OPTION(desc->cmd))
- return size;
- else
- size++;
- } else
- size++;
- }
- return size;
-}
-
-/* Return prompt character of specified node. */
-const char *cmd_prompt(enum node_type node)
-{
- struct cmd_node *cnode;
-
- cnode = vector_slot(cmdvec, node);
- return cnode->prompt;
-}
-
-/* Install a command into a node. */
-void install_element(enum node_type ntype, struct cmd_element *cmd)
-{
- struct cmd_node *cnode;
-
- cnode = vector_slot(cmdvec, ntype);
-
- if (cnode == NULL) {
- fprintf(stderr,
- "Command node %d doesn't exist, please check it\n",
- ntype);
- exit(1);
- }
-
- vector_set(cnode->cmd_vector, cmd);
-
- cmd->strvec = cmd_make_descvec(cmd->string, cmd->doc);
- cmd->cmdsize = cmd_cmdsize(cmd->strvec);
-}
-
-/* Install a command into VIEW and ENABLE node */
-void install_element_ve(struct cmd_element *cmd)
-{
- install_element(VIEW_NODE, cmd);
- install_element(ENABLE_NODE, cmd);
-}
-
-#ifdef VTY_CRYPT_PW
-static unsigned char itoa64[] =
- "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-static void to64(char *s, long v, int n)
-{
- while (--n >= 0) {
- *s++ = itoa64[v & 0x3f];
- v >>= 6;
- }
-}
-
-static char *zencrypt(const char *passwd)
-{
- char salt[6];
- struct timeval tv;
- char *crypt(const char *, const char *);
-
- gettimeofday(&tv, 0);
-
- to64(&salt[0], random(), 3);
- to64(&salt[3], tv.tv_usec, 3);
- salt[5] = '\0';
-
- return crypt(passwd, salt);
-}
-#endif
-
-/* This function write configuration of this host. */
-static int config_write_host(struct vty *vty)
-{
- if (host.name)
- vty_out(vty, "hostname %s%s", host.name, VTY_NEWLINE);
-
- if (host.encrypt) {
- if (host.password_encrypt)
- vty_out(vty, "password 8 %s%s", host.password_encrypt,
- VTY_NEWLINE);
- if (host.enable_encrypt)
- vty_out(vty, "enable password 8 %s%s",
- host.enable_encrypt, VTY_NEWLINE);
- } else {
- if (host.password)
- vty_out(vty, "password %s%s", host.password,
- VTY_NEWLINE);
- if (host.enable)
- vty_out(vty, "enable password %s%s", host.enable,
- VTY_NEWLINE);
- }
-
- if (host.advanced)
- vty_out(vty, "service advanced-vty%s", VTY_NEWLINE);
-
- if (host.encrypt)
- vty_out(vty, "service password-encryption%s", VTY_NEWLINE);
-
- if (host.lines >= 0)
- vty_out(vty, "service terminal-length %d%s", host.lines,
- VTY_NEWLINE);
-
- if (host.motdfile)
- vty_out(vty, "banner motd file %s%s", host.motdfile,
- VTY_NEWLINE);
- else if (!host.motd)
- vty_out(vty, "no banner motd%s", VTY_NEWLINE);
-
- return 1;
-}
-
-/* Utility function for getting command vector. */
-static vector cmd_node_vector(vector v, enum node_type ntype)
-{
- struct cmd_node *cnode = vector_slot(v, ntype);
- return cnode->cmd_vector;
-}
-
-/* Completion match types. */
-enum match_type {
- no_match,
- extend_match,
- ipv4_prefix_match,
- ipv4_match,
- ipv6_prefix_match,
- ipv6_match,
- range_match,
- vararg_match,
- partly_match,
- exact_match
-};
-
-static enum match_type cmd_ipv4_match(const char *str)
-{
- const char *sp;
- int dots = 0, nums = 0;
- char buf[4];
-
- if (str == NULL)
- return partly_match;
-
- for (;;) {
- memset(buf, 0, sizeof(buf));
- sp = str;
- while (*str != '\0') {
- if (*str == '.') {
- if (dots >= 3)
- return no_match;
-
- if (*(str + 1) == '.')
- return no_match;
-
- if (*(str + 1) == '\0')
- return partly_match;
-
- dots++;
- break;
- }
- if (!isdigit((int)*str))
- return no_match;
-
- str++;
- }
-
- if (str - sp > 3)
- return no_match;
-
- strncpy(buf, sp, str - sp);
- if (atoi(buf) > 255)
- return no_match;
-
- nums++;
-
- if (*str == '\0')
- break;
-
- str++;
- }
-
- if (nums < 4)
- return partly_match;
-
- return exact_match;
-}
-
-static enum match_type cmd_ipv4_prefix_match(const char *str)
-{
- const char *sp;
- int dots = 0;
- char buf[4];
-
- if (str == NULL)
- return partly_match;
-
- for (;;) {
- memset(buf, 0, sizeof(buf));
- sp = str;
- while (*str != '\0' && *str != '/') {
- if (*str == '.') {
- if (dots == 3)
- return no_match;
-
- if (*(str + 1) == '.' || *(str + 1) == '/')
- return no_match;
-
- if (*(str + 1) == '\0')
- return partly_match;
-
- dots++;
- break;
- }
-
- if (!isdigit((int)*str))
- return no_match;
-
- str++;
- }
-
- if (str - sp > 3)
- return no_match;
-
- strncpy(buf, sp, str - sp);
- if (atoi(buf) > 255)
- return no_match;
-
- if (dots == 3) {
- if (*str == '/') {
- if (*(str + 1) == '\0')
- return partly_match;
-
- str++;
- break;
- } else if (*str == '\0')
- return partly_match;
- }
-
- if (*str == '\0')
- return partly_match;
-
- str++;
- }
-
- sp = str;
- while (*str != '\0') {
- if (!isdigit((int)*str))
- return no_match;
-
- str++;
- }
-
- if (atoi(sp) > 32)
- return no_match;
-
- return exact_match;
-}
-
-#define IPV6_ADDR_STR "0123456789abcdefABCDEF:.%"
-#define IPV6_PREFIX_STR "0123456789abcdefABCDEF:.%/"
-#define STATE_START 1
-#define STATE_COLON 2
-#define STATE_DOUBLE 3
-#define STATE_ADDR 4
-#define STATE_DOT 5
-#define STATE_SLASH 6
-#define STATE_MASK 7
-
-#ifdef HAVE_IPV6
-
-static enum match_type cmd_ipv6_match(const char *str)
-{
- int state = STATE_START;
- int colons = 0, nums = 0, double_colon = 0;
- const char *sp = NULL;
- struct sockaddr_in6 sin6_dummy;
- int ret;
-
- if (str == NULL)
- return partly_match;
-
- if (strspn(str, IPV6_ADDR_STR) != strlen(str))
- return no_match;
-
- /* use inet_pton that has a better support,
- * for example inet_pton can support the automatic addresses:
- * ::1.2.3.4
- */
- ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr);
-
- if (ret == 1)
- return exact_match;
-
- while (*str != '\0') {
- switch (state) {
- case STATE_START:
- if (*str == ':') {
- if (*(str + 1) != ':' && *(str + 1) != '\0')
- return no_match;
- colons--;
- state = STATE_COLON;
- } else {
- sp = str;
- state = STATE_ADDR;
- }
-
- continue;
- case STATE_COLON:
- colons++;
- if (*(str + 1) == ':')
- state = STATE_DOUBLE;
- else {
- sp = str + 1;
- state = STATE_ADDR;
- }
- break;
- case STATE_DOUBLE:
- if (double_colon)
- return no_match;
-
- if (*(str + 1) == ':')
- return no_match;
- else {
- if (*(str + 1) != '\0')
- colons++;
- sp = str + 1;
- state = STATE_ADDR;
- }
-
- double_colon++;
- nums++;
- break;
- case STATE_ADDR:
- if (*(str + 1) == ':' || *(str + 1) == '\0') {
- if (str - sp > 3)
- return no_match;
-
- nums++;
- state = STATE_COLON;
- }
- if (*(str + 1) == '.')
- state = STATE_DOT;
- break;
- case STATE_DOT:
- state = STATE_ADDR;
- break;
- default:
- break;
- }
-
- if (nums > 8)
- return no_match;
-
- if (colons > 7)
- return no_match;
-
- str++;
- }
-
-#if 0
- if (nums < 11)
- return partly_match;
-#endif /* 0 */
-
- return exact_match;
-}
-
-static enum match_type cmd_ipv6_prefix_match(const char *str)
-{
- int state = STATE_START;
- int colons = 0, nums = 0, double_colon = 0;
- int mask;
- const char *sp = NULL;
- char *endptr = NULL;
-
- if (str == NULL)
- return partly_match;
-
- if (strspn(str, IPV6_PREFIX_STR) != strlen(str))
- return no_match;
-
- while (*str != '\0' && state != STATE_MASK) {
- switch (state) {
- case STATE_START:
- if (*str == ':') {
- if (*(str + 1) != ':' && *(str + 1) != '\0')
- return no_match;
- colons--;
- state = STATE_COLON;
- } else {
- sp = str;
- state = STATE_ADDR;
- }
-
- continue;
- case STATE_COLON:
- colons++;
- if (*(str + 1) == '/')
- return no_match;
- else if (*(str + 1) == ':')
- state = STATE_DOUBLE;
- else {
- sp = str + 1;
- state = STATE_ADDR;
- }
- break;
- case STATE_DOUBLE:
- if (double_colon)
- return no_match;
-
- if (*(str + 1) == ':')
- return no_match;
- else {
- if (*(str + 1) != '\0' && *(str + 1) != '/')
- colons++;
- sp = str + 1;
-
- if (*(str + 1) == '/')
- state = STATE_SLASH;
- else
- state = STATE_ADDR;
- }
-
- double_colon++;
- nums += 1;
- break;
- case STATE_ADDR:
- if (*(str + 1) == ':' || *(str + 1) == '.'
- || *(str + 1) == '\0' || *(str + 1) == '/') {
- if (str - sp > 3)
- return no_match;
-
- for (; sp <= str; sp++)
- if (*sp == '/')
- return no_match;
-
- nums++;
-
- if (*(str + 1) == ':')
- state = STATE_COLON;
- else if (*(str + 1) == '.')
- state = STATE_DOT;
- else if (*(str + 1) == '/')
- state = STATE_SLASH;
- }
- break;
- case STATE_DOT:
- state = STATE_ADDR;
- break;
- case STATE_SLASH:
- if (*(str + 1) == '\0')
- return partly_match;
-
- state = STATE_MASK;
- break;
- default:
- break;
- }
-
- if (nums > 11)
- return no_match;
-
- if (colons > 7)
- return no_match;
-
- str++;
- }
-
- if (state < STATE_MASK)
- return partly_match;
-
- mask = strtol(str, &endptr, 10);
- if (*endptr != '\0')
- return no_match;
-
- if (mask < 0 || mask > 128)
- return no_match;
-
-/* I don't know why mask < 13 makes command match partly.
- Forgive me to make this comments. I Want to set static default route
- because of lack of function to originate default in ospf6d; sorry
- yasu
- if (mask < 13)
- return partly_match;
-*/
-
- return exact_match;
-}
-
-#endif /* HAVE_IPV6 */
-
-#define DECIMAL_STRLEN_MAX 10
-
-static int cmd_range_match(const char *range, const char *str)
-{
- char *p;
- char buf[DECIMAL_STRLEN_MAX + 1];
- char *endptr = NULL;
- unsigned long min, max, val;
-
- if (str == NULL)
- return 1;
-
- val = strtoul(str, &endptr, 10);
- if (*endptr != '\0')
- return 0;
-
- range++;
- p = strchr(range, '-');
- if (p == NULL)
- return 0;
- if (p - range > DECIMAL_STRLEN_MAX)
- return 0;
- strncpy(buf, range, p - range);
- buf[p - range] = '\0';
- min = strtoul(buf, &endptr, 10);
- if (*endptr != '\0')
- return 0;
-
- range = p + 1;
- p = strchr(range, '>');
- if (p == NULL)
- return 0;
- if (p - range > DECIMAL_STRLEN_MAX)
- return 0;
- strncpy(buf, range, p - range);
- buf[p - range] = '\0';
- max = strtoul(buf, &endptr, 10);
- if (*endptr != '\0')
- return 0;
-
- if (val < min || val > max)
- return 0;
-
- return 1;
-}
-
-/* Make completion match and return match type flag. */
-static enum match_type
-cmd_filter_by_completion(char *command, vector v, unsigned int index)
-{
- unsigned int i;
- const char *str;
- struct cmd_element *cmd_element;
- enum match_type match_type;
- vector descvec;
- struct desc *desc;
-
- match_type = no_match;
-
- /* If command and cmd_element string does not match set NULL to vector */
- for (i = 0; i < vector_active(v); i++)
- if ((cmd_element = vector_slot(v, i)) != NULL) {
- if (index >= vector_active(cmd_element->strvec))
- vector_slot(v, i) = NULL;
- else {
- unsigned int j;
- int matched = 0;
-
- descvec =
- vector_slot(cmd_element->strvec, index);
-
- for (j = 0; j < vector_active(descvec); j++)
- if ((desc = vector_slot(descvec, j))) {
- str = desc->cmd;
-
- if (CMD_VARARG(str)) {
- if (match_type <
- vararg_match)
- match_type =
- vararg_match;
- matched++;
- } else if (CMD_RANGE(str)) {
- if (cmd_range_match
- (str, command)) {
- if (match_type <
- range_match)
- match_type
- =
- range_match;
-
- matched++;
- }
- }
-#ifdef HAVE_IPV6
- else if (CMD_IPV6(str)) {
- if (cmd_ipv6_match
- (command)) {
- if (match_type <
- ipv6_match)
- match_type
- =
- ipv6_match;
-
- matched++;
- }
- } else if (CMD_IPV6_PREFIX(str)) {
- if (cmd_ipv6_prefix_match(command)) {
- if (match_type <
- ipv6_prefix_match)
- match_type
- =
- ipv6_prefix_match;
-
- matched++;
- }
- }
-#endif /* HAVE_IPV6 */
- else if (CMD_IPV4(str)) {
- if (cmd_ipv4_match
- (command)) {
- if (match_type <
- ipv4_match)
- match_type
- =
- ipv4_match;
-
- matched++;
- }
- } else if (CMD_IPV4_PREFIX(str)) {
- if (cmd_ipv4_prefix_match(command)) {
- if (match_type <
- ipv4_prefix_match)
- match_type
- =
- ipv4_prefix_match;
- matched++;
- }
- } else
- /* Check is this point's argument optional ? */
- if (CMD_OPTION(str)
- ||
- CMD_VARIABLE(str)) {
- if (match_type <
- extend_match)
- match_type =
- extend_match;
- matched++;
- } else
- if (strncmp
- (command, str,
- strlen(command)) ==
- 0) {
- if (strcmp(command, str)
- == 0)
- match_type =
- exact_match;
- else {
- if (match_type <
- partly_match)
- match_type
- =
- partly_match;
- }
- matched++;
- }
- }
- if (!matched)
- vector_slot(v, i) = NULL;
- }
- }
- return match_type;
-}
-
-/* Filter vector by command character with index. */
-static enum match_type
-cmd_filter_by_string(char *command, vector v, unsigned int index)
-{
- unsigned int i;
- const char *str;
- struct cmd_element *cmd_element;
- enum match_type match_type;
- vector descvec;
- struct desc *desc;
-
- match_type = no_match;
-
- /* If command and cmd_element string does not match set NULL to vector */
- for (i = 0; i < vector_active(v); i++)
- if ((cmd_element = vector_slot(v, i)) != NULL) {
- /* If given index is bigger than max string vector of command,
- set NULL */
- if (index >= vector_active(cmd_element->strvec))
- vector_slot(v, i) = NULL;
- else {
- unsigned int j;
- int matched = 0;
-
- descvec =
- vector_slot(cmd_element->strvec, index);
-
- for (j = 0; j < vector_active(descvec); j++)
- if ((desc = vector_slot(descvec, j))) {
- str = desc->cmd;
-
- if (CMD_VARARG(str)) {
- if (match_type <
- vararg_match)
- match_type =
- vararg_match;
- matched++;
- } else if (CMD_RANGE(str)) {
- if (cmd_range_match
- (str, command)) {
- if (match_type <
- range_match)
- match_type
- =
- range_match;
- matched++;
- }
- }
-#ifdef HAVE_IPV6
- else if (CMD_IPV6(str)) {
- if (cmd_ipv6_match
- (command) ==
- exact_match) {
- if (match_type <
- ipv6_match)
- match_type
- =
- ipv6_match;
- matched++;
- }
- } else if (CMD_IPV6_PREFIX(str)) {
- if (cmd_ipv6_prefix_match(command) == exact_match) {
- if (match_type <
- ipv6_prefix_match)
- match_type
- =
- ipv6_prefix_match;
- matched++;
- }
- }
-#endif /* HAVE_IPV6 */
- else if (CMD_IPV4(str)) {
- if (cmd_ipv4_match
- (command) ==
- exact_match) {
- if (match_type <
- ipv4_match)
- match_type
- =
- ipv4_match;
- matched++;
- }
- } else if (CMD_IPV4_PREFIX(str)) {
- if (cmd_ipv4_prefix_match(command) == exact_match) {
- if (match_type <
- ipv4_prefix_match)
- match_type
- =
- ipv4_prefix_match;
- matched++;
- }
- } else if (CMD_OPTION(str)
- || CMD_VARIABLE(str))
- {
- if (match_type <
- extend_match)
- match_type =
- extend_match;
- matched++;
- } else {
- if (strcmp(command, str)
- == 0) {
- match_type =
- exact_match;
- matched++;
- }
- }
- }
- if (!matched)
- vector_slot(v, i) = NULL;
- }
- }
- return match_type;
-}
-
-/* Check ambiguous match */
-static int
-is_cmd_ambiguous(char *command, vector v, int index, enum match_type type)
-{
- unsigned int i;
- unsigned int j;
- const char *str = NULL;
- struct cmd_element *cmd_element;
- const char *matched = NULL;
- vector descvec;
- struct desc *desc;
-
- for (i = 0; i < vector_active(v); i++)
- if ((cmd_element = vector_slot(v, i)) != NULL) {
- int match = 0;
-
- descvec = vector_slot(cmd_element->strvec, index);
-
- for (j = 0; j < vector_active(descvec); j++)
- if ((desc = vector_slot(descvec, j))) {
- enum match_type ret;
-
- str = desc->cmd;
-
- switch (type) {
- case exact_match:
- if (!
- (CMD_OPTION(str)
- || CMD_VARIABLE(str))
-&& strcmp(command, str) == 0)
- match++;
- break;
- case partly_match:
- if (!
- (CMD_OPTION(str)
- || CMD_VARIABLE(str))
-&& strncmp(command, str, strlen(command)) == 0) {
- if (matched
- && strcmp(matched,
- str) != 0)
- return 1; /* There is ambiguous match. */
- else
- matched = str;
- match++;
- }
- break;
- case range_match:
- if (cmd_range_match
- (str, command)) {
- if (matched
- && strcmp(matched,
- str) != 0)
- return 1;
- else
- matched = str;
- match++;
- }
- break;
-#ifdef HAVE_IPV6
- case ipv6_match:
- if (CMD_IPV6(str))
- match++;
- break;
- case ipv6_prefix_match:
- if ((ret =
- cmd_ipv6_prefix_match
- (command)) != no_match) {
- if (ret == partly_match)
- return 2; /* There is incomplete match. */
-
- match++;
- }
- break;
-#endif /* HAVE_IPV6 */
- case ipv4_match:
- if (CMD_IPV4(str))
- match++;
- break;
- case ipv4_prefix_match:
- if ((ret =
- cmd_ipv4_prefix_match
- (command)) != no_match) {
- if (ret == partly_match)
- return 2; /* There is incomplete match. */
-
- match++;
- }
- break;
- case extend_match:
- if (CMD_OPTION(str)
- || CMD_VARIABLE(str))
- match++;
- break;
- case no_match:
- default:
- break;
- }
- }
- if (!match)
- vector_slot(v, i) = NULL;
- }
- return 0;
-}
-
-/* If src matches dst return dst string, otherwise return NULL */
-static const char *cmd_entry_function(const char *src, const char *dst)
-{
- /* Skip variable arguments. */
- if (CMD_OPTION(dst) || CMD_VARIABLE(dst) || CMD_VARARG(dst) ||
- CMD_IPV4(dst) || CMD_IPV4_PREFIX(dst) || CMD_RANGE(dst))
- return NULL;
-
- /* In case of 'command \t', given src is NULL string. */
- if (src == NULL)
- return dst;
-
- /* Matched with input string. */
- if (strncmp(src, dst, strlen(src)) == 0)
- return dst;
-
- return NULL;
-}
-
-/* If src matches dst return dst string, otherwise return NULL */
-/* This version will return the dst string always if it is
- CMD_VARIABLE for '?' key processing */
-static const char *cmd_entry_function_desc(const char *src, const char *dst)
-{
- if (CMD_VARARG(dst))
- return dst;
-
- if (CMD_RANGE(dst)) {
- if (cmd_range_match(dst, src))
- return dst;
- else
- return NULL;
- }
-#ifdef HAVE_IPV6
- if (CMD_IPV6(dst)) {
- if (cmd_ipv6_match(src))
- return dst;
- else
- return NULL;
- }
-
- if (CMD_IPV6_PREFIX(dst)) {
- if (cmd_ipv6_prefix_match(src))
- return dst;
- else
- return NULL;
- }
-#endif /* HAVE_IPV6 */
-
- if (CMD_IPV4(dst)) {
- if (cmd_ipv4_match(src))
- return dst;
- else
- return NULL;
- }
-
- if (CMD_IPV4_PREFIX(dst)) {
- if (cmd_ipv4_prefix_match(src))
- return dst;
- else
- return NULL;
- }
-
- /* Optional or variable commands always match on '?' */
- if (CMD_OPTION(dst) || CMD_VARIABLE(dst))
- return dst;
-
- /* In case of 'command \t', given src is NULL string. */
- if (src == NULL)
- return dst;
-
- if (strncmp(src, dst, strlen(src)) == 0)
- return dst;
- else
- return NULL;
-}
-
-/* Check same string element existence. If it isn't there return
- 1. */
-static int cmd_unique_string(vector v, const char *str)
-{
- unsigned int i;
- char *match;
-
- for (i = 0; i < vector_active(v); i++)
- if ((match = vector_slot(v, i)) != NULL)
- if (strcmp(match, str) == 0)
- return 0;
- return 1;
-}
-
-/* Compare string to description vector. If there is same string
- return 1 else return 0. */
-static int desc_unique_string(vector v, const char *str)
-{
- unsigned int i;
- struct desc *desc;
-
- for (i = 0; i < vector_active(v); i++)
- if ((desc = vector_slot(v, i)) != NULL)
- if (strcmp(desc->cmd, str) == 0)
- return 1;
- return 0;
-}
-
-static int cmd_try_do_shortcut(enum node_type node, char *first_word)
-{
- if (first_word != NULL &&
- node != AUTH_NODE &&
- node != VIEW_NODE &&
- node != AUTH_ENABLE_NODE &&
- node != ENABLE_NODE && 0 == strcmp("do", first_word))
- return 1;
- return 0;
-}
-
-/* '?' describe command support. */
-static vector
-cmd_describe_command_real(vector vline, struct vty *vty, int *status)
-{
- unsigned int i;
- vector cmd_vector;
-#define INIT_MATCHVEC_SIZE 10
- vector matchvec;
- struct cmd_element *cmd_element;
- unsigned int index;
- int ret;
- enum match_type match;
- char *command;
- static struct desc desc_cr = { "<cr>", "" };
-
- /* Set index. */
- if (vector_active(vline) == 0) {
- *status = CMD_ERR_NO_MATCH;
- return NULL;
- } else
- index = vector_active(vline) - 1;
-
- /* Make copy vector of current node's command vector. */
- cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node));
-
- /* Prepare match vector */
- matchvec = vector_init(INIT_MATCHVEC_SIZE);
-
- /* Filter commands. */
- /* Only words precedes current word will be checked in this loop. */
- for (i = 0; i < index; i++)
- if ((command = vector_slot(vline, i))) {
- match =
- cmd_filter_by_completion(command, cmd_vector, i);
-
- if (match == vararg_match) {
- struct cmd_element *cmd_element;
- vector descvec;
- unsigned int j, k;
-
- for (j = 0; j < vector_active(cmd_vector); j++)
- if ((cmd_element =
- vector_slot(cmd_vector, j)) != NULL
- &&
- (vector_active
- (cmd_element->strvec))) {
- descvec =
- vector_slot(cmd_element->
- strvec,
- vector_active
- (cmd_element->
- strvec) - 1);
- for (k = 0;
- k < vector_active(descvec);
- k++) {
- struct desc *desc =
- vector_slot(descvec,
- k);
- vector_set(matchvec,
- desc);
- }
- }
-
- vector_set(matchvec, &desc_cr);
- vector_free(cmd_vector);
-
- return matchvec;
- }
-
- if ((ret =
- is_cmd_ambiguous(command, cmd_vector, i,
- match)) == 1) {
- vector_free(cmd_vector);
- *status = CMD_ERR_AMBIGUOUS;
- return NULL;
- } else if (ret == 2) {
- vector_free(cmd_vector);
- *status = CMD_ERR_NO_MATCH;
- return NULL;
- }
- }
-
- /* Prepare match vector */
- /* matchvec = vector_init (INIT_MATCHVEC_SIZE); */
-
- /* Make sure that cmd_vector is filtered based on current word */
- command = vector_slot(vline, index);
- if (command)
- match = cmd_filter_by_completion(command, cmd_vector, index);
-
- /* Make description vector. */
- for (i = 0; i < vector_active(cmd_vector); i++)
- if ((cmd_element = vector_slot(cmd_vector, i)) != NULL) {
- const char *string = NULL;
- vector strvec = cmd_element->strvec;
-
- /* if command is NULL, index may be equal to vector_active */
- if (command && index >= vector_active(strvec))
- vector_slot(cmd_vector, i) = NULL;
- else {
- /* Check if command is completed. */
- if (command == NULL
- && index == vector_active(strvec)) {
- string = "<cr>";
- if (!desc_unique_string
- (matchvec, string))
- vector_set(matchvec, &desc_cr);
- } else {
- unsigned int j;
- vector descvec =
- vector_slot(strvec, index);
- struct desc *desc;
-
- for (j = 0; j < vector_active(descvec);
- j++)
- if ((desc =
- vector_slot(descvec, j))) {
- string =
- cmd_entry_function_desc
- (command,
- desc->cmd);
- if (string) {
- /* Uniqueness check */
- if (!desc_unique_string(matchvec, string))
- vector_set
- (matchvec,
- desc);
- }
- }
- }
- }
- }
- vector_free(cmd_vector);
-
- if (vector_slot(matchvec, 0) == NULL) {
- vector_free(matchvec);
- *status = CMD_ERR_NO_MATCH;
- } else
- *status = CMD_SUCCESS;
-
- return matchvec;
-}
-
-vector cmd_describe_command(vector vline, struct vty * vty, int *status)
-{
- vector ret;
-
- if (cmd_try_do_shortcut(vty->node, vector_slot(vline, 0))) {
- enum node_type onode;
- vector shifted_vline;
- unsigned int index;
-
- onode = vty->node;
- vty->node = ENABLE_NODE;
- /* We can try it on enable node, cos' the vty is authenticated */
-
- shifted_vline = vector_init(vector_count(vline));
- /* use memcpy? */
- for (index = 1; index < vector_active(vline); index++) {
- vector_set_index(shifted_vline, index - 1,
- vector_lookup(vline, index));
- }
-
- ret = cmd_describe_command_real(shifted_vline, vty, status);
-
- vector_free(shifted_vline);
- vty->node = onode;
- return ret;
- }
-
- return cmd_describe_command_real(vline, vty, status);
-}
-
-/* Check LCD of matched command. */
-static int cmd_lcd(char **matched)
-{
- int i;
- int j;
- int lcd = -1;
- char *s1, *s2;
- char c1, c2;
-
- if (matched[0] == NULL || matched[1] == NULL)
- return 0;
-
- for (i = 1; matched[i] != NULL; i++) {
- s1 = matched[i - 1];
- s2 = matched[i];
-
- for (j = 0; (c1 = s1[j]) && (c2 = s2[j]); j++)
- if (c1 != c2)
- break;
-
- if (lcd < 0)
- lcd = j;
- else {
- if (lcd > j)
- lcd = j;
- }
- }
- return lcd;
-}
-
-/* Command line completion support. */
-static char **cmd_complete_command_real(vector vline, struct vty *vty,
- int *status)
-{
- unsigned int i;
- vector cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node));
-#define INIT_MATCHVEC_SIZE 10
- vector matchvec;
- struct cmd_element *cmd_element;
- unsigned int index;
- char **match_str;
- struct desc *desc;
- vector descvec;
- char *command;
- int lcd;
-
- if (vector_active(vline) == 0) {
- *status = CMD_ERR_NO_MATCH;
- return NULL;
- } else
- index = vector_active(vline) - 1;
-
- /* First, filter by preceeding command string */
- for (i = 0; i < index; i++)
- if ((command = vector_slot(vline, i))) {
- enum match_type match;
- int ret;
-
- /* First try completion match, if there is exactly match return 1 */
- match =
- cmd_filter_by_completion(command, cmd_vector, i);
-
- /* If there is exact match then filter ambiguous match else check
- ambiguousness. */
- if ((ret =
- is_cmd_ambiguous(command, cmd_vector, i,
- match)) == 1) {
- vector_free(cmd_vector);
- *status = CMD_ERR_AMBIGUOUS;
- return NULL;
- }
- /*
- else if (ret == 2)
- {
- vector_free (cmd_vector);
- *status = CMD_ERR_NO_MATCH;
- return NULL;
- }
- */
- }
-
- /* Prepare match vector. */
- matchvec = vector_init(INIT_MATCHVEC_SIZE);
-
- /* Now we got into completion */
- for (i = 0; i < vector_active(cmd_vector); i++)
- if ((cmd_element = vector_slot(cmd_vector, i))) {
- const char *string;
- vector strvec = cmd_element->strvec;
-
- /* Check field length */
- if (index >= vector_active(strvec))
- vector_slot(cmd_vector, i) = NULL;
- else {
- unsigned int j;
-
- descvec = vector_slot(strvec, index);
- for (j = 0; j < vector_active(descvec); j++)
- if ((desc = vector_slot(descvec, j))) {
- if ((string = cmd_entry_function(vector_slot(vline, index), desc->cmd)))
- if (cmd_unique_string (matchvec, string))
- vector_set (matchvec, talloc_strdup(tall_vty_cmd_ctx, string));
- }
- }
- }
-
- /* We don't need cmd_vector any more. */
- vector_free(cmd_vector);
-
- /* No matched command */
- if (vector_slot(matchvec, 0) == NULL) {
- vector_free(matchvec);
-
- /* In case of 'command \t' pattern. Do you need '?' command at
- the end of the line. */
- if (vector_slot(vline, index) == '\0')
- *status = CMD_ERR_NOTHING_TODO;
- else
- *status = CMD_ERR_NO_MATCH;
- return NULL;
- }
-
- /* Only one matched */
- if (vector_slot(matchvec, 1) == NULL) {
- match_str = (char **)matchvec->index;
- vector_only_wrapper_free(matchvec);
- *status = CMD_COMPLETE_FULL_MATCH;
- return match_str;
- }
- /* Make it sure last element is NULL. */
- vector_set(matchvec, NULL);
-
- /* Check LCD of matched strings. */
- if (vector_slot(vline, index) != NULL) {
- lcd = cmd_lcd((char **)matchvec->index);
-
- if (lcd) {
- int len = strlen(vector_slot(vline, index));
-
- if (len < lcd) {
- char *lcdstr;
-
- lcdstr = _talloc_zero(tall_vty_cmd_ctx, lcd + 1,
- "complete-lcdstr");
- memcpy(lcdstr, matchvec->index[0], lcd);
- lcdstr[lcd] = '\0';
-
- /* match_str = (char **) &lcdstr; */
-
- /* Free matchvec. */
- for (i = 0; i < vector_active(matchvec); i++) {
- if (vector_slot(matchvec, i))
- talloc_free(vector_slot(matchvec, i));
- }
- vector_free(matchvec);
-
- /* Make new matchvec. */
- matchvec = vector_init(INIT_MATCHVEC_SIZE);
- vector_set(matchvec, lcdstr);
- match_str = (char **)matchvec->index;
- vector_only_wrapper_free(matchvec);
-
- *status = CMD_COMPLETE_MATCH;
- return match_str;
- }
- }
- }
-
- match_str = (char **)matchvec->index;
- vector_only_wrapper_free(matchvec);
- *status = CMD_COMPLETE_LIST_MATCH;
- return match_str;
-}
-
-char **cmd_complete_command(vector vline, struct vty *vty, int *status)
-{
- char **ret;
-
- if (cmd_try_do_shortcut(vty->node, vector_slot(vline, 0))) {
- enum node_type onode;
- vector shifted_vline;
- unsigned int index;
-
- onode = vty->node;
- vty->node = ENABLE_NODE;
- /* We can try it on enable node, cos' the vty is authenticated */
-
- shifted_vline = vector_init(vector_count(vline));
- /* use memcpy? */
- for (index = 1; index < vector_active(vline); index++) {
- vector_set_index(shifted_vline, index - 1,
- vector_lookup(vline, index));
- }
-
- ret = cmd_complete_command_real(shifted_vline, vty, status);
-
- vector_free(shifted_vline);
- vty->node = onode;
- return ret;
- }
-
- return cmd_complete_command_real(vline, vty, status);
-}
-
-/* return parent node */
-/* MUST eventually converge on CONFIG_NODE */
-enum node_type vty_go_parent(struct vty *vty)
-{
- assert(vty->node > CONFIG_NODE);
-
- switch (vty->node) {
- case GSMNET_NODE:
- vty->node = CONFIG_NODE;
- vty->index = NULL;
- break;
- case BTS_NODE:
- vty->node = GSMNET_NODE;
- {
- /* set vty->index correctly ! */
- struct gsm_bts *bts = vty->index;
- vty->index = bts->network;
- }
- break;
- case TRX_NODE:
- vty->node = BTS_NODE;
- {
- /* set vty->index correctly ! */
- struct gsm_bts_trx *trx = vty->index;
- vty->index = trx->bts;
- }
- break;
- case TS_NODE:
- vty->node = TRX_NODE;
- {
- /* set vty->index correctly ! */
- struct gsm_bts_trx_ts *ts = vty->index;
- vty->index = ts->trx;
- }
- break;
- case SUBSCR_NODE:
- vty->node = VIEW_NODE;
- subscr_put(vty->index);
- vty->index = NULL;
- break;
- default:
- vty->node = CONFIG_NODE;
- }
-
- return vty->node;
-}
-
-/* Execute command by argument vline vector. */
-static int
-cmd_execute_command_real(vector vline, struct vty *vty,
- struct cmd_element **cmd)
-{
- unsigned int i;
- unsigned int index;
- vector cmd_vector;
- struct cmd_element *cmd_element;
- struct cmd_element *matched_element;
- unsigned int matched_count, incomplete_count;
- int argc;
- const char *argv[CMD_ARGC_MAX];
- enum match_type match = 0;
- int varflag;
- char *command;
-
- /* Make copy of command elements. */
- cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node));
-
- for (index = 0; index < vector_active(vline); index++)
- if ((command = vector_slot(vline, index))) {
- int ret;
-
- match =
- cmd_filter_by_completion(command, cmd_vector,
- index);
-
- if (match == vararg_match)
- break;
-
- ret =
- is_cmd_ambiguous(command, cmd_vector, index, match);
-
- if (ret == 1) {
- vector_free(cmd_vector);
- return CMD_ERR_AMBIGUOUS;
- } else if (ret == 2) {
- vector_free(cmd_vector);
- return CMD_ERR_NO_MATCH;
- }
- }
-
- /* Check matched count. */
- matched_element = NULL;
- matched_count = 0;
- incomplete_count = 0;
-
- for (i = 0; i < vector_active(cmd_vector); i++)
- if ((cmd_element = vector_slot(cmd_vector, i))) {
- if (match == vararg_match
- || index >= cmd_element->cmdsize) {
- matched_element = cmd_element;
-#if 0
- printf("DEBUG: %s\n", cmd_element->string);
-#endif
- matched_count++;
- } else {
- incomplete_count++;
- }
- }
-
- /* Finish of using cmd_vector. */
- vector_free(cmd_vector);
-
- /* To execute command, matched_count must be 1. */
- if (matched_count == 0) {
- if (incomplete_count)
- return CMD_ERR_INCOMPLETE;
- else
- return CMD_ERR_NO_MATCH;
- }
-
- if (matched_count > 1)
- return CMD_ERR_AMBIGUOUS;
-
- /* Argument treatment */
- varflag = 0;
- argc = 0;
-
- for (i = 0; i < vector_active(vline); i++) {
- if (varflag)
- argv[argc++] = vector_slot(vline, i);
- else {
- vector descvec =
- vector_slot(matched_element->strvec, i);
-
- if (vector_active(descvec) == 1) {
- struct desc *desc = vector_slot(descvec, 0);
-
- if (CMD_VARARG(desc->cmd))
- varflag = 1;
-
- if (varflag || CMD_VARIABLE(desc->cmd)
- || CMD_OPTION(desc->cmd))
- argv[argc++] = vector_slot(vline, i);
- } else
- argv[argc++] = vector_slot(vline, i);
- }
-
- if (argc >= CMD_ARGC_MAX)
- return CMD_ERR_EXEED_ARGC_MAX;
- }
-
- /* For vtysh execution. */
- if (cmd)
- *cmd = matched_element;
-
- if (matched_element->daemon)
- return CMD_SUCCESS_DAEMON;
-
- /* Execute matched command. */
- return (*matched_element->func) (matched_element, vty, argc, argv);
-}
-
-int
-cmd_execute_command(vector vline, struct vty *vty, struct cmd_element **cmd,
- int vtysh)
-{
- int ret, saved_ret, tried = 0;
- enum node_type onode;
- void *oindex;
-
- onode = vty->node;
- oindex = vty->index;
-
- if (cmd_try_do_shortcut(vty->node, vector_slot(vline, 0))) {
- vector shifted_vline;
- unsigned int index;
-
- vty->node = ENABLE_NODE;
- /* We can try it on enable node, cos' the vty is authenticated */
-
- shifted_vline = vector_init(vector_count(vline));
- /* use memcpy? */
- for (index = 1; index < vector_active(vline); index++) {
- vector_set_index(shifted_vline, index - 1,
- vector_lookup(vline, index));
- }
-
- ret = cmd_execute_command_real(shifted_vline, vty, cmd);
-
- vector_free(shifted_vline);
- vty->node = onode;
- return ret;
- }
-
- saved_ret = ret = cmd_execute_command_real(vline, vty, cmd);
-
- if (vtysh)
- return saved_ret;
-
- /* This assumes all nodes above CONFIG_NODE are childs of CONFIG_NODE */
- while (ret != CMD_SUCCESS && ret != CMD_WARNING
- && vty->node > CONFIG_NODE) {
- vty_go_parent(vty);
- ret = cmd_execute_command_real(vline, vty, cmd);
- tried = 1;
- if (ret == CMD_SUCCESS || ret == CMD_WARNING) {
- /* succesfull command, leave the node as is */
- return ret;
- }
- }
- /* no command succeeded, reset the vty to the original node and
- return the error for this node */
- if (tried) {
- vty->node = onode;
- vty->index = oindex;
- }
- return saved_ret;
-}
-
-/* Execute command by argument readline. */
-int
-cmd_execute_command_strict(vector vline, struct vty *vty,
- struct cmd_element **cmd)
-{
- unsigned int i;
- unsigned int index;
- vector cmd_vector;
- struct cmd_element *cmd_element;
- struct cmd_element *matched_element;
- unsigned int matched_count, incomplete_count;
- int argc;
- const char *argv[CMD_ARGC_MAX];
- int varflag;
- enum match_type match = 0;
- char *command;
-
- /* Make copy of command element */
- cmd_vector = vector_copy(cmd_node_vector(cmdvec, vty->node));
-
- for (index = 0; index < vector_active(vline); index++)
- if ((command = vector_slot(vline, index))) {
- int ret;
-
- match = cmd_filter_by_string(vector_slot(vline, index),
- cmd_vector, index);
-
- /* If command meets '.VARARG' then finish matching. */
- if (match == vararg_match)
- break;
-
- ret =
- is_cmd_ambiguous(command, cmd_vector, index, match);
- if (ret == 1) {
- vector_free(cmd_vector);
- return CMD_ERR_AMBIGUOUS;
- }
- if (ret == 2) {
- vector_free(cmd_vector);
- return CMD_ERR_NO_MATCH;
- }
- }
-
- /* Check matched count. */
- matched_element = NULL;
- matched_count = 0;
- incomplete_count = 0;
- for (i = 0; i < vector_active(cmd_vector); i++)
- if (vector_slot(cmd_vector, i) != NULL) {
- cmd_element = vector_slot(cmd_vector, i);
-
- if (match == vararg_match
- || index >= cmd_element->cmdsize) {
- matched_element = cmd_element;
- matched_count++;
- } else
- incomplete_count++;
- }
-
- /* Finish of using cmd_vector. */
- vector_free(cmd_vector);
-
- /* To execute command, matched_count must be 1. */
- if (matched_count == 0) {
- if (incomplete_count)
- return CMD_ERR_INCOMPLETE;
- else
- return CMD_ERR_NO_MATCH;
- }
-
- if (matched_count > 1)
- return CMD_ERR_AMBIGUOUS;
-
- /* Argument treatment */
- varflag = 0;
- argc = 0;
-
- for (i = 0; i < vector_active(vline); i++) {
- if (varflag)
- argv[argc++] = vector_slot(vline, i);
- else {
- vector descvec =
- vector_slot(matched_element->strvec, i);
-
- if (vector_active(descvec) == 1) {
- struct desc *desc = vector_slot(descvec, 0);
-
- if (CMD_VARARG(desc->cmd))
- varflag = 1;
-
- if (varflag || CMD_VARIABLE(desc->cmd)
- || CMD_OPTION(desc->cmd))
- argv[argc++] = vector_slot(vline, i);
- } else
- argv[argc++] = vector_slot(vline, i);
- }
-
- if (argc >= CMD_ARGC_MAX)
- return CMD_ERR_EXEED_ARGC_MAX;
- }
-
- /* For vtysh execution. */
- if (cmd)
- *cmd = matched_element;
-
- if (matched_element->daemon)
- return CMD_SUCCESS_DAEMON;
-
- /* Now execute matched command */
- return (*matched_element->func) (matched_element, vty, argc, argv);
-}
-
-/* Configration make from file. */
-int config_from_file(struct vty *vty, FILE * fp)
-{
- int ret;
- vector vline;
-
- while (fgets(vty->buf, VTY_BUFSIZ, fp)) {
- vline = cmd_make_strvec(vty->buf);
-
- /* In case of comment line */
- if (vline == NULL)
- continue;
- /* Execute configuration command : this is strict match */
- ret = cmd_execute_command_strict(vline, vty, NULL);
-
- /* Try again with setting node to CONFIG_NODE */
- while (ret != CMD_SUCCESS && ret != CMD_WARNING
- && ret != CMD_ERR_NOTHING_TODO
- && vty->node != CONFIG_NODE) {
- vty_go_parent(vty);
- ret = cmd_execute_command_strict(vline, vty, NULL);
- }
-
- cmd_free_strvec(vline);
-
- if (ret != CMD_SUCCESS && ret != CMD_WARNING
- && ret != CMD_ERR_NOTHING_TODO)
- return ret;
- }
- return CMD_SUCCESS;
-}
-
-/* Configration from terminal */
-DEFUN(config_terminal,
- config_terminal_cmd,
- "configure terminal",
- "Configuration from vty interface\n" "Configuration terminal\n")
-{
- if (vty_config_lock(vty))
- vty->node = CONFIG_NODE;
- else {
- vty_out(vty, "VTY configuration is locked by other VTY%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
- return CMD_SUCCESS;
-}
-
-/* Enable command */
-DEFUN(enable, config_enable_cmd, "enable", "Turn on privileged mode command\n")
-{
- /* If enable password is NULL, change to ENABLE_NODE */
- if ((host.enable == NULL && host.enable_encrypt == NULL) ||
- vty->type == VTY_SHELL_SERV)
- vty->node = ENABLE_NODE;
- else
- vty->node = AUTH_ENABLE_NODE;
-
- return CMD_SUCCESS;
-}
-
-/* Disable command */
-DEFUN(disable,
- config_disable_cmd, "disable", "Turn off privileged mode command\n")
-{
- if (vty->node == ENABLE_NODE)
- vty->node = VIEW_NODE;
- return CMD_SUCCESS;
-}
-
-/* Down vty node level. */
-gDEFUN(config_exit,
- config_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
-{
- switch (vty->node) {
- case VIEW_NODE:
- case ENABLE_NODE:
- if (0) //vty_shell (vty))
- exit(0);
- else
- vty->status = VTY_CLOSE;
- break;
- case CONFIG_NODE:
- vty->node = ENABLE_NODE;
- vty_config_unlock(vty);
- break;
- case VTY_NODE:
- vty->node = CONFIG_NODE;
- break;
- default:
- break;
- }
- return CMD_SUCCESS;
-}
-
-/* End of configuration. */
- gDEFUN(config_end,
- config_end_cmd, "end", "End current mode and change to enable mode.")
-{
- switch (vty->node) {
- case VIEW_NODE:
- case ENABLE_NODE:
- /* Nothing to do. */
- break;
- case CONFIG_NODE:
- case VTY_NODE:
- vty_config_unlock(vty);
- vty->node = ENABLE_NODE;
- break;
- default:
- break;
- }
- return CMD_SUCCESS;
-}
-
-/* Show version. */
-DEFUN(show_version,
- show_version_cmd, "show version", SHOW_STR "Displays program version\n")
-{
- vty_out(vty, "%s %s (%s).%s", host.prog_name, host.prog_version,
- host.name ? host.name : "", VTY_NEWLINE);
- vty_out(vty, "%s%s", host.prog_copyright, VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-/* Help display function for all node. */
-gDEFUN(config_help,
- config_help_cmd, "help", "Description of the interactive help system\n")
-{
- vty_out(vty,
- "This VTY provides advanced help features. When you need help,%s\
-anytime at the command line please press '?'.%s\
-%s\
-If nothing matches, the help list will be empty and you must backup%s\
- until entering a '?' shows the available options.%s\
-Two styles of help are provided:%s\
-1. Full help is available when you are ready to enter a%s\
-command argument (e.g. 'show ?') and describes each possible%s\
-argument.%s\
-2. Partial help is provided when an abbreviated argument is entered%s\
- and you want to know what arguments match the input%s\
- (e.g. 'show me?'.)%s%s", VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE,
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
-/* Help display function for all node. */
-gDEFUN(config_list, config_list_cmd, "list", "Print command list\n")
-{
- unsigned int i;
- struct cmd_node *cnode = vector_slot(cmdvec, vty->node);
- struct cmd_element *cmd;
-
- for (i = 0; i < vector_active(cnode->cmd_vector); i++)
- if ((cmd = vector_slot(cnode->cmd_vector, i)) != NULL
- && !(cmd->attr == CMD_ATTR_DEPRECATED
- || cmd->attr == CMD_ATTR_HIDDEN))
- vty_out(vty, " %s%s", cmd->string, VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
-/* Write current configuration into file. */
-DEFUN(config_write_file,
- config_write_file_cmd,
- "write file",
- "Write running configuration to memory, network, or terminal\n"
- "Write to configuration file\n")
-{
- unsigned int i;
- int fd;
- struct cmd_node *node;
- char *config_file;
- char *config_file_tmp = NULL;
- char *config_file_sav = NULL;
- struct vty *file_vty;
-
- /* Check and see if we are operating under vtysh configuration */
- if (host.config == NULL) {
- vty_out(vty, "Can't save to configuration file, using vtysh.%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Get filename. */
- config_file = host.config;
-
- config_file_sav =
- _talloc_zero(tall_vty_cmd_ctx,
- strlen(config_file) + strlen(CONF_BACKUP_EXT) + 1,
- "config_file_sav");
- strcpy(config_file_sav, config_file);
- strcat(config_file_sav, CONF_BACKUP_EXT);
-
- config_file_tmp = _talloc_zero(tall_vty_cmd_ctx, strlen(config_file) + 8,
- "config_file_tmp");
- sprintf(config_file_tmp, "%s.XXXXXX", config_file);
-
- /* Open file to configuration write. */
- fd = mkstemp(config_file_tmp);
- if (fd < 0) {
- vty_out(vty, "Can't open configuration file %s.%s",
- config_file_tmp, VTY_NEWLINE);
- talloc_free(config_file_tmp);
- talloc_free(config_file_sav);
- return CMD_WARNING;
- }
-
- /* Make vty for configuration file. */
- file_vty = vty_new();
- file_vty->fd = fd;
- file_vty->type = VTY_FILE;
-
- /* Config file header print. */
- vty_out(file_vty, "!\n! %s (%s) configuration saved from vty\n!",
- host.prog_name, host.prog_version);
- //vty_time_print (file_vty, 1);
- vty_out(file_vty, "!\n");
-
- for (i = 0; i < vector_active(cmdvec); i++)
- if ((node = vector_slot(cmdvec, i)) && node->func) {
- if ((*node->func) (file_vty))
- vty_out(file_vty, "!\n");
- }
- vty_close(file_vty);
-
- if (unlink(config_file_sav) != 0)
- if (errno != ENOENT) {
- vty_out(vty,
- "Can't unlink backup configuration file %s.%s",
- config_file_sav, VTY_NEWLINE);
- talloc_free(config_file_sav);
- talloc_free(config_file_tmp);
- unlink(config_file_tmp);
- return CMD_WARNING;
- }
- if (link(config_file, config_file_sav) != 0) {
- vty_out(vty, "Can't backup old configuration file %s.%s",
- config_file_sav, VTY_NEWLINE);
- talloc_free(config_file_sav);
- talloc_free(config_file_tmp);
- unlink(config_file_tmp);
- return CMD_WARNING;
- }
- sync();
- if (unlink(config_file) != 0) {
- vty_out(vty, "Can't unlink configuration file %s.%s",
- config_file, VTY_NEWLINE);
- talloc_free(config_file_sav);
- talloc_free(config_file_tmp);
- unlink(config_file_tmp);
- return CMD_WARNING;
- }
- if (link(config_file_tmp, config_file) != 0) {
- vty_out(vty, "Can't save configuration file %s.%s", config_file,
- VTY_NEWLINE);
- talloc_free(config_file_sav);
- talloc_free(config_file_tmp);
- unlink(config_file_tmp);
- return CMD_WARNING;
- }
- unlink(config_file_tmp);
- sync();
-
- talloc_free(config_file_sav);
- talloc_free(config_file_tmp);
-
- if (chmod(config_file, 0666 & ~CONFIGFILE_MASK) != 0) {
- vty_out(vty, "Can't chmod configuration file %s: %s (%d).%s",
- config_file, strerror(errno), errno, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- vty_out(vty, "Configuration saved to %s%s", config_file, VTY_NEWLINE);
- return CMD_SUCCESS;
-}
-
-ALIAS(config_write_file,
- config_write_cmd,
- "write", "Write running configuration to memory, network, or terminal\n")
-
- ALIAS(config_write_file,
- config_write_memory_cmd,
- "write memory",
- "Write running configuration to memory, network, or terminal\n"
- "Write configuration to the file (same as write file)\n")
-
- ALIAS(config_write_file,
- copy_runningconfig_startupconfig_cmd,
- "copy running-config startup-config",
- "Copy configuration\n"
- "Copy running config to... \n"
- "Copy running config to startup config (same as write file)\n")
-
-/* Write current configuration into the terminal. */
- DEFUN(config_write_terminal,
- config_write_terminal_cmd,
- "write terminal",
- "Write running configuration to memory, network, or terminal\n"
- "Write to terminal\n")
-{
- unsigned int i;
- struct cmd_node *node;
-
- if (vty->type == VTY_SHELL_SERV) {
- for (i = 0; i < vector_active(cmdvec); i++)
- if ((node = vector_slot(cmdvec, i)) && node->func
- && node->vtysh) {
- if ((*node->func) (vty))
- vty_out(vty, "!%s", VTY_NEWLINE);
- }
- } else {
- vty_out(vty, "%sCurrent configuration:%s", VTY_NEWLINE,
- VTY_NEWLINE);
- vty_out(vty, "!%s", VTY_NEWLINE);
-
- for (i = 0; i < vector_active(cmdvec); i++)
- if ((node = vector_slot(cmdvec, i)) && node->func) {
- if ((*node->func) (vty))
- vty_out(vty, "!%s", VTY_NEWLINE);
- }
- vty_out(vty, "end%s", VTY_NEWLINE);
- }
- return CMD_SUCCESS;
-}
-
-/* Write current configuration into the terminal. */
-ALIAS(config_write_terminal,
- show_running_config_cmd,
- "show running-config", SHOW_STR "running configuration\n")
-
-/* Write startup configuration into the terminal. */
- DEFUN(show_startup_config,
- show_startup_config_cmd,
- "show startup-config", SHOW_STR "Contentes of startup configuration\n")
-{
- char buf[BUFSIZ];
- FILE *confp;
-
- confp = fopen(host.config, "r");
- if (confp == NULL) {
- vty_out(vty, "Can't open configuration file [%s]%s",
- host.config, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- while (fgets(buf, BUFSIZ, confp)) {
- char *cp = buf;
-
- while (*cp != '\r' && *cp != '\n' && *cp != '\0')
- cp++;
- *cp = '\0';
-
- vty_out(vty, "%s%s", buf, VTY_NEWLINE);
- }
-
- fclose(confp);
-
- return CMD_SUCCESS;
-}
-
-/* Hostname configuration */
-DEFUN(config_hostname,
- hostname_cmd,
- "hostname WORD",
- "Set system's network name\n" "This system's network name\n")
-{
- if (!isalpha((int)*argv[0])) {
- vty_out(vty, "Please specify string starting with alphabet%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (host.name)
- talloc_free(host.name);
-
- host.name = talloc_strdup(tall_vty_cmd_ctx, argv[0]);
- return CMD_SUCCESS;
-}
-
-DEFUN(config_no_hostname,
- no_hostname_cmd,
- "no hostname [HOSTNAME]",
- NO_STR "Reset system's network name\n" "Host name of this router\n")
-{
- if (host.name)
- talloc_free(host.name);
- host.name = NULL;
- return CMD_SUCCESS;
-}
-
-/* VTY interface password set. */
-DEFUN(config_password, password_cmd,
- "password (8|) WORD",
- "Assign the terminal connection password\n"
- "Specifies a HIDDEN password will follow\n"
- "dummy string \n" "The HIDDEN line password string\n")
-{
- /* Argument check. */
- if (argc == 0) {
- vty_out(vty, "Please specify password.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (argc == 2) {
- if (*argv[0] == '8') {
- if (host.password)
- talloc_free(host.password);
- host.password = NULL;
- if (host.password_encrypt)
- talloc_free(host.password_encrypt);
- host.password_encrypt = talloc_strdup(tall_vty_cmd_ctx, argv[1]);
- return CMD_SUCCESS;
- } else {
- vty_out(vty, "Unknown encryption type.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- if (!isalnum((int)*argv[0])) {
- vty_out(vty,
- "Please specify string starting with alphanumeric%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (host.password)
- talloc_free(host.password);
- host.password = NULL;
-
-#ifdef VTY_CRYPT_PW
- if (host.encrypt) {
- if (host.password_encrypt)
- talloc_free(host.password_encrypt);
- host.password_encrypt = talloc_strdup(tall_vty_cmd_ctx, zencrypt(argv[0]));
- } else
-#endif
- host.password = talloc_strdup(tall_vty_cmd_ctx, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-ALIAS(config_password, password_text_cmd,
- "password LINE",
- "Assign the terminal connection password\n"
- "The UNENCRYPTED (cleartext) line password\n")
-
-/* VTY enable password set. */
- DEFUN(config_enable_password, enable_password_cmd,
- "enable password (8|) WORD",
- "Modify enable password parameters\n"
- "Assign the privileged level password\n"
- "Specifies a HIDDEN password will follow\n"
- "dummy string \n" "The HIDDEN 'enable' password string\n")
-{
- /* Argument check. */
- if (argc == 0) {
- vty_out(vty, "Please specify password.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- /* Crypt type is specified. */
- if (argc == 2) {
- if (*argv[0] == '8') {
- if (host.enable)
- talloc_free(host.enable);
- host.enable = NULL;
-
- if (host.enable_encrypt)
- talloc_free(host.enable_encrypt);
- host.enable_encrypt = talloc_strdup(tall_vty_cmd_ctx, argv[1]);
-
- return CMD_SUCCESS;
- } else {
- vty_out(vty, "Unknown encryption type.%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- if (!isalnum((int)*argv[0])) {
- vty_out(vty,
- "Please specify string starting with alphanumeric%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (host.enable)
- talloc_free(host.enable);
- host.enable = NULL;
-
- /* Plain password input. */
-#ifdef VTY_CRYPT_PW
- if (host.encrypt) {
- if (host.enable_encrypt)
- talloc_free(host.enable_encrypt);
- host.enable_encrypt = talloc_strdup(tall_vty_cmd_ctx, zencrypt(argv[0]));
- } else
-#endif
- host.enable = talloc_strdup(tall_vty_cmd_ctx, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-ALIAS(config_enable_password,
- enable_password_text_cmd,
- "enable password LINE",
- "Modify enable password parameters\n"
- "Assign the privileged level password\n"
- "The UNENCRYPTED (cleartext) 'enable' password\n")
-
-/* VTY enable password delete. */
- DEFUN(no_config_enable_password, no_enable_password_cmd,
- "no enable password",
- NO_STR
- "Modify enable password parameters\n"
- "Assign the privileged level password\n")
-{
- if (host.enable)
- talloc_free(host.enable);
- host.enable = NULL;
-
- if (host.enable_encrypt)
- talloc_free(host.enable_encrypt);
- host.enable_encrypt = NULL;
-
- return CMD_SUCCESS;
-}
-
-#ifdef VTY_CRYPT_PW
-DEFUN(service_password_encrypt,
- service_password_encrypt_cmd,
- "service password-encryption",
- "Set up miscellaneous service\n" "Enable encrypted passwords\n")
-{
- if (host.encrypt)
- return CMD_SUCCESS;
-
- host.encrypt = 1;
-
- if (host.password) {
- if (host.password_encrypt)
- talloc_free(host.password_encrypt);
- host.password_encrypt = talloc_strdup(tall_vty_cmd_ctx, zencrypt(host.password));
- }
- if (host.enable) {
- if (host.enable_encrypt)
- talloc_free(host.enable_encrypt);
- host.enable_encrypt = talloc_strdup(tall_vty_cmd_ctx, zencrypt(host.enable));
- }
-
- return CMD_SUCCESS;
-}
-
-DEFUN(no_service_password_encrypt,
- no_service_password_encrypt_cmd,
- "no service password-encryption",
- NO_STR "Set up miscellaneous service\n" "Enable encrypted passwords\n")
-{
- if (!host.encrypt)
- return CMD_SUCCESS;
-
- host.encrypt = 0;
-
- if (host.password_encrypt)
- talloc_free(host.password_encrypt);
- host.password_encrypt = NULL;
-
- if (host.enable_encrypt)
- talloc_free(host.enable_encrypt);
- host.enable_encrypt = NULL;
-
- return CMD_SUCCESS;
-}
-#endif
-
-DEFUN(config_terminal_length, config_terminal_length_cmd,
- "terminal length <0-512>",
- "Set terminal line parameters\n"
- "Set number of lines on a screen\n"
- "Number of lines on screen (0 for no pausing)\n")
-{
- int lines;
- char *endptr = NULL;
-
- lines = strtol(argv[0], &endptr, 10);
- if (lines < 0 || lines > 512 || *endptr != '\0') {
- vty_out(vty, "length is malformed%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- vty->lines = lines;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(config_terminal_no_length, config_terminal_no_length_cmd,
- "terminal no length",
- "Set terminal line parameters\n"
- NO_STR "Set number of lines on a screen\n")
-{
- vty->lines = -1;
- return CMD_SUCCESS;
-}
-
-DEFUN(service_terminal_length, service_terminal_length_cmd,
- "service terminal-length <0-512>",
- "Set up miscellaneous service\n"
- "System wide terminal length configuration\n"
- "Number of lines of VTY (0 means no line control)\n")
-{
- int lines;
- char *endptr = NULL;
-
- lines = strtol(argv[0], &endptr, 10);
- if (lines < 0 || lines > 512 || *endptr != '\0') {
- vty_out(vty, "length is malformed%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- host.lines = lines;
-
- return CMD_SUCCESS;
-}
-
-DEFUN(no_service_terminal_length, no_service_terminal_length_cmd,
- "no service terminal-length [<0-512>]",
- NO_STR
- "Set up miscellaneous service\n"
- "System wide terminal length configuration\n"
- "Number of lines of VTY (0 means no line control)\n")
-{
- host.lines = -1;
- return CMD_SUCCESS;
-}
-
-DEFUN_HIDDEN(do_echo,
- echo_cmd,
- "echo .MESSAGE",
- "Echo a message back to the vty\n" "The message to echo\n")
-{
- char *message;
-
- vty_out(vty, "%s%s",
- ((message =
- argv_concat(argv, argc, 0)) ? message : ""), VTY_NEWLINE);
- if (message)
- talloc_free(message);
- return CMD_SUCCESS;
-}
-
-#if 0
-DEFUN(config_logmsg,
- config_logmsg_cmd,
- "logmsg " LOG_LEVELS " .MESSAGE",
- "Send a message to enabled logging destinations\n"
- LOG_LEVEL_DESC "The message to send\n")
-{
- int level;
- char *message;
-
- if ((level = level_match(argv[0])) == ZLOG_DISABLED)
- return CMD_ERR_NO_MATCH;
-
- zlog(NULL, level,
- ((message = argv_concat(argv, argc, 1)) ? message : ""));
- if (message)
- talloc_free(message);
- return CMD_SUCCESS;
-}
-
-DEFUN(show_logging,
- show_logging_cmd,
- "show logging", SHOW_STR "Show current logging configuration\n")
-{
- struct zlog *zl = zlog_default;
-
- vty_out(vty, "Syslog logging: ");
- if (zl->maxlvl[ZLOG_DEST_SYSLOG] == ZLOG_DISABLED)
- vty_out(vty, "disabled");
- else
- vty_out(vty, "level %s, facility %s, ident %s",
- zlog_priority[zl->maxlvl[ZLOG_DEST_SYSLOG]],
- facility_name(zl->facility), zl->ident);
- vty_out(vty, "%s", VTY_NEWLINE);
-
- vty_out(vty, "Stdout logging: ");
- if (zl->maxlvl[ZLOG_DEST_STDOUT] == ZLOG_DISABLED)
- vty_out(vty, "disabled");
- else
- vty_out(vty, "level %s",
- zlog_priority[zl->maxlvl[ZLOG_DEST_STDOUT]]);
- vty_out(vty, "%s", VTY_NEWLINE);
-
- vty_out(vty, "Monitor logging: ");
- if (zl->maxlvl[ZLOG_DEST_MONITOR] == ZLOG_DISABLED)
- vty_out(vty, "disabled");
- else
- vty_out(vty, "level %s",
- zlog_priority[zl->maxlvl[ZLOG_DEST_MONITOR]]);
- vty_out(vty, "%s", VTY_NEWLINE);
-
- vty_out(vty, "File logging: ");
- if ((zl->maxlvl[ZLOG_DEST_FILE] == ZLOG_DISABLED) || !zl->fp)
- vty_out(vty, "disabled");
- else
- vty_out(vty, "level %s, filename %s",
- zlog_priority[zl->maxlvl[ZLOG_DEST_FILE]],
- zl->filename);
- vty_out(vty, "%s", VTY_NEWLINE);
-
- vty_out(vty, "Protocol name: %s%s",
- zlog_proto_names[zl->protocol], VTY_NEWLINE);
- vty_out(vty, "Record priority: %s%s",
- (zl->record_priority ? "enabled" : "disabled"), VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(config_log_stdout,
- config_log_stdout_cmd,
- "log stdout", "Logging control\n" "Set stdout logging level\n")
-{
- zlog_set_level(NULL, ZLOG_DEST_STDOUT, zlog_default->default_lvl);
- return CMD_SUCCESS;
-}
-
-DEFUN(config_log_stdout_level,
- config_log_stdout_level_cmd,
- "log stdout " LOG_LEVELS,
- "Logging control\n" "Set stdout logging level\n" LOG_LEVEL_DESC)
-{
- int level;
-
- if ((level = level_match(argv[0])) == ZLOG_DISABLED)
- return CMD_ERR_NO_MATCH;
- zlog_set_level(NULL, ZLOG_DEST_STDOUT, level);
- return CMD_SUCCESS;
-}
-
-DEFUN(no_config_log_stdout,
- no_config_log_stdout_cmd,
- "no log stdout [LEVEL]",
- NO_STR "Logging control\n" "Cancel logging to stdout\n" "Logging level\n")
-{
- zlog_set_level(NULL, ZLOG_DEST_STDOUT, ZLOG_DISABLED);
- return CMD_SUCCESS;
-}
-
-DEFUN(config_log_monitor,
- config_log_monitor_cmd,
- "log monitor",
- "Logging control\n" "Set terminal line (monitor) logging level\n")
-{
- zlog_set_level(NULL, ZLOG_DEST_MONITOR, zlog_default->default_lvl);
- return CMD_SUCCESS;
-}
-
-DEFUN(config_log_monitor_level,
- config_log_monitor_level_cmd,
- "log monitor " LOG_LEVELS,
- "Logging control\n"
- "Set terminal line (monitor) logging level\n" LOG_LEVEL_DESC)
-{
- int level;
-
- if ((level = level_match(argv[0])) == ZLOG_DISABLED)
- return CMD_ERR_NO_MATCH;
- zlog_set_level(NULL, ZLOG_DEST_MONITOR, level);
- return CMD_SUCCESS;
-}
-
-DEFUN(no_config_log_monitor,
- no_config_log_monitor_cmd,
- "no log monitor [LEVEL]",
- NO_STR
- "Logging control\n"
- "Disable terminal line (monitor) logging\n" "Logging level\n")
-{
- zlog_set_level(NULL, ZLOG_DEST_MONITOR, ZLOG_DISABLED);
- return CMD_SUCCESS;
-}
-
-static int set_log_file(struct vty *vty, const char *fname, int loglevel)
-{
- int ret;
- char *p = NULL;
- const char *fullpath;
-
- /* Path detection. */
- if (!IS_DIRECTORY_SEP(*fname)) {
- char cwd[MAXPATHLEN + 1];
- cwd[MAXPATHLEN] = '\0';
-
- if (getcwd(cwd, MAXPATHLEN) == NULL) {
- zlog_err("config_log_file: Unable to alloc mem!");
- return CMD_WARNING;
- }
-
- if ((p = _talloc_zero(tall_vcmd_ctx,
- strlen(cwd) + strlen(fname) + 2),
- "set_log_file")
- == NULL) {
- zlog_err("config_log_file: Unable to alloc mem!");
- return CMD_WARNING;
- }
- sprintf(p, "%s/%s", cwd, fname);
- fullpath = p;
- } else
- fullpath = fname;
-
- ret = zlog_set_file(NULL, fullpath, loglevel);
-
- if (p)
- talloc_free(p);
-
- if (!ret) {
- vty_out(vty, "can't open logfile %s\n", fname);
- return CMD_WARNING;
- }
-
- if (host.logfile)
- talloc_free(host.logfile);
-
- host.logfile = talloc_strdup(tall_vty_cmd_ctx, fname);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(config_log_file,
- config_log_file_cmd,
- "log file FILENAME",
- "Logging control\n" "Logging to file\n" "Logging filename\n")
-{
- return set_log_file(vty, argv[0], zlog_default->default_lvl);
-}
-
-DEFUN(config_log_file_level,
- config_log_file_level_cmd,
- "log file FILENAME " LOG_LEVELS,
- "Logging control\n"
- "Logging to file\n" "Logging filename\n" LOG_LEVEL_DESC)
-{
- int level;
-
- if ((level = level_match(argv[1])) == ZLOG_DISABLED)
- return CMD_ERR_NO_MATCH;
- return set_log_file(vty, argv[0], level);
-}
-
-DEFUN(no_config_log_file,
- no_config_log_file_cmd,
- "no log file [FILENAME]",
- NO_STR
- "Logging control\n" "Cancel logging to file\n" "Logging file name\n")
-{
- zlog_reset_file(NULL);
-
- if (host.logfile)
- talloc_free(host.logfile);
-
- host.logfile = NULL;
-
- return CMD_SUCCESS;
-}
-
-ALIAS(no_config_log_file,
- no_config_log_file_level_cmd,
- "no log file FILENAME LEVEL",
- NO_STR
- "Logging control\n"
- "Cancel logging to file\n" "Logging file name\n" "Logging level\n")
-
- DEFUN(config_log_syslog,
- config_log_syslog_cmd,
- "log syslog", "Logging control\n" "Set syslog logging level\n")
-{
- zlog_set_level(NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
- return CMD_SUCCESS;
-}
-
-DEFUN(config_log_syslog_level,
- config_log_syslog_level_cmd,
- "log syslog " LOG_LEVELS,
- "Logging control\n" "Set syslog logging level\n" LOG_LEVEL_DESC)
-{
- int level;
-
- if ((level = level_match(argv[0])) == ZLOG_DISABLED)
- return CMD_ERR_NO_MATCH;
- zlog_set_level(NULL, ZLOG_DEST_SYSLOG, level);
- return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(config_log_syslog_facility,
- config_log_syslog_facility_cmd,
- "log syslog facility " LOG_FACILITIES,
- "Logging control\n"
- "Logging goes to syslog\n"
- "(Deprecated) Facility parameter for syslog messages\n"
- LOG_FACILITY_DESC)
-{
- int facility;
-
- if ((facility = facility_match(argv[0])) < 0)
- return CMD_ERR_NO_MATCH;
-
- zlog_set_level(NULL, ZLOG_DEST_SYSLOG, zlog_default->default_lvl);
- zlog_default->facility = facility;
- return CMD_SUCCESS;
-}
-
-DEFUN(no_config_log_syslog,
- no_config_log_syslog_cmd,
- "no log syslog [LEVEL]",
- NO_STR "Logging control\n" "Cancel logging to syslog\n" "Logging level\n")
-{
- zlog_set_level(NULL, ZLOG_DEST_SYSLOG, ZLOG_DISABLED);
- return CMD_SUCCESS;
-}
-
-ALIAS(no_config_log_syslog,
- no_config_log_syslog_facility_cmd,
- "no log syslog facility " LOG_FACILITIES,
- NO_STR
- "Logging control\n"
- "Logging goes to syslog\n"
- "Facility parameter for syslog messages\n" LOG_FACILITY_DESC)
-
- DEFUN(config_log_facility,
- config_log_facility_cmd,
- "log facility " LOG_FACILITIES,
- "Logging control\n"
- "Facility parameter for syslog messages\n" LOG_FACILITY_DESC)
-{
- int facility;
-
- if ((facility = facility_match(argv[0])) < 0)
- return CMD_ERR_NO_MATCH;
- zlog_default->facility = facility;
- return CMD_SUCCESS;
-}
-
-DEFUN(no_config_log_facility,
- no_config_log_facility_cmd,
- "no log facility [FACILITY]",
- NO_STR
- "Logging control\n"
- "Reset syslog facility to default (daemon)\n" "Syslog facility\n")
-{
- zlog_default->facility = LOG_DAEMON;
- return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(config_log_trap,
- config_log_trap_cmd,
- "log trap " LOG_LEVELS,
- "Logging control\n"
- "(Deprecated) Set logging level and default for all destinations\n"
- LOG_LEVEL_DESC)
-{
- int new_level;
- int i;
-
- if ((new_level = level_match(argv[0])) == ZLOG_DISABLED)
- return CMD_ERR_NO_MATCH;
-
- zlog_default->default_lvl = new_level;
- for (i = 0; i < ZLOG_NUM_DESTS; i++)
- if (zlog_default->maxlvl[i] != ZLOG_DISABLED)
- zlog_default->maxlvl[i] = new_level;
- return CMD_SUCCESS;
-}
-
-DEFUN_DEPRECATED(no_config_log_trap,
- no_config_log_trap_cmd,
- "no log trap [LEVEL]",
- NO_STR
- "Logging control\n"
- "Permit all logging information\n" "Logging level\n")
-{
- zlog_default->default_lvl = LOG_DEBUG;
- return CMD_SUCCESS;
-}
-
-DEFUN(config_log_record_priority,
- config_log_record_priority_cmd,
- "log record-priority",
- "Logging control\n"
- "Log the priority of the message within the message\n")
-{
- zlog_default->record_priority = 1;
- return CMD_SUCCESS;
-}
-
-DEFUN(no_config_log_record_priority,
- no_config_log_record_priority_cmd,
- "no log record-priority",
- NO_STR
- "Logging control\n"
- "Do not log the priority of the message within the message\n")
-{
- zlog_default->record_priority = 0;
- return CMD_SUCCESS;
-}
-#endif
-
-DEFUN(banner_motd_file,
- banner_motd_file_cmd,
- "banner motd file [FILE]",
- "Set banner\n" "Banner for motd\n" "Banner from a file\n" "Filename\n")
-{
- if (host.motdfile)
- talloc_free(host.motdfile);
- host.motdfile = talloc_strdup(tall_vty_cmd_ctx, argv[0]);
-
- return CMD_SUCCESS;
-}
-
-DEFUN(banner_motd_default,
- banner_motd_default_cmd,
- "banner motd default",
- "Set banner string\n" "Strings for motd\n" "Default string\n")
-{
- host.motd = default_motd;
- return CMD_SUCCESS;
-}
-
-DEFUN(no_banner_motd,
- no_banner_motd_cmd,
- "no banner motd", NO_STR "Set banner string\n" "Strings for motd\n")
-{
- host.motd = NULL;
- if (host.motdfile)
- talloc_free(host.motdfile);
- host.motdfile = NULL;
- return CMD_SUCCESS;
-}
-
-/* Set config filename. Called from vty.c */
-void host_config_set(const char *filename)
-{
- host.config = talloc_strdup(tall_vty_cmd_ctx, filename);
-}
-
-void install_default(enum node_type node)
-{
- install_element(node, &config_help_cmd);
- install_element(node, &config_list_cmd);
-
- install_element(node, &config_write_terminal_cmd);
- install_element(node, &config_write_file_cmd);
- install_element(node, &config_write_memory_cmd);
- install_element(node, &config_write_cmd);
- install_element(node, &show_running_config_cmd);
-}
-
-/* Initialize command interface. Install basic nodes and commands. */
-void cmd_init(int terminal)
-{
- /* Allocate initial top vector of commands. */
- cmdvec = vector_init(VECTOR_MIN_SIZE);
-
- /* Default host value settings. */
- host.name = NULL;
- host.password = NULL;
- host.enable = NULL;
- host.logfile = NULL;
- host.config = NULL;
- host.lines = -1;
- host.motd = default_motd;
- host.motdfile = NULL;
-
- /* Install top nodes. */
- install_node(&view_node, NULL);
- install_node(&enable_node, NULL);
- install_node(&auth_node, NULL);
- install_node(&auth_enable_node, NULL);
- install_node(&config_node, config_write_host);
-
- /* Each node's basic commands. */
- install_element(VIEW_NODE, &show_version_cmd);
- if (terminal) {
- install_element(VIEW_NODE, &config_list_cmd);
- install_element(VIEW_NODE, &config_exit_cmd);
- install_element(VIEW_NODE, &config_help_cmd);
- install_element(VIEW_NODE, &config_enable_cmd);
- install_element(VIEW_NODE, &config_terminal_length_cmd);
- install_element(VIEW_NODE, &config_terminal_no_length_cmd);
- install_element(VIEW_NODE, &echo_cmd);
- }
-
- if (terminal) {
- install_element(ENABLE_NODE, &config_exit_cmd);
- install_default(ENABLE_NODE);
- install_element(ENABLE_NODE, &config_disable_cmd);
- install_element(ENABLE_NODE, &config_terminal_cmd);
- install_element (ENABLE_NODE, &copy_runningconfig_startupconfig_cmd);
- }
- install_element (ENABLE_NODE, &show_startup_config_cmd);
- install_element(ENABLE_NODE, &show_version_cmd);
-
- if (terminal) {
- install_element(ENABLE_NODE, &config_terminal_length_cmd);
- install_element(ENABLE_NODE, &config_terminal_no_length_cmd);
- install_element(ENABLE_NODE, &echo_cmd);
-
- install_default(CONFIG_NODE);
- install_element(CONFIG_NODE, &config_exit_cmd);
- }
-
- install_element(CONFIG_NODE, &hostname_cmd);
- install_element(CONFIG_NODE, &no_hostname_cmd);
-
- if (terminal) {
- install_element(CONFIG_NODE, &password_cmd);
- install_element(CONFIG_NODE, &password_text_cmd);
- install_element(CONFIG_NODE, &enable_password_cmd);
- install_element(CONFIG_NODE, &enable_password_text_cmd);
- install_element(CONFIG_NODE, &no_enable_password_cmd);
-
-#ifdef VTY_CRYPT_PW
- install_element(CONFIG_NODE, &service_password_encrypt_cmd);
- install_element(CONFIG_NODE, &no_service_password_encrypt_cmd);
-#endif
- install_element(CONFIG_NODE, &banner_motd_default_cmd);
- install_element(CONFIG_NODE, &banner_motd_file_cmd);
- install_element(CONFIG_NODE, &no_banner_motd_cmd);
- install_element(CONFIG_NODE, &service_terminal_length_cmd);
- install_element(CONFIG_NODE, &no_service_terminal_length_cmd);
-
- }
- srand(time(NULL));
-}
diff --git a/openbsc/src/vty/utils.c b/openbsc/src/vty/utils.c
deleted file mode 100644
index d8dfb8ef9..000000000
--- a/openbsc/src/vty/utils.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/* utility routines for printing common objects in the Osmocom world */
-
-/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
- *
- * All Rights Reserved
- *
- * This program 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 of the License, or
- * (at your option) any later version.
- *
- * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <stdint.h>
-#include <inttypes.h>
-
-#include <osmocore/linuxlist.h>
-#include <osmocore/talloc.h>
-#include <osmocore/timer.h>
-#include <osmocore/rate_ctr.h>
-
-#include <vty/vty.h>
-
-void vty_out_rate_ctr_group(struct vty *vty, const char *prefix,
- struct rate_ctr_group *ctrg)
-{
- unsigned int i;
-
- vty_out(vty, "%s%s:%s", prefix, ctrg->desc->group_description, VTY_NEWLINE);
- for (i = 0; i < ctrg->desc->num_ctr; i++) {
- struct rate_ctr *ctr = &ctrg->ctr[i];
- vty_out(vty, " %s%s: %8" PRIu64 " "
- "(%" PRIu64 "/s %" PRIu64 "/m %" PRIu64 "/h %" PRIu64 "/d)%s",
- prefix, ctrg->desc->ctr_desc[i].description, ctr->current,
- ctr->intv[RATE_CTR_INTV_SEC].rate,
- ctr->intv[RATE_CTR_INTV_MIN].rate,
- ctr->intv[RATE_CTR_INTV_HOUR].rate,
- ctr->intv[RATE_CTR_INTV_DAY].rate,
- VTY_NEWLINE);
- };
-}
diff --git a/openbsc/src/vty/vector.c b/openbsc/src/vty/vector.c
deleted file mode 100644
index db47ae59a..000000000
--- a/openbsc/src/vty/vector.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/* Generic vector interface routine
- * Copyright (C) 1997 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
- * 02111-1307, USA.
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <vty/vector.h>
-#include <vty/vty.h>
-#include <osmocore/talloc.h>
-#include <memory.h>
-
-void *tall_vty_vec_ctx;
-
-/* Initialize vector : allocate memory and return vector. */
-vector vector_init(unsigned int size)
-{
- vector v = talloc_zero(tall_vty_vec_ctx, struct _vector);
- if (!v)
- return NULL;
-
- /* allocate at least one slot */
- if (size == 0)
- size = 1;
-
- v->alloced = size;
- v->active = 0;
- v->index = _talloc_zero(tall_vty_vec_ctx, sizeof(void *) * size,
- "vector_init:index");
- if (!v->index) {
- talloc_free(v);
- return NULL;
- }
- return v;
-}
-
-void vector_only_wrapper_free(vector v)
-{
- talloc_free(v);
-}
-
-void vector_only_index_free(void *index)
-{
- talloc_free(index);
-}
-
-void vector_free(vector v)
-{
- talloc_free(v->index);
- talloc_free(v);
-}
-
-vector vector_copy(vector v)
-{
- unsigned int size;
- vector new = talloc_zero(tall_vty_vec_ctx, struct _vector);
- if (!new)
- return NULL;
-
- new->active = v->active;
- new->alloced = v->alloced;
-
- size = sizeof(void *) * (v->alloced);
- new->index = _talloc_zero(tall_vty_vec_ctx, size, "vector_copy:index");
- if (!new->index) {
- talloc_free(new);
- return NULL;
- }
- memcpy(new->index, v->index, size);
-
- return new;
-}
-
-/* Check assigned index, and if it runs short double index pointer */
-void vector_ensure(vector v, unsigned int num)
-{
- if (v->alloced > num)
- return;
-
- v->index = talloc_realloc_size(tall_vty_vec_ctx, v->index,
- sizeof(void *) * (v->alloced * 2));
- memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
- v->alloced *= 2;
-
- if (v->alloced <= num)
- vector_ensure(v, num);
-}
-
-/* This function only returns next empty slot index. It dose not mean
- the slot's index memory is assigned, please call vector_ensure()
- after calling this function. */
-int vector_empty_slot(vector v)
-{
- unsigned int i;
-
- if (v->active == 0)
- return 0;
-
- for (i = 0; i < v->active; i++)
- if (v->index[i] == 0)
- return i;
-
- return i;
-}
-
-/* Set value to the smallest empty slot. */
-int vector_set(vector v, void *val)
-{
- unsigned int i;
-
- i = vector_empty_slot(v);
- vector_ensure(v, i);
-
- v->index[i] = val;
-
- if (v->active <= i)
- v->active = i + 1;
-
- return i;
-}
-
-/* Set value to specified index slot. */
-int vector_set_index(vector v, unsigned int i, void *val)
-{
- vector_ensure(v, i);
-
- v->index[i] = val;
-
- if (v->active <= i)
- v->active = i + 1;
-
- return i;
-}
-
-/* Look up vector. */
-void *vector_lookup(vector v, unsigned int i)
-{
- if (i >= v->active)
- return NULL;
- return v->index[i];
-}
-
-/* Lookup vector, ensure it. */
-void *vector_lookup_ensure(vector v, unsigned int i)
-{
- vector_ensure(v, i);
- return v->index[i];
-}
-
-/* Unset value at specified index slot. */
-void vector_unset(vector v, unsigned int i)
-{
- if (i >= v->alloced)
- return;
-
- v->index[i] = NULL;
-
- if (i + 1 == v->active) {
- v->active--;
- while (i && v->index[--i] == NULL && v->active--) ; /* Is this ugly ? */
- }
-}
-
-/* Count the number of not emplty slot. */
-unsigned int vector_count(vector v)
-{
- unsigned int i;
- unsigned count = 0;
-
- for (i = 0; i < v->active; i++)
- if (v->index[i] != NULL)
- count++;
-
- return count;
-}
diff --git a/openbsc/src/vty/vty.c b/openbsc/src/vty/vty.c
deleted file mode 100644
index 438b6c36e..000000000
--- a/openbsc/src/vty/vty.c
+++ /dev/null
@@ -1,1685 +0,0 @@
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-#include <termios.h>
-
-#include <sys/utsname.h>
-#include <sys/param.h>
-
-#include <arpa/telnet.h>
-
-#include <vty/vty.h>
-#include <vty/command.h>
-#include <vty/buffer.h>
-#include <osmocore/talloc.h>
-
-#define SYSCONFDIR "/usr/local/etc"
-
-/* our callback, located in telnet_interface.c */
-void vty_event(enum event event, int sock, struct vty *vty);
-
-extern struct host host;
-
-/* Vector which store each vty structure. */
-static vector vtyvec;
-
-vector Vvty_serv_thread;
-
-char *vty_cwd = NULL;
-
-/* Configure lock. */
-static int vty_config;
-
-static int no_password_check = 1;
-
-void *tall_vty_ctx;
-
-static void vty_clear_buf(struct vty *vty)
-{
- memset(vty->buf, 0, vty->max);
-}
-
-/* Allocate new vty struct. */
-struct vty *vty_new()
-{
- struct vty *new = talloc_zero(tall_vty_ctx, struct vty);
-
- if (!new)
- goto out;
-
- new->obuf = buffer_new(new, 0); /* Use default buffer size. */
- if (!new->obuf)
- goto out_new;
- new->buf = _talloc_zero(new, VTY_BUFSIZ, "vty_new->buf");
- if (!new->buf)
- goto out_obuf;
-
- new->max = VTY_BUFSIZ;
-
- return new;
-
-out_obuf:
- buffer_free(new->obuf);
-out_new:
- talloc_free(new);
- new = NULL;
-out:
- 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:
-#ifdef VTY_CRYPT_PW
- if (host.encrypt)
- passwd = host.password_encrypt;
- else
-#endif
- passwd = host.password;
- if (host.advanced)
- next_node = host.enable ? VIEW_NODE : ENABLE_NODE;
- else
- next_node = VIEW_NODE;
- break;
- case AUTH_ENABLE_NODE:
-#ifdef VTY_CRYPT_PW
- if (host.encrypt)
- passwd = host.enable_encrypt;
- else
-#endif
- passwd = host.enable;
- next_node = ENABLE_NODE;
- break;
- }
-
- if (passwd) {
-#ifdef VTY_CRYPT_PW
- if (host.encrypt)
- fail = strcmp(crypt(buf, passwd), passwd);
- else
-#endif
- fail = strcmp(buf, passwd);
- } else
- fail = 1;
-
- if (!fail) {
- vty->fail = 0;
- vty->node = next_node; /* Success ! */
- } else {
- vty->fail++;
- if (vty->fail >= 3) {
- 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);
- vty->node = VIEW_NODE;
- }
- }
- }
-}
-
-/* Close vty interface. */
-void vty_close(struct vty *vty)
-{
- int i;
-
- if (vty->obuf) {
- /* Flush buffer. */
- buffer_flush_all(vty->obuf, vty->fd);
-
- /* Free input buffer. */
- buffer_free(vty->obuf);
- vty->obuf = NULL;
- }
-
- /* Free command history. */
- for (i = 0; i < VTY_MAXHIST; i++)
- if (vty->hist[i])
- talloc_free(vty->hist[i]);
-
- /* Unset vector. */
- vector_unset(vtyvec, vty->fd);
-
- /* Close socket. */
- if (vty->fd > 0)
- close(vty->fd);
-
- if (vty->buf) {
- talloc_free(vty->buf);
- vty->buf = NULL;
- }
-
- /* Check configure. */
- vty_config_unlock(vty);
-
- /* VTY_CLOSED is handled by the telnet_interface */
- vty_event(VTY_CLOSED, vty->fd, vty);
-
- /* OK free vty. */
- talloc_free(vty);
-}
-
-int vty_shell(struct vty *vty)
-{
- return vty->type == VTY_SHELL ? 1 : 0;
-}
-
-
-/* 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)) {
- va_start(args, format);
- vprintf(format, args);
- va_end(args);
- } else {
- /* Try to write to initial buffer. */
- va_start(args, format);
- len = vsnprintf(buf, sizeof buf, format, args);
- va_end(args);
-
- /* Initial buffer is not enough. */
- if (len < 0 || len >= size) {
- while (1) {
- if (len > -1)
- size = len + 1;
- else
- size = size * 2;
-
- p = talloc_realloc_size(vty, 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;
- }
- }
-
- /* When initial buffer is enough to store all output. */
- if (!p)
- p = buf;
-
- /* Pointer p must point out buffer. */
- buffer_put(vty->obuf, (u_char *) p, len);
-
- /* If p is not different with buf, it is allocated buffer. */
- if (p != buf)
- talloc_free(p);
- }
-
- vty_event(VTY_WRITE, vty->fd, vty);
-
- return len;
-}
-
-int vty_out_newline(struct vty *vty)
-{
- char *p = vty_newline(vty);
- buffer_put(vty->obuf, p, strlen(p));
- return 0;
-}
-
-int vty_config_lock(struct vty *vty)
-{
- if (vty_config == 0) {
- vty->config = 1;
- vty_config = 1;
- }
- return vty->config;
-}
-
-int vty_config_unlock(struct vty *vty)
-{
- if (vty_config == 1 && vty->config == 1) {
- vty->config = 0;
- vty_config = 0;
- }
- return vty->config;
-}
-
-/* Say hello to vty interface. */
-void vty_hello(struct vty *vty)
-{
- if (host.motdfile) {
- FILE *f;
- char buf[4096];
-
- f = fopen(host.motdfile, "r");
- if (f) {
- while (fgets(buf, sizeof(buf), f)) {
- char *s;
- /* work backwards to ignore trailling isspace() */
- for (s = buf + strlen(buf);
- (s > buf) && isspace(*(s - 1)); s--) ;
- *s = '\0';
- vty_out(vty, "%s%s", buf, VTY_NEWLINE);
- }
- fclose(f);
- } else
- vty_out(vty, "MOTD file not found%s", VTY_NEWLINE);
- } else if (host.motd)
- vty_out(vty, "%s", host.motd);
-}
-
-/* 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) {
- uname(&names);
- hostname = names.nodename;
- }
- vty_out(vty, cmd_prompt(vty->node), hostname);
- }
-}
-
-/* Command execution over the vty interface. */
-static int vty_command(struct vty *vty, char *buf)
-{
- int ret;
- vector vline;
-
- /* Split readline string up into the vector */
- vline = cmd_make_strvec(buf);
-
- if (vline == NULL)
- return CMD_SUCCESS;
-
- ret = cmd_execute_command(vline, vty, NULL, 0);
- if (ret != CMD_SUCCESS)
- switch (ret) {
- case CMD_WARNING:
- if (vty->type == VTY_FILE)
- vty_out(vty, "Warning...%s", VTY_NEWLINE);
- break;
- case CMD_ERR_AMBIGUOUS:
- vty_out(vty, "%% Ambiguous command.%s", VTY_NEWLINE);
- break;
- case CMD_ERR_NO_MATCH:
- vty_out(vty, "%% Unknown command.%s", VTY_NEWLINE);
- break;
- case CMD_ERR_INCOMPLETE:
- vty_out(vty, "%% Command incomplete.%s", VTY_NEWLINE);
- break;
- }
- cmd_free_strvec(vline);
-
- return ret;
-}
-
-static const char telnet_backward_char = 0x08;
-static const char telnet_space_char = ' ';
-
-/* Basic function to write buffer to vty. */
-static void vty_write(struct vty *vty, const char *buf, size_t nbytes)
-{
- if ((vty->node == AUTH_NODE) || (vty->node == AUTH_ENABLE_NODE))
- return;
-
- /* Should we do buffering here ? And make vty_flush (vty) ? */
- buffer_put(vty->obuf, buf, nbytes);
-}
-
-/* Ensure length of input buffer. Is buffer is short, double it. */
-static void vty_ensure(struct vty *vty, int length)
-{
- if (vty->max <= length) {
- vty->max *= 2;
- vty->buf = talloc_realloc_size(vty, vty->buf, vty->max);
- // FIXME: check return
- }
-}
-
-/* Basic function to insert character into vty. */
-static void vty_self_insert(struct vty *vty, char c)
-{
- int i;
- int length;
-
- vty_ensure(vty, vty->length + 1);
- 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++;
-}
-
-/* Self insert character 'c' in overwrite mode. */
-static void vty_self_insert_overwrite(struct vty *vty, char c)
-{
- vty_ensure(vty, vty->length + 1);
- vty->buf[vty->cp++] = c;
-
- if (vty->cp > vty->length)
- vty->length++;
-
- if ((vty->node == AUTH_NODE) || (vty->node == AUTH_ENABLE_NODE))
- return;
-
- vty_write(vty, &c, 1);
-}
-
-/* Insert a word into vty interface with overwrite mode. */
-static void vty_insert_word_overwrite(struct vty *vty, char *str)
-{
- int len = strlen(str);
- vty_write(vty, str, len);
- strcpy(&vty->buf[vty->cp], str);
- vty->cp += len;
- vty->length = vty->cp;
-}
-
-/* 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);
-}
-
-/* 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])
- talloc_free(vty->hist[vty->hindex]);
- vty->hist[vty->hindex] = talloc_strdup(vty, vty->buf);
-
- /* History index rotation. */
- vty->hindex++;
- if (vty->hindex == VTY_MAXHIST)
- vty->hindex = 0;
-
- vty->hp = vty->hindex;
-}
-
-/* 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])
- {
- 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;
- }
- }
- vty_out (vty, "%s", VTY_NEWLINE);
-
-#endif /* TELNET_OPTION_DEBUG */
-
- switch (buf[0])
- {
- case SB:
- vty->sb_len = 0;
- vty->iac_sb_in_progress = 1;
- return 0;
- break;
- case SE:
- {
- 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)
- vty_out(vty,"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)
- vty_out(vty, "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]);
-#ifdef TELNET_OPTION_DEBUG
- vty_out(vty, "TELNET NAWS window size negotiation completed: "
- "width %d, height %d%s",
- vty->width, vty->height, VTY_NEWLINE);
-#endif
- }
- break;
- }
- vty->iac_sb_in_progress = 0;
- return 0;
- break;
- }
- 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)
- vty_hist_add(vty);
- break;
- }
-
- /* Clear command line buffer. */
- vty->cp = vty->length = 0;
- vty_clear_buf(vty);
-
- if (vty->status != VTY_CLOSE)
- vty_prompt(vty);
-
- return ret;
-}
-
-/* Send WILL TELOPT_ECHO to remote server. */
-static void
-vty_will_echo (struct vty *vty)
-{
- unsigned char cmd[] = { IAC, WILL, TELOPT_ECHO, '\0' };
- vty_out (vty, "%s", cmd);
-}
-
-/* Make suppress Go-Ahead telnet option. */
-static void
-vty_will_suppress_go_ahead (struct vty *vty)
-{
- unsigned char cmd[] = { IAC, WILL, TELOPT_SGA, '\0' };
- vty_out (vty, "%s", cmd);
-}
-
-/* Make don't use linemode over telnet. */
-static void
-vty_dont_linemode (struct vty *vty)
-{
- unsigned char cmd[] = { IAC, DONT, TELOPT_LINEMODE, '\0' };
- vty_out (vty, "%s", cmd);
-}
-
-/* Use window size. */
-static void
-vty_do_window_size (struct vty *vty)
-{
- unsigned char cmd[] = { IAC, DO, TELOPT_NAWS, '\0' };
- vty_out (vty, "%s", cmd);
-}
-
-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;
-
- /* Redraw current line */
- vty_redraw_line(vty);
-}
-
-/* Show next command line history. */
-static void 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. */
-static void 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);
-
- 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);
- /* FIXME: we need to call the exit function of the specific node
- * in question, not this generic one that doesn't know all nodes */
- (*config_exit_cmd.func) (NULL, vty, 0, NULL);
- vty_prompt(vty);
- vty->cp = 0;
-}
-
-/* When '^Z' is received from vty, move down to the enable mode. */
-static void vty_end_config(struct vty *vty)
-{
- vty_out(vty, "%s", VTY_NEWLINE);
-
- /* FIXME: we need to call the exit function of the specific node
- * in question, not this generic one that doesn't know all nodes */
- switch (vty->node) {
- case VIEW_NODE:
- case ENABLE_NODE:
- /* Nothing to do. */
- break;
- case CONFIG_NODE:
- 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->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
- return;
-
- if (vty->length == 0) {
- vty_down_level(vty);
- return;
- }
-
- if (vty->cp == vty->length)
- return; /* completion need here? */
-
- size = vty->length - vty->cp;
-
- vty->length--;
- memmove(&vty->buf[vty->cp], &vty->buf[vty->cp + 1], size - 1);
- vty->buf[vty->length] = '\0';
-
- 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;
-
- 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]))
- vector_set(vline, '\0');
-
- matched = cmd_complete_command(vline, vty, &ret);
-
- 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:
- vty_prompt(vty);
- vty_redraw_line(vty);
- vty_backward_pure_word(vty);
- vty_insert_word_overwrite(vty, matched[0]);
- vty_self_insert(vty, ' ');
- talloc_free(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]);
- talloc_free(matched[0]);
- break;
- case CMD_COMPLETE_LIST_MATCH:
- for (i = 0; matched[i] != NULL; i++) {
- if (i != 0 && ((i % 6) == 0))
- vty_out(vty, "%s", VTY_NEWLINE);
- vty_out(vty, "%-10s ", matched[i]);
- talloc_free(matched[i]);
- }
- 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)
- vector_only_index_free(matched);
-}
-
-static void
-vty_describe_fold(struct vty *vty, int cmd_width,
- unsigned int desc_width, struct desc *desc)
-{
- char *buf;
- const char *cmd, *p;
- int pos;
-
- cmd = desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd;
-
- if (desc_width <= 0) {
- vty_out(vty, " %-*s %s%s", cmd_width, cmd, desc->str,
- VTY_NEWLINE);
- return;
- }
-
- buf = _talloc_zero(vty, strlen(desc->str) + 1, "describe_fold");
- if (!buf)
- return;
-
- for (p = desc->str; strlen(p) > desc_width; p += pos + 1) {
- 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);
-
- talloc_free(buf);
-}
-
-/* Describe matched command function. */
-static void vty_describe_command(struct vty *vty)
-{
- int ret;
- vector vline;
- vector describe;
- unsigned int i, width, desc_width;
- struct desc *desc, *desc_cr = NULL;
-
- vline = cmd_make_strvec(vty->buf);
-
- /* In case of '> ?'. */
- if (vline == NULL) {
- vline = vector_init(1);
- vector_set(vline, '\0');
- } else if (isspace((int)vty->buf[vty->length - 1]))
- vector_set(vline, '\0');
-
- describe = cmd_describe_command(vline, vty, &ret);
-
- vty_out(vty, "%s", VTY_NEWLINE);
-
- /* Ambiguous error. */
- switch (ret) {
- case CMD_ERR_AMBIGUOUS:
- cmd_free_strvec(vline);
- vty_out(vty, "%% Ambiguous command.%s", VTY_NEWLINE);
- vty_prompt(vty);
- vty_redraw_line(vty);
- return;
- break;
- case CMD_ERR_NO_MATCH:
- cmd_free_strvec(vline);
- vty_out(vty, "%% There is no matched command.%s", VTY_NEWLINE);
- vty_prompt(vty);
- vty_redraw_line(vty);
- return;
- break;
- }
-
- /* Get width of command string. */
- width = 0;
- for (i = 0; i < vector_active(describe); i++)
- if ((desc = vector_slot(describe, i)) != NULL) {
- unsigned int len;
-
- if (desc->cmd[0] == '\0')
- continue;
-
- len = strlen(desc->cmd);
- if (desc->cmd[0] == '.')
- len--;
-
- if (width < len)
- width = len;
- }
-
- /* Get width of description string. */
- desc_width = vty->width - (width + 6);
-
- /* Print out description. */
- for (i = 0; i < vector_active(describe); i++)
- if ((desc = vector_slot(describe, i)) != NULL) {
- if (desc->cmd[0] == '\0')
- continue;
-
- if (strcmp(desc->cmd, "<cr>") == 0) {
- desc_cr = desc;
- continue;
- }
-
- if (!desc->str)
- vty_out(vty, " %-s%s",
- desc->cmd[0] ==
- '.' ? desc->cmd + 1 : desc->cmd,
- VTY_NEWLINE);
- else if (desc_width >= strlen(desc->str))
- vty_out(vty, " %-*s %s%s", width,
- desc->cmd[0] ==
- '.' ? desc->cmd + 1 : desc->cmd,
- desc->str, VTY_NEWLINE);
- else
- vty_describe_fold(vty, width, desc_width, desc);
-
-#if 0
- vty_out(vty, " %-*s %s%s", width
- desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
- desc->str ? desc->str : "", VTY_NEWLINE);
-#endif /* 0 */
- }
-
- if ((desc = desc_cr)) {
- if (!desc->str)
- vty_out(vty, " %-s%s",
- desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
- VTY_NEWLINE);
- else if (desc_width >= strlen(desc->str))
- vty_out(vty, " %-*s %s%s", width,
- desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
- desc->str, VTY_NEWLINE);
- else
- vty_describe_fold(vty, width, desc_width, desc);
- }
-
- cmd_free_strvec(vline);
- vector_free(describe);
-
- vty_prompt(vty);
- vty_redraw_line(vty);
-}
-
-/* ^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 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;
-}
-
-#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. */
-int vty_read(struct vty *vty)
-{
- int i;
- int nbytes;
- unsigned char buf[VTY_READ_BUFSIZ];
-
- int vty_sock = vty->fd;
-
- /* Read raw data from socket */
- if ((nbytes = read(vty->fd, buf, VTY_READ_BUFSIZ)) <= 0) {
- if (nbytes < 0) {
- if (ERRNO_IO_RETRY(errno)) {
- vty_event(VTY_READ, vty_sock, vty);
- return 0;
- }
- }
- buffer_reset(vty->obuf);
- vty->status = VTY_CLOSE;
- }
-
- for (i = 0; i < nbytes; i++) {
- if (buf[i] == IAC) {
- if (!vty->iac) {
- vty->iac = 1;
- continue;
- } else {
- vty->iac = 0;
- }
- }
-
- if (vty->iac_sb_in_progress && !vty->iac) {
- if (vty->sb_len < sizeof(vty->sb_buf))
- vty->sb_buf[vty->sb_len] = buf[i];
- vty->sb_len++;
- continue;
- }
-
- if (vty->iac) {
- /* In case of telnet command */
- int ret = 0;
- ret = vty_telnet_option(vty, buf + i, nbytes - i);
- vty->iac = 0;
- i += ret;
- continue;
- }
-
- if (vty->status == VTY_MORE) {
- switch (buf[i]) {
- case CONTROL('C'):
- case 'q':
- case 'Q':
- vty_buffer_reset(vty);
- break;
-#if 0 /* More line does not work for "show ip bgp". */
- case '\n':
- case '\r':
- vty->status = VTY_MORELINE;
- break;
-#endif
- default:
- break;
- }
- continue;
- }
-
- /* Escape character. */
- if (vty->escape == VTY_ESCAPE) {
- vty_escape_map(buf[i], vty);
- continue;
- }
-
- /* Pre-escape status. */
- if (vty->escape == VTY_PRE_ESCAPE) {
- 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;
- }
-
- switch (buf[i]) {
- 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;
- }
- }
-
- /* Check status. */
- if (vty->status == VTY_CLOSE)
- vty_close(vty);
- else {
- vty_event(VTY_WRITE, vty_sock, vty);
- vty_event(VTY_READ, vty_sock, vty);
- }
- return 0;
-}
-
-/* Read up configuration file */
-static int
-vty_read_file(FILE *confp, void *priv)
-{
- int ret;
- struct vty *vty;
-
- vty = vty_new();
- vty->fd = 0;
- vty->type = VTY_FILE;
- vty->node = CONFIG_NODE;
- vty->priv = priv;
-
- ret = config_from_file(vty, confp);
-
- if (ret != CMD_SUCCESS) {
- switch (ret) {
- case CMD_ERR_AMBIGUOUS:
- fprintf(stderr, "Ambiguous command.\n");
- break;
- case CMD_ERR_NO_MATCH:
- fprintf(stderr, "There is no such command.\n");
- break;
- }
- fprintf(stderr, "Error occurred during reading below "
- "line:\n%s\n", vty->buf);
- vty_close(vty);
- return -EINVAL;
- }
-
- vty_close(vty);
- return 0;
-}
-
-/* Create new vty structure. */
-struct vty *
-vty_create (int vty_sock, void *priv)
-{
- struct vty *vty;
-
- struct termios t;
-
- tcgetattr(vty_sock, &t);
- cfmakeraw(&t);
- tcsetattr(vty_sock, TCSANOW, &t);
-
- /* Allocate new vty structure and set up default values. */
- vty = vty_new ();
- vty->fd = vty_sock;
- vty->priv = priv;
- vty->type = VTY_TERM;
- if (no_password_check)
- {
- if (host.advanced)
- vty->node = ENABLE_NODE;
- else
- vty->node = VIEW_NODE;
- }
- else
- 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;
- if (host.lines >= 0)
- vty->lines = host.lines;
- else
- vty->lines = -1;
-
- if (! no_password_check)
- {
- /* Vty is not available if password isn't set. */
- if (host.password == NULL && host.password_encrypt == NULL)
- {
- vty_out (vty, "Vty password is not set.%s", VTY_NEWLINE);
- vty->status = VTY_CLOSE;
- vty_close (vty);
- return NULL;
- }
- }
-
- /* 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;
-}
-
-DEFUN(config_who, config_who_cmd, "who", "Display who is on vty\n")
-{
- unsigned int i;
- struct vty *v;
-
- for (i = 0; i < vector_active(vtyvec); i++)
- if ((v = vector_slot(vtyvec, i)) != NULL)
- vty_out(vty, "%svty[%d] %s",
- v->config ? "*" : " ", i, VTY_NEWLINE);
- 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;
-}
-
-/* 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;
-}
-
-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) {
- index = 0;
- continue;
- }
-
- if (vty->hist[index] != NULL)
- vty_out(vty, " %s%s", vty->hist[index], VTY_NEWLINE);
-
- index++;
- }
-
- return CMD_SUCCESS;
-}
-
-/* Display current configuration. */
-static int vty_config_write(struct vty *vty)
-{
- vty_out(vty, "line vty%s", VTY_NEWLINE);
-
- /* login */
- if (no_password_check)
- vty_out(vty, " no login%s", VTY_NEWLINE);
-
- vty_out(vty, "!%s", VTY_NEWLINE);
-
- return CMD_SUCCESS;
-}
-
-struct cmd_node vty_node = {
- VTY_NODE,
- "%s(config-line)# ",
- 1,
-};
-
-/* Reset all VTY status. */
-void vty_reset()
-{
- unsigned int i;
- struct vty *vty;
- struct thread *vty_serv_thread;
-
- for (i = 0; i < vector_active(vtyvec); i++)
- if ((vty = vector_slot(vtyvec, i)) != NULL) {
- buffer_reset(vty->obuf);
- vty->status = VTY_CLOSE;
- vty_close(vty);
- }
-
- for (i = 0; i < vector_active(Vvty_serv_thread); i++)
- if ((vty_serv_thread =
- vector_slot(Vvty_serv_thread, i)) != NULL) {
- //thread_cancel (vty_serv_thread);
- vector_slot(Vvty_serv_thread, i) = NULL;
- close(i);
- }
-}
-
-static void vty_save_cwd(void)
-{
- char cwd[MAXPATHLEN];
- char *c ;
-
- c = getcwd(cwd, MAXPATHLEN);
-
- if (!c) {
- if (chdir(SYSCONFDIR) != 0)
- perror("chdir failed");
- if (getcwd(cwd, MAXPATHLEN) == NULL)
- perror("getcwd failed");
- }
-
- vty_cwd = _talloc_zero(tall_vty_ctx, strlen(cwd) + 1, "save_cwd");
- strcpy(vty_cwd, cwd);
-}
-
-char *vty_get_cwd()
-{
- return vty_cwd;
-}
-
-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);
-}
-
-extern void *tall_bsc_ctx;
-/* Install vty's own commands like `who' command. */
-void vty_init(const char *name, const char *version, const char *copyright)
-{
- tall_vty_ctx = talloc_named_const(NULL, 0, "vty");
- tall_vty_vec_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_vector");
- tall_vty_cmd_ctx = talloc_named_const(tall_vty_ctx, 0, "vty_command");
-
- cmd_init(1);
-
- host.prog_name = name;
- host.prog_version = version;
- host.prog_copyright = copyright;
-
- /* For further configuration read, preserve current directory. */
- vty_save_cwd();
-
- vtyvec = vector_init(VECTOR_MIN_SIZE);
-
- /* Install bgp top node. */
- install_node(&vty_node, vty_config_write);
-
- install_element_ve(&config_who_cmd);
- install_element_ve(&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);
- install_element(ENABLE_NODE, &terminal_monitor_cmd);
- install_element(ENABLE_NODE, &terminal_no_monitor_cmd);
-
- install_default(VTY_NODE);
- install_element(VTY_NODE, &vty_login_cmd);
- install_element(VTY_NODE, &no_vty_login_cmd);
-}
-
-int vty_read_config_file(const char *file_name, void *priv)
-{
- FILE *cfile;
- int rc;
-
- cfile = fopen(file_name, "r");
- if (!cfile)
- return -ENOENT;
-
- rc = vty_read_file(cfile, priv);
- fclose(cfile);
-
- host_config_set(file_name);
-
- return rc;
-}
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index c18aef345..c23c1c2bf 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -23,9 +23,9 @@
#include <unistd.h>
#include <sys/types.h>
-#include <vty/command.h>
-#include <vty/buffer.h>
-#include <vty/vty.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/buffer.h>
+#include <osmocom/vty/vty.h>
#include <arpa/inet.h>