]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/vty.c
vtysh: return non-zero for configuration failures
[mirror_frr.git] / lib / vty.c
index 3c5b28a5df71fe2a9e3312014ea1cd0142c8a6de..00a4e9bf713b82e541d38af1fec4ad78bd883f0e 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
  * 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.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 #include <zebra.h>
@@ -35,6 +34,7 @@
 #include "vty.h"
 #include "privs.h"
 #include "network.h"
+#include "libfrr.h"
 
 #include <arpa/telnet.h>
 #include <termios.h>
@@ -92,28 +92,23 @@ char integrate_default[] = SYSCONFDIR INTEGRATE_DEFAULT_CONFIG;
 
 static int do_log_commands = 0;
 
-/* VTY standard output function. */
-int
-vty_out (struct vty *vty, const char *format, ...)
+static int
+vty_out_variadic (struct vty *vty, const char *format, va_list args)
 {
-  va_list args;
   int len = 0;
   int size = 1024;
   char buf[1024];
   char *p = NULL;
+  va_list cp;
 
   if (vty_shell (vty))
-    {
-      va_start (args, format);
-      vprintf (format, args);
-      va_end (args);
-    }
+    vprintf (format, args);
   else
     {
       /* Try to write to initial buffer.  */
-      va_start (args, format);
-      len = vsnprintf (buf, sizeof(buf), format, args);
-      va_end (args);
+      va_copy (cp, args);
+      len = vsnprintf (buf, sizeof(buf), format, cp);
+      va_end (cp);
 
       /* Initial buffer is not enough.  */
       if (len < 0 || len >= size)
@@ -129,9 +124,9 @@ vty_out (struct vty *vty, const char *format, ...)
               if (! p)
                 return -1;
 
-              va_start (args, format);
-              len = vsnprintf (p, size, format, args);
-              va_end (args);
+              va_copy (cp, args);
+              len = vsnprintf (p, size, format, cp);
+              va_end (cp);
 
               if (len > -1 && len < size)
                 break;
@@ -152,6 +147,32 @@ vty_out (struct vty *vty, const char *format, ...)
 
   return len;
 }
+/* VTY standard output function. */
+int
+vty_out (struct vty *vty, const char *format, ...)
+{
+  int len;
+  va_list args;
+
+  va_start (args, format);
+  len = vty_out_variadic (vty, format, args);
+  va_end (args);
+
+  return len;
+}
+
+int
+vty_outln (struct vty *vty, const char *format, ...)
+{
+  int len;
+  va_list args;
+
+  va_start (args, format);
+  len = vty_out_variadic (vty, format, args);
+  va_end (args);
+
+  return len + vty_out (vty, "%s", VTYNL);
+}
 
 static int
 vty_log_out (struct vty *vty, const char *level, const char *proto_str,
@@ -244,12 +265,12 @@ vty_hello (struct vty *vty)
               for (s = buf + strlen (buf); (s > buf) && isspace ((int)*(s - 1));
                    s--);
               *s = '\0';
-              vty_out (vty, "%s%s", buf, VTY_NEWLINE);
+              vty_outln (vty, "%s", buf);
             }
           fclose (f);
         }
       else
-        vty_out (vty, "MOTD file not found%s", VTY_NEWLINE);
+        vty_outln (vty, "MOTD file not found");
     }
   else if (host.motd)
     vty_out (vty, "%s", host.motd);
@@ -382,14 +403,14 @@ vty_auth (struct vty *vty, char *buf)
         {
           if (vty->node == AUTH_NODE)
             {
-              vty_out (vty, "%% Bad passwords, too many failures!%s", VTY_NEWLINE);
+              vty_outln (vty, "%% Bad passwords, too many failures!");
               vty->status = VTY_CLOSE;
             }
           else
             {
               /* AUTH_ENABLE_NODE */
               vty->fail = 0;
-              vty_out (vty, "%% Bad enable passwords, too many failures!%s", VTY_NEWLINE);
+              vty_outln (vty, "%% Bad enable passwords, too many failures!");
              vty->status = VTY_CLOSE;
             }
         }
@@ -457,7 +478,7 @@ vty_command (struct vty *vty, char *buf)
   ret = cmd_execute_command (vline, vty, NULL, 0);
 
   /* Get the name of the protocol if any */
-  protocolname = zlog_protoname();
+  protocolname = frr_protoname;
 
 #ifdef CONSUMED_TIME_CHECK
     GETRUSAGE(&after);
@@ -474,16 +495,16 @@ vty_command (struct vty *vty, char *buf)
       {
       case CMD_WARNING:
         if (vty->type == VTY_FILE)
-          vty_out (vty, "Warning...%s", VTY_NEWLINE);
+          vty_outln (vty, "Warning...");
         break;
       case CMD_ERR_AMBIGUOUS:
-        vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
+        vty_outln (vty, "%% Ambiguous command.");
         break;
       case CMD_ERR_NO_MATCH:
-        vty_out (vty, "%% [%s] Unknown command: %s%s", protocolname, buf, VTY_NEWLINE);
+        vty_outln (vty, "%% [%s] Unknown command: %s", protocolname, buf);
         break;
       case CMD_ERR_INCOMPLETE:
-        vty_out (vty, "%% Command incomplete.%s", VTY_NEWLINE);
+        vty_outln (vty, "%% Command incomplete.");
         break;
       }
   cmd_free_strvec (vline);
@@ -711,7 +732,7 @@ vty_backward_word (struct vty *vty)
 static void
 vty_down_level (struct vty *vty)
 {
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, VTYNL);
   cmd_exit (vty);
   vty_prompt (vty);
   vty->cp = 0;
@@ -721,7 +742,7 @@ vty_down_level (struct vty *vty)
 static void
 vty_end_config (struct vty *vty)
 {
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, VTYNL);
 
   switch (vty->node)
     {
@@ -734,11 +755,10 @@ vty_end_config (struct vty *vty)
     case ZEBRA_NODE:
     case RIP_NODE:
     case RIPNG_NODE:
+    case EIGRP_NODE:
     case BGP_NODE:
     case BGP_VPNV4_NODE:
     case BGP_VPNV6_NODE:
-    case BGP_ENCAP_NODE:
-    case BGP_ENCAPV6_NODE:
     case BGP_VRF_POLICY_NODE:
     case BGP_VNC_DEFAULTS_NODE:
     case BGP_VNC_NVE_GROUP_NODE:
@@ -927,16 +947,16 @@ vty_complete_command (struct vty *vty)
 
   cmd_free_strvec (vline);
 
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, VTYNL);
   switch (ret)
     {
     case CMD_ERR_AMBIGUOUS:
-      vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
+      vty_outln (vty, "%% Ambiguous command.");
       vty_prompt (vty);
       vty_redraw_line (vty);
       break;
     case CMD_ERR_NO_MATCH:
-      /* vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE); */
+      /* vty_out (vty, "%% There is no matched command.%s", VTYNL); */
       vty_prompt (vty);
       vty_redraw_line (vty);
       break;
@@ -944,7 +964,7 @@ vty_complete_command (struct vty *vty)
       if (!matched[0])
         {
           /* 2016-11-28 equinox -- need to debug, SEGV here */
-          vty_out (vty, "%% CLI BUG: FULL_MATCH with NULL str%s", VTY_NEWLINE);
+          vty_outln (vty, "%% CLI BUG: FULL_MATCH with NULL str");
           vty_prompt (vty);
           vty_redraw_line (vty);
           break;
@@ -954,24 +974,24 @@ vty_complete_command (struct vty *vty)
       vty_backward_pure_word (vty);
       vty_insert_word_overwrite (vty, matched[0]);
       vty_self_insert (vty, ' ');
-      XFREE (MTYPE_TMP, matched[0]);
+      XFREE (MTYPE_COMPLETION, matched[0]);
       break;
     case CMD_COMPLETE_MATCH:
       vty_prompt (vty);
       vty_redraw_line (vty);
       vty_backward_pure_word (vty);
       vty_insert_word_overwrite (vty, matched[0]);
-      XFREE (MTYPE_TMP, matched[0]);
+      XFREE (MTYPE_COMPLETION, 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, VTYNL);
           vty_out (vty, "%-10s ", matched[i]);
-          XFREE (MTYPE_TMP, matched[i]);
+          XFREE (MTYPE_COMPLETION, matched[i]);
         }
-      vty_out (vty, "%s", VTY_NEWLINE);
+      vty_out (vty, VTYNL);
 
       vty_prompt (vty);
       vty_redraw_line (vty);
@@ -999,7 +1019,7 @@ vty_describe_fold (struct vty *vty, int cmd_width,
 
   if (desc_width <= 0)
     {
-      vty_out (vty, "  %-*s  %s%s", cmd_width, cmd, token->desc, VTY_NEWLINE);
+      vty_outln (vty, "  %-*s  %s", cmd_width, cmd, token->desc);
       return;
     }
 
@@ -1016,12 +1036,12 @@ vty_describe_fold (struct vty *vty, int cmd_width,
 
       strncpy (buf, p, pos);
       buf[pos] = '\0';
-      vty_out (vty, "  %-*s  %s%s", cmd_width, cmd, buf, VTY_NEWLINE);
+      vty_outln (vty, "  %-*s  %s", cmd_width, cmd, buf);
 
       cmd = "";
     }
 
-  vty_out (vty, "  %-*s  %s%s", cmd_width, cmd, p, VTY_NEWLINE);
+  vty_outln (vty, "  %-*s  %s", cmd_width, cmd, p);
 
   XFREE (MTYPE_TMP, buf);
 }
@@ -1050,17 +1070,17 @@ vty_describe_command (struct vty *vty)
 
   describe = cmd_describe_command (vline, vty, &ret);
 
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, VTYNL);
 
   /* Ambiguous error. */
   switch (ret)
     {
     case CMD_ERR_AMBIGUOUS:
-      vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);
+      vty_outln (vty, "%% Ambiguous command.");
       goto out;
       break;
     case CMD_ERR_NO_MATCH:
