diff --git a/lib/command.c b/lib/command.c index 60c5f4e75b..6fe4ae2d8f 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1281,7 +1281,8 @@ int cmd_execute(struct vty *vty, const char *cmd, * as to why no command could be executed. */ int command_config_read_one_line(struct vty *vty, - const struct cmd_element **cmd, int use_daemon) + const struct cmd_element **cmd, + uint32_t line_num, int use_daemon) { vector vline; int saved_node; @@ -1322,8 +1323,16 @@ int command_config_read_one_line(struct vty *vty, } } - if (ret != CMD_SUCCESS && ret != CMD_WARNING) - memcpy(vty->error_buf, vty->buf, VTY_BUFSIZ); + if (ret != CMD_SUCCESS && ret != CMD_WARNING) { + struct vty_error *ve = XCALLOC(MTYPE_TMP, sizeof(*ve)); + + memcpy(ve->error_buf, vty->buf, VTY_BUFSIZ); + ve->line_num = line_num; + if (!vty->error) + vty->error = list_new(); + + listnode_add(vty->error, ve); + } cmd_free_strvec(vline); @@ -1337,10 +1346,9 @@ int config_from_file(struct vty *vty, FILE *fp, unsigned int *line_num) *line_num = 0; while (fgets(vty->buf, VTY_BUFSIZ, fp)) { - if (!error_ret) - ++(*line_num); + ++(*line_num); - ret = command_config_read_one_line(vty, NULL, 0); + ret = command_config_read_one_line(vty, NULL, *line_num, 0); if (ret != CMD_SUCCESS && ret != CMD_WARNING && ret != CMD_ERR_NOTHING_TODO) diff --git a/lib/command.h b/lib/command.h index 8e51641b88..fbff1e67f4 100644 --- a/lib/command.h +++ b/lib/command.h @@ -419,7 +419,7 @@ extern char **cmd_complete_command(vector, struct vty *, int *status); extern const char *cmd_prompt(enum node_type); extern int command_config_read_one_line(struct vty *vty, const struct cmd_element **, - int use_config_node); + uint32_t line_num, int use_config_node); extern int config_from_file(struct vty *, FILE *, unsigned int *line_num); extern enum node_type node_parent(enum node_type); /* diff --git a/lib/vty.c b/lib/vty.c index f812dd4279..a73cc23b97 100644 --- a/lib/vty.c +++ b/lib/vty.c @@ -1695,7 +1695,6 @@ struct vty *vty_new() new->lbuf = buffer_new(0); new->obuf = buffer_new(0); /* Use default buffer size. */ new->buf = XCALLOC(MTYPE_VTY, VTY_BUFSIZ); - new->error_buf = XCALLOC(MTYPE_VTY, VTY_BUFSIZ); new->max = VTY_BUFSIZ; return new; @@ -2278,6 +2277,13 @@ void vty_serv_sock(const char *addr, unsigned short port, const char *path) #endif /* VTYSH */ } +static void vty_error_delete(void *arg) +{ + struct vty_error *ve = arg; + + XFREE(MTYPE_TMP, ve); +} + /* Close vty interface. Warning: call this only from functions that will be careful not to access the vty afterwards (since it has now been freed). This is safest from top-level functions (called @@ -2329,8 +2335,10 @@ void vty_close(struct vty *vty) if (vty->buf) XFREE(MTYPE_VTY, vty->buf); - if (vty->error_buf) - XFREE(MTYPE_VTY, vty->error_buf); + if (vty->error) { + vty->error->del = vty_error_delete; + list_delete(&vty->error); + } /* Check configure. */ vty_config_unlock(vty); @@ -2368,6 +2376,8 @@ static void vty_read_file(FILE *confp) { int ret; struct vty *vty; + struct vty_error *ve; + struct listnode *node; unsigned int line_num = 0; vty = vty_new(); @@ -2417,11 +2427,13 @@ static void vty_read_file(FILE *confp) break; } - nl = strchr(vty->error_buf, '\n'); - if (nl) - *nl = '\0'; - flog_err(EC_LIB_VTY, "ERROR: %s on config line %u: %s", message, - line_num, vty->error_buf); + for (ALL_LIST_ELEMENTS_RO(vty->error, node, ve)) { + nl = strchr(ve->error_buf, '\n'); + if (nl) + *nl = '\0'; + flog_err(EC_LIB_VTY, "ERROR: %s on config line %u: %s", + message, ve->line_num, ve->error_buf); + } } vty_close(vty); diff --git a/lib/vty.h b/lib/vty.h index b55abf2204..efe91a568b 100644 --- a/lib/vty.h +++ b/lib/vty.h @@ -33,6 +33,11 @@ #define VTY_BUFSIZ 4096 #define VTY_MAXHIST 20 +struct vty_error { + char error_buf[VTY_BUFSIZ]; + uint32_t line_num; +}; + /* VTY struct. */ struct vty { /* File descripter of this vty. */ @@ -71,7 +76,7 @@ struct vty { char *buf; /* Command input error buffer */ - char *error_buf; + struct list *error; /* Command cursor point */ int cp; diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 6a92b90813..8ed11f1876 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -856,7 +856,7 @@ int vtysh_config_from_file(struct vty *vty, FILE *fp) while (fgets(vty->buf, VTY_BUFSIZ, fp)) { lineno++; - ret = command_config_read_one_line(vty, &cmd, 1); + ret = command_config_read_one_line(vty, &cmd, lineno, 1); switch (ret) { case CMD_WARNING: