Ejemplo n.º 1
0
/********************************************************************
 * FUNCTION clear_one_level
 * Clear the current level for the ecurptr
 * The exit command was given so backing up top the
 * parent of the config_ecurptr
 *
 * INPUTS:
 *    session_cb == session control block to use
 *********************************************************************/
static void
    clear_one_level (session_cb_t *session_cb)
{
    val_value_t *target = session_cb->config_ecurval;
    if (target == NULL) {
        return;
    }

    val_value_t *parent = target->parent;

    if (session_cb->config_estartval == target) {
        session_cb->config_estartval = NULL;
    }

    if (parent) {
        val_remove_child(target);
    }
    val_free_value(target);

    session_cb->config_ecurval = parent;
    if (parent == NULL) {
        session_cb->config_etree = NULL;
        session_cb->config_estartval = NULL;
    }

}  /* clear_one_level */
Ejemplo n.º 2
0
/********************************************************************
 * FUNCTION clear_current_level
 * Clear the current level without changing it
 *
 * INPUTS:
 *    session_cb == session control block to use
 *********************************************************************/
static void
    clear_current_level (session_cb_t *session_cb)
{
    val_value_t *target = session_cb->config_ecurval;
    if (target == NULL) {
        return;
    }

    if (session_cb->config_estartval == NULL) {
        /* clear everything out */
        val_free_value(session_cb->config_etree);
        session_cb->config_etree = NULL;
        session_cb->config_ecurval = NULL;
        return;
    }

    boolean islist = obj_is_list(target->obj);
    val_value_t *chval = val_get_first_child(target);
    val_value_t *nextval = NULL;
    for (; chval; chval = nextval) {
        nextval = val_get_next_child(chval);
        if (islist && obj_is_key(chval->obj)) {
            continue;
        }
        val_remove_child(chval);
        val_free_value(chval);
    }

}  /* clear_current_level */
Ejemplo n.º 3
0
/********************************************************************
* FUNCTION clean_undorec
*
* Clean all the memory used by the specified agt_cfg_undo_rec_t
* but do not free the struct itself
*
*  !!! The caller must free internal pointers that were malloced
*  !!! instead of copied.  This function does not check them!!!
*  
* INPUTS:
*   undo == agt_cfg_undo_rec_t to clean
*   reuse == TRUE if possible reuse
*            FALSE if this node is being freed right now
*
* RETURNS:
*   none
*********************************************************************/
static void 
    clean_undorec (agt_cfg_undo_rec_t *undo,
                   boolean reuse)
{
    if (undo->free_curnode && undo->curnode) {
        val_free_value(undo->curnode);
    }

    if (undo->curnode_clone) {
        val_free_value(undo->curnode_clone);
    }

    if (undo->newnode_marker) {
        val_free_value(undo->newnode_marker);
    }

    if (undo->curnode_marker) {
        val_free_value(undo->curnode_marker);
    }

    /* really expecting the extra_deleteQ to be empty at this point */
    while (!dlq_empty(&undo->extra_deleteQ)) {
        agt_cfg_nodeptr_t *nodeptr = (agt_cfg_nodeptr_t *)
            dlq_deque(&undo->extra_deleteQ);
        if (nodeptr && nodeptr->node) {
            val_remove_child(nodeptr->node);
            val_free_value(nodeptr->node);
        } else {
            SET_ERROR(ERR_INTERNAL_VAL);
        }
        agt_cfg_free_nodeptr(nodeptr);
    }

    if (reuse) {
        agt_cfg_init_undorec(undo);
    }

} /* clean_undorec */
Ejemplo n.º 4
0
/********************************************************************
 * FUNCTION do_while (local RPC)
 * 
 * Handle the while command; start a new loopcb context
 *
 * while expr='xpath-str' [docroot=$foo]
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the show command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    do_while (server_cb_t *server_cb,
              obj_template_t *rpc,
              const xmlChar *line,
              uint32  len)
{
    val_value_t        *valset, *docroot, *expr, *dummydoc, *maxloops;
    xpath_pcb_t        *pcb;
    status_t            res;
    uint32              maxloopsval;

    docroot = NULL;
    expr = NULL;
    pcb = NULL;
    dummydoc = NULL;
    res = NO_ERR;
    maxloopsval = YANGCLI_DEF_MAXLOOPS;

    valset = get_valset(server_cb, rpc, &line[len], &res);
    if (valset == NULL) {
        return res;
    }
    if (res != NO_ERR) {
        val_free_value(valset);
        return res;
    }
    if (valset->res != NO_ERR) {
        res = valset->res;
        val_free_value(valset);
        return res;
    }

    /* get the expr parameter */
    expr = val_find_child(valset, 
                          YANGCLI_MOD, 
                          YANGCLI_EXPR);
    if (expr == NULL) {
        res = ERR_NCX_MISSING_PARM;
    } else if (expr->res != NO_ERR) {
        res = expr->res;
    }

    if (res == NO_ERR) {
        /* get the optional docroot parameter */
        docroot = val_find_child(valset, 
                                 YANGCLI_MOD, 
                                 YANGCLI_DOCROOT);
        if (docroot != NULL) {
            if (docroot->res != NO_ERR) {
                res = docroot->res;
            } else {
                val_remove_child(docroot);
            }
        }
    }

    if (res == NO_ERR && docroot == NULL) {
        dummydoc = xml_val_new_struct(NCX_EL_DATA, xmlns_nc_id());
        if (dummydoc == NULL) {
            res = ERR_INTERNAL_MEM;
        } else {
            docroot = dummydoc;
        }
    }

    if (res == NO_ERR) {
        /* get the optional maxloops parameter */
        maxloops = val_find_child(valset, 
                                  YANGCLI_MOD, 
                                  YANGCLI_MAXLOOPS);
        if (maxloops != NULL) {
            if (maxloops->res != NO_ERR) {
                res = maxloops->res;
            } else {
                maxloopsval = VAL_UINT(maxloops);
            }
        }
    }

    if (res == NO_ERR) {
        /* got all the parameters, and setup the XPath control block */
        pcb = xpath_new_pcb_ex(VAL_STR(expr), 
                               xpath_getvar_fn,
                               server_cb->runstack_context);
        if (pcb == NULL) {
            res = ERR_INTERNAL_MEM;
        } else {
            /* save these parameter and start a new while context block */
            res = runstack_handle_while(server_cb->runstack_context,
                                        maxloopsval,
                                        pcb,  /* hand off memory here */
                                        docroot);  /* hand off memory here */
            if (res == NO_ERR) {
                /* hand off the pcb and docroot memory above */
                pcb = NULL;
                docroot = NULL;
            }
        }
    }

    /* cleanup and exit */
    if (valset) {
        val_free_value(valset);
    }
    if (pcb) {
        xpath_free_pcb(pcb);
    }
    if (docroot) {
        val_free_value(docroot);
    }
    return res;

}  /* do_while */
Ejemplo n.º 5
0
/********************************************************************
 * 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 */