-      vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE);
+      vty_outln (vty, "%% There is no matched command.");
       goto out;
       break;
     }
@@ -1098,33 +1118,51 @@ vty_describe_command (struct vty *vty)
           }
 
         if (!token->desc)
-          vty_out (vty, "  %-s%s",
-                   token->text,
-                   VTY_NEWLINE);
+          vty_outln (vty, "  %-s",
+                   token->text);
         else if (desc_width >= strlen (token->desc))
-          vty_out (vty, "  %-*s  %s%s", width,
+          vty_outln (vty, "  %-*s  %s", width,
                    token->text,
-                   token->desc, VTY_NEWLINE);
+                   token->desc);
         else
           vty_describe_fold (vty, width, desc_width, token);
 
+        if (IS_VARYING_TOKEN(token->type))
+          {
+            const char *ref = vector_slot(vline, vector_active(vline) - 1);
+
+            vector varcomps = vector_init (VECTOR_MIN_SIZE);
+            cmd_variable_complete (token, ref, varcomps);
+
+            if (vector_active(varcomps) > 0)
+              {
+                vty_out(vty, "     ");
+                for (size_t j = 0; j < vector_active (varcomps); j++)
+                  {
+                    char *item = vector_slot (varcomps, j);
+                    vty_out(vty, " %s", item);
+                    XFREE(MTYPE_COMPLETION, item);
+                  }
+                vty_out (vty, VTYNL);
+              }
+            vector_free(varcomps);
+          }
 #if 0
         vty_out (vty, "  %-*s %s%s", width
                  desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
-                 desc->str ? desc->str : "", VTY_NEWLINE);
+                 desc->str ? desc->str : "", VTYNL);
 #endif /* 0 */
       }
 
   if ((token = token_cr))
     {
       if (!token->desc)
-        vty_out (vty, "  %-s%s",
-                 token->text,
-                 VTY_NEWLINE);
+        vty_outln (vty, "  %-s",
+                 token->text);
       else if (desc_width >= strlen (token->desc))
-        vty_out (vty, "  %-*s  %s%s", width,
+        vty_outln (vty, "  %-*s  %s", width,
                  token->text,
-                 token->desc, VTY_NEWLINE);
+                 token->desc);
       else
         vty_describe_fold (vty, width, desc_width, token);
     }
