/******************************************************************** * FUNCTION process_exit * (config mode input received) * Handle the exit command based on the current mode * * INPUTS: * server_cb == server control block to use * session_cb == session control block to use * RETURNS: * status *********************************************************************/ static status_t process_exit (server_cb_t *server_cb, session_cb_t *session_cb) { /*** TBD: add warning about edits pending ***/ status_t res = NO_ERR; /* exit to previous level or root or out of config mode */ if (session_cb->config_curobj) { /* check if edits are applied when the mode is exited */ if (session_cb->config_edit_mode == CFG_EDITMODE_LEVEL) { if (session_cb->config_etree) { /* there may be an edit to apply */ if (!session_cb->config_edit_dirty || dlq_count(&session_cb->config_editQ) == 0) { /* entered mode and then exited without adding any * edits so try adding the container or list */ res = add_edit(session_cb); } //clear_one_level(session_cb); } if (res == NO_ERR) { res = process_apply(server_cb, session_cb); } } /* get parent of current object */ session_cb->config_curobj = obj_get_real_parent(session_cb->config_curobj); if (!session_cb->config_curobj || obj_is_root(session_cb->config_curobj)) { /* exit to root-level, stay in config mode */ session_cb->config_curobj = NULL; session_cb->config_ecurval = NULL; val_free_value(session_cb->config_etree); session_cb->config_etree = NULL; } else if (session_cb->config_ecurval) { clear_one_level(session_cb); } } else { /* no current object so exit config mode */ exit_config_mode(session_cb); } return res; } /* process_exit */
/* * ASSUMES: rootObj is not NULL * - done is FALSE */ static int travP_find_first(ABTraversal trav) { #define rootObj (trav->rootObj) #define curObj (trav->curObj) curObj = NULL; switch (travP_get_qualifier(trav)) { case AB_TRAV_ACTIONS_FOR_OBJ: curObj= find_first_action(rootObj, trav); break; case AB_TRAV_CHILDREN: case AB_TRAV_SALIENT_CHILDREN: case AB_TRAV_SALIENT_UI_CHILDREN: curObj= travP_obj_first_child(rootObj, trav); break; case AB_TRAV_COMP_SUBOBJS: if (obj_is_root(rootObj)) { curObj = rootObj; } break; case AB_TRAV_ITEMS_FOR_OBJ: curObj= find_first_item(rootObj); break; case AB_TRAV_MODULES: curObj= obj_is_module(rootObj)? rootObj : find_first_child_of_type(rootObj, trav, AB_TYPE_MODULE); break; case AB_TRAV_PARENTS: travP_find_first_for_parents(trav); break; case AB_TRAV_SIBLINGS: { ABObj prevSibling= NULL; curObj= rootObj; while ((prevSibling= travP_obj_prev_sibling(curObj, trav)) != NULL) { curObj= prevSibling; } } break; default: curObj= rootObj; break; } return 0; #undef rootObj #undef curObj }
/******************************************************************** * FUNCTION handle_config_input * (config mode input received) * * e.g., * nacm * interface eth0 * interface eth0 mtu 1500 * * INPUTS: * server_cb == server control block to use * session_cb == session control block to use * line == CLI input in progress; this line is passed to the * tk_parse functions which expects non-const ptr * * RETURNS: * status *********************************************************************/ status_t handle_config_input (server_cb_t *server_cb, session_cb_t *session_cb, xmlChar *line) { if (LOGDEBUG2) { log_debug2("\nconfig mode input for line '%s'\n", line); } /* get a token chain and parse the line of input into tokens */ tk_chain_t *tkc = tk_new_chain(); if (tkc == NULL) { log_error("\nError: could not malloc token chain\n"); return ERR_INTERNAL_MEM; } tk_setup_chain_cli(tkc, line); status_t res = tk_tokenize_input(tkc, NULL); if (res != NO_ERR) { tk_free_chain(tkc); return res; } /* check the number of tokens parsed */ uint32 tkcount = tk_token_count(tkc); if (LOGDEBUG2) { log_debug2("\nconfig token count: %u", tkcount); } if (tkcount == 0) { tk_free_chain(tkc); return NO_ERR; } obj_template_t *startobj = session_cb->config_curobj; val_value_t *startval = session_cb->config_curval; val_value_t *startroot = session_cb->config_etree; val_value_t *starteval = session_cb->config_ecurval; session_cb->config_no_active = FALSE; session_cb->config_estartval = starteval; session_cb->config_firstnew = NULL; boolean gotleafys = FALSE; boolean gotexit = FALSE; boolean gotapply = FALSE; boolean gotdo = FALSE; boolean done = FALSE; while (!done && res == NO_ERR) { /* parse nodes and possibly keys until a value node or the end * of the token chain is reached */ res = parse_node(tkc, session_cb, &done, &gotexit, &gotapply, &gotdo); obj_template_t *obj = session_cb->config_curobj; if (res == NO_ERR && done && !gotdo && !gotexit && !gotapply && obj && obj_is_leafy(obj)) { /* get the next node as a value node */ res = parse_value(session_cb, tkc); gotleafys = TRUE; if (tk_next_typ(tkc) != TK_TT_NONE) { res = ERR_NCX_EXTRA_NODE; log_error("\nError: unexpected input at end of line\n"); } if (res == NO_ERR && !session_cb->config_no_active) { if (obj->parent && !obj_is_root(obj->parent)) { session_cb->config_curobj = obj->parent; } else { session_cb->config_curobj = NULL; } /* reset to parent of the leaf just parsed */ session_cb->config_ecurval = session_cb->config_ecurval->parent; } } } /* check exit conditions */ if (res != NO_ERR || done || gotexit || gotapply || gotdo) { if (res == NO_ERR && gotexit) { res = process_exit(server_cb, session_cb); if (res == NO_ERR) { res = set_config_path(session_cb); } } else if (res == NO_ERR && gotapply) { if (session_cb->config_curobj && dlq_empty(&session_cb->config_editQ) && session_cb->config_edit_mode != CFG_EDITMODE_LINE) { /* add an edit just because the user entered a * sub-mode and then invoked apply */ res = add_edit(session_cb); } clear_current_level(session_cb); if (res == NO_ERR) { res = process_apply(server_cb, session_cb); } } else if (res == NO_ERR && gotdo) { res = process_do_command(server_cb, session_cb, tkc, line); } else if (res == NO_ERR && done) { res = process_line_done(server_cb, session_cb, startobj, gotleafys); if (res == NO_ERR && session_cb->config_curobj && session_cb->config_curobj != startobj) { res = set_config_path(session_cb); } } if (res != NO_ERR) { /* reset current node pointers */ session_cb->config_curobj = startobj; session_cb->config_curval = startval; if (startroot == NULL) { val_free_value(session_cb->config_etree); session_cb->config_etree = NULL; session_cb->config_ecurval = NULL; session_cb->config_firstnew = NULL; } else { if (session_cb->config_firstnew) { if (session_cb->config_firstnew->parent) { val_remove_child(session_cb->config_firstnew); } val_free_value(session_cb->config_firstnew); session_cb->config_firstnew = NULL; } session_cb->config_etree = startroot; session_cb->config_ecurval = starteval; } (void)set_config_path(session_cb); } } tk_free_chain(tkc); return res; } /* handle_config_input */