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

📄 vty.c

📁 大名鼎鼎的路由器源码。程序分ZEBRA、OSPFRIP等3个包。程序框架采用一个路由协议一个进程的方式
💻 C
📖 第 1 页 / 共 4 页
字号:
  vty_backward_char (vty);  vty_delete_char (vty);}/* Kill rest of line from current point. */static voidvty_kill_line (struct vty *vty){  int i;  int size;  size = vty->length - vty->cp;    if (size == 0)    return;  for (i = 0; i < size; i++)    vty_write (vty, &telnet_space_char, 1);  for (i = 0; i < size; i++)    vty_write (vty, &telnet_backward_char, 1);  memset (&vty->buf[vty->cp], 0, size);  vty->length = vty->cp;}/* Kill line from the beginning. */static voidvty_kill_line_from_beginning (struct vty *vty){  vty_beginning_of_line (vty);  vty_kill_line (vty);}/* Delete a word before the point. */static voidvty_forward_kill_word (struct vty *vty){  while (vty->cp != vty->length && vty->buf[vty->cp] == ' ')    vty_delete_char (vty);  while (vty->cp != vty->length && vty->buf[vty->cp] != ' ')    vty_delete_char (vty);}/* Delete a word before the point. */static voidvty_backward_kill_word (struct vty *vty){  while (vty->cp > 0 && vty->buf[vty->cp - 1] == ' ')    vty_delete_backward_char (vty);  while (vty->cp > 0 && vty->buf[vty->cp - 1] != ' ')    vty_delete_backward_char (vty);}/* Transpose chars before or at the point. */static voidvty_transpose_chars (struct vty *vty){  char c1, c2;  /* If length is short or point is near by the beginning of line then     return. */  if (vty->length < 2 || vty->cp < 1)    return;  /* In case of point is located at the end of the line. */  if (vty->cp == vty->length)    {      c1 = vty->buf[vty->cp - 1];      c2 = vty->buf[vty->cp - 2];      vty_backward_char (vty);      vty_backward_char (vty);      vty_self_insert_overwrite (vty, c1);      vty_self_insert_overwrite (vty, c2);    }  else    {      c1 = vty->buf[vty->cp];      c2 = vty->buf[vty->cp - 1];      vty_backward_char (vty);      vty_self_insert_overwrite (vty, c1);      vty_self_insert_overwrite (vty, c2);    }}/* Do completion at vty interface. */static voidvty_complete_command (struct vty *vty){  int i;  int ret;  char **matched = NULL;  vector vline;  if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)    return;  vline = cmd_make_strvec (vty->buf);  if (vline == NULL)    return;  /* In case of 'help \t'. */  if (isspace ((int) vty->buf[vty->length - 1]))    vector_set (vline, '\0');  matched = cmd_complete_command (vline, vty, &ret);    cmd_free_strvec (vline);  vty_out (vty, "%s", VTY_NEWLINE);  switch (ret)    {    case CMD_ERR_AMBIGUOUS:      vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);      vty_prompt (vty);      vty_redraw_line (vty);      break;    case CMD_ERR_NO_MATCH:      /* vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE); */      vty_prompt (vty);      vty_redraw_line (vty);      break;    case CMD_COMPLETE_FULL_MATCH:      vty_prompt (vty);      vty_redraw_line (vty);      vty_backward_pure_word (vty);      vty_insert_word_overwrite (vty, matched[0]);      vty_self_insert (vty, ' ');      XFREE (MTYPE_TMP, 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]);      vector_only_index_free (matched);      return;      break;    case CMD_COMPLETE_LIST_MATCH:      for (i = 0; matched[i] != NULL; i++)	{	  if (i != 0 && ((i % 6) == 0))	    vty_out (vty, "%s", VTY_NEWLINE);	  vty_out (vty, "%-10s ", matched[i]);	  XFREE (MTYPE_TMP, matched[i]);	}      vty_out (vty, "%s", VTY_NEWLINE);      vty_prompt (vty);      vty_redraw_line (vty);      break;    case CMD_ERR_NOTHING_TODO:      vty_prompt (vty);      vty_redraw_line (vty);      break;    default:      break;    }  if (matched)    vector_only_index_free (matched);}voidvty_describe_fold (struct vty *vty, int cmd_width,		   int desc_width, struct desc *desc){  char *buf, *cmd, *p;  int pos;  cmd = desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd;  if (desc_width <= 0)    {      vty_out (vty, "  %-*s  %s%s", cmd_width, cmd, desc->str, VTY_NEWLINE);      return;    }  buf = XCALLOC (MTYPE_TMP, strlen (desc->str) + 1);  for (p = desc->str; strlen (p) > desc_width; p += pos + 1)    {      for (pos = desc_width; pos > 0; pos--)	if (*(p + pos) == ' ')	  break;      if (pos == 0)	break;      strncpy (buf, p, pos);      buf[pos] = '\0';      vty_out (vty, "  %-*s  %s%s", cmd_width, cmd, buf, VTY_NEWLINE);      cmd = "";    }  vty_out (vty, "  %-*s  %s%s", cmd_width, cmd, p, VTY_NEWLINE);  XFREE (MTYPE_TMP, buf);}/* Describe matched command function. */static voidvty_describe_command (struct vty *vty){  int ret;  vector vline;  vector describe;  int i, width, desc_width;  struct desc *desc, *desc_cr = NULL;  vline = cmd_make_strvec (vty->buf);  /* In case of '> ?'. */  if (vline == NULL)    {      vline = vector_init (1);      vector_set (vline, '\0');    }  else     if (isspace ((int) vty->buf[vty->length - 1]))      vector_set (vline, '\0');  describe = cmd_describe_command (vline, vty, &ret);  vty_out (vty, "%s", VTY_NEWLINE);  /* Ambiguous error. */  switch (ret)    {    case CMD_ERR_AMBIGUOUS:      cmd_free_strvec (vline);      vty_out (vty, "%% Ambiguous command.%s", VTY_NEWLINE);      vty_prompt (vty);      vty_redraw_line (vty);      return;      break;    case CMD_ERR_NO_MATCH:      cmd_free_strvec (vline);      vty_out (vty, "%% There is no matched command.%s", VTY_NEWLINE);      vty_prompt (vty);      vty_redraw_line (vty);      return;      break;    }    /* Get width of command string. */  width = 0;  for (i = 0; i < vector_max (describe); i++)    if ((desc = vector_slot (describe, i)) != NULL)      {	int len;	if (desc->cmd[0] == '\0')	  continue;	len = strlen (desc->cmd);	if (desc->cmd[0] == '.')	  len--;	if (width < len)	  width = len;      }  /* Get width of description string. */  desc_width = vty->width - (width + 6);  /* Print out description. */  for (i = 0; i < vector_max (describe); i++)    if ((desc = vector_slot (describe, i)) != NULL)      {	if (desc->cmd[0] == '\0')	  continue;		if (strcmp (desc->cmd, "<cr>") == 0)	  {	    desc_cr = desc;	    continue;	  }	if (!desc->str)	  vty_out (vty, "  %-s%s",		   desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,		   VTY_NEWLINE);	else if (desc_width >= strlen (desc->str))	  vty_out (vty, "  %-*s  %s%s", width,		   desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,		   desc->str, VTY_NEWLINE);	else	  vty_describe_fold (vty, width, desc_width, desc);#if 0	vty_out (vty, "  %-*s %s%s", width		 desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,		 desc->str ? desc->str : "", VTY_NEWLINE);#endif /* 0 */      }  if ((desc = desc_cr))    {      if (!desc->str)	vty_out (vty, "  %-s%s",		 desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,		 VTY_NEWLINE);      else if (desc_width >= strlen (desc->str))	vty_out (vty, "  %-*s  %s%s", width,		 desc->cmd[0] == '.' ? desc->cmd + 1 : desc->cmd,		 desc->str, VTY_NEWLINE);      else	vty_describe_fold (vty, width, desc_width, desc);    }  cmd_free_strvec (vline);  vector_free (describe);  vty_prompt (vty);  vty_redraw_line (vty);}voidvty_clear_buf (struct vty *vty){  memset (vty->buf, 0, vty->max);}/* ^C stop current input and do not add command line to the history. */static voidvty_stop_input (struct vty *vty){  vty->cp = vty->length = 0;  vty_clear_buf (vty);  vty_out (vty, "%s", VTY_NEWLINE);  switch (vty->node)    {    case VIEW_NODE:    case ENABLE_NODE:      /* Nothing to do. */      break;    case CONFIG_NODE:    case INTERFACE_NODE:    case ZEBRA_NODE:    case RIP_NODE:    case RIPNG_NODE:    case BGP_NODE:    case RMAP_NODE:    case OSPF_NODE:    case OSPF6_NODE:    case KEYCHAIN_NODE:    case KEYCHAIN_KEY_NODE:    case MASC_NODE:    case VTY_NODE:      vty_config_unlock (vty);      vty->node = ENABLE_NODE;      break;    default:      /* Unknown node, we have to ignore it. */      break;    }  vty_prompt (vty);  /* Set history pointer to the latest one. */  vty->hp = vty->hindex;}/* Add current command line to the history buffer. */static voidvty_hist_add (struct vty *vty){  int index;  if (vty->length == 0)    return;  index = vty->hindex ? vty->hindex - 1 : VTY_MAXHIST - 1;  /* Ignore the same string as previous one. */  if (vty->hist[index])    if (strcmp (vty->buf, vty->hist[index]) == 0)      {	vty->hp = vty->hindex;	return;      }  /* Insert history entry. */  if (vty->hist[vty->hindex])    XFREE (MTYPE_VTY_HIST, vty->hist[vty->hindex]);  vty->hist[vty->hindex] = XSTRDUP (MTYPE_VTY_HIST, vty->buf);  /* History index rotation. */  vty->hindex++;  if (vty->hindex == VTY_MAXHIST)    vty->hindex = 0;  vty->hp = vty->hindex;}/* #define TELNET_OPTION_DEBUG *//* Get telnet window size. */static intvty_telnet_option (struct vty *vty, unsigned char *buf, int nbytes){#ifdef TELNET_OPTION_DEBUG  int i;  for (i = 0; i < nbytes; i++)    {      switch (buf[i])	{	case IAC:	  vty_out (vty, "IAC ");	  break;	case WILL:	  vty_out (vty, "WILL ");	  break;	case WONT:	  vty_out (vty, "WONT ");	  break;	case DO:	  vty_out (vty, "DO ");	  break;	case DONT:	  vty_out (vty, "DONT ");	  break;	case SB:	  vty_out (vty, "SB ");	  break;	case SE:	  vty_out (vty, "SE ");	  break;	case TELOPT_ECHO:	  vty_out (vty, "TELOPT_ECHO %s", VTY_NEWLINE);	  break;	case TELOPT_SGA:	  vty_out (vty, "TELOPT_SGA %s", VTY_NEWLINE);	  break;	case TELOPT_NAWS:	  vty_out (vty, "TELOPT_NAWS %s", VTY_NEWLINE);	  break;	default:	  vty_out (vty, "%x ", buf[i]);	  break;	}    }  vty_out (vty, "%s", VTY_NEWLINE);#endif /* TELNET_OPTION_DEBUG */  switch (buf[0])    {    case SB:      buffer_reset(vty->sb_buffer);      vty->iac_sb_in_progress = 1;      return 0;      break;    case SE:       {	char *buffer;	int length;	if (!vty->iac_sb_in_progress)	  return 0;	buffer = (char *)vty->sb_buffer->head->data;	length = vty->sb_buffer->length;	if (buffer == NULL)	  return 0;	if (buffer[0] == '\0')	  {	    vty->iac_sb_in_progress = 0;	    return 0;	  }	switch (buffer[0])	  {	  case TELOPT_NAWS:	    if (length < 5)	      break;	    vty->width = buffer[2];	    vty->height = vty->lines >= 0 ? vty->lines : buffer[4];	    break;	  }	vty->iac_sb_in_progress = 0;	return 0;	break;      }    default:      break;    }  return 1;}/* Execute current command line. */static intvty_execute (struct vty *vty){  int ret;  ret = CMD_SUCCESS;  switch (vty->node)    {    case AUTH_NODE:    case AUTH_ENABLE_NODE:      vty_auth (vty, vty->buf);      break;    default:      ret = vty_command (vty, vty->buf);      if (vty->type == VTY_TERM)	vty_hist_add (vty);      break;    }  /* Clear command line buffer. */  vty->cp = vty->length = 0;  vty_clear_buf (vty);  if (vty->status != VTY_CLOSE       && vty->status != VTY_START      && vty->status != VTY_CONTINUE)    vty_prompt (vty);  return ret;}#define CONTROL(X)  ((X) - '@')#define VTY_NORMAL     0#define VTY_PRE_ESCAPE 1#define VTY_ESCAPE     2/* Escape character command map. */static voidvty_escape_map (unsigned char c, struct vty *vty){  switch (c)    {    case ('A'):      vty_previous_line (vty);      break;    case ('B'):      vty_next_line (vty);      break;    case ('C'):      vty_forward_char (vty);      break;    case ('D'):      vty_backward_char (vty);      break;    default:      break;    }  /* Go back to normal mode. */  vty->escape = VTY_NORMAL;}/* Quit print out to the buffer. */static voidvty_buffer_reset (struct vty *vty){  buffer_reset (vty->obuf);  vty_prompt (vty);  vty_redraw_line (vty);}/* Read data via vty socket. */static intvty_read (struct thread *thread){  int i;  int ret;  int nbytes;  unsigned char buf[VTY_READ_BUFSIZ];  int vty_sock = THREAD_FD (thread);  struct vty *vty = THREAD_ARG (thread);  vty->t_read = NULL;  /* Read raw data from socket */  nbytes = read (vty->fd, buf, VTY_READ_BUFSIZ);  if (nbytes <= 0)    vty->status = VTY_CLOSE;  for (i = 0; i < nbytes; i++)     {      if (buf[i] == IAC)	{	  if (!vty->iac)	    {	      vty->iac = 1;	      continue;	    }	  else	    {	      vty->iac = 0;	    }	}            if (vty->iac_sb_in_progress && !vty->iac)	{	  buffer_putc(vty->sb_buffer, buf[i]);	  continue;	}      if (vty->iac)	{	  /* In case of telnet command */	  ret = vty_telnet_option (vty, buf + i, nbytes - i);	  vty->iac = 0;	  i += ret;	  continue;	}      if (vty->status == VTY_MORE)	{	  switch (buf[i])	    {	    case CONTROL('C'):	    case 'q':	    case 'Q':	      if (vty->output_func)		(*vty->output_func) (vty, 1);	      vty_buffer_reset (vty);	      break;#if 0 /* More line does not work for "show ip bgp".  */	    case '\n':	    case '\r':	      vty->status = VTY_MORELINE;	      break;#endif	    default:	      if (vty->output_func)		(*vty->output_func) (vty, 0);	      break;	    }	  continue;	}      /* Escape character. */      if (vty->escape == VTY_ESCAPE)	{	  vty_escape_map (buf[i], vty);	  continue;	}      /* Pre-escape status. */      if (vty->escape == VTY_PRE_ESCAPE)	{	  switch (buf[i])	    {	    case '[':	      vty->escape = VTY_ESCAPE;	      break;	    case 'b':	      vty_backward_word (vty);	      vty->escape = VTY_NORMAL;	      break;	    case 'f':	      vty_forward_word (vty);	      vty->escape = VTY_NORMAL;	      break;	    case 'd':	      vty_forward_kill_word (vty);	      vty->escape = VTY_NORMAL;	      break;	    case CONTROL('H'):	    case 0x7f:	      vty_backward_kill_word (vty);	      vty->escape = VTY_NORMAL;	      break;	    default:	      vty->escape = VTY_NORMAL;	      break;	    }	  continue;	}      switch (buf[i])	{	case CONTROL('A'):	  vty_beginning_of_line (vty);	  break;	case CONTROL('B'):	  vty_backward_char (vty);	  break;	case CONTROL('C'):	  vty_stop_input (vty);	  break;	case CONTROL('D'):	  vty_delete_char (vty);	  break;	case CONTROL('E'):	  vty_end_of_line (vty);	  break;	case CONTROL('F'):	  vty_forward_char (vty);	  break;	case CONTROL('H'):	case 0x7f:	  vty_delete_backward_char (vty);

⌨️ 快捷键说明

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