File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / vtysh / vtysh.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:26:12 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    1: /* Virtual terminal interface shell.
    2:  * Copyright (C) 2000 Kunihiro Ishiguro
    3:  *
    4:  * This file is part of GNU Zebra.
    5:  *
    6:  * GNU Zebra is free software; you can redistribute it and/or modify it
    7:  * under the terms of the GNU General Public License as published by the
    8:  * Free Software Foundation; either version 2, or (at your option) any
    9:  * later version.
   10:  *
   11:  * GNU Zebra is distributed in the hope that it will be useful, but
   12:  * WITHOUT ANY WARRANTY; without even the implied warranty of
   13:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14:  * General Public License for more details.
   15:  *
   16:  * You should have received a copy of the GNU General Public License
   17:  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
   18:  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   19:  * 02111-1307, USA.  
   20:  */
   21: 
   22: #include <zebra.h>
   23: 
   24: #include <sys/un.h>
   25: #include <setjmp.h>
   26: #include <sys/wait.h>
   27: #include <sys/resource.h>
   28: #include <sys/stat.h>
   29: 
   30: #include <readline/readline.h>
   31: #include <readline/history.h>
   32: 
   33: #include "command.h"
   34: #include "memory.h"
   35: #include "vtysh/vtysh.h"
   36: #include "log.h"
   37: #include "bgpd/bgp_vty.h"
   38: 
   39: /* Struct VTY. */
   40: struct vty *vty;
   41: 
   42: /* VTY shell pager name. */
   43: char *vtysh_pager_name = NULL;
   44: 
   45: /* VTY shell client structure. */
   46: struct vtysh_client
   47: {
   48:   int fd;
   49:   const char *name;
   50:   int flag;
   51:   const char *path;
   52: } vtysh_client[] =
   53: {
   54:   { .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path = ZEBRA_VTYSH_PATH},
   55:   { .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH},
   56:   { .fd = -1, .name = "ripngd", .flag = VTYSH_RIPNGD, .path = RIPNG_VTYSH_PATH},
   57:   { .fd = -1, .name = "ospfd", .flag = VTYSH_OSPFD, .path = OSPF_VTYSH_PATH},
   58:   { .fd = -1, .name = "ospf6d", .flag = VTYSH_OSPF6D, .path = OSPF6_VTYSH_PATH},
   59:   { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH},
   60:   { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH},
   61: };
   62: 
   63: #define VTYSH_INDEX_MAX (sizeof(vtysh_client)/sizeof(vtysh_client[0]))
   64: 
   65: /* We need direct access to ripd to implement vtysh_exit_ripd_only. */
   66: static struct vtysh_client *ripd_client = NULL;
   67:  
   68: 
   69: /* Using integrated config from Quagga.conf. Default is no. */
   70: int vtysh_writeconfig_integrated = 0;
   71: 
   72: extern char config_default[];
   73: 
   74: static void
   75: vclient_close (struct vtysh_client *vclient)
   76: {
   77:   if (vclient->fd >= 0)
   78:     {
   79:       fprintf(stderr,
   80: 	      "Warning: closing connection to %s because of an I/O error!\n",
   81: 	      vclient->name);
   82:       close (vclient->fd);
   83:       vclient->fd = -1;
   84:     }
   85: }
   86: 
   87: /* Following filled with debug code to trace a problematic condition
   88:  * under load - it SHOULD handle it. */
   89: #define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
   90: static int
   91: vtysh_client_config (struct vtysh_client *vclient, char *line)
   92: {
   93:   int ret;
   94:   char *buf;
   95:   size_t bufsz;
   96:   char *pbuf;
   97:   size_t left;
   98:   char *eoln;
   99:   int nbytes;
  100:   int i;
  101:   int readln;
  102: 
  103:   if (vclient->fd < 0)
  104:     return CMD_SUCCESS;
  105: 
  106:   ret = write (vclient->fd, line, strlen (line) + 1);
  107:   if (ret <= 0)
  108:     {
  109:       vclient_close (vclient);
  110:       return CMD_SUCCESS;
  111:     }
  112: 	
  113:   /* Allow enough room for buffer to read more than a few pages from socket. */
  114:   bufsz = 5 * getpagesize() + 1;
  115:   buf = XMALLOC(MTYPE_TMP, bufsz);
  116:   memset(buf, 0, bufsz);
  117:   pbuf = buf;
  118: 
  119:   while (1)
  120:     {
  121:       if (pbuf >= ((buf + bufsz) -1))
  122: 	{
  123: 	  fprintf (stderr, ERR_WHERE_STRING \
  124: 		   "warning - pbuf beyond buffer end.\n");
  125: 	  return CMD_WARNING;
  126: 	}
  127: 
  128:       readln = (buf + bufsz) - pbuf - 1;
  129:       nbytes = read (vclient->fd, pbuf, readln);
  130: 
  131:       if (nbytes <= 0)
  132: 	{
  133: 
  134: 	  if (errno == EINTR)
  135: 	    continue;
  136: 
  137: 	  fprintf(stderr, ERR_WHERE_STRING "(%u)", errno);
  138: 	  perror("");
  139: 
  140: 	  if (errno == EAGAIN || errno == EIO)
  141: 	    continue;
  142: 
  143: 	  vclient_close (vclient);
  144: 	  XFREE(MTYPE_TMP, buf);
  145: 	  return CMD_SUCCESS;
  146: 	}
  147: 
  148:       pbuf[nbytes] = '\0';
  149: 
  150:       if (nbytes >= 4)
  151: 	{
  152: 	  i = nbytes - 4;
  153: 	  if (pbuf[i] == '\0' && pbuf[i + 1] == '\0' && pbuf[i + 2] == '\0')
  154: 	    {
  155: 	      ret = pbuf[i + 3];
  156: 	      break;
  157: 	    }
  158: 	}
  159:       pbuf += nbytes;
  160: 
  161:       /* See if a line exists in buffer, if so parse and consume it, and
  162:        * reset read position. */
  163:       if ((eoln = strrchr(buf, '\n')) == NULL)
  164: 	continue;
  165: 
  166:       if (eoln >= ((buf + bufsz) - 1))
  167: 	{
  168: 	  fprintf (stderr, ERR_WHERE_STRING \
  169: 		   "warning - eoln beyond buffer end.\n");
  170: 	}
  171:       vtysh_config_parse(buf);
  172: 
  173:       eoln++;
  174:       left = (size_t)(buf + bufsz - eoln);
  175:       memmove(buf, eoln, left);
  176:       buf[bufsz-1] = '\0';
  177:       pbuf = buf + strlen(buf);
  178:     }
  179: 
  180:   /* Parse anything left in the buffer. */
  181: 
  182:   vtysh_config_parse (buf);
  183: 
  184:   XFREE(MTYPE_TMP, buf);
  185:   return ret;
  186: }
  187: 
  188: static int
  189: vtysh_client_execute (struct vtysh_client *vclient, const char *line, FILE *fp)
  190: {
  191:   int ret;
  192:   char buf[1001];
  193:   int nbytes;
  194:   int i; 
  195:   int numnulls = 0;
  196: 
  197:   if (vclient->fd < 0)
  198:     return CMD_SUCCESS;
  199: 
  200:   ret = write (vclient->fd, line, strlen (line) + 1);
  201:   if (ret <= 0)
  202:     {
  203:       vclient_close (vclient);
  204:       return CMD_SUCCESS;
  205:     }
  206: 	
  207:   while (1)
  208:     {
  209:       nbytes = read (vclient->fd, buf, sizeof(buf)-1);
  210: 
  211:       if (nbytes <= 0 && errno != EINTR)
  212: 	{
  213: 	  vclient_close (vclient);
  214: 	  return CMD_SUCCESS;
  215: 	}
  216: 
  217:       if (nbytes > 0)
  218: 	{
  219: 	  if ((numnulls == 3) && (nbytes == 1))
  220: 	    return buf[0];
  221: 
  222: 	  buf[nbytes] = '\0';
  223: 	  fputs (buf, fp);
  224: 	  fflush (fp);
  225: 	  
  226: 	  /* check for trailling \0\0\0<ret code>, 
  227: 	   * even if split across reads 
  228: 	   * (see lib/vty.c::vtysh_read)
  229: 	   */
  230:           if (nbytes >= 4) 
  231:             {
  232:               i = nbytes-4;
  233:               numnulls = 0;
  234:             }
  235:           else
  236:             i = 0;
  237:           
  238:           while (i < nbytes && numnulls < 3)
  239:             {
  240:               if (buf[i++] == '\0')
  241:                 numnulls++;
  242:               else
  243:                 numnulls = 0;
  244:             }
  245: 
  246:           /* got 3 or more trailing NULs? */
  247:           if ((numnulls >= 3) && (i < nbytes))
  248:             return (buf[nbytes-1]);
  249: 	}
  250:     }
  251: }
  252: 
  253: void
  254: vtysh_exit_ripd_only (void)
  255: {
  256:   if (ripd_client)
  257:     vtysh_client_execute (ripd_client, "exit", stdout);
  258: }
  259: 
  260: 
  261: void
  262: vtysh_pager_init (void)
  263: {
  264:   char *pager_defined;
  265: 
  266:   pager_defined = getenv ("VTYSH_PAGER");
  267: 
  268:   if (pager_defined)
  269:     vtysh_pager_name = strdup (pager_defined);
  270:   else
  271:     vtysh_pager_name = strdup ("more");
  272: }
  273: 
  274: /* Command execution over the vty interface. */
  275: static int
  276: vtysh_execute_func (const char *line, int pager)
  277: {
  278:   int ret, cmd_stat;
  279:   u_int i;
  280:   vector vline;
  281:   struct cmd_element *cmd;
  282:   FILE *fp = NULL;
  283:   int closepager = 0;
  284:   int tried = 0;
  285:   int saved_ret, saved_node;
  286: 
  287:   /* Split readline string up into the vector. */
  288:   vline = cmd_make_strvec (line);
  289: 
  290:   if (vline == NULL)
  291:     return CMD_SUCCESS;
  292: 
  293:   saved_ret = ret = cmd_execute_command (vline, vty, &cmd, 1);
  294:   saved_node = vty->node;
  295: 
  296:   /* If command doesn't succeeded in current node, try to walk up in node tree.
  297:    * Changing vty->node is enough to try it just out without actual walkup in
  298:    * the vtysh. */
  299:   while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON && ret != CMD_WARNING
  300: 	 && vty->node > CONFIG_NODE)
  301:     {
  302:       vty->node = node_parent(vty->node);
  303:       ret = cmd_execute_command (vline, vty, &cmd, 1);
  304:       tried++;
  305:     }
  306: 
  307:   vty->node = saved_node;
  308: 
  309:   /* If command succeeded in any other node than current (tried > 0) we have
  310:    * to move into node in the vtysh where it succeeded. */
  311:   if (ret == CMD_SUCCESS || ret == CMD_SUCCESS_DAEMON || ret == CMD_WARNING)
  312:     {
  313:       if ((saved_node == BGP_VPNV4_NODE || saved_node == BGP_IPV4_NODE
  314: 	   || saved_node == BGP_IPV6_NODE || saved_node == BGP_IPV4M_NODE
  315: 	   || saved_node == BGP_IPV6M_NODE)
  316: 	  && (tried == 1))
  317: 	{
  318: 	  vtysh_execute("exit-address-family");
  319: 	}
  320:       else if ((saved_node == KEYCHAIN_KEY_NODE) && (tried == 1))
  321: 	{
  322: 	  vtysh_execute("exit");
  323: 	}
  324:       else if (tried)
  325: 	{
  326: 	  vtysh_execute ("end");
  327: 	  vtysh_execute ("configure terminal");
  328: 	}
  329:     }
  330:   /* If command didn't succeed in any node, continue with return value from
  331:    * first try. */
  332:   else if (tried)
  333:     {
  334:       ret = saved_ret;
  335:     }
  336: 
  337:   cmd_free_strvec (vline);
  338: 
  339:   cmd_stat = ret;
  340:   switch (ret)
  341:     {
  342:     case CMD_WARNING:
  343:       if (vty->type == VTY_FILE)
  344: 	fprintf (stdout,"Warning...\n");
  345:       break;
  346:     case CMD_ERR_AMBIGUOUS:
  347:       fprintf (stdout,"%% Ambiguous command.\n");
  348:       break;
  349:     case CMD_ERR_NO_MATCH:
  350:       fprintf (stdout,"%% Unknown command.\n");
  351:       break;
  352:     case CMD_ERR_INCOMPLETE:
  353:       fprintf (stdout,"%% Command incomplete.\n");
  354:       break;
  355:     case CMD_SUCCESS_DAEMON:
  356:       {
  357: 	/* FIXME: Don't open pager for exit commands. popen() causes problems
  358: 	 * if exited from vtysh at all. This hack shouldn't cause any problem
  359: 	 * but is really ugly. */
  360: 	if (pager && vtysh_pager_name && (strncmp(line, "exit", 4) != 0))
  361: 	  {
  362: 	    fp = popen (vtysh_pager_name, "w");
  363: 	    if (fp == NULL)
  364: 	      {
  365: 		perror ("popen failed for pager");
  366: 		fp = stdout;
  367: 	      }
  368: 	    else
  369: 	      closepager=1;
  370: 	  }
  371: 	else
  372: 	  fp = stdout;
  373: 
  374: 	if (! strcmp(cmd->string,"configure terminal"))
  375: 	  {
  376: 	    for (i = 0; i < VTYSH_INDEX_MAX; i++)
  377: 	      {
  378: 	        cmd_stat = vtysh_client_execute(&vtysh_client[i], line, fp);
  379: 		if (cmd_stat == CMD_WARNING)
  380: 		  break;
  381: 	      }
  382: 
  383: 	    if (cmd_stat)
  384: 	      {
  385: 		line = "end";
  386: 		vline = cmd_make_strvec (line);
  387: 
  388: 		if (vline == NULL)
  389: 		  {
  390: 		    if (pager && vtysh_pager_name && fp && closepager)
  391: 		      {
  392: 			if (pclose (fp) == -1)
  393: 			  {
  394: 			    perror ("pclose failed for pager");
  395: 			  }
  396: 			fp = NULL;
  397: 		      }
  398: 		    return CMD_SUCCESS;
  399: 		  }
  400: 
  401: 		ret = cmd_execute_command (vline, vty, &cmd, 1);
  402: 		cmd_free_strvec (vline);
  403: 		if (ret != CMD_SUCCESS_DAEMON)
  404: 		  break;
  405: 	      }
  406: 	    else
  407: 	      if (cmd->func)
  408: 		{
  409: 		  (*cmd->func) (cmd, vty, 0, NULL);
  410: 		  break;
  411: 		}
  412: 	  }
  413: 
  414: 	cmd_stat = CMD_SUCCESS;
  415: 	for (i = 0; i < VTYSH_INDEX_MAX; i++)
  416: 	  {
  417: 	    if (cmd->daemon & vtysh_client[i].flag)
  418: 	      {
  419: 	        cmd_stat = vtysh_client_execute(&vtysh_client[i], line, fp);
  420: 		if (cmd_stat != CMD_SUCCESS)
  421: 		  break;
  422: 	      }
  423: 	  }
  424: 	if (cmd_stat != CMD_SUCCESS)
  425: 	  break;
  426: 
  427: 	if (cmd->func)
  428: 	  (*cmd->func) (cmd, vty, 0, NULL);
  429:       }
  430:     }
  431:   if (pager && vtysh_pager_name && fp && closepager)
  432:     {
  433:       if (pclose (fp) == -1)
  434: 	{
  435: 	  perror ("pclose failed for pager");
  436: 	}
  437:       fp = NULL;
  438:     }
  439:   return cmd_stat;
  440: }
  441: 
  442: int
  443: vtysh_execute_no_pager (const char *line)
  444: {
  445:   return vtysh_execute_func (line, 0);
  446: }
  447: 
  448: int
  449: vtysh_execute (const char *line)
  450: {
  451:   return vtysh_execute_func (line, 1);
  452: }
  453: 
  454: /* Configration make from file. */
  455: int
  456: vtysh_config_from_file (struct vty *vty, FILE *fp)
  457: {
  458:   int ret;
  459:   vector vline;
  460:   struct cmd_element *cmd;
  461: 
  462:   while (fgets (vty->buf, VTY_BUFSIZ, fp))
  463:     {
  464:       if (vty->buf[0] == '!' || vty->buf[1] == '#')
  465: 	continue;
  466: 
  467:       vline = cmd_make_strvec (vty->buf);
  468: 
  469:       /* In case of comment line. */
  470:       if (vline == NULL)
  471: 	continue;
  472: 
  473:       /* Execute configuration command : this is strict match. */
  474:       ret = cmd_execute_command_strict (vline, vty, &cmd);
  475: 
  476:       /* Try again with setting node to CONFIG_NODE. */
  477:       if (ret != CMD_SUCCESS 
  478: 	  && ret != CMD_SUCCESS_DAEMON
  479: 	  && ret != CMD_WARNING)
  480: 	{
  481: 	  if (vty->node == KEYCHAIN_KEY_NODE)
  482: 	    {
  483: 	      vty->node = KEYCHAIN_NODE;
  484: 	      vtysh_exit_ripd_only ();
  485: 	      ret = cmd_execute_command_strict (vline, vty, &cmd);
  486: 
  487: 	      if (ret != CMD_SUCCESS 
  488: 		  && ret != CMD_SUCCESS_DAEMON 
  489: 		  && ret != CMD_WARNING)
  490: 		{
  491: 		  vtysh_exit_ripd_only ();
  492: 		  vty->node = CONFIG_NODE;
  493: 		  ret = cmd_execute_command_strict (vline, vty, &cmd);
  494: 		}
  495: 	    }
  496: 	  else
  497: 	    {
  498: 	      vtysh_execute ("end");
  499: 	      vtysh_execute ("configure terminal");
  500: 	      vty->node = CONFIG_NODE;
  501: 	      ret = cmd_execute_command_strict (vline, vty, &cmd);
  502: 	    }
  503: 	}	  
  504: 
  505:       cmd_free_strvec (vline);
  506: 
  507:       switch (ret)
  508: 	{
  509: 	case CMD_WARNING:
  510: 	  if (vty->type == VTY_FILE)
  511: 	    fprintf (stdout,"Warning...\n");
  512: 	  break;
  513: 	case CMD_ERR_AMBIGUOUS:
  514: 	  fprintf (stdout,"%% Ambiguous command.\n");
  515: 	  break;
  516: 	case CMD_ERR_NO_MATCH:
  517: 	  fprintf (stdout,"%% Unknown command: %s", vty->buf);
  518: 	  break;
  519: 	case CMD_ERR_INCOMPLETE:
  520: 	  fprintf (stdout,"%% Command incomplete.\n");
  521: 	  break;
  522: 	case CMD_SUCCESS_DAEMON:
  523: 	  {
  524: 	    u_int i;
  525: 	    int cmd_stat = CMD_SUCCESS;
  526: 
  527: 	    for (i = 0; i < VTYSH_INDEX_MAX; i++)
  528: 	      {
  529: 	        if (cmd->daemon & vtysh_client[i].flag)
  530: 		  {
  531: 		    cmd_stat = vtysh_client_execute (&vtysh_client[i],
  532: 						     vty->buf, stdout);
  533: 		    if (cmd_stat != CMD_SUCCESS)
  534: 		      break;
  535: 		  }
  536: 	      }
  537: 	    if (cmd_stat != CMD_SUCCESS)
  538: 	      break;
  539: 
  540: 	    if (cmd->func)
  541: 	      (*cmd->func) (cmd, vty, 0, NULL);
  542: 	  }
  543: 	}
  544:     }
  545:   return CMD_SUCCESS;
  546: }
  547: 
  548: /* We don't care about the point of the cursor when '?' is typed. */
  549: int
  550: vtysh_rl_describe (void)
  551: {
  552:   int ret;
  553:   unsigned int i;
  554:   vector vline;
  555:   vector describe;
  556:   int width;
  557:   struct desc *desc;
  558: 
  559:   vline = cmd_make_strvec (rl_line_buffer);
  560: 
  561:   /* In case of '> ?'. */
  562:   if (vline == NULL)
  563:     {
  564:       vline = vector_init (1);
  565:       vector_set (vline, '\0');
  566:     }
  567:   else 
  568:     if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
  569:       vector_set (vline, '\0');
  570: 
  571:   describe = cmd_describe_command (vline, vty, &ret);
  572: 
  573:   fprintf (stdout,"\n");
  574: 
  575:   /* Ambiguous and no match error. */
  576:   switch (ret)
  577:     {
  578:     case CMD_ERR_AMBIGUOUS:
  579:       cmd_free_strvec (vline);
  580:       fprintf (stdout,"%% Ambiguous command.\n");
  581:       rl_on_new_line ();
  582:       return 0;
  583:       break;
  584:     case CMD_ERR_NO_MATCH:
  585:       cmd_free_strvec (vline);
  586:       fprintf (stdout,"%% There is no matched command.\n");
  587:       rl_on_new_line ();
  588:       return 0;
  589:       break;
  590:     }  
  591: 
  592:   /* Get width of command string. */
  593:   width = 0;
  594:   for (i = 0; i < vector_active (describe); i++)
  595:     if ((desc = vector_slot (describe, i)) != NULL)
  596:       {
  597: 	int len;
  598: 
  599: 	if (desc->cmd[0] == '\0')
  600: 	  continue;
  601: 
  602: 	len = strlen (desc->cmd);
  603: 	if (desc->cmd[0] == '.')
  604: 	  len--;
  605: 
  606: 	if (width < len)
  607: 	  width = len;
  608:       }
  609: 
  610:   for (i = 0; i < vector_active (describe); i++)
  611:     if ((desc = vector_slot (describe, i)) != NULL)
  612:       {
  613: 	if (desc->cmd[0] == '\0')
  614: 	  continue;
  615: 
  616: 	if (! desc->str)
  617: 	  fprintf (stdout,"  %-s\n",
  618: 		   desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd);
  619: 	else
  620: 	  fprintf (stdout,"  %-*s  %s\n",
  621: 		   width,
  622: 		   desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,
  623: 		   desc->str);
  624:       }
  625: 
  626:   cmd_free_strvec (vline);
  627:   vector_free (describe);
  628: 
  629:   rl_on_new_line();
  630: 
  631:   return 0;
  632: }
  633: 
  634: /* Result of cmd_complete_command() call will be stored here
  635:  * and used in new_completion() in order to put the space in
  636:  * correct places only. */
  637: int complete_status;
  638: 
  639: static char *
  640: command_generator (const char *text, int state)
  641: {
  642:   vector vline;
  643:   static char **matched = NULL;
  644:   static int index = 0;
  645: 
  646:   /* First call. */
  647:   if (! state)
  648:     {
  649:       index = 0;
  650: 
  651:       if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
  652: 	return NULL;
  653: 
  654:       vline = cmd_make_strvec (rl_line_buffer);
  655:       if (vline == NULL)
  656: 	return NULL;
  657: 
  658:       if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
  659: 	vector_set (vline, '\0');
  660: 
  661:       matched = cmd_complete_command (vline, vty, &complete_status);
  662:     }
  663: 
  664:   if (matched && matched[index])
  665:     return matched[index++];
  666: 
  667:   return NULL;
  668: }
  669: 
  670: static char **
  671: new_completion (char *text, int start, int end)
  672: {
  673:   char **matches;
  674: 
  675:   matches = rl_completion_matches (text, command_generator);
  676: 
  677:   if (matches)
  678:     {
  679:       rl_point = rl_end;
  680:       if (complete_status == CMD_COMPLETE_FULL_MATCH)
  681: 	rl_pending_input = ' ';
  682:     }
  683: 
  684:   return matches;
  685: }
  686: 
  687: #if 0
  688: /* This function is not actually being used. */
  689: static char **
  690: vtysh_completion (char *text, int start, int end)
  691: {
  692:   int ret;
  693:   vector vline;
  694:   char **matched = NULL;
  695: 
  696:   if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
  697:     return NULL;
  698: 
  699:   vline = cmd_make_strvec (rl_line_buffer);
  700:   if (vline == NULL)
  701:     return NULL;
  702: 
  703:   /* In case of 'help \t'. */
  704:   if (rl_end && isspace ((int) rl_line_buffer[rl_end - 1]))
  705:     vector_set (vline, '\0');
  706: 
  707:   matched = cmd_complete_command (vline, vty, &ret);
  708: 
  709:   cmd_free_strvec (vline);
  710: 
  711:   return (char **) matched;
  712: }
  713: #endif
  714: 
  715: /* Vty node structures. */
  716: static struct cmd_node bgp_node =
  717: {
  718:   BGP_NODE,
  719:   "%s(config-router)# ",
  720: };
  721: 
  722: static struct cmd_node rip_node =
  723: {
  724:   RIP_NODE,
  725:   "%s(config-router)# ",
  726: };
  727: 
  728: static struct cmd_node isis_node =
  729: {
  730:   ISIS_NODE,
  731:   "%s(config-router)# ",
  732: };
  733: 
  734: static struct cmd_node interface_node =
  735: {
  736:   INTERFACE_NODE,
  737:   "%s(config-if)# ",
  738: };
  739: 
  740: static struct cmd_node rmap_node =
  741: {
  742:   RMAP_NODE,
  743:   "%s(config-route-map)# "
  744: };
  745: 
  746: static struct cmd_node zebra_node =
  747: {
  748:   ZEBRA_NODE,
  749:   "%s(config-router)# "
  750: };
  751: 
  752: static struct cmd_node bgp_vpnv4_node =
  753: {
  754:   BGP_VPNV4_NODE,
  755:   "%s(config-router-af)# "
  756: };
  757: 
  758: static struct cmd_node bgp_ipv4_node =
  759: {
  760:   BGP_IPV4_NODE,
  761:   "%s(config-router-af)# "
  762: };
  763: 
  764: static struct cmd_node bgp_ipv4m_node =
  765: {
  766:   BGP_IPV4M_NODE,
  767:   "%s(config-router-af)# "
  768: };
  769: 
  770: static struct cmd_node bgp_ipv6_node =
  771: {
  772:   BGP_IPV6_NODE,
  773:   "%s(config-router-af)# "
  774: };
  775: 
  776: static struct cmd_node bgp_ipv6m_node =
  777: {
  778:   BGP_IPV6M_NODE,
  779:   "%s(config-router-af)# "
  780: };
  781: 
  782: static struct cmd_node ospf_node =
  783: {
  784:   OSPF_NODE,
  785:   "%s(config-router)# "
  786: };
  787: 
  788: static struct cmd_node ripng_node =
  789: {
  790:   RIPNG_NODE,
  791:   "%s(config-router)# "
  792: };
  793: 
  794: static struct cmd_node ospf6_node =
  795: {
  796:   OSPF6_NODE,
  797:   "%s(config-ospf6)# "
  798: };
  799: 
  800: static struct cmd_node keychain_node =
  801: {
  802:   KEYCHAIN_NODE,
  803:   "%s(config-keychain)# "
  804: };
  805: 
  806: static struct cmd_node keychain_key_node =
  807: {
  808:   KEYCHAIN_KEY_NODE,
  809:   "%s(config-keychain-key)# "
  810: };
  811: 
  812: /* Defined in lib/vty.c */
  813: extern struct cmd_node vty_node;
  814: 
  815: /* When '^Z' is received from vty, move down to the enable mode. */
  816: int
  817: vtysh_end (void)
  818: {
  819:   switch (vty->node)
  820:     {
  821:     case VIEW_NODE:
  822:     case ENABLE_NODE:
  823:       /* Nothing to do. */
  824:       break;
  825:     default:
  826:       vty->node = ENABLE_NODE;
  827:       break;
  828:     }
  829:   return CMD_SUCCESS;
  830: }
  831: 
  832: DEFUNSH (VTYSH_ALL,
  833: 	 vtysh_end_all,
  834: 	 vtysh_end_all_cmd,
  835: 	 "end",
  836: 	 "End current mode and change to enable mode\n")
  837: {
  838:   return vtysh_end ();
  839: }
  840: 
  841: DEFUNSH (VTYSH_BGPD,
  842: 	 router_bgp,
  843: 	 router_bgp_cmd,
  844: 	 "router bgp " CMD_AS_RANGE,
  845: 	 ROUTER_STR
  846: 	 BGP_STR
  847: 	 AS_STR)
  848: {
  849:   vty->node = BGP_NODE;
  850:   return CMD_SUCCESS;
  851: }
  852: 
  853: ALIAS_SH (VTYSH_BGPD,
  854: 	  router_bgp,
  855: 	  router_bgp_view_cmd,
  856: 	  "router bgp " CMD_AS_RANGE " view WORD",
  857: 	  ROUTER_STR
  858: 	  BGP_STR
  859: 	  AS_STR
  860: 	  "BGP view\n"
  861: 	  "view name\n")
  862: 
  863: DEFUNSH (VTYSH_BGPD,
  864: 	 address_family_vpnv4,
  865: 	 address_family_vpnv4_cmd,
  866: 	 "address-family vpnv4",
  867: 	 "Enter Address Family command mode\n"
  868: 	 "Address family\n")
  869: {
  870:   vty->node = BGP_VPNV4_NODE;
  871:   return CMD_SUCCESS;
  872: }
  873: 
  874: DEFUNSH (VTYSH_BGPD,
  875: 	 address_family_vpnv4_unicast,
  876: 	 address_family_vpnv4_unicast_cmd,
  877: 	 "address-family vpnv4 unicast",
  878: 	 "Enter Address Family command mode\n"
  879: 	 "Address family\n"
  880: 	 "Address Family Modifier\n")
  881: {
  882:   vty->node = BGP_VPNV4_NODE;
  883:   return CMD_SUCCESS;
  884: }
  885: 
  886: DEFUNSH (VTYSH_BGPD,
  887: 	 address_family_ipv4_unicast,
  888: 	 address_family_ipv4_unicast_cmd,
  889: 	 "address-family ipv4 unicast",
  890: 	 "Enter Address Family command mode\n"
  891: 	 "Address family\n"
  892: 	 "Address Family Modifier\n")
  893: {
  894:   vty->node = BGP_IPV4_NODE;
  895:   return CMD_SUCCESS;
  896: }
  897: 
  898: DEFUNSH (VTYSH_BGPD,
  899: 	 address_family_ipv4_multicast,
  900: 	 address_family_ipv4_multicast_cmd,
  901: 	 "address-family ipv4 multicast",
  902: 	 "Enter Address Family command mode\n"
  903: 	 "Address family\n"
  904: 	 "Address Family Modifier\n")
  905: {
  906:   vty->node = BGP_IPV4M_NODE;
  907:   return CMD_SUCCESS;
  908: }
  909: 
  910: DEFUNSH (VTYSH_BGPD,
  911: 	 address_family_ipv6,
  912: 	 address_family_ipv6_cmd,
  913: 	 "address-family ipv6",
  914: 	 "Enter Address Family command mode\n"
  915: 	 "Address family\n")
  916: {
  917:   vty->node = BGP_IPV6_NODE;
  918:   return CMD_SUCCESS;
  919: }
  920: 
  921: DEFUNSH (VTYSH_BGPD,
  922: 	 address_family_ipv6_unicast,
  923: 	 address_family_ipv6_unicast_cmd,
  924: 	 "address-family ipv6 unicast",
  925: 	 "Enter Address Family command mode\n"
  926: 	 "Address family\n"
  927: 	 "Address Family Modifier\n")
  928: {
  929:   vty->node = BGP_IPV6_NODE;
  930:   return CMD_SUCCESS;
  931: }
  932: 
  933: DEFUNSH (VTYSH_BGPD,
  934: 	 address_family_ipv6_multicast,
  935: 	 address_family_ipv6_multicast_cmd,
  936: 	 "address-family ipv6 multicast",
  937: 	 "Enter Address Family command mode\n"
  938: 	 "Address family\n"
  939: 	 "Address Family Modifier\n")
  940: {
  941:   vty->node = BGP_IPV6M_NODE;
  942:   return CMD_SUCCESS;
  943: }
  944: 
  945: DEFUNSH (VTYSH_RIPD,
  946: 	 key_chain,
  947: 	 key_chain_cmd,
  948: 	 "key chain WORD",
  949: 	 "Authentication key management\n"
  950: 	 "Key-chain management\n"
  951: 	 "Key-chain name\n")
  952: {
  953:   vty->node = KEYCHAIN_NODE;
  954:   return CMD_SUCCESS;
  955: }	 
  956: 
  957: DEFUNSH (VTYSH_RIPD,
  958: 	 key,
  959: 	 key_cmd,
  960: 	 "key <0-2147483647>",
  961: 	 "Configure a key\n"
  962: 	 "Key identifier number\n")
  963: {
  964:   vty->node = KEYCHAIN_KEY_NODE;
  965:   return CMD_SUCCESS;
  966: }
  967: 
  968: DEFUNSH (VTYSH_RIPD,
  969: 	 router_rip,
  970: 	 router_rip_cmd,
  971: 	 "router rip",
  972: 	 ROUTER_STR
  973: 	 "RIP")
  974: {
  975:   vty->node = RIP_NODE;
  976:   return CMD_SUCCESS;
  977: }
  978: 
  979: DEFUNSH (VTYSH_RIPNGD,
  980: 	 router_ripng,
  981: 	 router_ripng_cmd,
  982: 	 "router ripng",
  983: 	 ROUTER_STR
  984: 	 "RIPng")
  985: {
  986:   vty->node = RIPNG_NODE;
  987:   return CMD_SUCCESS;
  988: }
  989: 
  990: DEFUNSH (VTYSH_OSPFD,
  991: 	 router_ospf,
  992: 	 router_ospf_cmd,
  993: 	 "router ospf",
  994: 	 "Enable a routing process\n"
  995: 	 "Start OSPF configuration\n")
  996: {
  997:   vty->node = OSPF_NODE;
  998:   return CMD_SUCCESS;
  999: }
 1000: 
 1001: DEFUNSH (VTYSH_OSPF6D,
 1002: 	 router_ospf6,
 1003: 	 router_ospf6_cmd,
 1004: 	 "router ospf6",
 1005: 	 OSPF6_ROUTER_STR
 1006: 	 OSPF6_STR)
 1007: {
 1008:   vty->node = OSPF6_NODE;
 1009:   return CMD_SUCCESS;
 1010: }
 1011: 
 1012: DEFUNSH (VTYSH_ISISD,
 1013: 	 router_isis,
 1014: 	 router_isis_cmd,
 1015: 	 "router isis WORD",
 1016: 	 ROUTER_STR
 1017: 	 "ISO IS-IS\n"
 1018: 	 "ISO Routing area tag")
 1019: {
 1020:   vty->node = ISIS_NODE;
 1021:   return CMD_SUCCESS;
 1022: }
 1023: 
 1024: DEFUNSH (VTYSH_RMAP,
 1025: 	 route_map,
 1026: 	 route_map_cmd,
 1027: 	 "route-map WORD (deny|permit) <1-65535>",
 1028: 	 "Create route-map or enter route-map command mode\n"
 1029: 	 "Route map tag\n"
 1030: 	 "Route map denies set operations\n"
 1031: 	 "Route map permits set operations\n"
 1032: 	 "Sequence to insert to/delete from existing route-map entry\n")
 1033: {
 1034:   vty->node = RMAP_NODE;
 1035:   return CMD_SUCCESS;
 1036: }
 1037: 
 1038: DEFUNSH (VTYSH_ALL,
 1039: 	 vtysh_line_vty,
 1040: 	 vtysh_line_vty_cmd,
 1041: 	 "line vty",
 1042: 	 "Configure a terminal line\n"
 1043: 	 "Virtual terminal\n")
 1044: {
 1045:   vty->node = VTY_NODE;
 1046:   return CMD_SUCCESS;
 1047: }
 1048: 
 1049: DEFUNSH (VTYSH_ALL,
 1050: 	 vtysh_enable, 
 1051: 	 vtysh_enable_cmd,
 1052: 	 "enable",
 1053: 	 "Turn on privileged mode command\n")
 1054: {
 1055:   vty->node = ENABLE_NODE;
 1056:   return CMD_SUCCESS;
 1057: }
 1058: 
 1059: DEFUNSH (VTYSH_ALL,
 1060: 	 vtysh_disable, 
 1061: 	 vtysh_disable_cmd,
 1062: 	 "disable",
 1063: 	 "Turn off privileged mode command\n")
 1064: {
 1065:   if (vty->node == ENABLE_NODE)
 1066:     vty->node = VIEW_NODE;
 1067:   return CMD_SUCCESS;
 1068: }
 1069: 
 1070: DEFUNSH (VTYSH_ALL,
 1071: 	 vtysh_config_terminal,
 1072: 	 vtysh_config_terminal_cmd,
 1073: 	 "configure terminal",
 1074: 	 "Configuration from vty interface\n"
 1075: 	 "Configuration terminal\n")
 1076: {
 1077:   vty->node = CONFIG_NODE;
 1078:   return CMD_SUCCESS;
 1079: }
 1080: 
 1081: static int
 1082: vtysh_exit (struct vty *vty)
 1083: {
 1084:   switch (vty->node)
 1085:     {
 1086:     case VIEW_NODE:
 1087:     case ENABLE_NODE:
 1088:       exit (0);
 1089:       break;
 1090:     case CONFIG_NODE:
 1091:       vty->node = ENABLE_NODE;
 1092:       break;
 1093:     case INTERFACE_NODE:
 1094:     case ZEBRA_NODE:
 1095:     case BGP_NODE:
 1096:     case RIP_NODE:
 1097:     case RIPNG_NODE:
 1098:     case OSPF_NODE:
 1099:     case OSPF6_NODE:
 1100:     case ISIS_NODE:
 1101:     case MASC_NODE:
 1102:     case RMAP_NODE:
 1103:     case VTY_NODE:
 1104:     case KEYCHAIN_NODE:
 1105:       vtysh_execute("end");
 1106:       vtysh_execute("configure terminal");
 1107:       vty->node = CONFIG_NODE;
 1108:       break;
 1109:     case BGP_VPNV4_NODE:
 1110:     case BGP_IPV4_NODE:
 1111:     case BGP_IPV4M_NODE:
 1112:     case BGP_IPV6_NODE:
 1113:     case BGP_IPV6M_NODE:
 1114:       vty->node = BGP_NODE;
 1115:       break;
 1116:     case KEYCHAIN_KEY_NODE:
 1117:       vty->node = KEYCHAIN_NODE;
 1118:       break;
 1119:     default:
 1120:       break;
 1121:     }
 1122:   return CMD_SUCCESS;
 1123: }
 1124: 
 1125: DEFUNSH (VTYSH_ALL,
 1126: 	 vtysh_exit_all,
 1127: 	 vtysh_exit_all_cmd,
 1128: 	 "exit",
 1129: 	 "Exit current mode and down to previous mode\n")
 1130: {
 1131:   return vtysh_exit (vty);
 1132: }
 1133: 
 1134: ALIAS (vtysh_exit_all,
 1135:        vtysh_quit_all_cmd,
 1136:        "quit",
 1137:        "Exit current mode and down to previous mode\n")
 1138: 
 1139: DEFUNSH (VTYSH_BGPD,
 1140: 	 exit_address_family,
 1141: 	 exit_address_family_cmd,
 1142: 	 "exit-address-family",
 1143: 	 "Exit from Address Family configuration mode\n")
 1144: {
 1145:   if (vty->node == BGP_IPV4_NODE
 1146:       || vty->node == BGP_IPV4M_NODE
 1147:       || vty->node == BGP_VPNV4_NODE
 1148:       || vty->node == BGP_IPV6_NODE
 1149:       || vty->node == BGP_IPV6M_NODE)
 1150:     vty->node = BGP_NODE;
 1151:   return CMD_SUCCESS;
 1152: }
 1153: 
 1154: DEFUNSH (VTYSH_ZEBRA,
 1155: 	 vtysh_exit_zebra,
 1156: 	 vtysh_exit_zebra_cmd,
 1157: 	 "exit",
 1158: 	 "Exit current mode and down to previous mode\n")
 1159: {
 1160:   return vtysh_exit (vty);
 1161: }
 1162: 
 1163: ALIAS (vtysh_exit_zebra,
 1164:        vtysh_quit_zebra_cmd,
 1165:        "quit",
 1166:        "Exit current mode and down to previous mode\n")
 1167: 
 1168: DEFUNSH (VTYSH_RIPD,
 1169: 	 vtysh_exit_ripd,
 1170: 	 vtysh_exit_ripd_cmd,
 1171: 	 "exit",
 1172: 	 "Exit current mode and down to previous mode\n")
 1173: {
 1174:   return vtysh_exit (vty);
 1175: }
 1176: 
 1177: ALIAS (vtysh_exit_ripd,
 1178:        vtysh_quit_ripd_cmd,
 1179:        "quit",
 1180:        "Exit current mode and down to previous mode\n")
 1181: 
 1182: DEFUNSH (VTYSH_RIPNGD,
 1183: 	 vtysh_exit_ripngd,
 1184: 	 vtysh_exit_ripngd_cmd,
 1185: 	 "exit",
 1186: 	 "Exit current mode and down to previous mode\n")
 1187: {
 1188:   return vtysh_exit (vty);
 1189: }
 1190: 
 1191: ALIAS (vtysh_exit_ripngd,
 1192:        vtysh_quit_ripngd_cmd,
 1193:        "quit",
 1194:        "Exit current mode and down to previous mode\n")
 1195: 
 1196: DEFUNSH (VTYSH_RMAP,
 1197: 	 vtysh_exit_rmap,
 1198: 	 vtysh_exit_rmap_cmd,
 1199: 	 "exit",
 1200: 	 "Exit current mode and down to previous mode\n")
 1201: {
 1202:   return vtysh_exit (vty);
 1203: }
 1204: 
 1205: ALIAS (vtysh_exit_rmap,
 1206:        vtysh_quit_rmap_cmd,
 1207:        "quit",
 1208:        "Exit current mode and down to previous mode\n")
 1209: 
 1210: DEFUNSH (VTYSH_BGPD,
 1211: 	 vtysh_exit_bgpd,
 1212: 	 vtysh_exit_bgpd_cmd,
 1213: 	 "exit",
 1214: 	 "Exit current mode and down to previous mode\n")
 1215: {
 1216:   return vtysh_exit (vty);
 1217: }
 1218: 
 1219: ALIAS (vtysh_exit_bgpd,
 1220:        vtysh_quit_bgpd_cmd,
 1221:        "quit",
 1222:        "Exit current mode and down to previous mode\n")
 1223: 
 1224: DEFUNSH (VTYSH_OSPFD,
 1225: 	 vtysh_exit_ospfd,
 1226: 	 vtysh_exit_ospfd_cmd,
 1227: 	 "exit",
 1228: 	 "Exit current mode and down to previous mode\n")
 1229: {
 1230:   return vtysh_exit (vty);
 1231: }
 1232: 
 1233: ALIAS (vtysh_exit_ospfd,
 1234:        vtysh_quit_ospfd_cmd,
 1235:        "quit",
 1236:        "Exit current mode and down to previous mode\n")
 1237: 
 1238: DEFUNSH (VTYSH_OSPF6D,
 1239: 	 vtysh_exit_ospf6d,
 1240: 	 vtysh_exit_ospf6d_cmd,
 1241: 	 "exit",
 1242: 	 "Exit current mode and down to previous mode\n")
 1243: {
 1244:   return vtysh_exit (vty);
 1245: }
 1246: 
 1247: ALIAS (vtysh_exit_ospf6d,
 1248:        vtysh_quit_ospf6d_cmd,
 1249:        "quit",
 1250:        "Exit current mode and down to previous mode\n")
 1251: 
 1252: DEFUNSH (VTYSH_ISISD,
 1253: 	 vtysh_exit_isisd,
 1254: 	 vtysh_exit_isisd_cmd,
 1255: 	 "exit",
 1256: 	 "Exit current mode and down to previous mode\n")
 1257: {
 1258:   return vtysh_exit (vty);
 1259: }
 1260: 
 1261: ALIAS (vtysh_exit_isisd,
 1262:        vtysh_quit_isisd_cmd,
 1263:        "quit",
 1264:        "Exit current mode and down to previous mode\n")
 1265: 
 1266: DEFUNSH (VTYSH_ALL,
 1267:          vtysh_exit_line_vty,
 1268:          vtysh_exit_line_vty_cmd,
 1269:          "exit",
 1270:          "Exit current mode and down to previous mode\n")
 1271: {
 1272:   return vtysh_exit (vty);
 1273: }
 1274: 
 1275: ALIAS (vtysh_exit_line_vty,
 1276:        vtysh_quit_line_vty_cmd,
 1277:        "quit",
 1278:        "Exit current mode and down to previous mode\n")
 1279: 
 1280: DEFUNSH (VTYSH_INTERFACE,
 1281: 	 vtysh_interface,
 1282: 	 vtysh_interface_cmd,
 1283: 	 "interface IFNAME",
 1284: 	 "Select an interface to configure\n"
 1285: 	 "Interface's name\n")
 1286: {
 1287:   vty->node = INTERFACE_NODE;
 1288:   return CMD_SUCCESS;
 1289: }
 1290: 
 1291: /* TODO Implement "no interface command in isisd. */
 1292: DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D,
 1293:        vtysh_no_interface_cmd,
 1294:        "no interface IFNAME",
 1295:        NO_STR
 1296:        "Delete a pseudo interface's configuration\n"
 1297:        "Interface's name\n")
 1298: 
 1299: /* TODO Implement interface description commands in ripngd, ospf6d
 1300:  * and isisd. */
 1301: DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
 1302:        interface_desc_cmd,
 1303:        "description .LINE",
 1304:        "Interface specific description\n"
 1305:        "Characters describing this interface\n")
 1306:        
 1307: DEFSH (VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_OSPFD,
 1308:        no_interface_desc_cmd,
 1309:        "no description",
 1310:        NO_STR
 1311:        "Interface specific description\n")
 1312: 
 1313: DEFUNSH (VTYSH_INTERFACE,
 1314: 	 vtysh_exit_interface,
 1315: 	 vtysh_exit_interface_cmd,
 1316: 	 "exit",
 1317: 	 "Exit current mode and down to previous mode\n")
 1318: {
 1319:   return vtysh_exit (vty);
 1320: }
 1321: 
 1322: ALIAS (vtysh_exit_interface,
 1323:        vtysh_quit_interface_cmd,
 1324:        "quit",
 1325:        "Exit current mode and down to previous mode\n")
 1326: 
 1327: /* Memory */
 1328: DEFUN (vtysh_show_memory,
 1329:        vtysh_show_memory_cmd,
 1330:        "show memory",
 1331:        SHOW_STR
 1332:        "Memory statistics\n")
 1333: {
 1334:   unsigned int i;
 1335:   int ret = CMD_SUCCESS;
 1336:   char line[] = "show memory\n";
 1337:   
 1338:   for (i = 0; i < VTYSH_INDEX_MAX; i++)
 1339:     if ( vtysh_client[i].fd >= 0 )
 1340:       {
 1341:         fprintf (stdout, "Memory statistics for %s:\n", 
 1342:                  vtysh_client[i].name);
 1343:         ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
 1344:         fprintf (stdout,"\n");
 1345:       }
 1346:   
 1347:   return ret;
 1348: }
 1349: 
 1350: /* Logging commands. */
 1351: DEFUN (vtysh_show_logging,
 1352:        vtysh_show_logging_cmd,
 1353:        "show logging",
 1354:        SHOW_STR
 1355:        "Show current logging configuration\n")
 1356: {
 1357:   unsigned int i;
 1358:   int ret = CMD_SUCCESS;
 1359:   char line[] = "show logging\n";
 1360:   
 1361:   for (i = 0; i < VTYSH_INDEX_MAX; i++)
 1362:     if ( vtysh_client[i].fd >= 0 )
 1363:       {
 1364:         fprintf (stdout,"Logging configuration for %s:\n", 
 1365:                  vtysh_client[i].name);
 1366:         ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
 1367:         fprintf (stdout,"\n");
 1368:       }
 1369:   
 1370:   return ret;
 1371: }
 1372: 
 1373: DEFUNSH (VTYSH_ALL,
 1374: 	 vtysh_log_stdout,
 1375: 	 vtysh_log_stdout_cmd,
 1376: 	 "log stdout",
 1377: 	 "Logging control\n"
 1378: 	 "Set stdout logging level\n")
 1379: {
 1380:   return CMD_SUCCESS;
 1381: }
 1382: 
 1383: DEFUNSH (VTYSH_ALL,
 1384: 	 vtysh_log_stdout_level,
 1385: 	 vtysh_log_stdout_level_cmd,
 1386: 	 "log stdout "LOG_LEVELS,
 1387: 	 "Logging control\n"
 1388: 	 "Set stdout logging level\n"
 1389: 	 LOG_LEVEL_DESC)
 1390: {
 1391:   return CMD_SUCCESS;
 1392: }
 1393: 
 1394: DEFUNSH (VTYSH_ALL,
 1395: 	 no_vtysh_log_stdout,
 1396: 	 no_vtysh_log_stdout_cmd,
 1397: 	 "no log stdout [LEVEL]",
 1398: 	 NO_STR
 1399: 	 "Logging control\n"
 1400: 	 "Cancel logging to stdout\n"
 1401: 	 "Logging level\n")
 1402: {
 1403:   return CMD_SUCCESS;
 1404: }
 1405: 
 1406: DEFUNSH (VTYSH_ALL,
 1407: 	 vtysh_log_file,
 1408: 	 vtysh_log_file_cmd,
 1409: 	 "log file FILENAME",
 1410: 	 "Logging control\n"
 1411: 	 "Logging to file\n"
 1412: 	 "Logging filename\n")
 1413: {
 1414:   return CMD_SUCCESS;
 1415: }
 1416: 
 1417: DEFUNSH (VTYSH_ALL,
 1418: 	 vtysh_log_file_level,
 1419: 	 vtysh_log_file_level_cmd,
 1420: 	 "log file FILENAME "LOG_LEVELS,
 1421: 	 "Logging control\n"
 1422: 	 "Logging to file\n"
 1423: 	 "Logging filename\n"
 1424: 	 LOG_LEVEL_DESC)
 1425: {
 1426:   return CMD_SUCCESS;
 1427: }
 1428: 
 1429: DEFUNSH (VTYSH_ALL,
 1430: 	 no_vtysh_log_file,
 1431: 	 no_vtysh_log_file_cmd,
 1432: 	 "no log file [FILENAME]",
 1433: 	 NO_STR
 1434: 	 "Logging control\n"
 1435: 	 "Cancel logging to file\n"
 1436: 	 "Logging file name\n")
 1437: {
 1438:   return CMD_SUCCESS;
 1439: }
 1440: 
 1441: ALIAS_SH (VTYSH_ALL,
 1442: 	  no_vtysh_log_file,
 1443: 	  no_vtysh_log_file_level_cmd,
 1444: 	  "no log file FILENAME LEVEL",
 1445: 	  NO_STR
 1446: 	  "Logging control\n"
 1447: 	  "Cancel logging to file\n"
 1448: 	  "Logging file name\n"
 1449: 	  "Logging level\n")
 1450: 
 1451: DEFUNSH (VTYSH_ALL,
 1452: 	 vtysh_log_monitor,
 1453: 	 vtysh_log_monitor_cmd,
 1454: 	 "log monitor",
 1455: 	 "Logging control\n"
 1456: 	 "Set terminal line (monitor) logging level\n")
 1457: {
 1458:   return CMD_SUCCESS;
 1459: }
 1460: 
 1461: DEFUNSH (VTYSH_ALL,
 1462: 	 vtysh_log_monitor_level,
 1463: 	 vtysh_log_monitor_level_cmd,
 1464: 	 "log monitor "LOG_LEVELS,
 1465: 	 "Logging control\n"
 1466: 	 "Set terminal line (monitor) logging level\n"
 1467: 	 LOG_LEVEL_DESC)
 1468: {
 1469:   return CMD_SUCCESS;
 1470: }
 1471: 
 1472: DEFUNSH (VTYSH_ALL,
 1473: 	 no_vtysh_log_monitor,
 1474: 	 no_vtysh_log_monitor_cmd,
 1475: 	 "no log monitor [LEVEL]",
 1476: 	 NO_STR
 1477: 	 "Logging control\n"
 1478: 	 "Disable terminal line (monitor) logging\n"
 1479: 	 "Logging level\n")
 1480: {
 1481:   return CMD_SUCCESS;
 1482: }
 1483: 
 1484: DEFUNSH (VTYSH_ALL,
 1485: 	 vtysh_log_syslog,
 1486: 	 vtysh_log_syslog_cmd,
 1487: 	 "log syslog",
 1488: 	 "Logging control\n"
 1489: 	 "Set syslog logging level\n")
 1490: {
 1491:   return CMD_SUCCESS;
 1492: }
 1493: 
 1494: DEFUNSH (VTYSH_ALL,
 1495: 	 vtysh_log_syslog_level,
 1496: 	 vtysh_log_syslog_level_cmd,
 1497: 	 "log syslog "LOG_LEVELS,
 1498: 	 "Logging control\n"
 1499: 	 "Set syslog logging level\n"
 1500: 	 LOG_LEVEL_DESC)
 1501: {
 1502:   return CMD_SUCCESS;
 1503: }
 1504: 
 1505: DEFUNSH (VTYSH_ALL,
 1506: 	 no_vtysh_log_syslog,
 1507: 	 no_vtysh_log_syslog_cmd,
 1508: 	 "no log syslog [LEVEL]",
 1509: 	 NO_STR
 1510: 	 "Logging control\n"
 1511: 	 "Cancel logging to syslog\n"
 1512: 	 "Logging level\n")
 1513: {
 1514:   return CMD_SUCCESS;
 1515: }
 1516: 
 1517: DEFUNSH (VTYSH_ALL,
 1518: 	 vtysh_log_facility,
 1519: 	 vtysh_log_facility_cmd,
 1520: 	 "log facility "LOG_FACILITIES,
 1521: 	 "Logging control\n"
 1522: 	 "Facility parameter for syslog messages\n"
 1523: 	 LOG_FACILITY_DESC)
 1524: 
 1525: {
 1526:   return CMD_SUCCESS;
 1527: }
 1528: 
 1529: DEFUNSH (VTYSH_ALL,
 1530: 	 no_vtysh_log_facility,
 1531: 	 no_vtysh_log_facility_cmd,
 1532: 	 "no log facility [FACILITY]",
 1533: 	 NO_STR
 1534: 	 "Logging control\n"
 1535: 	 "Reset syslog facility to default (daemon)\n"
 1536: 	 "Syslog facility\n")
 1537: 
 1538: {
 1539:   return CMD_SUCCESS;
 1540: }
 1541: 
 1542: DEFUNSH_DEPRECATED (VTYSH_ALL,
 1543: 		    vtysh_log_trap,
 1544: 		    vtysh_log_trap_cmd,
 1545: 		    "log trap "LOG_LEVELS,
 1546: 		    "Logging control\n"
 1547: 		    "(Deprecated) Set logging level and default for all destinations\n"
 1548: 		    LOG_LEVEL_DESC)
 1549: 
 1550: {
 1551:   return CMD_SUCCESS;
 1552: }
 1553: 
 1554: DEFUNSH_DEPRECATED (VTYSH_ALL,
 1555: 		    no_vtysh_log_trap,
 1556: 		    no_vtysh_log_trap_cmd,
 1557: 		    "no log trap [LEVEL]",
 1558: 		    NO_STR
 1559: 		    "Logging control\n"
 1560: 		    "Permit all logging information\n"
 1561: 		    "Logging level\n")
 1562: {
 1563:   return CMD_SUCCESS;
 1564: }
 1565: 
 1566: DEFUNSH (VTYSH_ALL,
 1567: 	 vtysh_log_record_priority,
 1568: 	 vtysh_log_record_priority_cmd,
 1569: 	 "log record-priority",
 1570: 	 "Logging control\n"
 1571: 	 "Log the priority of the message within the message\n")
 1572: {
 1573:   return CMD_SUCCESS;
 1574: }
 1575: 
 1576: DEFUNSH (VTYSH_ALL,
 1577: 	 no_vtysh_log_record_priority,
 1578: 	 no_vtysh_log_record_priority_cmd,
 1579: 	 "no log record-priority",
 1580: 	 NO_STR
 1581: 	 "Logging control\n"
 1582: 	 "Do not log the priority of the message within the message\n")
 1583: {
 1584:   return CMD_SUCCESS;
 1585: }
 1586: 
 1587: DEFUNSH (VTYSH_ALL,
 1588: 	 vtysh_log_timestamp_precision,
 1589: 	 vtysh_log_timestamp_precision_cmd,
 1590: 	 "log timestamp precision <0-6>",
 1591: 	 "Logging control\n"
 1592: 	 "Timestamp configuration\n"
 1593: 	 "Set the timestamp precision\n"
 1594: 	 "Number of subsecond digits\n")
 1595: {
 1596:   return CMD_SUCCESS;
 1597: }
 1598: 
 1599: DEFUNSH (VTYSH_ALL,
 1600: 	 no_vtysh_log_timestamp_precision,
 1601: 	 no_vtysh_log_timestamp_precision_cmd,
 1602: 	 "no log timestamp precision",
 1603: 	 NO_STR
 1604: 	 "Logging control\n"
 1605: 	 "Timestamp configuration\n"
 1606: 	 "Reset the timestamp precision to the default value of 0\n")
 1607: {
 1608:   return CMD_SUCCESS;
 1609: }
 1610: 
 1611: DEFUNSH (VTYSH_ALL,
 1612: 	 vtysh_service_password_encrypt,
 1613: 	 vtysh_service_password_encrypt_cmd,
 1614: 	 "service password-encryption",
 1615: 	 "Set up miscellaneous service\n"
 1616: 	 "Enable encrypted passwords\n")
 1617: {
 1618:   return CMD_SUCCESS;
 1619: }
 1620: 
 1621: DEFUNSH (VTYSH_ALL,
 1622: 	 no_vtysh_service_password_encrypt,
 1623: 	 no_vtysh_service_password_encrypt_cmd,
 1624: 	 "no service password-encryption",
 1625: 	 NO_STR
 1626: 	 "Set up miscellaneous service\n"
 1627: 	 "Enable encrypted passwords\n")
 1628: {
 1629:   return CMD_SUCCESS;
 1630: }
 1631: 
 1632: DEFUNSH (VTYSH_ALL,
 1633: 	 vtysh_config_password,
 1634: 	 vtysh_password_cmd,
 1635: 	 "password (8|) WORD",
 1636: 	 "Assign the terminal connection password\n"
 1637: 	 "Specifies a HIDDEN password will follow\n"
 1638: 	 "dummy string \n"
 1639: 	 "The HIDDEN line password string\n")
 1640: {
 1641:   return CMD_SUCCESS;
 1642: }
 1643: 
 1644: DEFUNSH (VTYSH_ALL,
 1645: 	 vtysh_password_text,
 1646: 	 vtysh_password_text_cmd,
 1647: 	 "password LINE",
 1648: 	 "Assign the terminal connection password\n"
 1649: 	 "The UNENCRYPTED (cleartext) line password\n")
 1650: {
 1651:   return CMD_SUCCESS;
 1652: }
 1653: 
 1654: DEFUNSH (VTYSH_ALL,
 1655: 	 vtysh_config_enable_password,
 1656: 	 vtysh_enable_password_cmd,
 1657: 	 "enable password (8|) WORD",
 1658: 	 "Modify enable password parameters\n"
 1659: 	 "Assign the privileged level password\n"
 1660: 	 "Specifies a HIDDEN password will follow\n"
 1661: 	 "dummy string \n"
 1662: 	 "The HIDDEN 'enable' password string\n")
 1663: {
 1664:   return CMD_SUCCESS;
 1665: }
 1666: 
 1667: DEFUNSH (VTYSH_ALL,
 1668: 	 vtysh_enable_password_text,
 1669: 	 vtysh_enable_password_text_cmd,
 1670: 	 "enable password LINE",
 1671: 	 "Modify enable password parameters\n"
 1672: 	 "Assign the privileged level password\n"
 1673: 	 "The UNENCRYPTED (cleartext) 'enable' password\n")
 1674: {
 1675:   return CMD_SUCCESS;
 1676: }
 1677: 
 1678: DEFUNSH (VTYSH_ALL,
 1679: 	 no_vtysh_config_enable_password,
 1680: 	 no_vtysh_enable_password_cmd,
 1681: 	 "no enable password",
 1682: 	 NO_STR
 1683: 	 "Modify enable password parameters\n"
 1684: 	 "Assign the privileged level password\n")
 1685: {
 1686:   return CMD_SUCCESS;
 1687: }
 1688: 
 1689: DEFUN (vtysh_write_terminal,
 1690:        vtysh_write_terminal_cmd,
 1691:        "write terminal",
 1692:        "Write running configuration to memory, network, or terminal\n"
 1693:        "Write to terminal\n")
 1694: {
 1695:   u_int i;
 1696:   int ret;
 1697:   char line[] = "write terminal\n";
 1698:   FILE *fp = NULL;
 1699: 
 1700:   if (vtysh_pager_name)
 1701:     {
 1702:       fp = popen (vtysh_pager_name, "w");
 1703:       if (fp == NULL)
 1704: 	{
 1705: 	  perror ("popen");
 1706: 	  exit (1);
 1707: 	}
 1708:     }
 1709:   else
 1710:     fp = stdout;
 1711: 
 1712:   vty_out (vty, "Building configuration...%s", VTY_NEWLINE);
 1713:   vty_out (vty, "%sCurrent configuration:%s", VTY_NEWLINE,
 1714: 	   VTY_NEWLINE);
 1715:   vty_out (vty, "!%s", VTY_NEWLINE);
 1716: 
 1717:   for (i = 0; i < VTYSH_INDEX_MAX; i++)
 1718:     ret = vtysh_client_config (&vtysh_client[i], line);
 1719: 
 1720:   /* Integrate vtysh specific configuration. */
 1721:   vtysh_config_write ();
 1722: 
 1723:   vtysh_config_dump (fp);
 1724: 
 1725:   if (vtysh_pager_name && fp)
 1726:     {
 1727:       fflush (fp);
 1728:       if (pclose (fp) == -1)
 1729: 	{
 1730: 	  perror ("pclose");
 1731: 	  exit (1);
 1732: 	}
 1733:       fp = NULL;
 1734:     }
 1735: 
 1736:   vty_out (vty, "end%s", VTY_NEWLINE);
 1737:   
 1738:   return CMD_SUCCESS;
 1739: }
 1740: 
 1741: DEFUN (vtysh_integrated_config,
 1742:        vtysh_integrated_config_cmd,
 1743:        "service integrated-vtysh-config",
 1744:        "Set up miscellaneous service\n"
 1745:        "Write configuration into integrated file\n")
 1746: {
 1747:   vtysh_writeconfig_integrated = 1;
 1748:   return CMD_SUCCESS;
 1749: }
 1750: 
 1751: DEFUN (no_vtysh_integrated_config,
 1752:        no_vtysh_integrated_config_cmd,
 1753:        "no service integrated-vtysh-config",
 1754:        NO_STR
 1755:        "Set up miscellaneous service\n"
 1756:        "Write configuration into integrated file\n")
 1757: {
 1758:   vtysh_writeconfig_integrated = 0;
 1759:   return CMD_SUCCESS;
 1760: }
 1761: 
 1762: static int
 1763: write_config_integrated(void)
 1764: {
 1765:   u_int i;
 1766:   int ret;
 1767:   char line[] = "write terminal\n";
 1768:   FILE *fp;
 1769:   char *integrate_sav = NULL;
 1770: 
 1771:   integrate_sav = malloc (strlen (integrate_default) +
 1772: 			  strlen (CONF_BACKUP_EXT) + 1);
 1773:   strcpy (integrate_sav, integrate_default);
 1774:   strcat (integrate_sav, CONF_BACKUP_EXT);
 1775: 
 1776:   fprintf (stdout,"Building Configuration...\n");
 1777: 
 1778:   /* Move current configuration file to backup config file. */
 1779:   unlink (integrate_sav);
 1780:   rename (integrate_default, integrate_sav);
 1781:   free (integrate_sav);
 1782:  
 1783:   fp = fopen (integrate_default, "w");
 1784:   if (fp == NULL)
 1785:     {
 1786:       fprintf (stdout,"%% Can't open configuration file %s.\n",
 1787: 	       integrate_default);
 1788:       return CMD_SUCCESS;
 1789:     }
 1790: 
 1791:   for (i = 0; i < VTYSH_INDEX_MAX; i++)
 1792:     ret = vtysh_client_config (&vtysh_client[i], line);
 1793: 
 1794:   vtysh_config_dump (fp);
 1795: 
 1796:   fclose (fp);
 1797: 
 1798:   if (chmod (integrate_default, CONFIGFILE_MASK) != 0)
 1799:     {
 1800:       fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n", 
 1801: 	integrate_default, safe_strerror(errno), errno);
 1802:       return CMD_WARNING;
 1803:     }
 1804: 
 1805:   fprintf(stdout,"Integrated configuration saved to %s\n",integrate_default);
 1806: 
 1807:   fprintf (stdout,"[OK]\n");
 1808: 
 1809:   return CMD_SUCCESS;
 1810: }
 1811: 
 1812: DEFUN (vtysh_write_memory,
 1813:        vtysh_write_memory_cmd,
 1814:        "write memory",
 1815:        "Write running configuration to memory, network, or terminal\n"
 1816:        "Write configuration to the file (same as write file)\n")
 1817: {
 1818:   int ret = CMD_SUCCESS;
 1819:   char line[] = "write memory\n";
 1820:   u_int i;
 1821:   
 1822:   /* If integrated Quagga.conf explicitely set. */
 1823:   if (vtysh_writeconfig_integrated)
 1824:     return write_config_integrated();
 1825: 
 1826:   fprintf (stdout,"Building Configuration...\n");
 1827: 	  
 1828:   for (i = 0; i < VTYSH_INDEX_MAX; i++)
 1829:     ret = vtysh_client_execute (&vtysh_client[i], line, stdout);
 1830:   
 1831:   fprintf (stdout,"[OK]\n");
 1832: 
 1833:   return ret;
 1834: }
 1835: 
 1836: ALIAS (vtysh_write_memory,
 1837:        vtysh_copy_runningconfig_startupconfig_cmd,
 1838:        "copy running-config startup-config",  
 1839:        "Copy from one file to another\n"
 1840:        "Copy from current system configuration\n"
 1841:        "Copy to startup configuration\n")
 1842: 
 1843: ALIAS (vtysh_write_memory,
 1844:        vtysh_write_file_cmd,
 1845:        "write file",
 1846:        "Write running configuration to memory, network, or terminal\n"
 1847:        "Write configuration to the file (same as write memory)\n")
 1848: 
 1849: ALIAS (vtysh_write_memory,
 1850:        vtysh_write_cmd,
 1851:        "write",
 1852:        "Write running configuration to memory, network, or terminal\n")
 1853: 
 1854: ALIAS (vtysh_write_terminal,
 1855:        vtysh_show_running_config_cmd,
 1856:        "show running-config",
 1857:        SHOW_STR
 1858:        "Current operating configuration\n")
 1859: 
 1860: DEFUN (vtysh_terminal_length,
 1861:        vtysh_terminal_length_cmd,
 1862:        "terminal length <0-512>",
 1863:        "Set terminal line parameters\n"
 1864:        "Set number of lines on a screen\n"
 1865:        "Number of lines on screen (0 for no pausing)\n")
 1866: {
 1867:   int lines;
 1868:   char *endptr = NULL;
 1869:   char default_pager[10];
 1870: 
 1871:   lines = strtol (argv[0], &endptr, 10);
 1872:   if (lines < 0 || lines > 512 || *endptr != '\0')
 1873:     {
 1874:       vty_out (vty, "length is malformed%s", VTY_NEWLINE);
 1875:       return CMD_WARNING;
 1876:     }
 1877: 
 1878:   if (vtysh_pager_name)
 1879:     {
 1880:       free (vtysh_pager_name);
 1881:       vtysh_pager_name = NULL;
 1882:     }
 1883: 
 1884:   if (lines != 0)
 1885:     {
 1886:       snprintf(default_pager, 10, "more -%i", lines);
 1887:       vtysh_pager_name = strdup (default_pager);
 1888:     }
 1889: 
 1890:   return CMD_SUCCESS;
 1891: }
 1892: 
 1893: DEFUN (vtysh_terminal_no_length,
 1894:        vtysh_terminal_no_length_cmd,
 1895:        "terminal no length",
 1896:        "Set terminal line parameters\n"
 1897:        NO_STR
 1898:        "Set number of lines on a screen\n")
 1899: {
 1900:   if (vtysh_pager_name)
 1901:     {
 1902:       free (vtysh_pager_name);
 1903:       vtysh_pager_name = NULL;
 1904:     }
 1905: 
 1906:   vtysh_pager_init();
 1907:   return CMD_SUCCESS;
 1908: }
 1909: 
 1910: DEFUN (vtysh_show_daemons,
 1911:        vtysh_show_daemons_cmd,
 1912:        "show daemons",
 1913:        SHOW_STR
 1914:        "Show list of running daemons\n")
 1915: {
 1916:   u_int i;
 1917: 
 1918:   for (i = 0; i < VTYSH_INDEX_MAX; i++)
 1919:     if ( vtysh_client[i].fd >= 0 )
 1920:       vty_out(vty, " %s", vtysh_client[i].name);
 1921:   vty_out(vty, "%s", VTY_NEWLINE);
 1922: 
 1923:   return CMD_SUCCESS;
 1924: }
 1925: 
 1926: /* Execute command in child process. */
 1927: static int
 1928: execute_command (const char *command, int argc, const char *arg1,
 1929: 		 const char *arg2)
 1930: {
 1931:   int ret;
 1932:   pid_t pid;
 1933:   int status;
 1934: 
 1935:   /* Call fork(). */
 1936:   pid = fork ();
 1937: 
 1938:   if (pid < 0)
 1939:     {
 1940:       /* Failure of fork(). */
 1941:       fprintf (stderr, "Can't fork: %s\n", safe_strerror (errno));
 1942:       exit (1);
 1943:     }
 1944:   else if (pid == 0)
 1945:     {
 1946:       /* This is child process. */
 1947:       switch (argc)
 1948: 	{
 1949: 	case 0:
 1950: 	  ret = execlp (command, command, (const char *)NULL);
 1951: 	  break;
 1952: 	case 1:
 1953: 	  ret = execlp (command, command, arg1, (const char *)NULL);
 1954: 	  break;
 1955: 	case 2:
 1956: 	  ret = execlp (command, command, arg1, arg2, (const char *)NULL);
 1957: 	  break;
 1958: 	}
 1959: 
 1960:       /* When execlp suceed, this part is not executed. */
 1961:       fprintf (stderr, "Can't execute %s: %s\n", command, safe_strerror (errno));
 1962:       exit (1);
 1963:     }
 1964:   else
 1965:     {
 1966:       /* This is parent. */
 1967:       execute_flag = 1;
 1968:       ret = wait4 (pid, &status, 0, NULL);
 1969:       execute_flag = 0;
 1970:     }
 1971:   return 0;
 1972: }
 1973: 
 1974: DEFUN (vtysh_ping,
 1975:        vtysh_ping_cmd,
 1976:        "ping WORD",
 1977:        "Send echo messages\n"
 1978:        "Ping destination address or hostname\n")
 1979: {
 1980:   execute_command ("ping", 1, argv[0], NULL);
 1981:   return CMD_SUCCESS;
 1982: }
 1983: 
 1984: ALIAS (vtysh_ping,
 1985:        vtysh_ping_ip_cmd,
 1986:        "ping ip WORD",
 1987:        "Send echo messages\n"
 1988:        "IP echo\n"
 1989:        "Ping destination address or hostname\n")
 1990: 
 1991: DEFUN (vtysh_traceroute,
 1992:        vtysh_traceroute_cmd,
 1993:        "traceroute WORD",
 1994:        "Trace route to destination\n"
 1995:        "Trace route to destination address or hostname\n")
 1996: {
 1997:   execute_command ("traceroute", 1, argv[0], NULL);
 1998:   return CMD_SUCCESS;
 1999: }
 2000: 
 2001: ALIAS (vtysh_traceroute,
 2002:        vtysh_traceroute_ip_cmd,
 2003:        "traceroute ip WORD",
 2004:        "Trace route to destination\n"
 2005:        "IP trace\n"
 2006:        "Trace route to destination address or hostname\n")
 2007: 
 2008: #ifdef HAVE_IPV6
 2009: DEFUN (vtysh_ping6,
 2010:        vtysh_ping6_cmd,
 2011:        "ping ipv6 WORD",
 2012:        "Send echo messages\n"
 2013:        "IPv6 echo\n"
 2014:        "Ping destination address or hostname\n")
 2015: {
 2016:   execute_command ("ping6", 1, argv[0], NULL);
 2017:   return CMD_SUCCESS;
 2018: }
 2019: 
 2020: DEFUN (vtysh_traceroute6,
 2021:        vtysh_traceroute6_cmd,
 2022:        "traceroute ipv6 WORD",
 2023:        "Trace route to destination\n"
 2024:        "IPv6 trace\n"
 2025:        "Trace route to destination address or hostname\n")
 2026: {
 2027:   execute_command ("traceroute6", 1, argv[0], NULL);
 2028:   return CMD_SUCCESS;
 2029: }
 2030: #endif
 2031: 
 2032: DEFUN (vtysh_telnet,
 2033:        vtysh_telnet_cmd,
 2034:        "telnet WORD",
 2035:        "Open a telnet connection\n"
 2036:        "IP address or hostname of a remote system\n")
 2037: {
 2038:   execute_command ("telnet", 1, argv[0], NULL);
 2039:   return CMD_SUCCESS;
 2040: }
 2041: 
 2042: DEFUN (vtysh_telnet_port,
 2043:        vtysh_telnet_port_cmd,
 2044:        "telnet WORD PORT",
 2045:        "Open a telnet connection\n"
 2046:        "IP address or hostname of a remote system\n"
 2047:        "TCP Port number\n")
 2048: {
 2049:   execute_command ("telnet", 2, argv[0], argv[1]);
 2050:   return CMD_SUCCESS;
 2051: }
 2052: 
 2053: DEFUN (vtysh_ssh,
 2054:        vtysh_ssh_cmd,
 2055:        "ssh WORD",
 2056:        "Open an ssh connection\n"
 2057:        "[user@]host\n")
 2058: {
 2059:   execute_command ("ssh", 1, argv[0], NULL);
 2060:   return CMD_SUCCESS;
 2061: }
 2062: 
 2063: DEFUN (vtysh_start_shell,
 2064:        vtysh_start_shell_cmd,
 2065:        "start-shell",
 2066:        "Start UNIX shell\n")
 2067: {
 2068:   execute_command ("sh", 0, NULL, NULL);
 2069:   return CMD_SUCCESS;
 2070: }
 2071: 
 2072: DEFUN (vtysh_start_bash,
 2073:        vtysh_start_bash_cmd,
 2074:        "start-shell bash",
 2075:        "Start UNIX shell\n"
 2076:        "Start bash\n")
 2077: {
 2078:   execute_command ("bash", 0, NULL, NULL);
 2079:   return CMD_SUCCESS;
 2080: }
 2081: 
 2082: DEFUN (vtysh_start_zsh,
 2083:        vtysh_start_zsh_cmd,
 2084:        "start-shell zsh",
 2085:        "Start UNIX shell\n"
 2086:        "Start Z shell\n")
 2087: {
 2088:   execute_command ("zsh", 0, NULL, NULL);
 2089:   return CMD_SUCCESS;
 2090: }
 2091: 
 2092: static void
 2093: vtysh_install_default (enum node_type node)
 2094: {
 2095:   install_element (node, &config_list_cmd);
 2096: }
 2097: 
 2098: /* Making connection to protocol daemon. */
 2099: static int
 2100: vtysh_connect (struct vtysh_client *vclient)
 2101: {
 2102:   int ret;
 2103:   int sock, len;
 2104:   struct sockaddr_un addr;
 2105:   struct stat s_stat;
 2106: 
 2107:   /* Stat socket to see if we have permission to access it. */
 2108:   ret = stat (vclient->path, &s_stat);
 2109:   if (ret < 0 && errno != ENOENT)
 2110:     {
 2111:       fprintf  (stderr, "vtysh_connect(%s): stat = %s\n", 
 2112: 		vclient->path, safe_strerror(errno)); 
 2113:       exit(1);
 2114:     }
 2115:   
 2116:   if (ret >= 0)
 2117:     {
 2118:       if (! S_ISSOCK(s_stat.st_mode))
 2119: 	{
 2120: 	  fprintf (stderr, "vtysh_connect(%s): Not a socket\n",
 2121: 		   vclient->path);
 2122: 	  exit (1);
 2123: 	}
 2124:       
 2125:     }
 2126: 
 2127:   sock = socket (AF_UNIX, SOCK_STREAM, 0);
 2128:   if (sock < 0)
 2129:     {
 2130: #ifdef DEBUG
 2131:       fprintf(stderr, "vtysh_connect(%s): socket = %s\n", vclient->path,
 2132: 	      safe_strerror(errno));
 2133: #endif /* DEBUG */
 2134:       return -1;
 2135:     }
 2136: 
 2137:   memset (&addr, 0, sizeof (struct sockaddr_un));
 2138:   addr.sun_family = AF_UNIX;
 2139:   strncpy (addr.sun_path, vclient->path, strlen (vclient->path));
 2140: #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
 2141:   len = addr.sun_len = SUN_LEN(&addr);
 2142: #else
 2143:   len = sizeof (addr.sun_family) + strlen (addr.sun_path);
 2144: #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */
 2145: 
 2146:   ret = connect (sock, (struct sockaddr *) &addr, len);
 2147:   if (ret < 0)
 2148:     {
 2149: #ifdef DEBUG
 2150:       fprintf(stderr, "vtysh_connect(%s): connect = %s\n", vclient->path,
 2151: 	      safe_strerror(errno));
 2152: #endif /* DEBUG */
 2153:       close (sock);
 2154:       return -1;
 2155:     }
 2156:   vclient->fd = sock;
 2157: 
 2158:   return 0;
 2159: }
 2160: 
 2161: int
 2162: vtysh_connect_all(const char *daemon_name)
 2163: {
 2164:   u_int i;
 2165:   int rc = 0;
 2166:   int matches = 0;
 2167: 
 2168:   for (i = 0; i < VTYSH_INDEX_MAX; i++)
 2169:     {
 2170:       if (!daemon_name || !strcmp(daemon_name, vtysh_client[i].name))
 2171: 	{
 2172: 	  matches++;
 2173: 	  if (vtysh_connect(&vtysh_client[i]) == 0)
 2174: 	    rc++;
 2175: 	  /* We need direct access to ripd in vtysh_exit_ripd_only. */
 2176: 	  if (vtysh_client[i].flag == VTYSH_RIPD)
 2177: 	    ripd_client = &vtysh_client[i];
 2178: 	}
 2179:     }
 2180:   if (!matches)
 2181:     fprintf(stderr, "Error: no daemons match name %s!\n", daemon_name);
 2182:   return rc;
 2183: }
 2184: 
 2185: /* To disable readline's filename completion. */
 2186: static char *
 2187: vtysh_completion_entry_function (const char *ignore, int invoking_key)
 2188: {
 2189:   return NULL;
 2190: }
 2191: 
 2192: void
 2193: vtysh_readline_init (void)
 2194: {
 2195:   /* readline related settings. */
 2196:   rl_bind_key ('?', (Function *) vtysh_rl_describe);
 2197:   rl_completion_entry_function = vtysh_completion_entry_function;
 2198:   rl_attempted_completion_function = (CPPFunction *)new_completion;
 2199:   /* do not append space after completion. It will be appended
 2200:    * in new_completion() function explicitly. */
 2201:   rl_completion_append_character = '\0';
 2202: }
 2203: 
 2204: char *
 2205: vtysh_prompt (void)
 2206: {
 2207:   static struct utsname names;
 2208:   static char buf[100];
 2209:   const char*hostname;
 2210:   extern struct host host;
 2211: 
 2212:   hostname = host.name;
 2213: 
 2214:   if (!hostname)
 2215:     {
 2216:       if (!names.nodename[0])
 2217: 	uname (&names);
 2218:       hostname = names.nodename;
 2219:     }
 2220: 
 2221:   snprintf (buf, sizeof buf, cmd_prompt (vty->node), hostname);
 2222: 
 2223:   return buf;
 2224: }
 2225: 
 2226: void
 2227: vtysh_init_vty (void)
 2228: {
 2229:   /* Make vty structure. */
 2230:   vty = vty_new ();
 2231:   vty->type = VTY_SHELL;
 2232:   vty->node = VIEW_NODE;
 2233: 
 2234:   /* Initialize commands. */
 2235:   cmd_init (0);
 2236: 
 2237:   /* Install nodes. */
 2238:   install_node (&bgp_node, NULL);
 2239:   install_node (&rip_node, NULL);
 2240:   install_node (&interface_node, NULL);
 2241:   install_node (&rmap_node, NULL);
 2242:   install_node (&zebra_node, NULL);
 2243:   install_node (&bgp_vpnv4_node, NULL);
 2244:   install_node (&bgp_ipv4_node, NULL);
 2245:   install_node (&bgp_ipv4m_node, NULL);
 2246: /* #ifdef HAVE_IPV6 */
 2247:   install_node (&bgp_ipv6_node, NULL);
 2248:   install_node (&bgp_ipv6m_node, NULL);
 2249: /* #endif */
 2250:   install_node (&ospf_node, NULL);
 2251: /* #ifdef HAVE_IPV6 */
 2252:   install_node (&ripng_node, NULL);
 2253:   install_node (&ospf6_node, NULL);
 2254: /* #endif */
 2255:   install_node (&keychain_node, NULL);
 2256:   install_node (&keychain_key_node, NULL);
 2257:   install_node (&isis_node, NULL);
 2258:   install_node (&vty_node, NULL);
 2259: 
 2260:   vtysh_install_default (VIEW_NODE);
 2261:   vtysh_install_default (ENABLE_NODE);
 2262:   vtysh_install_default (CONFIG_NODE);
 2263:   vtysh_install_default (BGP_NODE);
 2264:   vtysh_install_default (RIP_NODE);
 2265:   vtysh_install_default (INTERFACE_NODE);
 2266:   vtysh_install_default (RMAP_NODE);
 2267:   vtysh_install_default (ZEBRA_NODE);
 2268:   vtysh_install_default (BGP_VPNV4_NODE);
 2269:   vtysh_install_default (BGP_IPV4_NODE);
 2270:   vtysh_install_default (BGP_IPV4M_NODE);
 2271:   vtysh_install_default (BGP_IPV6_NODE);
 2272:   vtysh_install_default (BGP_IPV6M_NODE);
 2273:   vtysh_install_default (OSPF_NODE);
 2274:   vtysh_install_default (RIPNG_NODE);
 2275:   vtysh_install_default (OSPF6_NODE);
 2276:   vtysh_install_default (ISIS_NODE);
 2277:   vtysh_install_default (KEYCHAIN_NODE);
 2278:   vtysh_install_default (KEYCHAIN_KEY_NODE);
 2279:   vtysh_install_default (VTY_NODE);
 2280: 
 2281:   install_element (VIEW_NODE, &vtysh_enable_cmd);
 2282:   install_element (ENABLE_NODE, &vtysh_config_terminal_cmd);
 2283:   install_element (ENABLE_NODE, &vtysh_disable_cmd);
 2284: 
 2285:   /* "exit" command. */
 2286:   install_element (VIEW_NODE, &vtysh_exit_all_cmd);
 2287:   install_element (VIEW_NODE, &vtysh_quit_all_cmd);
 2288:   install_element (CONFIG_NODE, &vtysh_exit_all_cmd);
 2289:   /* install_element (CONFIG_NODE, &vtysh_quit_all_cmd); */
 2290:   install_element (ENABLE_NODE, &vtysh_exit_all_cmd);
 2291:   install_element (ENABLE_NODE, &vtysh_quit_all_cmd);
 2292:   install_element (RIP_NODE, &vtysh_exit_ripd_cmd);
 2293:   install_element (RIP_NODE, &vtysh_quit_ripd_cmd);
 2294:   install_element (RIPNG_NODE, &vtysh_exit_ripngd_cmd);
 2295:   install_element (RIPNG_NODE, &vtysh_quit_ripngd_cmd);
 2296:   install_element (OSPF_NODE, &vtysh_exit_ospfd_cmd);
 2297:   install_element (OSPF_NODE, &vtysh_quit_ospfd_cmd);
 2298:   install_element (OSPF6_NODE, &vtysh_exit_ospf6d_cmd);
 2299:   install_element (OSPF6_NODE, &vtysh_quit_ospf6d_cmd);
 2300:   install_element (BGP_NODE, &vtysh_exit_bgpd_cmd);
 2301:   install_element (BGP_NODE, &vtysh_quit_bgpd_cmd);
 2302:   install_element (BGP_VPNV4_NODE, &vtysh_exit_bgpd_cmd);
 2303:   install_element (BGP_VPNV4_NODE, &vtysh_quit_bgpd_cmd);
 2304:   install_element (BGP_IPV4_NODE, &vtysh_exit_bgpd_cmd);
 2305:   install_element (BGP_IPV4_NODE, &vtysh_quit_bgpd_cmd);
 2306:   install_element (BGP_IPV4M_NODE, &vtysh_exit_bgpd_cmd);
 2307:   install_element (BGP_IPV4M_NODE, &vtysh_quit_bgpd_cmd);
 2308:   install_element (BGP_IPV6_NODE, &vtysh_exit_bgpd_cmd);
 2309:   install_element (BGP_IPV6_NODE, &vtysh_quit_bgpd_cmd);
 2310:   install_element (BGP_IPV6M_NODE, &vtysh_exit_bgpd_cmd);
 2311:   install_element (BGP_IPV6M_NODE, &vtysh_quit_bgpd_cmd);
 2312:   install_element (ISIS_NODE, &vtysh_exit_isisd_cmd);
 2313:   install_element (ISIS_NODE, &vtysh_quit_isisd_cmd);
 2314:   install_element (KEYCHAIN_NODE, &vtysh_exit_ripd_cmd);
 2315:   install_element (KEYCHAIN_NODE, &vtysh_quit_ripd_cmd);
 2316:   install_element (KEYCHAIN_KEY_NODE, &vtysh_exit_ripd_cmd);
 2317:   install_element (KEYCHAIN_KEY_NODE, &vtysh_quit_ripd_cmd);
 2318:   install_element (RMAP_NODE, &vtysh_exit_rmap_cmd);
 2319:   install_element (RMAP_NODE, &vtysh_quit_rmap_cmd);
 2320:   install_element (VTY_NODE, &vtysh_exit_line_vty_cmd);
 2321:   install_element (VTY_NODE, &vtysh_quit_line_vty_cmd);
 2322: 
 2323:   /* "end" command. */
 2324:   install_element (CONFIG_NODE, &vtysh_end_all_cmd);
 2325:   install_element (ENABLE_NODE, &vtysh_end_all_cmd);
 2326:   install_element (RIP_NODE, &vtysh_end_all_cmd);
 2327:   install_element (RIPNG_NODE, &vtysh_end_all_cmd);
 2328:   install_element (OSPF_NODE, &vtysh_end_all_cmd);
 2329:   install_element (OSPF6_NODE, &vtysh_end_all_cmd);
 2330:   install_element (BGP_NODE, &vtysh_end_all_cmd);
 2331:   install_element (BGP_IPV4_NODE, &vtysh_end_all_cmd);
 2332:   install_element (BGP_IPV4M_NODE, &vtysh_end_all_cmd);
 2333:   install_element (BGP_VPNV4_NODE, &vtysh_end_all_cmd);
 2334:   install_element (BGP_IPV6_NODE, &vtysh_end_all_cmd);
 2335:   install_element (BGP_IPV6M_NODE, &vtysh_end_all_cmd);
 2336:   install_element (ISIS_NODE, &vtysh_end_all_cmd);
 2337:   install_element (KEYCHAIN_NODE, &vtysh_end_all_cmd);
 2338:   install_element (KEYCHAIN_KEY_NODE, &vtysh_end_all_cmd);
 2339:   install_element (RMAP_NODE, &vtysh_end_all_cmd);
 2340:   install_element (VTY_NODE, &vtysh_end_all_cmd);
 2341: 
 2342:   install_element (INTERFACE_NODE, &interface_desc_cmd);
 2343:   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
 2344:   install_element (INTERFACE_NODE, &vtysh_end_all_cmd);
 2345:   install_element (INTERFACE_NODE, &vtysh_exit_interface_cmd);
 2346:   install_element (INTERFACE_NODE, &vtysh_quit_interface_cmd);
 2347:   install_element (CONFIG_NODE, &router_rip_cmd);
 2348: #ifdef HAVE_IPV6
 2349:   install_element (CONFIG_NODE, &router_ripng_cmd);
 2350: #endif
 2351:   install_element (CONFIG_NODE, &router_ospf_cmd);
 2352: #ifdef HAVE_IPV6
 2353:   install_element (CONFIG_NODE, &router_ospf6_cmd);
 2354: #endif
 2355:   install_element (CONFIG_NODE, &router_isis_cmd);
 2356:   install_element (CONFIG_NODE, &router_bgp_cmd);
 2357:   install_element (CONFIG_NODE, &router_bgp_view_cmd);
 2358:   install_element (BGP_NODE, &address_family_vpnv4_cmd);
 2359:   install_element (BGP_NODE, &address_family_vpnv4_unicast_cmd);
 2360:   install_element (BGP_NODE, &address_family_ipv4_unicast_cmd);
 2361:   install_element (BGP_NODE, &address_family_ipv4_multicast_cmd);
 2362: #ifdef HAVE_IPV6
 2363:   install_element (BGP_NODE, &address_family_ipv6_cmd);
 2364:   install_element (BGP_NODE, &address_family_ipv6_unicast_cmd);
 2365: #endif
 2366:   install_element (BGP_VPNV4_NODE, &exit_address_family_cmd);
 2367:   install_element (BGP_IPV4_NODE, &exit_address_family_cmd);
 2368:   install_element (BGP_IPV4M_NODE, &exit_address_family_cmd);
 2369:   install_element (BGP_IPV6_NODE, &exit_address_family_cmd);
 2370:   install_element (BGP_IPV6M_NODE, &exit_address_family_cmd);
 2371:   install_element (CONFIG_NODE, &key_chain_cmd);
 2372:   install_element (CONFIG_NODE, &route_map_cmd);
 2373:   install_element (CONFIG_NODE, &vtysh_line_vty_cmd);
 2374:   install_element (KEYCHAIN_NODE, &key_cmd);
 2375:   install_element (KEYCHAIN_NODE, &key_chain_cmd);
 2376:   install_element (KEYCHAIN_KEY_NODE, &key_chain_cmd);
 2377:   install_element (CONFIG_NODE, &vtysh_interface_cmd);
 2378:   install_element (CONFIG_NODE, &vtysh_no_interface_cmd);
 2379:   install_element (ENABLE_NODE, &vtysh_show_running_config_cmd);
 2380:   install_element (ENABLE_NODE, &vtysh_copy_runningconfig_startupconfig_cmd);
 2381:   install_element (ENABLE_NODE, &vtysh_write_file_cmd);
 2382:   install_element (ENABLE_NODE, &vtysh_write_cmd);
 2383: 
 2384:   /* "write terminal" command. */
 2385:   install_element (ENABLE_NODE, &vtysh_write_terminal_cmd);
 2386:  
 2387:   install_element (CONFIG_NODE, &vtysh_integrated_config_cmd);
 2388:   install_element (CONFIG_NODE, &no_vtysh_integrated_config_cmd);
 2389: 
 2390:   /* "write memory" command. */
 2391:   install_element (ENABLE_NODE, &vtysh_write_memory_cmd);
 2392: 
 2393:   install_element (VIEW_NODE, &vtysh_terminal_length_cmd);
 2394:   install_element (ENABLE_NODE, &vtysh_terminal_length_cmd);
 2395:   install_element (VIEW_NODE, &vtysh_terminal_no_length_cmd);
 2396:   install_element (ENABLE_NODE, &vtysh_terminal_no_length_cmd);
 2397:   install_element (VIEW_NODE, &vtysh_show_daemons_cmd);
 2398:   install_element (ENABLE_NODE, &vtysh_show_daemons_cmd);
 2399: 
 2400:   install_element (VIEW_NODE, &vtysh_ping_cmd);
 2401:   install_element (VIEW_NODE, &vtysh_ping_ip_cmd);
 2402:   install_element (VIEW_NODE, &vtysh_traceroute_cmd);
 2403:   install_element (VIEW_NODE, &vtysh_traceroute_ip_cmd);
 2404: #ifdef HAVE_IPV6
 2405:   install_element (VIEW_NODE, &vtysh_ping6_cmd);
 2406:   install_element (VIEW_NODE, &vtysh_traceroute6_cmd);
 2407: #endif
 2408:   install_element (VIEW_NODE, &vtysh_telnet_cmd);
 2409:   install_element (VIEW_NODE, &vtysh_telnet_port_cmd);
 2410:   install_element (VIEW_NODE, &vtysh_ssh_cmd);
 2411:   install_element (ENABLE_NODE, &vtysh_ping_cmd);
 2412:   install_element (ENABLE_NODE, &vtysh_ping_ip_cmd);
 2413:   install_element (ENABLE_NODE, &vtysh_traceroute_cmd);
 2414:   install_element (ENABLE_NODE, &vtysh_traceroute_ip_cmd);
 2415: #ifdef HAVE_IPV6
 2416:   install_element (ENABLE_NODE, &vtysh_ping6_cmd);
 2417:   install_element (ENABLE_NODE, &vtysh_traceroute6_cmd);
 2418: #endif
 2419:   install_element (ENABLE_NODE, &vtysh_telnet_cmd);
 2420:   install_element (ENABLE_NODE, &vtysh_telnet_port_cmd);
 2421:   install_element (ENABLE_NODE, &vtysh_ssh_cmd);
 2422:   install_element (ENABLE_NODE, &vtysh_start_shell_cmd);
 2423:   install_element (ENABLE_NODE, &vtysh_start_bash_cmd);
 2424:   install_element (ENABLE_NODE, &vtysh_start_zsh_cmd);
 2425:   
 2426:   install_element (VIEW_NODE, &vtysh_show_memory_cmd);
 2427:   install_element (ENABLE_NODE, &vtysh_show_memory_cmd);
 2428: 
 2429:   /* Logging */
 2430:   install_element (ENABLE_NODE, &vtysh_show_logging_cmd);
 2431:   install_element (VIEW_NODE, &vtysh_show_logging_cmd);
 2432:   install_element (CONFIG_NODE, &vtysh_log_stdout_cmd);
 2433:   install_element (CONFIG_NODE, &vtysh_log_stdout_level_cmd);
 2434:   install_element (CONFIG_NODE, &no_vtysh_log_stdout_cmd);
 2435:   install_element (CONFIG_NODE, &vtysh_log_file_cmd);
 2436:   install_element (CONFIG_NODE, &vtysh_log_file_level_cmd);
 2437:   install_element (CONFIG_NODE, &no_vtysh_log_file_cmd);
 2438:   install_element (CONFIG_NODE, &no_vtysh_log_file_level_cmd);
 2439:   install_element (CONFIG_NODE, &vtysh_log_monitor_cmd);
 2440:   install_element (CONFIG_NODE, &vtysh_log_monitor_level_cmd);
 2441:   install_element (CONFIG_NODE, &no_vtysh_log_monitor_cmd);
 2442:   install_element (CONFIG_NODE, &vtysh_log_syslog_cmd);
 2443:   install_element (CONFIG_NODE, &vtysh_log_syslog_level_cmd);
 2444:   install_element (CONFIG_NODE, &no_vtysh_log_syslog_cmd);
 2445:   install_element (CONFIG_NODE, &vtysh_log_trap_cmd);
 2446:   install_element (CONFIG_NODE, &no_vtysh_log_trap_cmd);
 2447:   install_element (CONFIG_NODE, &vtysh_log_facility_cmd);
 2448:   install_element (CONFIG_NODE, &no_vtysh_log_facility_cmd);
 2449:   install_element (CONFIG_NODE, &vtysh_log_record_priority_cmd);
 2450:   install_element (CONFIG_NODE, &no_vtysh_log_record_priority_cmd);
 2451:   install_element (CONFIG_NODE, &vtysh_log_timestamp_precision_cmd);
 2452:   install_element (CONFIG_NODE, &no_vtysh_log_timestamp_precision_cmd);
 2453: 
 2454:   install_element (CONFIG_NODE, &vtysh_service_password_encrypt_cmd);
 2455:   install_element (CONFIG_NODE, &no_vtysh_service_password_encrypt_cmd);
 2456: 
 2457:   install_element (CONFIG_NODE, &vtysh_password_cmd);
 2458:   install_element (CONFIG_NODE, &vtysh_password_text_cmd);
 2459:   install_element (CONFIG_NODE, &vtysh_enable_password_cmd);
 2460:   install_element (CONFIG_NODE, &vtysh_enable_password_text_cmd);
 2461:   install_element (CONFIG_NODE, &no_vtysh_enable_password_cmd);
 2462: 
 2463: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>