@@ -1150,7 +1188,7 @@ vty_stop_input (struct vty *vty)
 {
   vty->cp = vty->length = 0;
   vty_clear_buf (vty);
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, VTYNL);
 
   switch (vty->node)
     {
@@ -1163,6 +1201,7 @@ vty_stop_input (struct vty *vty)
     case ZEBRA_NODE:
     case RIP_NODE:
     case RIPNG_NODE:
+    case EIGRP_NODE:
     case BGP_NODE:
     case RMAP_NODE:
     case OSPF_NODE:
@@ -1260,20 +1299,20 @@ vty_telnet_option (struct vty *vty, unsigned char *buf, int nbytes)
           vty_out (vty, "SE ");
           break;
         case TELOPT_ECHO:
-          vty_out (vty, "TELOPT_ECHO %s", VTY_NEWLINE);
+          vty_outln (vty, "TELOPT_ECHO ");
           break;
         case TELOPT_SGA:
-          vty_out (vty, "TELOPT_SGA %s", VTY_NEWLINE);
+          vty_outln (vty, "TELOPT_SGA ");
           break;
         case TELOPT_NAWS:
-          vty_out (vty, "TELOPT_NAWS %s", VTY_NEWLINE);
+          vty_outln (vty, "TELOPT_NAWS ");
           break;
         default:
           vty_out (vty, "%x ", buf[i]);
           break;
         }
     }
-  vty_out (vty, "%s", VTY_NEWLINE);
+  vty_out (vty, VTYNL);
 
 #endif /* TELNET_OPTION_DEBUG */
 
@@ -1310,9 +1349,9 @@ vty_telnet_option (struct vty *vty, unsigned char *buf, int nbytes)
                 vty->width = ((vty->sb_buf[1] << 8)|vty->sb_buf[2]);
                 vty->height = ((vty->sb_buf[3] << 8)|vty->sb_buf[4]);
 #ifdef TELNET_OPTION_DEBUG
-                vty_out(vty, "TELNET NAWS window size negotiation completed: "
-                              "width %d, height %d%s",
-                        vty->width, vty->height, VTY_NEWLINE);
+                vty_outln (vty, "TELNET NAWS window size negotiation completed: "
+                              "width %d, height %d",
+                        vty->width, vty->height);
 #endif
               }
             break;
@@ -1569,7 +1608,7 @@ vty_read (struct thread *thread)
           break;
         case '\n':
         case '\r':
-          vty_out (vty, "%s", VTY_NEWLINE);
+          vty_out (vty, VTYNL);
           vty_execute (vty);
           break;
         case '\t':
@@ -1728,7 +1767,7 @@ vty_create (int vty_sock, union sockunion *su)
       /* Vty is not available if password isn't set. */
       if (host.password == NULL && host.password_encrypt == NULL)
         {
-          vty_out (vty, "Vty password is not set.%s", VTY_NEWLINE);
+          vty_outln (vty, "Vty password is not set.");
           vty->status = VTY_CLOSE;
           vty_close (vty);
           return NULL;
@@ -1738,7 +1777,8 @@ vty_create (int vty_sock, union sockunion *su)
   /* Say hello to the world. */
   vty_hello (vty);
   if (! no_password_check)
-    vty_out (vty, "%sUser Access Verification%s%s", VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
+    vty_outln (vty, "%sUser Access Verification%s", VTYNL,
+               VTYNL);
 
   /* Setting up terminal. */
   vty_will_echo (vty);
@@ -2155,7 +2195,7 @@ vtysh_read (struct thread *thread)
       /* Clear command line buffer. */
       vty->cp = vty->length = 0;
       vty_clear_buf (vty);
-      vty_out (vty, "%% Command is too long.%s", VTY_NEWLINE);
+      vty_outln (vty, "%% Command is too long.");
     }
   else
     {
@@ -2181,7 +2221,7 @@ vtysh_read (struct thread *thread)
               if (ret == CMD_SUSPEND)
                 break;
 
-              /* warning: watchquagga hardcodes this result write */
+              /* warning: watchfrr hardcodes this result write */
               header[3] = ret;
               buffer_put(vty->obuf, header, 4);
 
@@ -2192,7 +2232,10 @@ vtysh_read (struct thread *thread)
         }
     }
 
-  vty_event (VTYSH_READ, sock, vty);
+  if (vty->status == VTY_CLOSE)
+    vty_close (vty);
+  else
+    vty_event (VTYSH_READ, sock, vty);
 
   return 0;
 }
@@ -2295,7 +2338,7 @@ vty_timeout (struct thread *thread)
 
   /* Clear buffer*/
   buffer_reset (vty->obuf);
-  vty_out (vty, "%sVty connection is timed out.%s", VTY_NEWLINE, VTY_NEWLINE);
+  vty_outln (vty, "%sVty connection is timed out.", VTYNL);
 
   /* Close connection. */
   vty->status = VTY_CLOSE;
@@ -2611,41 +2654,44 @@ static struct thread_master *vty_master;
 static void
 vty_event (enum event event, int sock, struct vty *vty)
 {
-  struct thread *vty_serv_thread;
+  struct thread *vty_serv_thread = NULL;
 
   switch (event)
     {
     case VTY_SERV:
-      vty_serv_thread = thread_add_read (vty_master, vty_accept, vty, sock);
+      vty_serv_thread = thread_add_read(vty_master, vty_accept, vty, sock, NULL);
       vector_set_index (Vvty_serv_thread, sock, vty_serv_thread);
       break;
 #ifdef VTYSH
     case VTYSH_SERV:
-      vty_serv_thread = thread_add_read (vty_master, vtysh_accept, vty, sock);
+      vty_serv_thread = thread_add_read(vty_master, vtysh_accept, vty, sock, NULL);
       vector_set_index (Vvty_serv_thread, sock, vty_serv_thread);
       break;
     case VTYSH_READ:
-      vty->t_read = thread_add_read (vty_master, vtysh_read, vty, sock);
+      vty->t_read = NULL;
+      thread_add_read(vty_master, vtysh_read, vty, sock, &vty->t_read);
       break;
     case VTYSH_WRITE:
-      vty->t_write = thread_add_write (vty_master, vtysh_write, vty, sock);
+      vty->t_write = NULL;
+      thread_add_write(vty_master, vtysh_write, vty, sock, &vty->t_write);
       break;
 #endif /* VTYSH */
     case VTY_READ:
-      vty->t_read = thread_add_read (vty_master, vty_read, vty, sock);
+      vty->t_read = NULL;
+      thread_add_read(vty_master, vty_read, vty, sock, &vty->t_read);
 
       /* Time out treatment. */
       if (vty->v_timeout)
         {
           if (vty->t_timeout)
             thread_cancel (vty->t_timeout);
-          vty->t_timeout =
-            thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
+          vty->t_timeout = NULL;
+          thread_add_timer(vty_master, vty_timeout, vty, vty->v_timeout,
+                           &vty->t_timeout);
         }
       break;
     case VTY_WRITE:
-      if (! vty->t_write)
-        vty->t_write = thread_add_write (vty_master, vty_flush, vty, sock);
+      thread_add_write(vty_master, vty_flush, vty, sock, &vty->t_write);
       break;
     case VTY_TIMEOUT_RESET:
       if (vty->t_timeout)
@@ -2655,8 +2701,9 @@ vty_event (enum event event, int sock, struct vty *vty)
         }
       if (vty->v_timeout)
         {
-          vty->t_timeout =
-            thread_add_timer (vty_master, vty_timeout, vty, vty->v_timeout);
+          vty->t_timeout = NULL;
+          thread_add_timer(vty_master, vty_timeout, vty, vty->v_timeout,
+                           &vty->t_timeout);
         }
       break;
     }
@@ -2674,7 +2721,7 @@ DEFUN_NOSH (config_who,
     if ((v = vector_slot (vtyvec, i)) != NULL)
       vty_out (vty, "%svty[%d] connected from %s.%s",
                v->config ? "*" : " ",
-               i, v->address, VTY_NEWLINE);
+               i, v->address, VTYNL);
   return CMD_SUCCESS;
 }
 
