summaryrefslogtreecommitdiffstats
path: root/vtysh
diff options
context:
space:
mode:
authorChris Hall <chris.hall@highwayman.com>2012-06-08 15:01:11 +0100
committerChris Hall <chris.hall@highwayman.com>2012-06-08 15:01:11 +0100
commit58b4a3411f12d3ef34ef52ab197729887074f321 (patch)
treee456eec427d977e2e723039b83d614d13edcf983 /vtysh
parent12d01b8b9c68f5dc72f2accdb29a760feb31420a (diff)
downloadquagga-ex25b.tar.bz2
quagga-ex25b.tar.xz
Fix bugs in vty error handlingex25b
Advance version to 0.99.20ex25b. Bug fixes: * when closing a vty, if close() returned an error, the vtys would fall into a loop trying to recover. This was found on FreeBSD, which will return ECONNRESET on close(), which is not standard POSIX behaviour. * when closing a vty in response to EPIPE or ECONNRESET, managed to leave the vty mutex locked. This stopped the Routing Engine *dead* on the next CLI command that required the Routing Engine. SIGTERM/SIGINT would not stop bgpd -- a SIGKILL would be required. Other changes: * toned down the error reporting of EPIPE in the vty -- so no longer looks like an error... ...closing a vty by "exit" command is logged as "closed" ...closing a vty in response to the client closing their end of the connection is logged as "terminated: terminal closed", and no longer logs an EPIPE error. * changed error reporting on close() and shutdown() for vty, so that nothing is logged if an i/o error has already logged... ...so that redundant error messages are suppressed. * applied slightly finer jittering to bgpd timers. * work in progress on new vtysh.
Diffstat (limited to 'vtysh')
-rw-r--r--vtysh/vtysh_config.c650
1 files changed, 449 insertions, 201 deletions
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index e7afc49d..c6be8ea3 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -391,6 +391,7 @@ typedef config_item_list_t* config_item_list ;
typedef enum /* types of config_item */
{
it_dummy = 0,
+
it_node, /* Node is a list of line/group */
it_line,
it_group,
@@ -500,6 +501,7 @@ struct config_collection
config_fragment fragment_list ;
qstring_t temp ; /* used when creating fragments and names */
+ qstring_t comment ; /* used when creating comment names */
} ;
/*------------------------------------------------------------------------------
@@ -524,10 +526,11 @@ static void vtysh_config_parse_group_end(config_collection collection) ;
static void vtysh_config_node_find(config_collection collection) ;
static bool vtysh_config_item_insert(config_collection collection,
config_item_type_t it) ;
-static bool vtysh_config_try_merge(config_collection collection,
- config_item parent, config_name name) ;
-static config_name vtysh_config_get_name(config_collection collection,
- config_item parent, config_item_type_t type) ;
+static config_item vtysh_config_try_merge(config_collection collection,
+ config_item_list list) ;
+static config_name vtysh_config_get_name(config_collection collection) ;
+static config_name vtysh_config_get_comment_name(config_collection collection,
+ config_item comment) ;
static symbol_cmp_func vtysh_config_match_cmp ;
static symbol_free_func vtysh_config_match_free ;
@@ -573,6 +576,7 @@ vtysh_config_collection_new(void)
* lump_list -- NULLs -- empty
* fragment_list -- NULL -- empty
* temp -- empty qstring (embedded)
+ * comment -- empty qstring (embedded)
*/
confirm(NULL_NODE == 0) ;
confirm(ELSTRING_INIT_ALL_ZEROS) ;
@@ -936,7 +940,7 @@ vtysh_config_item_insert(config_collection collection, config_item_type_t it)
{
config_item parent ;
config_name name ;
- bool merged ;
+ config_item merged ;
bool co_opted ;
assert((it == it_line) || (it == it_group) || (it == it_dummy)) ;
@@ -997,8 +1001,8 @@ vtysh_config_item_insert(config_collection collection, config_item_type_t it)
ddl_append(parent->list, collection->last_item, siblings) ;
} ;
- /* We now have a new item, attached to the parent. For that item we have
- * the following set:
+ /* We now have a new collection->last_item, attached to its parent. For that
+ * item we have the following set:
*
* parent
* ordinal
@@ -1009,10 +1013,10 @@ vtysh_config_item_insert(config_collection collection, config_item_type_t it)
*
* And everything else is clear.
*
- * Now need to establish, and register, the name of the item.
+ * Now need to establish, and register, the name of the item -- based on the
+ * parsed stuff still sitting in the collection.
*/
- collection->last_item->name =
- name = vtysh_config_get_name(collection, parent, it) ;
+ name = vtysh_config_get_name(collection) ;
/* If the name is unique, then cannot merge.
*
@@ -1022,14 +1026,16 @@ vtysh_config_item_insert(config_collection collection, config_item_type_t it)
* If does not merge, we add the new item to the owners of the name.
*/
if (name->list == NULL)
- merged = false ;
+ merged = NULL ;
else
- merged = vtysh_config_try_merge(collection, parent, name) ;
+ merged = vtysh_config_try_merge(collection, &parent->list) ;
- if (!merged)
- ssl_append(name->list, collection->last_item, also) ;
+ if (merged == NULL)
+ ssl_push(name->list, collection->last_item, also) ;
+ else
+ collection->last_item = merged ;
- return merged ;
+ return merged != NULL ;
} ;
/*------------------------------------------------------------------------------
@@ -1205,11 +1211,14 @@ vtysh_config_node_find(config_collection collection)
* separator "following" it. This means that multiple blank lines at the start
* of a block of comments will be squashed together, and squashed with blank
* '!' and/or '#' comment lines.
+ *
+ * NB: does not name the comment item. That is done when the it_dummy item
+ * is merged with a real item.
*/
static void
vtysh_config_parse_comment(config_collection collection)
{
- config_item new_item, parent ;
+ config_item new_item, comment_parent ;
/* If the last item was it_comment, then need to create new item
* and attach it to the comment part of the parent
@@ -1217,29 +1226,112 @@ vtysh_config_parse_comment(config_collection collection)
* If the last item was not comment, then need to start a (pro tem) it_dummy
* item, to which the comment can be attached.
*/
- parent = collection->last_item ;
+ comment_parent = collection->last_item ;
- if (parent != NULL)
+ if ((comment_parent != NULL) && (comment_parent->type == it_comment))
{
- if (parent->type == it_comment)
- parent = parent->parent ;
+ comment_parent = comment_parent->parent ;
}
else
{
- vtysh_config_item_insert(collection, it_dummy) ;
+ if (comment_parent != NULL)
+ qassert(comment_parent->type != it_dummy) ;
- parent = collection->last_item ;
+ vtysh_config_item_insert(collection, it_dummy) ;
+ comment_parent = collection->last_item ;
} ;
- new_item = vtysh_config_item_new(collection, parent, it_comment) ;
+ new_item = vtysh_config_item_new(collection, comment_parent, it_comment) ;
*new_item->line = *collection->line ;
- ddl_append(parent->pre_comments, new_item, siblings) ;
+ ddl_append(comment_parent->pre_comments, new_item, siblings) ;
collection->last_item = new_item ;
} ;
/*------------------------------------------------------------------------------
+ * Merge one set of pre-comment lines with an existing one.
+ *
+ * This is used where items are being merged.
+ *
+ * If the target pre-comment lines are unnamed, names them. Then, name each
+ * source pre-comment line and merge it in.
+ */
+static void
+vtysh_config_merge_comment(config_collection collection,
+ config_item target, config_item source)
+{
+ config_item comment ;
+
+ /* Get the trivial cases out of the way.
+ */
+ comment = ddl_head(source->pre_comments) ;
+ if (comment == NULL)
+ return ;
+
+ qassert(comment->type == it_comment) ;
+
+ comment = ddl_head(target->pre_comments) ;
+ if (comment == NULL)
+ {
+ /* Move source pre-comments to target, and update parent of all of
+ * those.
+ */
+ target->pre_comments = source->pre_comments ;
+ ddl_init( source->pre_comments) ;
+
+ comment = ddl_head(target->pre_comments) ;
+ while (comment != NULL)
+ {
+ qassert(comment->parent == source) ;
+ qassert(comment->type == it_comment) ;
+
+ comment->parent = target ;
+
+ comment = ddl_next(comment, siblings) ;
+ } ;
+
+ return ;
+ } ;
+
+ qassert(comment->type == it_comment) ;
+
+ /* Name the target pre-comments, if required.
+ */
+ if (comment->name == NULL)
+ {
+ qassert(comment->parent == target) ;
+
+ comment->name = vtysh_config_get_comment_name(collection, comment) ;
+ comment = ddl_next(comment, siblings) ;
+ } ;
+
+ /* Now merge the source comments in
+ */
+ while (ddl_pop(&comment, source->pre_comments, siblings) != NULL)
+ {
+ config_name name ;
+ config_item merged ;
+
+ qassert(comment->parent == source) ;
+ qassert(comment->type == it_comment) ;
+ qassert(ddl_head(comment->pre_comments) == NULL) ;
+
+ comment->parent = target ;
+ name = vtysh_config_get_comment_name(collection, comment) ;
+ ddl_append(target->pre_comments, comment, siblings) ;
+
+ if (name->list != NULL)
+ merged = vtysh_config_try_merge(collection, &target->pre_comments) ;
+ else
+ merged = NULL ;
+
+ if (merged == NULL)
+ ssl_push(comment->name->list, comment, also) ;
+ } ;
+} ;
+
+/*------------------------------------------------------------------------------
* We have a separator line.
*
* If we have a last_item, then we add a separator to it.
@@ -1380,87 +1472,182 @@ vtysh_config_parse_group_end(config_collection collection)
* Try to merge new item with an earlier one of the same name.
*
* The current last_item has been appended to the given parent, and has the
- * given name. At least one other item has the same name.
+ * given name. At least one other item has the same name, so we have one or
+ * more "targets" to attempt to merge with.
*
* No value has yet been set for the current last_item, but it may have
* pre_comments.
*
- * If we can move a "bubble" of items up the parent's list, such that the
- * current last_item overlaps (one of) the items with the same name, then
- * we do that and discard the duplicate node -- this is a "merge". Must also
- * merge any pre-comment(s).
+ * We can move items up the parent's list, provided we are moving past items
+ * which have no daemons in common with the items we are moving.
+ *
+ * We have two cases:
+ *
+ * 1) where the current last_item and one or more items above it have
+ * at least one daemon in common.
+ *
+ * In this case we have a "bubble" above the current last_item which we
+ * will need to move past the "target", if the current last_item is to
+ * be merged with the "target". This means that:
+ *
+ * a) all items between the current last_item and the target must
+ * have nothing in common with the bubble and nothing in
+ * common with the current last_item.
+ *
+ * For otherwise neither the bubble nor the current last_item can
+ * slide up past these items.
*
- * Each item with the same name is known as a "target".
+ * b) the target must have nothing in common with the bubble.
*
- * We can collect a "bubble" of items to move up, by scanning up from the
- * current last_item, while each item has at least the daemons in the bubble
- * so far (and adding an item adds all its daemons to the bubble).
+ * For otherwise the "bubble" cannot slide up past the target.
*
- * The bubble can move up to the target, provided that no item between the
- * bubble and the target has any items in common with the bubble.
+ * 2) where the current last_item has no daemons in common with its
+ * immediate predecessor.
+ *
+ * In this case we have an empty bubble.
+ *
+ * If we can move the (possibly empty) bubble and the current last_item up the
+ * list such that the current last_item overlaps (one of) the items with the
+ * same name, then we do that and discard the duplicate node -- this is a
+ * "merge". Must also merge any pre-comment(s).
+ *
+ * If there is a choice, will attempt to merge as far up the parent's list as
+ * possible.
+
+
+
*
* Note that since we do this as we add items to the collection, the bubble is
* always below the target.
*
*/
-static bool
-vtysh_config_try_merge(config_collection collection, config_item parent,
- config_name name)
+static config_item
+vtysh_config_try_merge(config_collection collection, config_item_list list)
{
- daemon_set_t bubble_daemons ;
- config_item item, bubble, seek, target ;
+ daemon_set_t bubble_daemons, total_daemons ;
+ config_item item, bubble, this, target ;
/* Set bubble to contain the current last_item
*/
- bubble = item = collection->last_item ;
- bubble_daemons = bubble->daemons ;
+ item = ddl_tail(*list) ;
+ total_daemons = item->daemons ;
+
+ bubble = item ; /* bubble == item <=> empty bubble */
+ bubble_daemons = 0 ;
- target = NULL ;
+ target = NULL ;
+
+ qassert(item->name->list != NULL) ;
/* Scan upwards adding to "bubble", looking out for a name match.
*
- * We can add an item to the bubble iff it has all the bubble's daemons, at
- * least.
+ * We can add an item to the bubble iff it has one or more daemons in common
+ * with the bubble or the item, and is NOT a target.
*/
while (1)
{
- bool addable ;
-
- seek = ddl_prev(bubble, siblings) ;
+ this = ddl_prev(bubble, siblings) ;
- if (seek == NULL)
- return false ; /* failed to find target */
+ if (this == NULL)
+ return NULL ; /* failed to find target */
- /* If we cannot add the current seek item to the bubble, we are
- * done with this phase.
+ /* Do not add completely disjoint item to the bubble.
*/
- if ((seek->daemons & bubble_daemons) != bubble_daemons)
+ if ((this->daemons & total_daemons) == 0)
break ;
- /* If we have a name match, then we are done.
+ /* Do not add a target item to the bubble.
*
- * If the bubble contains more than just the current last item,
- * then we cannot merge, because we cannot slide the rest of the
- * bubble past the target.
+ * If we find a target item, then we are either going to merge with it,
+ * or move past it.
*
- * If there is more than one target, then this one could not be merged
- * with the nearest one above, which implies that something above this
- * target prevented it and/or its bubble from sliding up.
+ * If there is more than one target item, then this one could not be
+ * merged with its predecessor, so something above prevented it from
+ * being moved. Adding this to the bubble would, therefore, be a waste
+ * of time.
*/
- if (seek->name == name)
+ if (this->name == item->name)
+ break ;
+
+ /* Add item to bubble.
+ */
+ bubble = this ;
+ bubble_daemons |= bubble->daemons ;
+
+ total_daemons |= bubble_daemons ;
+ } ;
+
+ /* Have constructed a (possibly empty) bubble, and we have "this" item above
+ * it.
+ *
+ * If we cannot move the bubble past this item, then we are done. If we have
+ * a target then note that. If we cannot move the bubble + the current
+ * last_item past this item, we are done.
+ */
+ while ((this->daemons & bubble_daemons) == 0)
+ {
+ /* If we have found a target, then make a note, and stop immediately
+ * if there are no further targets.
+ */
+ if (this->name == item->name)
{
- if (bubble != item)
- return false ;
+ /* Good news -- found target !
+ */
+ if (target != NULL)
+ qassert(this == target->also) ;
+ target = this ;
+
+ qassert(target->ordinal < item->ordinal) ;
+
+ /* If there is only one possible target, then we stop.
+ */
+ if (target->also == NULL)
+ break ;
} ;
- /* Add item to bubble.
+ /* If we cannot slide the bubble + current item past here, then we
+ * stop immediately.
+ */
+ if ((this->daemons & total_daemons) != 0)
+ break ;
+
+ /* Step up the list, stopping if run out.
*/
- bubble_daemons |= seek->daemons ;
- bubble = seek ;
+ this = ddl_prev(this, siblings) ;
+
+ if (this == NULL)
+ break ;
+ } ;
+
+ /* If we have found a target to merge with:
+ *
+ * - merging any pre-comments with the target pre-comments.
+ *
+ * - merge the daemons.
+ *
+ * - merge the post-xxxx
+ *
+ * - discard the item being merged.
+ *
+ * - move the bubble above the target.
+ */
+ if (target != NULL)
+ {
+ vtysh_config_merge_comment(collection, target, item) ;
+
+ target->daemons |= item->daemons ;
+
+ if (target->post_sep < item->post_sep)
+ target->post_sep = item->post_sep ;
+
+ ddl_del(*list, item, siblings) ;
+ vtysh_config_item_free(item) ;
+
+
} ;
- return false ;
+ return target ;
} ;
/*==============================================================================
@@ -1698,10 +1885,199 @@ vtysh_config_raw_free(config_collection collection)
} ;
qs_reset(collection->temp, keep_it) ; /* embedded */
+ qs_reset(collection->comment, keep_it) ; /* embedded */
+} ;
+
+/*==============================================================================
+ * Name handling.
+ *
+ * The name of an item covers:
+ *
+ * * the ordinal of the parent item
+ *
+ * * the type of item
+ *
+ * * the item's "raw_name", which may be:
+ *
+ * - the tokens which form the item, separated by spaces
+ *
+ * - the entire line (for comments) less trailing whitespace
+ *
+ * While there is a single, global symbol table, the form of the name means
+ * that each name has local scope within the parent.
+ */
+
+static config_name vtysh_config_make_name(config_collection collection,
+ config_item item, qstring raw_name) ;
+
+/*------------------------------------------------------------------------------
+ * Get and set name for the new collection->last_item (just parsed and created)
+ *
+ * Returns: address of name object.
+ */
+static config_name
+vtysh_config_get_name(config_collection collection)
+{
+ uint ti, tn ;
+
+ ti = (collection->last_item->type == it_group) ? 2 : 0 ;
+ tn = collection->parsed->num_tokens ;
+
+ return vtysh_config_make_name(collection, collection->last_item,
+ cmd_tokens_concat(collection->parsed, ti, tn - ti)) ;
} ;
+/*------------------------------------------------------------------------------
+ * Get name for a comment item.
+ *
+ * Comment items only need names when two items carrying pre-comments are
+ * merged.
+ *
+ * For comments the original line is used, verbatim, for the name -- less any
+ * trailing whitespace.
+ *
+ * Returns: address of name object.
+ */
+static config_name
+vtysh_config_get_comment_name(config_collection collection, config_item comment)
+{
+ qassert(comment->type == it_comment) ;
+
+ qs_set_els(collection->comment, comment->line) ;
+ qs_trim(collection->comment, '\0') ;
+
+ return vtysh_config_make_name(collection, comment, collection->comment) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Make a name and either look it up in the collection's global name table,
+ * or add new entry to that.
+ *
+ * Requires: item->parent
+ * item->type
+ * the given "raw name"
+ *
+ * Returns: address of name object -- set into item->name
+ *
+ * All items with the same name share the same name object. So, can
+ * test for name equality by comparing name object addresses.
+ *
+ * The items to which a name applies are hung off the name->list entry, in
+ * LIFO order. A NULL name->list entry implies this is a new name.
+ */
+static config_name
+vtysh_config_make_name(config_collection collection, config_item item,
+ qstring raw_name)
+{
+ config_name name ;
+ const char* tag ;
+ symbol sym ;
+
+ qassert(item->name == NULL) ; /* can only have one */
+
+ switch (item->type)
+ {
+ case it_line:
+ tag = "" ;
+ break ;
+
+ case it_group:
+ tag = "$" ;
+ break ;
+
+ case it_comment:
+ tag = "!" ;
+ break ;
+
+ default:
+ qassert(false) ;
+ tag = "?" ;
+ break ;
+ } ;
+
+ qs_clear(collection->temp) ;
+
+ qs_printf(collection->temp, "%u%s:%s", item->parent->ordinal, tag,
+ qs_string(raw_name)) ;
+
+ sym = symbol_lookup(collection->match, qs_string(collection->temp), add) ;
+
+ name = symbol_get_body(sym) ;
+
+ if (name == NULL)
+ {
+ ulen len ;
+
+ len = qs_len(collection->temp) + 1 ; /* including terminator */
+
+ name = vtysh_config_fragment_new(collection,
+ offsetof(config_name_t, string[len]), true /* align */) ;
+
+ name->list = NULL ;
+ memcpy(name->string, qs_char(collection->temp), len) ;
+
+ symbol_set_body(sym, name, true /* set */, free_it /* previous ! */) ;
+ } ;
+
+ return item->name = name ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Compare name in the given config_name with the given name_string.
+ */
+static int
+vtysh_config_match_cmp(const void* body, const void* name_string)
+{
+ const config_name_t* name = body ;
+ return strcmp(name->string, name_string) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * The symbol bodies are in fragments and are freed automatically.
+ */
+static void
+vtysh_config_match_free(void* body)
+{
+} ;
+
+/*==============================================================================
+ * The vtysh own configuration.
+ *
+ * There is not much of this.
+ *
+ * We don't write vtysh specific into file from vtysh. vtysh.conf should
+ * be edited by hand.
+ */
+
+/*------------------------------------------------------------------------------
+ * Show vtysh own configuration -- same like client daemon #vtysh-config-write
+ *
+ * This is for collecting the integrated configuration.
+ */
+static void
+vtysh_config_own_config(vty vtysh)
+{
+ vty_out(vtysh, "#vtysh-config-daemon vtysh\n") ;
+ vty_out(vtysh, "#vtysh-config-node %s\n", cmd_node_name(CONFIG_NODE)) ;
+
+ if (host.name_set)
+ vty_out(vtysh, "hostname %s\n", host.name) ;
+
+ if (vtysh_integrated_vtysh_config)
+ vty_out(vtysh, "service integrated-vtysh-config\n") ;
+} ;
+
+/*==============================================================================
+ * For diagnostic purposes -- "show" functions for data structures.
+ */
+
extern void show_collected(config_collection collection) ;
+static void show_collected_item(config_item item, qstring line) ;
+
+/*------------------------------------------------------------------------------
+ * Output given collection to stderr
+ */
extern void
show_collected(config_collection collection)
{
@@ -1726,8 +2102,9 @@ show_collected(config_collection collection)
fprintf(stderr, "%d lumps\n", i) ;
} ;
-static void show_collected_item(config_item item, qstring line) ;
-
+/*------------------------------------------------------------------------------
+ * Output given node to stderr
+ */
extern void
show_collected_node(config_collection collection)
{
@@ -1768,6 +2145,9 @@ show_collected_node(config_collection collection)
qs_free(line) ;
} ;
+/*------------------------------------------------------------------------------
+ * Output given item to stderr
+ */
static void
show_collected_item(config_item item, qstring line)
{
@@ -1820,135 +2200,3 @@ show_collected_item(config_item item, qstring line)
} ;
} ;
-/*==============================================================================
- * Name handling.
- *
- * When a new item is about to be inserted in the tree, need to get its name,
- * so we can check if we have the same item already or later.
- *
- * If the config_name object has a NULL items entry, then this is the first
- * occurrence of this name.
- *
- * The name covers:
- *
- * * the ordinal of the parent item
- *
- * * the type of item
- *
- * * the tokens which form the item, separated by spaces
- *
- * While there is a single, global symbol table, the form of the name means
- * that each name has local scope within the parent.
- *
- * Returns: address of name object.
- *
- * All items with the same name share the same name object. So, can
- * test for name equality by comparing name object addresses.
- */
-static config_name
-vtysh_config_get_name(config_collection collection, config_item parent,
- config_item_type_t type)
-{
- qstring tokens ;
- config_name name ;
- const char* tag ;
- uint ti, tn ;
- symbol sym ;
-
- ti = 0 ;
- tn = collection->parsed->num_tokens ;
-
- switch (type)
- {
- case it_line:
- tag = "" ;
- break ;
-
- case it_group:
- tag = "$" ;
- ti = 2 ;
- break ;
-
- case it_comment:
- tag = "!" ;
- break ;
-
- default:
- qassert(false) ;
- tag = "?" ;
- break ;
- } ;
-
- tokens = cmd_tokens_concat(collection->parsed, ti, tn - ti) ;
-
- qs_clear(collection->temp) ;
-
- qs_printf(collection->temp, "%u%s:%s", parent->ordinal, tag, qs_string(tokens)) ;
-
- sym = symbol_lookup(collection->match, qs_string(collection->temp), add) ;
-
- name = symbol_get_body(sym) ;
-
- if (name == NULL)
- {
- ulen len ;
-
- len = qs_len(collection->temp) + 1 ; /* including terminator */
-
- name = vtysh_config_fragment_new(collection,
- offsetof(config_name_t, string[len]), true /* align */) ;
-
- name->list = NULL ;
- memcpy(name->string, qs_char(collection->temp), len) ;
-
- symbol_set_body(sym, name, true /* set */, free_it /* previous ! */) ;
- } ;
-
- return name ;
-} ;
-
-/*------------------------------------------------------------------------------
- * Compare name in the given config_name with the given name_string.
- */
-static int
-vtysh_config_match_cmp(const void* body, const void* name_string)
-{
- const config_name_t* name = body ;
- return strcmp(name->string, name_string) ;
-} ;
-
-/*------------------------------------------------------------------------------
- * The symbol bodies are in fragments and are freed automatically.
- */
-static void
-vtysh_config_match_free(void* body)
-{
-} ;
-
-/*==============================================================================
- * The vtysh own configuration.
- *
- * There is not much of this.
- *
- * We don't write vtysh specific into file from vtysh. vtysh.conf should
- * be edited by hand.
- */
-
-/*------------------------------------------------------------------------------
- * Show vtysh own configuration -- same like client daemon #vtysh-config-write
- *
- * This is for collecting the integrated configuration.
- */
-static void
-vtysh_config_own_config(vty vtysh)
-{
- vty_out(vtysh, "#vtysh-config-daemon vtysh\n") ;
- vty_out(vtysh, "#vtysh-config-node %s\n", cmd_node_name(CONFIG_NODE)) ;
-
- if (host.name_set)
- vty_out(vtysh, "hostname %s\n", host.name) ;
-
- if (vtysh_integrated_vtysh_config)
- vty_out(vtysh, "service integrated-vtysh-config\n") ;
-} ;
-