[VTY] Remove OpenBSC specific node-exit handling from src/vty

The idea is to move the VTY code into libosmocore at some point,
and for that we need to eliminate OpenBSC specifics from it
diff --git a/openbsc/src/gprs/gb_proxy_vty.c b/openbsc/src/gprs/gb_proxy_vty.c
index e1cf97e..babb089 100644
--- a/openbsc/src/gprs/gb_proxy_vty.c
+++ b/openbsc/src/gprs/gb_proxy_vty.c
@@ -29,6 +29,7 @@
 #include <openbsc/debug.h>
 #include <openbsc/gb_proxy.h>
 #include <openbsc/gprs_ns.h>
+#include <openbsc/vty.h>
 
 #include <vty/command.h>
 #include <vty/vty.h>
@@ -157,6 +158,7 @@
 	install_element(CONFIG_NODE, &cfg_gbproxy_cmd);
 	install_node(&gbproxy_node, config_write_gbproxy);
 	install_default(GBPROXY_NODE);
+	install_element(GBPROXY_NODE, &ournode_exit_cmd);
 	install_element(GBPROXY_NODE, &cfg_nsip_bss_local_ip_cmd);
 	install_element(GBPROXY_NODE, &cfg_nsip_bss_local_port_cmd);
 	install_element(GBPROXY_NODE, &cfg_nsip_sgsn_ip_cmd);
diff --git a/openbsc/src/gprs/gprs_ns_vty.c b/openbsc/src/gprs/gprs_ns_vty.c
index 8f0628a..b18e651 100644
--- a/openbsc/src/gprs/gprs_ns_vty.c
+++ b/openbsc/src/gprs/gprs_ns_vty.c
@@ -37,6 +37,7 @@
 #include <openbsc/signal.h>
 #include <openbsc/gprs_ns.h>
 #include <openbsc/gprs_bssgp.h>
+#include <openbsc/vty.h>
 
 #include <vty/vty.h>
 #include <vty/command.h>
@@ -281,6 +282,7 @@
 	install_element(CONFIG_NODE, &cfg_ns_cmd);
 	install_node(&ns_node, config_write_ns);
 	install_default(NS_NODE);
+	install_element(NS_NODE, &ournode_exit_cmd);
 	install_element(NS_NODE, &cfg_nse_nsvci_cmd);
 	install_element(NS_NODE, &cfg_nse_remoteip_cmd);
 	install_element(NS_NODE, &cfg_nse_remoteport_cmd);
diff --git a/openbsc/src/gprs/sgsn_vty.c b/openbsc/src/gprs/sgsn_vty.c
index ec18fcb..4dc6257 100644
--- a/openbsc/src/gprs/sgsn_vty.c
+++ b/openbsc/src/gprs/sgsn_vty.c
@@ -29,6 +29,7 @@
 #include <openbsc/debug.h>
 #include <openbsc/sgsn.h>
 #include <openbsc/gprs_ns.h>
+#include <openbsc/vty.h>
 
 #include <vty/command.h>
 #include <vty/vty.h>
@@ -125,6 +126,7 @@
 	install_element(CONFIG_NODE, &cfg_sgsn_cmd);
 	install_node(&sgsn_node, config_write_sgsn);
 	install_default(SGSN_NODE);
+	install_element(SGSN_NODE, &ournode_exit_cmd);
 	install_element(SGSN_NODE, &cfg_nsip_local_ip_cmd);
 	install_element(SGSN_NODE, &cfg_nsip_local_port_cmd);
 
diff --git a/openbsc/src/mgcp/mgcp_vty.c b/openbsc/src/mgcp/mgcp_vty.c
index dd0293a..6d2aff0 100644
--- a/openbsc/src/mgcp/mgcp_vty.c
+++ b/openbsc/src/mgcp/mgcp_vty.c
@@ -29,6 +29,7 @@
 #include <openbsc/debug.h>
 #include <openbsc/mgcp.h>
 #include <openbsc/mgcp_internal.h>
+#include <openbsc/vty.h>
 
 #include <vty/command.h>
 #include <vty/vty.h>
@@ -243,6 +244,7 @@
 	install_element(CONFIG_NODE, &cfg_mgcp_cmd);
 	install_node(&mgcp_node, config_write_mgcp);
 	install_default(MGCP_NODE);
+	install_element(MGCP_NODE, &ournode_exit_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_local_ip_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_bts_ip_cmd);
 	install_element(MGCP_NODE, &cfg_mgcp_bind_ip_cmd);
diff --git a/openbsc/src/vty/command.c b/openbsc/src/vty/command.c
index a1130b6..811cbf1 100644
--- a/openbsc/src/vty/command.c
+++ b/openbsc/src/vty/command.c
@@ -2322,39 +2322,6 @@
       config_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
 {
 	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;
 	case VIEW_NODE:
 	case ENABLE_NODE:
 		if (0)		//vty_shell (vty))
@@ -2369,22 +2336,12 @@
 	case VTY_NODE:
 		vty->node = CONFIG_NODE;
 		break;
-	case MGCP_NODE:
-	case GBPROXY_NODE:
-	case SGSN_NODE:
-	case NS_NODE:
-		vty->node = CONFIG_NODE;
-		vty->index = NULL;
 	default:
 		break;
 	}
 	return CMD_SUCCESS;
 }
 
-/* quit is alias of exit. */
-gALIAS(config_exit,
-      config_quit_cmd, "quit", "Exit current mode and down to previous mode\n")
-
 /* End of configuration. */
     gDEFUN(config_end,
       config_end_cmd, "end", "End current mode and change to enable mode.")
@@ -3333,9 +3290,6 @@
 
 void install_default(enum node_type node)
 {
-	install_element(node, &config_exit_cmd);
-	install_element(node, &config_quit_cmd);
-	install_element(node, &config_end_cmd);
 	install_element(node, &config_help_cmd);
 	install_element(node, &config_list_cmd);
 
@@ -3374,7 +3328,6 @@
 	if (terminal) {
 		install_element(VIEW_NODE, &config_list_cmd);
 		install_element(VIEW_NODE, &config_exit_cmd);
-		install_element(VIEW_NODE, &config_quit_cmd);
 		install_element(VIEW_NODE, &config_help_cmd);
 		install_element(VIEW_NODE, &config_enable_cmd);
 		install_element(VIEW_NODE, &config_terminal_length_cmd);
@@ -3383,6 +3336,7 @@
 	}
 
 	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);
@@ -3397,6 +3351,7 @@
 		install_element(ENABLE_NODE, &echo_cmd);
 
 		install_default(CONFIG_NODE);
+		install_element(CONFIG_NODE, &config_exit_cmd);
 	}
 
 	install_element(CONFIG_NODE, &hostname_cmd);
diff --git a/openbsc/src/vty/vty.c b/openbsc/src/vty/vty.c
index 0806856..986902a 100644
--- a/openbsc/src/vty/vty.c
+++ b/openbsc/src/vty/vty.c
@@ -731,6 +731,8 @@
 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;
