⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vtysh.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Virtual terminal interface shell. * Copyright (C) 2000 Kunihiro Ishiguro * * This file is part of GNU Zebra. * * GNU Zebra is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * GNU Zebra is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Zebra; see the file COPYING.  If not, write to the Free * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA.   */#include <zebra.h>#include <sys/un.h>#include <setjmp.h>#include <sys/wait.h>#include <sys/resource.h>#include <sys/stat.h>#include <readline/readline.h>#include <readline/history.h>#include "command.h"#include "memory.h"#include "vtysh/vtysh.h"/* Struct VTY. */struct vty *vty;/* VTY shell pager name. */char *vtysh_pager_name = NULL;/* VTY shell client structure. */struct vtysh_client{  int fd;} vtysh_client[VTYSH_INDEX_MAX];/* When '^Z' is received from vty, move down to the enable mode. */intvtysh_end (){  switch (vty->node)    {    case VIEW_NODE:    case ENABLE_NODE:      /* Nothing to do. */      break;    default:      vty->node = ENABLE_NODE;      break;    }  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,	 vtysh_end_all,	 vtysh_end_all_cmd,	 "end",	 "End current mode and down to previous mode\n"){  return vtysh_end (vty);}DEFUNSH (VTYSH_ALL,	 vtysh_log_stdout,	 vtysh_log_stdout_cmd,	 "log stdout",	 "Logging control\n"	 "Logging goes to stdout\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,	 no_vtysh_log_stdout,	 no_vtysh_log_stdout_cmd,	 "no log stdout",	 NO_STR	 "Logging control\n"	 "Logging goes to stdout\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,       vtysh_log_file,       vtysh_log_file_cmd,       "log file FILENAME",       "Logging control\n"       "Logging to file\n"       "Logging filename\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,       no_vtysh_log_file,       no_vtysh_log_file_cmd,       "no log file [FILENAME]",       NO_STR       "Logging control\n"       "Cancel logging to file\n"       "Logging file name\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,	 vtysh_log_syslog,	 vtysh_log_syslog_cmd,	 "log syslog",	 "Logging control\n"	 "Logging goes to syslog\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,	 no_vtysh_log_syslog,	 no_vtysh_log_syslog_cmd,	 "no log syslog",	 NO_STR	 "Logging control\n"	 "Cancel logging to syslog\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,	 vtysh_log_trap,	 vtysh_log_trap_cmd,	 "log trap (emergencies|alerts|critical|errors|warnings|notifications|informational|debugging)",	 "Logging control\n"	 "Limit logging to specifed level\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,	 no_vtysh_log_trap,	 no_vtysh_log_trap_cmd,	 "no log trap",	 NO_STR	 "Logging control\n"	 "Permit all logging information\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,	 vtysh_log_record_priority,	 vtysh_log_record_priority_cmd,	 "log record-priority",	 "Logging control\n"	 "Log the priority of the message within the message\n"){  return CMD_SUCCESS;}DEFUNSH (VTYSH_ALL,	 no_vtysh_log_record_priority,	 no_vtysh_log_record_priority_cmd,	 "no log record-priority",	 NO_STR	 "Logging control\n"	 "Do not log the priority of the message within the message\n"){  return CMD_SUCCESS;}voidvclient_close (struct vtysh_client *vclient){  if (vclient->fd > 0)    close (vclient->fd);  vclient->fd = -1;}/* Following filled with debug code to trace a problematic condition   under load - it SHOULD handle it.*/#define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "intvtysh_client_config (struct vtysh_client *vclient, char *line){  int ret;  char *buf;  size_t bufsz;  char *pbuf;  size_t left;  char *eoln;  int nbytes;  int i;  int readln;  if (vclient->fd < 0)    return CMD_SUCCESS;  ret = write (vclient->fd, line, strlen (line) + 1);  if (ret <= 0)    {      vclient_close (vclient);      return CMD_SUCCESS;    }	  /* Allow enough room for buffer to read more than a few pages from socket   */  bufsz = 5 * sysconf(_SC_PAGESIZE) + 1;  buf = XMALLOC(MTYPE_TMP, bufsz);  memset(buf, 0, bufsz);  pbuf = buf;  while (1)    {      if (pbuf >= ((buf + bufsz) -1))	{	  fprintf (stderr, ERR_WHERE_STRING \		   "warning - pbuf beyond buffer end.\n");	  return CMD_WARNING;	}      readln = (buf + bufsz) - pbuf - 1;      nbytes = read (vclient->fd, pbuf, readln);      if (nbytes <= 0)	{	  if (errno == EINTR)	    continue;	  fprintf(stderr, ERR_WHERE_STRING "(%u)", errno);	  perror("");	  if (errno == EAGAIN || errno == EIO)	    continue;	  vclient_close (vclient);	  XFREE(MTYPE_TMP, buf);	  return CMD_SUCCESS;	}      pbuf[nbytes] = '\0';      if (nbytes >= 4)	{	  i = nbytes - 4;	  if (pbuf[i] == '\0' && pbuf[i + 1] == '\0' && pbuf[i + 2] == '\0')	    {	      ret = pbuf[i + 3];	      break;	    }	}      pbuf += nbytes;      /* See if a line exists in buffer, if so parse and consume it, and	 reset read position */      if ((eoln = strrchr(buf, '\n')) == NULL)	continue;      if (eoln >= ((buf + bufsz) - 1))	{	  fprintf (stderr, ERR_WHERE_STRING \		   "warning - eoln beyond buffer end.\n");	}      vtysh_config_parse(buf);      eoln++;      left = (size_t)(buf + bufsz - eoln);      memmove(buf, eoln, left);      buf[bufsz-1] = '\0';      pbuf = buf + strlen(buf);    }  /* parse anything left in the buffer */  vtysh_config_parse (buf);  XFREE(MTYPE_TMP, buf);  return ret;}intvtysh_client_execute (struct vtysh_client *vclient, char *line, FILE *fp){  int ret;  char buf[1001];  int nbytes;  int i;  if (vclient->fd < 0)    return CMD_SUCCESS;  ret = write (vclient->fd, line, strlen (line) + 1);  if (ret <= 0)    {      vclient_close (vclient);      return CMD_SUCCESS;    }	  while (1)    {      nbytes = read (vclient->fd, buf, sizeof(buf)-1);      if (nbytes <= 0 && errno != EINTR)	{	  vclient_close (vclient);	  return CMD_SUCCESS;	}      if (nbytes > 0)	{	  buf[nbytes] = '\0';	  fprintf (fp, "%s", buf);	  fflush (fp);	  if (nbytes >= 4)	    {	      i = nbytes - 4;	      if (buf[i] == '\0' && buf[i + 1] == '\0' && buf[i + 2] == '\0')		{		  ret = buf[i + 3];		  break;		}	    }	}    }  return ret;}voidvtysh_exit_ripd_only (){  vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP], "exit", stdout);}voidvtysh_pager_init (){  vtysh_pager_name = getenv ("VTYSH_PAGER");  if (! vtysh_pager_name)    vtysh_pager_name = "more";}/* Command execution over the vty interface. */voidvtysh_execute_func (char *line, int pager){  int ret, cmd_stat;  vector vline;  struct cmd_element *cmd;  FILE *fp = NULL;  /* Split readline string up into the vector */  vline = cmd_make_strvec (line);  if (vline == NULL)    return;  ret = cmd_execute_command (vline, vty, &cmd);  cmd_free_strvec (vline);  switch (ret)    {    case CMD_WARNING:      if (vty->type == VTY_FILE)	printf ("Warning...\n");      break;    case CMD_ERR_AMBIGUOUS:      printf ("%% Ambiguous command.\n");      break;    case CMD_ERR_NO_MATCH:      printf ("%% Unknown command.\n");      break;    case CMD_ERR_INCOMPLETE:      printf ("%% Command incomplete.\n");      break;    case CMD_SUCCESS_DAEMON:      {	if (pager && vtysh_pager_name)	  {	    fp = popen ("more", "w");	    if (fp == NULL)	      {		perror ("popen");		exit (1);	      }	  }	else	  fp = stdout;	if (! strcmp(cmd->string,"configure terminal"))	  {	    cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_ZEBRA],					     line, fp);	    if (cmd_stat != CMD_WARNING)	      cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP],					       line, fp);	    if (cmd_stat != CMD_WARNING)	      cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIPNG], line, fp);	    if (cmd_stat != CMD_WARNING)	      cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF],					       line, fp);	    if (cmd_stat != CMD_WARNING)	      cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF6], line, fp);	    if (cmd_stat != CMD_WARNING)	      cmd_stat = vtysh_client_execute (&vtysh_client[VTYSH_INDEX_BGP],					       line, fp);	    if (cmd_stat)	      {                line = "end";                vline = cmd_make_strvec (line);                if (vline == NULL)		  {		    if (pager && vtysh_pager_name && fp)		      {			if (pclose (fp) == -1)			  {			    perror ("pclose");			    exit (1);			  }			fp = NULL;		      }		    return;		  }                ret = cmd_execute_command (vline, vty, &cmd);                cmd_free_strvec (vline);                if (ret != CMD_SUCCESS_DAEMON)                  break;	      }	    else	      if (cmd->func)		{		  (*cmd->func) (cmd, vty, 0, NULL);		  break;                }	  }	if (cmd->daemon & VTYSH_ZEBRA)	  if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_ZEBRA], line, fp)	      != CMD_SUCCESS)	    break;	if (cmd->daemon & VTYSH_RIPD)	  if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP], line, fp)	      != CMD_SUCCESS)	    break;	if (cmd->daemon & VTYSH_RIPNGD)	  if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIPNG], line, fp)	      != CMD_SUCCESS)	    break;	if (cmd->daemon & VTYSH_OSPFD)	  if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF], line, fp)	      != CMD_SUCCESS)	    break;	if (cmd->daemon & VTYSH_OSPF6D)	  if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF6], line, fp)	      != CMD_SUCCESS)	    break;	if (cmd->daemon & VTYSH_BGPD)	  if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_BGP], line, fp)	      != CMD_SUCCESS)	    break;	if (cmd->func)	  (*cmd->func) (cmd, vty, 0, NULL);      }    }  if (pager && vtysh_pager_name && fp)    {      if (pclose (fp) == -1)	{	  perror ("pclose");	  exit (1);	}      fp = NULL;    }}voidvtysh_execute_no_pager (char *line){  vtysh_execute_func (line, 0);}voidvtysh_execute (char *line){  vtysh_execute_func (line, 1);}/* Configration make from file. */intvtysh_config_from_file (struct vty *vty, FILE *fp){  int ret;  vector vline;  struct cmd_element *cmd;  while (fgets (vty->buf, VTY_BUFSIZ, fp))    {      if (vty->buf[0] == '!' || vty->buf[1] == '#')	continue;      vline = cmd_make_strvec (vty->buf);      /* In case of comment line */      if (vline == NULL)	continue;      /* Execute configuration command : this is strict match */      ret = cmd_execute_command_strict (vline, vty, &cmd);      /* Try again with setting node to CONFIG_NODE */      if (ret != CMD_SUCCESS 	  && ret != CMD_SUCCESS_DAEMON	  && ret != CMD_WARNING)	{	  if (vty->node == KEYCHAIN_KEY_NODE)	    {	      vty->node = KEYCHAIN_NODE;	      vtysh_exit_ripd_only ();	      ret = cmd_execute_command_strict (vline, vty, &cmd);	      if (ret != CMD_SUCCESS 		  && ret != CMD_SUCCESS_DAEMON 		  && ret != CMD_WARNING)		{		  vtysh_exit_ripd_only ();		  vty->node = CONFIG_NODE;		  ret = cmd_execute_command_strict (vline, vty, &cmd);		}	    }	  else	    {	      vtysh_execute ("end");	      vtysh_execute ("configure terminal");	      vty->node = CONFIG_NODE;	      ret = cmd_execute_command_strict (vline, vty, &cmd);	    }	}	        cmd_free_strvec (vline);      switch (ret)	{	case CMD_WARNING:	  if (vty->type == VTY_FILE)	    printf ("Warning...\n");	  break;	case CMD_ERR_AMBIGUOUS:	  printf ("%% Ambiguous command.\n");	  break;	case CMD_ERR_NO_MATCH:	  printf ("%% Unknown command: %s", vty->buf);	  break;	case CMD_ERR_INCOMPLETE:	  printf ("%% Command incomplete.\n");	  break;	case CMD_SUCCESS_DAEMON:	  {	    if (cmd->daemon & VTYSH_ZEBRA)	      if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_ZEBRA],					vty->buf, stdout) != CMD_SUCCESS)		break;	    if (cmd->daemon & VTYSH_RIPD)	      if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIP],					vty->buf, stdout) != CMD_SUCCESS)		break;	    if (cmd->daemon & VTYSH_RIPNGD)	      if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_RIPNG],					vty->buf, stdout) != CMD_SUCCESS)		break;	    if (cmd->daemon & VTYSH_OSPFD)	      if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF],					vty->buf, stdout) != CMD_SUCCESS)		break;	    if (cmd->daemon & VTYSH_OSPF6D)	      if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_OSPF6],					vty->buf, stdout) != CMD_SUCCESS)		break;	    if (cmd->daemon & VTYSH_BGPD)	      if (vtysh_client_execute (&vtysh_client[VTYSH_INDEX_BGP],					vty->buf, stdout) != CMD_SUCCESS)		break;	    if (cmd->func)	      (*cmd->func) (cmd, vty, 0, NULL);	  }	}    }  return CMD_SUCCESS;}/* We don't care about the point of the cursor when '?' is typed. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -