Beispiel #1
0
/********************************************************************
* FUNCTION grp_has_typedefs
* 
* Check if the grouping contains any typedefs
*
* INPUTS:
*    grp == grp_template_t struct to check
*
* RETURNS:
*    TRUE if any embedded typedefs
*    FALSE if no embedded typedefs
*********************************************************************/
boolean
    grp_has_typedefs (const grp_template_t *grp)
{
    const grp_template_t *chgrp;

#ifdef DEBUG
    if (!grp) {
        SET_ERROR(ERR_INTERNAL_PTR);
        return FALSE;
    }
#endif

    if (!dlq_empty(&grp->typedefQ)) {
        return TRUE;
    }

    for (chgrp = (const grp_template_t *)
             dlq_firstEntry(&grp->groupingQ);
         chgrp != NULL;
         chgrp = (const grp_template_t *)dlq_nextEntry(chgrp)) {
        if (grp_has_typedefs(chgrp)) {
            return TRUE;
        }
    }

    return FALSE;

}  /* grp_has_typedefs */
Beispiel #2
0
/********************************************************************
* FUNCTION rpc_err_clean_record
*
* Clean an rpc_err_rec_t struct
*
* INPUTS:
*   err == rpc_err_rec_t struct to clean
* RETURNS:
*   none
*********************************************************************/
void
    rpc_err_clean_record (rpc_err_rec_t  *err)
{
    rpc_err_info_t  *errinfo;

#ifdef DEBUG
    if (!err) {
        SET_ERROR(ERR_INTERNAL_PTR);
        return;
    }
#endif

    err->error_res = NO_ERR;
    err->error_id = RPC_ERR_NONE;
    err->error_type = NCX_LAYER_NONE;
    err->error_severity = RPC_ERR_SEV_NONE;
    err->error_tag = NULL;
    err->error_app_tag = NULL;
    if (err->error_path) {
        m__free(err->error_path);
        err->error_path = NULL;
    }
    if (err->error_message) {
        m__free(err->error_message);
    }
    err->error_message_lang = NULL;

    while (!dlq_empty(&err->error_info)) {
        errinfo = (rpc_err_info_t *)dlq_deque(&err->error_info);
        rpc_err_free_info(errinfo);
    }

}  /* rpc_err_clean_record */
Beispiel #3
0
/********************************************************************
* FUNCTION rpc_free_msg
*
* Free all the memory used by the specified rpc_msg_t
*
* INPUTS:
*   msg == rpc_msg_t to clean and delete
* RETURNS:
*   none
*********************************************************************/
void rpc_free_msg (rpc_msg_t *msg)
{
    if (!msg) {
        return;
    }

    xml_msg_clean_hdr(&msg->mhdr);

    //msg->rpc_in_attrs = NULL;
    //msg->rpc_method = NULL;
    //msg->rpc_agt_state = 0;

    /* clean input parameter set */
    if (msg->rpc_input) {
        val_free_value(msg->rpc_input);
    }
    //msg->rpc_user1 = NULL;
    //msg->rpc_user2 = NULL;

    //msg->rpc_filter.op_filtyp = OP_FILTER_NONE;
    //msg->rpc_filter.op_filter = NULL;
    //msg->rpc_datacb = NULL;

    /* clean data queue */
    while (!dlq_empty(&msg->rpc_dataQ)) {
        val_value_t *val = (val_value_t *)dlq_deque(&msg->rpc_dataQ);
        val_free_value(val);
    }

    m__free(msg);

} /* rpc_free_msg */
Beispiel #4
0
/********************************************************************
* FUNCTION yangapi_clean_keyvalQ
*
* Free all the YANGAPI keyval
*
* INPUTS:
*   rcb == control block to use
* RETURNS:
*   none
*********************************************************************/
void
    yangapi_clean_keyvalQ (yangapi_cb_t *rcb)
{
    while (!dlq_empty(&rcb->keyvalQ)) {
        yangapi_keyval_t *kv = (yangapi_keyval_t *)
            dlq_deque(&rcb->keyvalQ);
        yangapi_free_keyval(kv);
    }
}  /* yangapi_clean_keyvalQ */
Beispiel #5
0
/********************************************************************
* FUNCTION agt_cfg_free_transaction
*
* Clean and free a agt_cfg_transaction_t struct
*
* INPUTS:
*    txcb == transaction struct to free
*********************************************************************/
void
    agt_cfg_free_transaction (agt_cfg_transaction_t *txcb)
{
    if (txcb == NULL) {
        return;
    }

    /* clear current config txid if any */
    if (txcb->txid) {
        cfg_template_t *cfg = cfg_get_config_id(txcb->cfg_id);
        if (cfg) {
            if (cfg->cur_txid == txcb->txid) {
                log_debug3("\nClearing current txid for %s config",
                           cfg->name);
                cfg->cur_txid = 0;
            }
        }
    }

    /* clean undo queue */
    while (!dlq_empty(&txcb->undoQ)) {
        agt_cfg_undo_rec_t *undorec = (agt_cfg_undo_rec_t *)
            dlq_deque(&txcb->undoQ);
        agt_cfg_free_undorec(undorec);
    }

    /* clean audit queue */
    while (!dlq_empty(&txcb->auditQ)) {
        agt_cfg_audit_rec_t *auditrec = (agt_cfg_audit_rec_t *)
            dlq_deque(&txcb->auditQ);
        agt_cfg_free_auditrec(auditrec);
    }

    /* clean dead node queue */
    while (!dlq_empty(&txcb->deadnodeQ)) {
        agt_cfg_nodeptr_t *nodeptr = (agt_cfg_nodeptr_t *)
            dlq_deque(&txcb->deadnodeQ);
        agt_cfg_free_nodeptr(nodeptr);
    }

    m__free(txcb);

}  /* agt_cfg_free_transaction */
Beispiel #6
0
/********************************************************************
 * Clean a queue of grp_template_t structs
 *
 * \param que Q of grp_template_t data structures to free
 *********************************************************************/
