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
