I don't understand the rework of the Makefile.am, nor do I understand the
move of 'struct vtysh_client' from vtysh.c to vtysh.h.  Why also the
exposure of vtysh_client_execute?  Am I missreading the code?  There is
no-one calling vtysh_client_execute outside of vtysh.c.

thanks!

donald

On Sun, Sep 27, 2015 at 5:49 AM, Gautam Kumar <[email protected]> wrote:

> ---
>  vtysh/Makefile.am  |   6 +-
>  vtysh/vtysh.c      | 207
> +++++++++++++++++++++++++----------------------------
>  vtysh/vtysh.h      |  14 ++++
>  vtysh/vtysh_main.c |   4 +-
>  4 files changed, 115 insertions(+), 116 deletions(-)
>
> diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am
> index d347735..9d5f8d3 100644
> --- a/vtysh/Makefile.am
> +++ b/vtysh/Makefile.am
> @@ -8,12 +8,14 @@ LIBS = @LIBS@ @CURSES@ @LIBPAM@
>  AM_CFLAGS = $(WERROR)
>
>  bin_PROGRAMS = vtysh
> +noinst_LIBRARIES = libvtysh.a
>
> -vtysh_SOURCES = vtysh_main.c vtysh.c vtysh_user.c vtysh_config.c
> +libvtysh_a_SOURCES = vtysh.c vtysh_user.c vtysh_config.c
> +vtysh_SOURCES = vtysh_main.c
>  nodist_vtysh_SOURCES = vtysh_cmd.c
>  CLEANFILES = vtysh_cmd.c
>  noinst_HEADERS = vtysh.h vtysh_user.h
> -vtysh_LDADD = ../lib/libzebra.la @LIBCAP@ @LIBREADLINE@
> +vtysh_LDADD = libvtysh.a ../lib/libzebra.la @LIBCAP@ @LIBREADLINE@
>
>  examplesdir = $(exampledir)
>  dist_examples_DATA = vtysh.conf.sample
> diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
> index 04ac550..0e33dea 100644
> --- a/vtysh/vtysh.c
> +++ b/vtysh/vtysh.c
> @@ -44,13 +44,7 @@ struct vty *vty;
>  char *vtysh_pager_name = NULL;
>
>  /* VTY shell client structure. */
> -struct vtysh_client
> -{
> -  int fd;
> -  const char *name;
> -  int flag;
> -  const char *path;
> -} vtysh_client[] =
> +struct vtysh_client vtysh_client[] =
>  {
>    { .fd = -1, .name = "zebra", .flag = VTYSH_ZEBRA, .path =
> ZEBRA_VTYSH_PATH},
>    { .fd = -1, .name = "ripd", .flag = VTYSH_RIPD, .path = RIP_VTYSH_PATH},
> @@ -62,6 +56,11 @@ struct vtysh_client
>    { .fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .path = PIM_VTYSH_PATH},
>  };
>
> +/* Flag for indicate executing child command. */
> +int execute_flag = 0;
> +
> +/* To store the vtysh buffer size */
> +int vtysh_buf_sz;
>
>  /* We need direct access to ripd to implement vtysh_exit_ripd_only. */
>  static struct vtysh_client *ripd_client = NULL;
> @@ -87,9 +86,9 @@ vclient_close (struct vtysh_client *vclient)
>
>  /* Following filled with debug code to trace a problematic condition
>   * under load - it SHOULD handle it. */
> -#define ERR_WHERE_STRING "vtysh(): vtysh_client_config(): "
> -static int
> -vtysh_client_config (struct vtysh_client *vclient, char *line)
> +#define ERR_WHERE_STRING "vtysh(): vtysh_client_execute(): "
> +int
> +vtysh_client_execute (struct vtysh_client *vclient, char *line, FILE *fp)
>  {
>    int ret;
>    char *buf;
> @@ -100,6 +99,7 @@ vtysh_client_config (struct vtysh_client *vclient, char
> *line)
>    int nbytes;
>    int i;
>    int readln;
> +  int numnulls = 0;
>
>    if (vclient->fd < 0)
>      return CMD_SUCCESS;
> @@ -112,7 +112,7 @@ vtysh_client_config (struct vtysh_client *vclient,
> char *line)
>      }
>
>    /* Allow enough room for buffer to read more than a few pages from
> socket. */
> -  bufsz = 5 * getpagesize() + 1;
> +  bufsz = vtysh_buf_sz;
>    buf = XMALLOC(MTYPE_TMP, bufsz);
>    memset(buf, 0, bufsz);
>    pbuf = buf;
> @@ -145,112 +145,90 @@ vtysh_client_config (struct vtysh_client *vclient,
> char *line)
>           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);
> +      else
> +        {
> +           /* If we have already seen 3 nulls, then current byte is ret
> code */
> +           if ((numnulls == 3) && (nbytes == 1))
> +             {
> +                ret = pbuf[0];
> +                break;
> +             }
> +           pbuf[nbytes] = '\0';
> +           /* If the config needs to be written in file or stdout */
> +           if (fp)
> +           {
> +             fputs(pbuf, fp);
> +             fflush (fp);
> +           }
> +
> +           /* At max look last four bytes */
> +           if (nbytes >= 4)
> +           {
> +             i = nbytes - 4;
> +             numnulls = 0;
> +           }
> +           else
> +             i = 0;
> +
> +           /* Count the numnulls */
> +           while (i < nbytes && numnulls <3)
> +           {
> +             if (pbuf[i++] == '\0')
> +                numnulls++;
> +             else
> +                numnulls = 0;
> +           }
> +           /* We might have seen 3 consecutive nulls so store the ret
> code before updating pbuf*/
> +           ret = pbuf[nbytes-1];
> +           pbuf += nbytes;
> +
> +
> +           /* See if a line exists in buffer, if so parse and consume it,
> and
> +            * reset read position. If 3 nulls has been encountered
> consume the buffer before
> +            * next read.
> +            */
> +           if (((eoln = strrchr(buf, '\n')) == NULL) && (numnulls<3))
> +             continue;
> +
> +           if (eoln >= ((buf + bufsz) - 1))
> +           {
> +              fprintf (stderr, ERR_WHERE_STRING \
> +                   "warning - eoln beyond buffer end.\n");
> +           }
> +
> +           /* If the config needs parsing, consume it */
> +           if(!fp)
> +             vtysh_config_parse(buf);
> +
> +           eoln++;
> +           left = (size_t)(buf + bufsz - eoln);
> +           /*
> +            * This check is required since when a config line split
> between two consecutive reads,
> +            * then buf will have first half of config line and current
> read will bring rest of the
> +            * line. So in this case eoln will be 1 here, hence
> calculation of left will be wrong.
> +            * In this case we don't need to do memmove, because we have
> already seen 3 nulls.
> +            */
> +           if(left < bufsz)
> +             memmove(buf, eoln, left);
> +
> +           buf[bufsz-1] = '\0';
> +           pbuf = buf + strlen(buf);
> +           /* got 3 or more trailing NULs? */
> +           if ((numnulls >=3) && (i < nbytes))
> +           {
> +              break;
> +           }
> +        }
>      }
>
>    /* Parse anything left in the buffer. */
> -
> -  vtysh_config_parse (buf);
> +  if(!fp)
> +    vtysh_config_parse (buf);
>
>    XFREE(MTYPE_TMP, buf);
>    return ret;
>  }
>
> -static int
> -vtysh_client_execute (struct vtysh_client *vclient, const char *line,
> FILE *fp)
> -{
> -  int ret;
> -  char buf[1001];
> -  int nbytes;
> -  int i;
> -  int numnulls = 0;
> -
> -  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)
> -       {
> -         if ((numnulls == 3) && (nbytes == 1))
> -           return buf[0];
> -
> -         buf[nbytes] = '\0';
> -         fputs (buf, fp);
> -         fflush (fp);
> -
> -         /* check for trailling \0\0\0<ret code>,
> -          * even if split across reads
> -          * (see lib/vty.c::vtysh_read)
> -          */
> -          if (nbytes >= 4)
> -            {
> -              i = nbytes-4;
> -              numnulls = 0;
> -            }
> -          else
> -            i = 0;
> -
> -          while (i < nbytes && numnulls < 3)
> -            {
> -              if (buf[i++] == '\0')
> -                numnulls++;
> -              else
> -                numnulls = 0;
> -            }
> -
> -          /* got 3 or more trailing NULs? */
> -          if ((numnulls >= 3) && (i < nbytes))
> -            return (buf[nbytes-1]);
> -       }
> -    }
> -}
> -
>  static void
>  vtysh_exit_ripd_only (void)
>  {
> @@ -1739,7 +1717,7 @@ DEFUN (vtysh_write_terminal,
>    vty_out (vty, "!%s", VTY_NEWLINE);
>
>    for (i = 0; i < array_size(vtysh_client); i++)
> -    vtysh_client_config (&vtysh_client[i], line);
> +    vtysh_client_execute (&vtysh_client[i], line, NULL);
>
>    /* Integrate vtysh specific configuration. */
>    vtysh_config_write ();
> @@ -1812,7 +1790,7 @@ write_config_integrated(void)
>      }
>
>    for (i = 0; i < array_size(vtysh_client); i++)
> -    vtysh_client_config (&vtysh_client[i], line);
> +    vtysh_client_execute (&vtysh_client[i], line, NULL);
>
>    vtysh_config_dump (fp);
>
> @@ -2485,3 +2463,10 @@ vtysh_init_vty (void)
>    install_element (CONFIG_NODE, &no_vtysh_enable_password_cmd);
>
>  }
> +
> +void
> +vty_buf_sz_init(void)
> +{
> + /* Allow enough room for buffer to read more than a few pages from
> socket. */
> +  vtysh_buf_sz =  5 * getpagesize() + 1;;
> +}
> diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
> index 1681a71..b712ca5 100644
> --- a/vtysh/vtysh.h
> +++ b/vtysh/vtysh.h
> @@ -38,6 +38,15 @@
>  /* vtysh local configuration file. */
>  #define VTYSH_DEFAULT_CONFIG "vtysh.conf"
>
> +/* VTY shell client structure. */
> +struct vtysh_client
> +{
> +  int fd;
> +  const char *name;
> +  int flag;
> +  const char *path;
> +};
> +
>  void vtysh_init_vty (void);
>  void vtysh_init_cmd (void);
>  extern int vtysh_connect_all (const char *optional_daemon_name);
> @@ -46,6 +55,7 @@ void vtysh_user_init (void);
>
>  int vtysh_execute (const char *);
>  int vtysh_execute_no_pager (const char *);
> +int vtysh_client_execute (struct vtysh_client *vclient, const char *line,
> FILE *fp);
>
>  char *vtysh_prompt (void);
>
> @@ -63,9 +73,13 @@ void vtysh_config_init (void);
>
>  void vtysh_pager_init (void);
>
> +void vty_buf_sz_init(void);
> +
>  /* Child process execution flag. */
>  extern int execute_flag;
>
>  extern struct vty *vty;
>
> +extern int vtysh_buf_sz;
> +
>  #endif /* VTYSH_H */
> diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
> index aa7d021..df790c6 100644
> --- a/vtysh/vtysh_main.c
> +++ b/vtysh/vtysh_main.c
> @@ -44,9 +44,6 @@ char *progname;
>  char config_default[] = SYSCONFDIR VTYSH_DEFAULT_CONFIG;
>  char history_file[MAXPATHLEN];
>
> -/* Flag for indicate executing child command. */
> -int execute_flag = 0;
> -
>  /* For sigsetjmp() & siglongjmp(). */
>  static sigjmp_buf jmpbuf;
>
> @@ -289,6 +286,7 @@ main (int argc, char **argv, char **env)
>    vtysh_signal_init ();
>
>    /* Make vty structure and register commands. */
> +  vty_buf_sz_init ();
>    vtysh_init_vty ();
>    vtysh_init_cmd ();
>    vtysh_user_init ();
> --
> 2.5.3
>
>
> _______________________________________________
> Quagga-dev mailing list
> [email protected]
> https://lists.quagga.net/mailman/listinfo/quagga-dev
>
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to