void grp_clean_groupingQ (dlq_hdr_t *que)
{
    if (!que) {
        return;
    }

    while (!dlq_empty(que)) {
        grp_template_t *grp = (grp_template_t *)dlq_deque(que);
        grp_free_template(grp);
    }
}  /* grp_clean_groupingQ */
/********************************************************************
 * FUNCTION free_aliases
 * 
 * Free all the command aliases
 *
 *********************************************************************/
void
    free_aliases (void)
{
    dlq_hdr_t   *aliasQ = get_aliasQ();
    alias_cb_t  *alias;

    while (!dlq_empty(aliasQ)) {
        alias = (alias_cb_t *)dlq_deque(aliasQ);
        free_alias(alias);
    }

}  /* free_aliases */
/********************************************************************
 * FUNCTION yangcli_notif_cleanup
 * 
 * Cleanup this module
 *
 *********************************************************************/
void
    yangcli_notif_cleanup (void)
{
    if (yangcli_notif_init_done) {
        while (!dlq_empty(&event_cbQ)) {
            event_cb_t *cb = dlq_deque(&event_cbQ);
            free_event_cb(cb);
        }
        yangcli_notif_init_done = FALSE;
    }

}  /* yangcli_notif_cleanup */
Beispiel #9
0
/********************************************************************
* FUNCTION rpc_err_any_errors
*
* Check if there are any errors in the RPC message error Q
*
* INPUTS:
*   msg == rpc_msg_t struct to check for errors
*
* RETURNS:
*   TRUE if any errors recorded; FALSE if none
*********************************************************************/
boolean
    rpc_err_any_errors (const rpc_msg_t  *msg)
{

#ifdef DEBUG
    if (!msg) {
        SET_ERROR(ERR_INTERNAL_PTR);
        return FALSE;
    }
#endif

    return (dlq_empty(&msg->mhdr.errQ)) ? FALSE : TRUE;

}  /* rpc_err_any_errors */
Beispiel #10
0
void agt_commit_complete_cleanup( void )
{
    if ( initialised )
    {
        agt_cb_commit_complete_set_t* cbSet;

        while ( !dlq_empty( &callbackQ ) )
        {
            cbSet = ( agt_cb_commit_complete_set_t* )dlq_deque( &callbackQ );
            free_callback_set( cbSet );
        }
        initialised = false;
    }
} /* agt_commit_complete_cleanup */
void agt_not_queue_notification_cb_cleanup( void )
{
    if ( initialised )
    {
        agt_cb_queue_notification_set_t* cbSet;

        while ( !dlq_empty( &callbackQ ) )
        {
            cbSet = ( agt_cb_queue_notification_set_t* )dlq_deque( &callbackQ );
            free_callback_set( cbSet );
        }
        initialised = false;
    }
} /* agt_not_queue_notification_callbacks_cleanup */
Beispiel #12
0
/********************************************************************
* FUNCTION ncx_feature_cleanup
* 
* Cleanup the ncx_feature module
*
* INPUTS:
*    none
* RETURNS:
*    none
*********************************************************************/
void
    ncx_feature_cleanup (void)
{
    feature_entry_t  *feature_entry;

    if (!feature_init_done) {
        return;
    }

    while (!dlq_empty(&feature_entryQ)) {
        feature_entry = (feature_entry_t *)dlq_deque(&feature_entryQ);
        free_feature_entry(feature_entry);
    }

    feature_init_done = FALSE;

}  /* ncx_feature_cleanup */
Beispiel #13
0
/********************************************************************
* FUNCTION clean_server_profile
* 
* Clean the server profile variables
*
* OUTPUTS:
*  *agt_profile is filled in with params of defaults
*
*********************************************************************/
static void
    clean_server_profile (void)
{
    ncx_clean_save_deviationsQ(&agt_profile.agt_savedevQ);

    while (!dlq_empty(&agt_profile.agt_commit_testQ)) {
        agt_cfg_commit_test_t *commit_test = (agt_cfg_commit_test_t *)
            dlq_deque(&agt_profile.agt_commit_testQ);
        agt_cfg_free_commit_test(commit_test);
    }

    if (agt_profile.agt_startup_txid_file) {
        m__free(agt_profile.agt_startup_txid_file);
        agt_profile.agt_startup_txid_file = NULL;
    }

} /* clean_server_profile */
Beispiel #14
0
/********************************************************************
* FUNCTION ncx_clean_iffeatureQ
* 
* Clean a Q of malloced ncx_iffeature_t struct
*
* INPUTS:
*    iffeatureQ == address of Q to clean
*
*********************************************************************/
void 
    ncx_clean_iffeatureQ (dlq_hdr_t *iffeatureQ)
{

    ncx_iffeature_t  *iff;

#ifdef DEBUG
    if (!iffeatureQ) {
        SET_ERROR(ERR_INTERNAL_PTR);
        return;
    }
#endif

    while (!dlq_empty(iffeatureQ)) {
        iff = (ncx_iffeature_t *)dlq_deque(iffeatureQ);
        ncx_free_iffeature(iff);
    }
    
} /* ncx_clean_iffeatureQ */
Beispiel #15
0
/********************************************************************
* FUNCTION rpc_err_clean_errQ
*
* Clean all the entries from a Q of rpc_err_rec_t
*
* INPUTS:
*   errQ == Q of rpc_err_rec_t to clean
* RETURNS:
*   none
*********************************************************************/
void 
    rpc_err_clean_errQ (dlq_hdr_t *errQ)
{
    rpc_err_rec_t *err;

#ifdef DEBUG
    if (!errQ) {
        SET_ERROR(ERR_INTERNAL_PTR);
        return;
    }
#endif

    /* clean error queue */
    while (!dlq_empty(errQ)) {
        err = (rpc_err_rec_t *)dlq_deque(errQ);
        rpc_err_free_record(err);
    }

} /* rpc_err_clean_errQ */
Beispiel #16
0
/********************************************************************
* FUNCTION xml_msg_clean_hdr
*
* Clean all the memory used by the specified xml_msg_hdr_t
* but do not free the struct itself
*
* Do NOT reuse this header without calling xml_msg_init_hdr first!!!
* xml_msg_t headers were originally meant to be used
* only in other messages, but <hello> messages use the hdr
* without a wrapper message
*
* INPUTS:
*   msg == xml_msg_hdr_t to clean
* RETURNS:
*   none
*********************************************************************/
void
xml_msg_clean_hdr (xml_msg_hdr_t *msg)
{
    if (!msg) {
        return;
    }

    /* clean prefix queue */
    while (!dlq_empty(&msg->prefixQ)) {
        xmlns_pmap_t *pmap = (xmlns_pmap_t *)dlq_deque(&msg->prefixQ);
        xmlns_free_pmap(pmap);
    }

    /* clean error queue */
    rpc_err_clean_errQ(&msg->errQ);

    // this step not needed; not sure why it was added!
    msg->withdef = NCX_DEF_WITHDEF;

} /* xml_msg_clean_hdr */
Beispiel #17
0
/********************************************************************
* FUNCTION yangapi_free_rcb
*
* Free a YANGAPI control block
*
* INPUTS:
*   rcb == Yuma REST-API control block to free
* RETURNS:
*   none
*********************************************************************/
void
    yangapi_free_rcb (yangapi_cb_t *rcb)
{

    if (rcb == NULL) {
        return;
    }

    while (!dlq_empty(&rcb->paramQ)) {
        yangapi_param_t *param = (yangapi_param_t *)dlq_deque(&rcb->paramQ);
        if (param) {
            yangapi_free_param(param);
        }
    }

    yangapi_clean_keyvalQ(rcb);

    m__free(rcb->accept);
    m__free(rcb->request_method);
    m__free(rcb->request_uri);

    xpath_free_pcb(rcb->request_xpath);
    xpath_free_result(rcb->request_xpath_result);

    xpath_free_pcb(rcb->query_select_xpath);
    xpath_free_result(rcb->query_select_xpath_result);

    xpath_free_pcb(rcb->query_test_xpath);
    xpath_free_result(rcb->query_test_xpath_result);

    m__free(rcb->content_type);
    m__free(rcb->content_length);
    m__free(rcb->if_modified_since);
    m__free(rcb->if_unmodified_since);
    m__free(rcb->if_match);
    m__free(rcb->if_none_match);

    m__free(rcb);

}  /* yangapi_free_rcb */
Beispiel #18
0
/********************************************************************
* FUNCTION agt_ses_request_close
*
* Start the close of the specified session
*
* INPUTS:
*   sid == session ID to close
*   killedby == session ID executing the kill-session or close-session
*   termreason == termination reason code
*
* RETURNS:
*   none
*********************************************************************/
void
    agt_ses_request_close (ses_cb_t *scb,
                           ses_id_t killedby,
                           ses_term_reason_t termreason)
{
    if (!scb) {
        return;
    }

    /* N/A for dummy sessions */
    if (scb->type==SES_TYP_DUMMY) {
        return;
    }

    scb->killedbysid = killedby;
    scb->termreason = termreason;

    /* change the session control block state */
    switch (scb->state) {
    case SES_ST_IDLE:
    case SES_ST_SHUTDOWN:
    case SES_ST_SHUTDOWN_REQ:
        agt_ses_kill_session(scb, 
                             killedby,
                             termreason);
        break;
    case SES_ST_IN_MSG:
        scb->state = SES_ST_SHUTDOWN_REQ;
        break;
    default:
        if (dlq_empty(&scb->outQ)) {
            agt_ses_kill_session(scb, 
                                 killedby,
                                 termreason);
        } else {
            scb->state = SES_ST_SHUTDOWN_REQ;
        }
    }

}  /* agt_ses_request_close */
Beispiel #19
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 */
/********************************************************************
 * FUNCTION exit_config_mode
 * 
 * Exit the configuration mode
 *
 * INPUTS:
 *    session_cb == session control block to use
 *
 *********************************************************************/
static void
    exit_config_mode (session_cb_t *session_cb)
{
    session_cb->config_mode = FALSE;
    session_cb->config_no_active = FALSE;
    session_cb->config_edit_dirty = FALSE;
    session_cb->alt_names = session_cb->config_alt_names;
    session_cb->match_names = session_cb->config_match_names;
    m__free(session_cb->config_path);
    session_cb->config_path = NULL;
    session_cb->config_curval = NULL;
    session_cb->config_curobj = NULL;
    session_cb->config_curkey = NULL;
    val_free_value(session_cb->config_etree);
    session_cb->config_etree = NULL;
    session_cb->config_ecurval = NULL;
    while (!dlq_empty(&session_cb->config_editQ)) {
        config_edit_t *edit = (config_edit_t *)
            dlq_deque(&session_cb->config_editQ);
        free_config_edit(edit);
    }

} /* exit_config_mode */
/********************************************************************
 * 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 */
/********************************************************************
 * FUNCTION process_apply
 * (config mode input received)
 *  Handle the apply command and check if there are edits
 *  to apply to the server.  If so apply the edits.
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    session_cb == session control block to use
 *
 * RETURNS:
 *   status
 *********************************************************************/
static status_t
    process_apply (server_cb_t *server_cb,
                   session_cb_t *session_cb)
{
    if (dlq_empty(&session_cb->config_editQ)) {
        if (LOGDEBUG2) {
            log_debug2("\nSkipping apply, no edits");
        }
        session_cb->config_edit_dirty = FALSE;
        return NO_ERR;
    }

    /* make a dummy config root -- it will not be used; only the child
     * nodes added to this container will be added to the <config>
     * parameter in the <edit-config> operation
     */
    val_value_t *configval = xml_val_new_root(NCX_EL_CONFIG, xmlns_nc_id());
    if (configval == NULL) {
        log_error("\nError: malloc failed");
        return ERR_INTERNAL_MEM;
    }
 
    status_t res = NO_ERR;
    boolean anyedits = FALSE;
    uint32 editcnt = dlq_count(&session_cb->config_editQ);
    
    while (!dlq_empty(&session_cb->config_editQ)) {
        config_edit_t *edit = (config_edit_t *)
            dlq_deque(&session_cb->config_editQ);

        /* compare the edit to the shadow config to see if it
         * represents any change or not   */
        boolean ischange = check_edit(session_cb, edit);

        if (ischange) {
            /** TBD: add to tree and collapse all edits!!! */
            val_add_child(edit->edit_payload, configval);
            edit->edit_payload = NULL;
            anyedits = TRUE;
        } else if (LOGDEBUG3) {
            log_debug3("\nSkipping edit due to no change:\n");
            val_dump_value(edit->edit_payload, 0);
        }
        free_config_edit(edit);
    }

    if (!anyedits) {
        val_free_value(configval);
        return NO_ERR;
    }

    if (server_cb->program_mode == PROG_MODE_SERVER) {
        if (LOGDEBUG) {
            if (editcnt == 1) {
                log_debug("\nApplying 1 edit\n");
            } else {
                log_debug("\nApplying %u edits\n", editcnt);
            }
        }
    } else {
        if (LOGINFO) {
            const xmlChar *sesname = (session_cb->session_cfg)
                ? session_cb->session_cfg->name : NCX_EL_DEFAULT;

            if (editcnt == 1) {
                log_info("\nApplying 1 edit to session '%s'\n", sesname);
            } else {
                log_info("\nApplying %u edits to session '%s'\n", editcnt,
                         sesname);
            }
        }
    }

    session_cb->command_mode = CMD_MODE_CONF_APPLY;
    session_cb->config_edit_dirty = FALSE;

    res = send_edit_config_to_server(server_cb, session_cb, NULL,
                                     configval, TRUE, session_cb->timeout,
                                     OP_DEFOP_MERGE);
    /* configval consumed no matter what! */

    return res;

}  /* process_apply */
/********************************************************************
 * FUNCTION do_aliases (local RPC)
 * 
 * aliases
 * aliases clear
 * aliases show
 * aliases load[=filespec]
 * aliases save[=filespec]
 *
 * Handle the aliases command, based on the parameter
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the aliases command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    do_aliases (server_cb_t *server_cb,
              obj_template_t *rpc,
              const xmlChar *line,
              uint32  len)
{
    val_value_t   *valset;
    status_t       res = NO_ERR;

    valset = get_valset(server_cb, rpc, &line[len], &res);

    if (res == NO_ERR && valset) {
        /* get the 1 of N 'alias-action' choice */
        val_value_t *parm;
        const xmlChar *parmval = NULL;
        boolean done = FALSE;
        
        /* aliases show */
        parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_SHOW);
        if (parm) {
            show_aliases();
            done = TRUE;
        }

        /* aliases clear */
        if (!done) {
            parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_CLEAR);
            if (parm) {
                dlq_hdr_t *aliasQ = get_aliasQ();
                if (!dlq_empty(aliasQ)) {
                    free_aliases();
                    log_info("\nDeleted all aliases from memory\n");
                    update_yangcli_param_change_flag (ALIASES_FILE, TRUE);
                }else {
                    log_info("\nNo aliases found\n");
                }
                done = TRUE;
            }
        }

        /* aliases load */
        if (!done) {
            parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_LOAD);
            if (parm) {
                if (xml_strlen(VAL_STR(parm))) {
                    parmval = VAL_STR(parm);
                } else {
                    parmval = get_aliases_file();
                }
                res = load_aliases(parmval, !val_set_by_default(parm));
                if (res == NO_ERR) {
                    log_info("\nLoaded aliases OK from '%s'\n", parmval);
                } else {
                    log_error("\nLoad aliases from '%s' failed (%s)\n", 
                              parmval, get_error_string(res));
                }
                done = TRUE;
            }
        }

        /* aliases save */
        if (!done) {
            parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_SAVE);
            if (parm) {
                if (xml_strlen(VAL_STR(parm))) {
                    parmval = VAL_STR(parm);
                } else {
                    parmval = get_aliases_file();
                }
                res = save_aliases(parmval);
                if (res == NO_ERR) {
                    log_info("\nSaved aliases OK to '%s'\n", parmval);
                } else if (res != ERR_NCX_CANCELED) {
                    log_error("\nSave aliases to '%s' failed (%s)\n", 
                              parmval, get_error_string(res));
                }
                done = TRUE;
            }
        }

        if (!done) {
            /* no parameters; show all aliases */
            show_aliases();
        }
    }

    if (valset) {
        val_free_value(valset);
    }

    return res;

}  /* do_aliases */
Beispiel #24
0
/********************************************************************
* FUNCTION load_running_config
* 
* Load the NV startup config into the running config
* 
* INPUTS:
*   startup == startup filespec provided by the user
*           == NULL if not set by user 
*              (use default name and specified search path instead)
*   loaded == address of return config loaded flag
*
* OUTPUTS:
*   *loaded == TRUE if some config file was loaded
*
*   The <running> config is loaded from NV-storage,
*   if the NV-storage <startup> config can be found an read
* RETURNS:
*   status
*********************************************************************/
static status_t
    load_running_config (const xmlChar *startup,
                         boolean *loaded)
{
    cfg_template_t  *cfg;
    xmlChar         *fname;
    agt_profile_t   *profile;
    status_t         res;

    res = NO_ERR;
    *loaded = FALSE;
    profile = agt_get_profile();

    cfg = cfg_get_config(NCX_CFG_RUNNING);
    if (!cfg) {
        log_error("\nagt: No running config found!!");
        return SET_ERROR(ERR_INTERNAL_VAL);
    }

    /* use the user-set startup or default filename */
    if (startup) {
        /* relative filespec, use search path */
        fname = ncxmod_find_data_file(startup, FALSE, &res);
    } else {
        /* search for the default startup-cfg.xml filename */
        fname = ncxmod_find_data_file(NCX_DEF_STARTUP_FILE, FALSE, &res);
    }

    /* check if error finding the filespec */
    if (!fname) {
        if (startup) {
            if (res == NO_ERR) {
                res = ERR_NCX_MISSING_FILE;
            }
            log_error("\nError: Startup config file (%s) not found (%s).",
                      startup, get_error_string(res));
            return res;
        } else {
            log_info("\nDefault startup config file (%s) not found."
                     "\n   Booting with default running configuration!\n",
                     NCX_DEF_STARTUP_FILE);
            return NO_ERR;
        }
    } else if (LOGDEBUG2) {
        log_debug2("\nFound startup config: '%s'", fname);
    }
    
    /* try to load the config file that was found or given */
    res = agt_ncx_cfg_load(cfg, CFG_LOC_FILE, fname);
    if (res == ERR_XML_READER_START_FAILED) {
        log_error("\nagt: Error: Could not open startup config file"
                  "\n     (%s)\n", fname);
    } else if (res != NO_ERR) {
        /* if an error is returned then it was a hard error
         * since the startup_error and running_error profile
         * variables have already been accounted for.
         * An error in the setup or in the AGT_RPC_PH_INVOKE phase
         * of the <load-config> operation occurred
         */
        log_error("\nError: load startup config failed (%s)",
                  get_error_string(res));
        if (!dlq_empty(&cfg->load_errQ)) {
            *loaded = TRUE;
        }
    } else {
        /* assume OK or startup and running continue; if 1 or both is not
         * set then the server will exit anyway and the config state
         * will not matter
         */
        profile->agt_config_state = AGT_CFG_STATE_OK;

        *loaded = TRUE;

        boolean errdone = FALSE;
        boolean errcontinue = FALSE;

        if (profile->agt_load_validate_errors) {
            if (profile->agt_startup_error) {
                /* quit if any startup validation errors */
                log_error("\nError: validation errors occurred loading the "
                          "<running> database\n   from NV-storage"
                          " (%s)\n", fname);
                errdone = TRUE;
            } else {
                /* continue if any startup errors */
                log_warn("\nWarning: validation errors occurred loading "
                         "the <running> database\n   from NV-storage"
                         " (%s)\n", fname);
                errcontinue = TRUE;
            }
        }
        if (!errdone && profile->agt_load_rootcheck_errors) {
            if (profile->agt_startup_error) {
                /* quit if any startup root-check validation errors */
                log_error("\nError: root-check validation errors "
                          "occurred loading the <running> database\n"
                          "   from NV-storage (%s)\n", fname);
                errdone = TRUE;
            } else {
                /* continue if any root-check validation errors */
                log_warn("\nWarning: root-check validation errors "
                         "occurred loading the <running> database\n"
                         "   from NV-storage (%s)\n", fname);
                errcontinue = TRUE;
            }
        }
        if (!errdone && profile->agt_load_top_rootcheck_errors) {
            if (profile->agt_running_error) {
                /* quit if any top-level root-check validation errors */
                log_error("\nError: top-node root-check validation errors "
                          "occurred loading the <running> database\n"
                          "   from NV-storage (%s)\n", fname);
                errdone = TRUE;
            } else {
                /* continue if any startup errors */
                log_warn("\nWarning: top-node root-check validation errors "
                         "occurred loading the <running> database\n"
                         "   from NV-storage (%s)\n", fname);
                profile->agt_config_state = AGT_CFG_STATE_BAD;
                errcontinue = TRUE;
            }
        }
        if (!errdone && profile->agt_load_apply_errors) {
            /* quit if any apply-to-running SIL errors */
            errdone = TRUE;
            log_error("\nError: fatal errors "
                      "occurred loading the <running> database "
                      "from NV-storage\n     (%s)\n", fname);
        }

        if (errdone) {
            res = ERR_NCX_OPERATION_FAILED;
        } else if (errcontinue) {
            val_purge_errors_from_root(cfg->root);
            log_info("\nagt: Startup config loaded after pruning error nodes\n"
                     "Source: %s\n", fname);
        } else {
            log_info("\nagt: Startup config loaded OK\n     Source: %s\n",
                     fname);
        }
    }

    if (LOGDEBUG) {
        log_debug("\nContents of %s configuration:", cfg->name);
        val_dump_value(cfg->root, 0);
        log_debug("\n");
    }

    if (fname) {
        m__free(fname);
    }

    return res;

} /* load_running_config */
Beispiel #25
0
/********************************************************************
* FUNCTION y_ietf_netconf_partial_lock_partial_lock_invoke
* 
* RPC invocation phase
* All constraints have passed at this point.
* Call device instrumentation code in this function.
* 
* INPUTS:
*     see agt/agt_rpc.h for details
* 
* RETURNS:
*     error status
********************************************************************/
static status_t
    y_ietf_netconf_partial_lock_partial_lock_invoke (
        ses_cb_t *scb,
        rpc_msg_t *msg,
        xml_node_t *methnode)
{
    plock_cb_t *plcb;
    val_value_t *testval, *newval;
    xpath_result_t *result;
    xpath_resnode_t *resnode, *clearnode;
    xmlChar *pathbuff;
    cfg_template_t *running;
    status_t res;
    ncx_num_t num;

    res = NO_ERR;

    plcb = (plock_cb_t *)msg->rpc_user1;
    result = plock_get_final_result(plcb);
    running = cfg_get_config_id(NCX_CFGID_RUNNING);

    /* try to lock all the target nodes */
    for (resnode = xpath_get_first_resnode(result);
         resnode != NULL && res == NO_ERR;
         resnode = xpath_get_next_resnode(resnode)) {

        testval = xpath_get_resnode_valptr(resnode);

        res = val_set_partial_lock(testval, plcb);
        if (res != NO_ERR) {
            agt_record_error(scb,
                             &msg->mhdr,
                             NCX_LAYER_OPERATION,
                             res,
                             methnode,
                             NCX_NT_NONE,
                             NULL,
                             NCX_NT_VAL,
                             testval);
        }
    }

    /* unlock any nodes already attempted if any fail */
    if (res != NO_ERR) {
        for (clearnode = xpath_get_first_resnode(result);
             clearnode != NULL;
             clearnode = xpath_get_next_resnode(clearnode)) {

            testval = xpath_get_resnode_valptr(clearnode);

            val_clear_partial_lock(testval, plcb);
            if (clearnode == resnode) {
                return res;
            }
        }
        return res;
    }

    /* add this partial lock to the running config */
    res = cfg_add_partial_lock(running, plcb);
    if (res != NO_ERR) {
        /* should not happen since config lock state could
         * not have changed since validate callback
         */
        agt_record_error(scb,
                         &msg->mhdr,
                         NCX_LAYER_OPERATION,
                         res,
                         methnode,
                         NCX_NT_NONE,
                         NULL,
                         NCX_NT_NONE,
                         NULL);
        for (clearnode = xpath_get_first_resnode(result);
             clearnode != NULL;
             clearnode = xpath_get_next_resnode(clearnode)) {

            testval = xpath_get_resnode_valptr(clearnode);
            val_clear_partial_lock(testval, plcb);
        }
        plock_cb_free(plcb);
        return res;
    }

    /* setup return data only if lock successful
     * cache the reply instead of stream the reply
     * in case there is any error; if so; the partial
     * lock will be backed out and the dataQ cleaned
     * for an error exit; add lock-id leaf first 
     */
    msg->rpc_data_type = RPC_DATA_YANG;
    
    ncx_init_num(&num);
    num.u = plock_get_id(plcb);
    newval = xml_val_new_number
        (y_ietf_netconf_partial_lock_N_lock_id,
         val_get_nsid(msg->rpc_input),
         &num,
         NCX_BT_UINT32);
    ncx_clean_num(NCX_BT_UINT32, &num);

    if (newval == NULL) {
        res = ERR_INTERNAL_MEM;
        agt_record_error(scb, 
                         &msg->mhdr, 
                         NCX_LAYER_OPERATION, 
                         res,
                         methnode, 
                         NCX_NT_NONE, 
                         NULL, 
                         NCX_NT_NONE, 
                         NULL);
    } else {
        dlq_enque(newval, &msg->rpc_dataQ);
    }

    /* add lock-node leaf-list instance for each resnode */
    for (resnode = xpath_get_first_resnode(result);
         resnode != NULL && res == NO_ERR;
         resnode = xpath_get_next_resnode(resnode)) {

        /* Q&D method: generate the i-i string as a plain
         * string and add any needed prefixes to the global
         * prefix map for the reply message (in mhdr)
         */
        pathbuff = NULL;
        testval = xpath_get_resnode_valptr(resnode);
        res = val_gen_instance_id(&msg->mhdr, 
                                  testval,
                                  NCX_IFMT_XPATH1, 
                                  &pathbuff);
        if (res == NO_ERR) {
            /* make leaf; pass off pathbuff malloced memory */
            newval = xml_val_new_string
                (y_ietf_netconf_partial_lock_N_locked_node,
                 val_get_nsid(msg->rpc_input),
                 pathbuff);
            if (newval == NULL) {
                res = ERR_INTERNAL_MEM;
                m__free(pathbuff);
                pathbuff = NULL;
            }
        }

        if (res == NO_ERR) {
            dlq_enque(newval, &msg->rpc_dataQ);
        } else {
            agt_record_error(scb, 
                             &msg->mhdr, 
                             NCX_LAYER_OPERATION, 
                             res,
                             methnode, 
                             NCX_NT_NONE, 
                             NULL, 
                             NCX_NT_NONE, 
                             NULL);
        }
    }

    if (res != NO_ERR) {
        /* back out everything, except waste the lock ID */
        for (clearnode = xpath_get_first_resnode(result);
             clearnode != NULL;
             clearnode = xpath_get_next_resnode(clearnode)) {

            testval = xpath_get_resnode_valptr(clearnode);
            val_clear_partial_lock(testval, plcb);
        }
        cfg_delete_partial_lock(running, plock_get_id(plcb));

        /* clear any data already queued */
        while (!dlq_empty(&msg->rpc_dataQ)) {
            testval = (val_value_t *)
                dlq_deque(&msg->rpc_dataQ);
            val_free_value(testval);
        }
        msg->rpc_data_type = RPC_DATA_NONE;
    }

    return res;

} /* y_ietf_netconf_partial_lock_partial_lock_invoke */