@@ -2772,9 +2819,8 @@ DEFUN (no_vty_access_class,
   const char *accesslist = (argc == 3) ? argv[idx_word]->arg : NULL;
   if (! vty_accesslist_name || (argc == 3 && strcmp(vty_accesslist_name, accesslist)))
     {
-      vty_out (vty, "Access-class is not currently applied to vty%s",
-               VTY_NEWLINE);
-      return CMD_WARNING;
+      vty_outln (vty,"Access-class is not currently applied to vty");
+      return CMD_WARNING_CONFIG_FAILED;
     }
 
   XFREE(MTYPE_VTY, vty_accesslist_name);
@@ -2816,9 +2862,8 @@ DEFUN (no_vty_ipv6_access_class,
   if (! vty_ipv6_accesslist_name ||
       (argc == 4 && strcmp(vty_ipv6_accesslist_name, accesslist)))
     {
-      vty_out (vty, "IPv6 access-class is not currently applied to vty%s",
-               VTY_NEWLINE);
-      return CMD_WARNING;
+      vty_outln (vty,"IPv6 access-class is not currently applied to vty");
+      return CMD_WARNING_CONFIG_FAILED;
     }
 
   XFREE(MTYPE_VTY, vty_ipv6_accesslist_name);
@@ -2918,7 +2963,7 @@ DEFUN_NOSH (show_history,
         }
 
       if (vty->hist[index] != NULL)
-        vty_out (vty, "  %s%s", vty->hist[index], VTY_NEWLINE);
+        vty_out (vty, "  %s%s", vty->hist[index], VTYNL);
 
       index++;
     }
@@ -2941,30 +2986,30 @@ DEFUN (log_commands,
 static int
 vty_config_write (struct vty *vty)
 {
-  vty_out (vty, "line vty%s", VTY_NEWLINE);
+  vty_outln (vty, "line vty");
 
   if (vty_accesslist_name)
-    vty_out (vty, " access-class %s%s",
-             vty_accesslist_name, VTY_NEWLINE);
+    vty_outln (vty, " access-class %s",
+             vty_accesslist_name);
 
   if (vty_ipv6_accesslist_name)
-    vty_out (vty, " ipv6 access-class %s%s",
-             vty_ipv6_accesslist_name, VTY_NEWLINE);
+    vty_outln (vty, " ipv6 access-class %s",
+             vty_ipv6_accesslist_name);
 
   /* exec-timeout */
   if (vty_timeout_val != VTY_TIMEOUT_DEFAULT)
-    vty_out (vty, " exec-timeout %ld %ld%s",
+    vty_outln (vty, " exec-timeout %ld %ld",
              vty_timeout_val / 60,
-             vty_timeout_val % 60, VTY_NEWLINE);
+             vty_timeout_val % 60);
 
   /* login */
   if (no_password_check)
-    vty_out (vty, " no login%s", VTY_NEWLINE);
+    vty_outln (vty, " no login");
 
   if (do_log_commands)
-    vty_out (vty, "log commands%s", VTY_NEWLINE);
+    vty_outln (vty, "log commands");
 
-  vty_out (vty, "!%s", VTY_NEWLINE);
+  vty_outln (vty, "!");
 
   return CMD_SUCCESS;
 }
@@ -3127,29 +3172,3 @@ vty_terminate (void)
       Vvty_serv_thread = NULL;
     }
 }
-
-/* Utility functions to get arguments from commands generated
-   by the xml2cli.pl script. */
-const char *
-vty_get_arg_value (struct vty_arg *args[], const char *arg)
-{
-  while (*args)
-    {
-      if (strcmp ((*args)->name, arg) == 0)
-        return (*args)->value;
-      args++;
-    }
-  return NULL;
-}
-
-struct vty_arg *
-vty_get_arg (struct vty_arg *args[], const char *arg)
-{
-  while (*args)
-    {
-      if (strcmp ((*args)->name, arg) == 0)
-        return *args;
-      args++;
-    }
-  return NULL;
-}