/********************************************************************
 * 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 */
Exemple #2
0
/*
 * 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 */