@@ -741,6 +743,8 @@
 {
 	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:
diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c
index 8af9153..0ceab5b 100644
--- a/openbsc/src/vty_interface.c
+++ b/openbsc/src/vty_interface.c
@@ -1954,6 +1954,7 @@
 	install_element(CONFIG_NODE, &cfg_net_cmd);
 	install_node(&net_node, config_write_net);
 	install_default(GSMNET_NODE);
+	install_element(GSMNET_NODE, &ournode_exit_cmd);
 	install_element(GSMNET_NODE, &cfg_net_ncc_cmd);
 	install_element(GSMNET_NODE, &cfg_net_mnc_cmd);
 	install_element(GSMNET_NODE, &cfg_net_name_short_cmd);
@@ -1986,6 +1987,7 @@
 	install_element(GSMNET_NODE, &cfg_bts_cmd);
 	install_node(&bts_node, config_write_bts);
 	install_default(BTS_NODE);
+	install_element(BTS_NODE, &ournode_exit_cmd);
 	install_element(BTS_NODE, &cfg_bts_type_cmd);
 	install_element(BTS_NODE, &cfg_description_cmd);
 	install_element(BTS_NODE, &cfg_no_description_cmd);
@@ -2023,6 +2025,7 @@
 	install_element(BTS_NODE, &cfg_trx_cmd);
 	install_node(&trx_node, dummy_config_write);
 	install_default(TRX_NODE);
+	install_element(TRX_NODE, &ournode_exit_cmd);
 	install_element(TRX_NODE, &cfg_trx_arfcn_cmd);
 	install_element(TRX_NODE, &cfg_description_cmd);
 	install_element(TRX_NODE, &cfg_no_description_cmd);
@@ -2035,6 +2038,7 @@
 	install_element(TRX_NODE, &cfg_ts_cmd);
 	install_node(&ts_node, dummy_config_write);
 	install_default(TS_NODE);
+	install_element(TS_NODE, &ournode_exit_cmd);
 	install_element(TS_NODE, &cfg_ts_pchan_cmd);
 	install_element(TS_NODE, &cfg_ts_e1_subslot_cmd);
 
diff --git a/openbsc/src/vty_interface_cmds.c b/openbsc/src/vty_interface_cmds.c
index 4e5dc29..134a8d3 100644
--- a/openbsc/src/vty_interface_cmds.c
+++ b/openbsc/src/vty_interface_cmds.c
@@ -71,6 +71,55 @@
 	return target;
 }
 
+/* Down vty node level. */
+gDEFUN(ournode_exit,
+       ournode_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
+{
+	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;
+			vty->index_sub = NULL;
+		}
+		break;
+	case TRX_NODE:
+		vty->node = BTS_NODE;
+		{
+			/* set vty->index correctly ! */
+			struct gsm_bts_trx *trx = vty->index;
+			vty->index = trx->bts;
+			vty->index_sub = &trx->bts->description;
+		}
+		break;
+	case TS_NODE:
+		vty->node = TRX_NODE;
+		{
+			/* set vty->index correctly ! */
+			struct gsm_bts_trx_ts *ts = vty->index;
+			vty->index = ts->trx;
+			vty->index_sub = &ts->trx->description;
+		}
+		break;
+	case MGCP_NODE:
+	case GBPROXY_NODE:
+	case SGSN_NODE:
+	case NS_NODE:
+		vty->node = CONFIG_NODE;
+		vty->index = NULL;
+		break;
+	default:
+		break;
+	}
+	return CMD_SUCCESS;
+}
+
 DEFUN(enable_logging,
       enable_logging_cmd,
       "logging enable",
diff --git a/openbsc/src/vty_interface_layer3.c b/openbsc/src/vty_interface_layer3.c
index 029f0c4..5aa24d3 100644
--- a/openbsc/src/vty_interface_layer3.c
+++ b/openbsc/src/vty_interface_layer3.c
@@ -51,6 +51,20 @@
 	1,
 };
 
+/* Down vty node level. */
+DEFUN(subscr_node_exit,
+      subscr_node_exit_cmd, "exit", "Exit current mode and down to previous mode\n")
+{
+	switch (vty->node) {
+	case SUBSCR_NODE:
+		vty->node = VIEW_NODE;
+		subscr_put(vty->index);
+		vty->index = NULL;
+		break;
+	}
+	return CMD_SUCCESS;
+}
+
 static int dummy_config_write(struct vty *v)
 {
 	return CMD_SUCCESS;
@@ -542,6 +556,7 @@
 	install_node(&subscr_node, dummy_config_write);
 
 	install_default(SUBSCR_NODE);
+	install_element(SUBSCR_NODE, &subscr_node_exit_cmd);
 	install_element(SUBSCR_NODE, &cfg_subscr_name_cmd);
 	install_element(SUBSCR_NODE, &cfg_subscr_extension_cmd);
 	install_element(SUBSCR_NODE, &cfg_subscr_authorized_cmd);