Index: lib/command.c =================================================================== RCS file: /var/cvsroot/quagga/lib/command.c,v retrieving revision 1.51 diff -u -p -r1.51 command.c --- lib/command.c 26 Oct 2005 05:49:54 -0000 1.51 +++ lib/command.c 20 Nov 2005 01:43:08 -0000 @@ -21,6 +21,9 @@ along with GNU Zebra; see the file COPYI Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#pragma FINI "cmd_terminate" +#pragma fini (cmd_terminate) + #include @@ -167,7 +170,7 @@ argv_concat (const char **argv, int argc len += strlen(argv[i])+1; if (!len) return NULL; - p = str = XMALLOC(MTYPE_TMP, len); + p = str = XMALLOC (MTYPE_TMP, len); for (i = shift; i < argc; i++) { size_t arglen; @@ -342,7 +345,7 @@ cmd_desc_str (const char **string) } /* New string vector. */ -static vector +vector cmd_make_descvec (const char *string, const char *descstr) { int multiple = 0; @@ -362,8 +365,8 @@ cmd_make_descvec (const char *string, co return NULL; allvec = vector_init (VECTOR_MIN_SIZE); - - while (1) + + do { while (isspace ((int) *cp) && *cp != '\0') cp++; @@ -430,7 +433,7 @@ cmd_make_descvec (const char *string, co vector_set (allvec, strvec); } vector_set (strvec, desc); - } + } while (1); } /* Count mandantory string vector size. This is to determine inputed @@ -2283,36 +2286,31 @@ cmd_execute_command_strict (vector vline /* Configration make from file. */ int -config_from_file (struct vty *vty, FILE *fp) +config_from_file (struct vty *vty, vector vline) { int ret; - vector vline; - while (fgets (vty->buf, VTY_BUFSIZ, fp)) - { - vline = cmd_make_strvec (vty->buf); + /* Execute configuration command : this is strict match */ + ret = cmd_execute_command_strict (vline, vty, NULL); - /* In case of comment line */ - if (vline == NULL) - continue; - /* Execute configuration command : this is strict match */ + /* Try again with setting node to CONFIG_NODE */ + while (ret != CMD_SUCCESS && ret != CMD_WARNING + && ret != CMD_ERR_NOTHING_TODO && vty->node != CONFIG_NODE) + { + vty->node = node_parent(vty->node); ret = cmd_execute_command_strict (vline, vty, NULL); - - /* Try again with setting node to CONFIG_NODE */ - while (ret != CMD_SUCCESS && ret != CMD_WARNING - && ret != CMD_ERR_NOTHING_TODO && vty->node != CONFIG_NODE) - { - vty->node = node_parent(vty->node); - ret = cmd_execute_command_strict (vline, vty, NULL); - } - - cmd_free_strvec (vline); - - if (ret != CMD_SUCCESS && ret != CMD_WARNING - && ret != CMD_ERR_NOTHING_TODO) - return ret; } - return CMD_SUCCESS; + + switch (ret) + { + case CMD_SUCCESS: + case CMD_WARNING: + case CMD_ERR_NOTHING_TODO: + return CMD_SUCCESS; + break; + default: + return ret; + } } /* Configration from terminal */ @@ -2520,11 +2518,11 @@ DEFUN (config_write_file, { unsigned int i; int fd; + int ret = CMD_WARNING; struct cmd_node *node; char *config_file; char *config_file_tmp = NULL; char *config_file_sav = NULL; - int ret = CMD_WARNING; struct vty *file_vty; /* Check and see if we are operating under vtysh configuration */ @@ -2542,9 +2540,9 @@ DEFUN (config_write_file, XMALLOC (MTYPE_TMP, strlen (config_file) + strlen (CONF_BACKUP_EXT) + 1); strcpy (config_file_sav, config_file); strcat (config_file_sav, CONF_BACKUP_EXT); - - + config_file_tmp = XMALLOC (MTYPE_TMP, strlen (config_file) + 8); + sprintf (config_file_tmp, "%s.XXXXXX", config_file); /* Open file to configuration write. */ @@ -2579,7 +2577,7 @@ DEFUN (config_write_file, { vty_out (vty, "Can't unlink backup configuration file %s.%s", config_file_sav, VTY_NEWLINE); - goto finished; + goto finished; } if (link (config_file, config_file_sav) != 0) { @@ -3019,7 +3017,7 @@ DEFUN_HIDDEN (do_echo, vty_out (vty, "%s%s", ((message = argv_concat(argv, argc, 0)) ? message : ""), VTY_NEWLINE); if (message) - XFREE(MTYPE_TMP, message); + XFREE (MTYPE_TMP, message); return CMD_SUCCESS; } @@ -3038,7 +3036,7 @@ DEFUN (config_logmsg, zlog(NULL, level, ((message = argv_concat(argv, argc, 1)) ? message : "")); if (message) - XFREE(MTYPE_TMP, message); + XFREE (MTYPE_TMP, message); return CMD_SUCCESS; } @@ -3476,6 +3474,74 @@ install_default (enum node_type node) install_element (node, &show_running_config_cmd); } +void +cmd_descvec_free (vector descvec) +{ + unsigned int i; + struct desc *desc; + + for (i = 0; i < vector_active (descvec); i++) + if ( (desc = vector_slot (descvec, i)) != NULL) + { + XFREE (MTYPE_TMP, desc->cmd); + XFREE (MTYPE_STRVEC, desc->str); + desc->cmd = NULL; + desc->str = NULL; + XFREE (MTYPE_DESC, desc); + desc = NULL; + } + vector_free (descvec); + descvec = NULL; +} + +void +cmd_element_terminate (struct cmd_element *cmd_element) +{ + unsigned int i; + + if (!cmd_element->strvec) + return; + + for (i = 0; i < vector_active (cmd_element->strvec); i++) + if (vector_slot (cmd_element->strvec, i) != NULL) + cmd_descvec_free (vector_slot (cmd_element->strvec, i)); + + vector_free (cmd_element->strvec); + cmd_element->strvec = NULL; +} + +void +cmd_node_terminate (struct cmd_node *cnode) +{ + unsigned int i; + + if (!cnode->cmd_vector) + return; + + for (i = 0; i < vector_active (cnode->cmd_vector); i++) + if (vector_slot (cnode->cmd_vector, i) != NULL) + cmd_element_terminate (vector_slot (cnode->cmd_vector, i)); + + vector_free (cnode->cmd_vector); + cnode->cmd_vector = NULL; +} + +/* Free all cmdnode's and cmd_elements in the master cmdvec */ +__attribute__ ((destructor)) +void +cmd_terminate (void) +{ + unsigned int i; + + if (!cmdvec) + return; + + for (i = 0; i < vector_active (cmdvec); i++) + if (vector_slot (cmdvec, i) != NULL) + cmd_node_terminate (vector_slot (cmdvec, i)); + vector_free (cmdvec); +} + /* Initialize command interface. Install basic nodes and commands. */ void cmd_init (int terminal) Index: lib/command.h =================================================================== RCS file: /var/cvsroot/quagga/lib/command.h,v retrieving revision 1.21 diff -u -p -r1.21 command.h --- lib/command.h 3 Nov 2005 09:00:23 -0000 1.21 +++ lib/command.h 20 Nov 2005 01:43:08 -0000 @@ -334,7 +334,7 @@ extern void cmd_free_strvec (vector); extern vector cmd_describe_command (vector, struct vty *, int *status); extern char **cmd_complete_command (vector, struct vty *, int *status); extern const char *cmd_prompt (enum node_type); -extern int config_from_file (struct vty *, FILE *); +extern int config_from_file (struct vty *, vector vline); extern enum node_type node_parent (enum node_type); extern int cmd_execute_command (vector, struct vty *, struct cmd_element **, int); extern int cmd_execute_command_strict (vector, struct vty *, struct cmd_element **);