コード例 #1
0
ファイル: yangcli_autolock.c プロジェクト: 0xDEC0DE8/OpenYuma
/********************************************************************
* FUNCTION send_discard_changes_pdu_to_server
* 
* Send a <discard-changes> operation to the server
*
* INPUTS:
*   server_cb == server control block to use
*
* RETURNS:
*    status
*********************************************************************/
status_t
    send_discard_changes_pdu_to_server (server_cb_t *server_cb)
{
    obj_template_t        *rpc;
    mgr_rpc_req_t         *req;
    val_value_t           *reqdata;
    ses_cb_t              *scb;
    status_t               res;
    xmlns_id_t             obj_nsid;

    req = NULL;
    reqdata = NULL;
    res = NO_ERR;

    if (LOGDEBUG) {
        log_debug("\nSending <discard-changes> request");
    }
    
    rpc = ncx_find_object(get_netconf_mod(server_cb), 
                          NCX_EL_DISCARD_CHANGES);
    if (!rpc) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    obj_nsid = obj_get_nsid(rpc);

    /* construct a method node */
    reqdata = xml_val_new_flag(obj_get_name(rpc), 
                               obj_nsid);
    if (!reqdata) {
        log_error("\nError allocating a new RPC request");
        return ERR_INTERNAL_MEM;
    }

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (!scb) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    } else {
        req = mgr_rpc_new_request(scb);
        if (!req) {
            res = ERR_INTERNAL_MEM;
            log_error("\nError allocating a new RPC request");
        } else {
            req->data = reqdata;
            req->rpc = rpc;
            req->timeout = server_cb->timeout;
        }
    }
        
    /* if all OK, send the RPC request */
    if (res == NO_ERR) {
        if (LOGDEBUG2) {
            log_debug2("\nabout to send RPC request with reqdata:");
            val_dump_value_max(reqdata, 
                               0,
                               server_cb->defindent,
                               DUMP_VAL_LOG,
                               server_cb->display_mode,
                               FALSE,
                               FALSE);
        }

        /* the request will be stored if this returns NO_ERR */
        res = mgr_rpc_send_request(scb, req, yangcli_reply_handler);
        if (res == NO_ERR) {
            server_cb->command_mode = CMD_MODE_AUTODISCARD;
        }
    }

    /* cleanup and set next state */
    if (res != NO_ERR) {
        if (req) {
            mgr_rpc_free_request(req);
        } else if (reqdata) {
            val_free_value(reqdata);
        }
    } else {
        server_cb->state = MGR_IO_ST_CONN_RPYWAIT;
    }

    return res;

} /* send_discard_changes_pdu_to_server */
コード例 #2
0
ファイル: conf.c プロジェクト: 0xDEC0DE8/OpenYuma
/********************************************************************
* FUNCTION parse_val
* 
* Parse, and fill one val_value_t struct during
* processing of a text config file
*
* Error messages are printed by this function!!
* Do not duplicate error messages upon error return
*
* The value name is the current token.
* Based on the value typdef, the res of the tokens
* comprising the value statement will be processed
*
* INPUTS:
*   tkc == token chain
*   obj == the object template struct to use for filling in 'val'
*   val == initialized value struct, without any value,
*          which will be filled in by this function
*   nsid == namespace ID to use for this value
*   valname == name of the value struct
*
* RETURNS:
*   status of the operation
*********************************************************************/
static status_t 
    parse_val (tk_chain_t  *tkc,
               obj_template_t *obj,
               val_value_t *val)
{
    obj_template_t  *chobj;
    val_value_t     *chval;
    const xmlChar   *valname, *useval;
    typ_def_t       *typdef;
    status_t         res;
    ncx_btype_t      btyp;
    boolean          done;
    xmlns_id_t       nsid;

    btyp = obj_get_basetype(obj);
    nsid = obj_get_nsid(obj);
    valname = obj_get_name(obj);
    typdef = obj_get_typdef(obj);

    /* check if there is an index clause expected */
    if (typ_has_index(btyp)) {
        res = parse_index(tkc, obj, val, nsid);
        if (res != NO_ERR) {
            return res;
        }
    }

    /* get next token, NEWLINE is significant at this point */
    res = adv_tk(tkc);
    if (res != NO_ERR) {
        return res;
    }

    /* the current token should be the value for a leaf
     * or a left brace for the start of a complex type
     * A NEWLINE is treated as if the user entered a
     * zero-length string for the value.  (Unless the
     * base type is NCX_BT_EMPTY, in which case the NEWLINE
     * is the expected token
     */
    if (typ_is_simple(btyp)) {
        /* form for a leaf is: foo [value] NEWLINE  */
        if (TK_CUR_TYP(tkc)==TK_TT_NEWLINE) {
            useval = NULL;
        } else {
            useval = TK_CUR_VAL(tkc);
        }
        res = val_set_simval(val, 
                             typdef, 
                             nsid, 
                             valname,
                             useval);

        if (res != NO_ERR) {
            log_error("\nError: '%s' cannot be set to '%s'",
                      valname,
                      (TK_CUR_VAL(tkc)) ? TK_CUR_VAL(tkc) : EMPTY_STRING);
            if (btyp == NCX_BT_EMPTY) {
                ncx_conf_exp_err(tkc, res, "empty");
            } else {
                ncx_conf_exp_err(tkc, res, "simple value string");
            }
            return res;
        }

        /* get a NEWLINE unless current token is already a NEWLINE */
        if (TK_CUR_TYP(tkc) != TK_TT_NEWLINE) {
            res = adv_tk(tkc);
            if (res != NO_ERR) {
                return res;
            }
            if (TK_CUR_TYP(tkc) != TK_TT_NEWLINE) {
                res = ERR_NCX_WRONG_TKTYPE;
                ncx_conf_exp_err(tkc, res, "\\n");
            }
        }
    } else {
        /* complex type is foo {  ... } or
         * foo index1 index2 { ... }
         * If there is an index, it was already parsed
         */
        res = consume_tk(tkc, TK_TT_LBRACE);
        if (res != NO_ERR) {
            ncx_conf_exp_err(tkc, res, "left brace");
            return res;
        }

        /* get all the child nodes specified for this complex type */
        res = NO_ERR;
        done = FALSE;
        while (!done && res==NO_ERR) {
            /* start out looking for a child node name or a
             * right brace to end the sub-section
             */
            if (tk_next_typ(tkc)==TK_TT_NEWLINE) {
                /* skip the NEWLINE token */
                (void)adv_tk(tkc);
            } else if (tk_next_typ(tkc)==TK_TT_RBRACE) {
                /* found end of sub-section */
                done = TRUE;
            } else {
                /* get the next token */
                res = adv_tk(tkc);
                if (res != NO_ERR) {
                    continue;
                }

                /* make sure cur token is an identifier string
                 * if so, find the child node and call this function
                 * recursively to fill it in and add it to
                 * the parent 'val'
                 */
                if (TK_CUR_ID(tkc)) {
                    /* parent 'typdef' must have a child with a name
                     * that matches the current token vale
                     */
                    chobj = obj_find_child(obj, 
                                           TK_CUR_MOD(tkc),
                                           TK_CUR_VAL(tkc));
                    if (chobj) {
                        chval = val_new_value();
                        if (!chval) {
                            res = ERR_INTERNAL_MEM;
                            ncx_print_errormsg(tkc, NULL, res);
                        } else {
                            val_init_from_template(chval, chobj);
                            res = parse_val(tkc, chobj, chval);
                            if (res == NO_ERR) {
                                val_add_child(chval, val);
                            } else {
                                val_free_value(chval);
                            }
                        }
                    } else {
                        /* string is not a child name in this typdef */
                        res = ERR_NCX_DEF_NOT_FOUND;
                        ncx_conf_exp_err(tkc, res, "identifier string");
                    }
                } else {
                    /* token is not an identifier string */
                    res = ERR_NCX_WRONG_TKTYPE;
                    ncx_conf_exp_err(tkc, res, "identifier string");
                }
            }
        }  /* end loop through all the child nodes */

        /* expecting a right brace to finish the complex value */
        if (res == NO_ERR) {
            res = consume_tk(tkc, TK_TT_RBRACE);
            if (res != NO_ERR) {
                ncx_conf_exp_err(tkc, res, "right brace");
                return res;
            }
        }
    }

    return res;

}  /* parse_val */
コード例 #3
0
ファイル: yangcli_autolock.c プロジェクト: 0xDEC0DE8/OpenYuma
/********************************************************************
* FUNCTION send_lock_pdu_to_server
* 
* Send a <lock> or <unlock> operation to the server
*
* INPUTS:
*   server_cb == server control block to use
*   lockcb == lock control block to use within server_cb
*   islock == TRUE for lock; FALSE for unlock
*
* RETURNS:
*    status
*********************************************************************/
static status_t
    send_lock_pdu_to_server (server_cb_t *server_cb,
                            lock_cb_t *lockcb,
                            boolean islock)
{
    obj_template_t        *rpc, *input;
    mgr_rpc_req_t         *req;
    val_value_t           *reqdata, *targetval, *parmval;
    ses_cb_t              *scb;
    status_t               res;
    xmlns_id_t             obj_nsid;

    req = NULL;
    reqdata = NULL;
    res = NO_ERR;

    if (LOGDEBUG) {
        log_debug("\nSending <%s> request",
                  (islock) ? NCX_EL_LOCK : NCX_EL_UNLOCK);
    }

    if (islock) {
        rpc = ncx_find_object(get_netconf_mod(server_cb), 
                              NCX_EL_LOCK);
    } else {
        rpc = ncx_find_object(get_netconf_mod(server_cb), 
                              NCX_EL_UNLOCK);
    }
    if (!rpc) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    obj_nsid = obj_get_nsid(rpc);

    /* get the 'input' section container */
    input = obj_find_child(rpc, NULL, YANG_K_INPUT);
    if (!input) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    /* construct a method + parameter tree */
    reqdata = xml_val_new_struct(obj_get_name(rpc), obj_nsid);
    if (!reqdata) {
        log_error("\nError allocating a new RPC request");
        return ERR_INTERNAL_MEM;
    }

    /* set the [un]lock/input/target node XML namespace */
    targetval = xml_val_new_struct(NCX_EL_TARGET, obj_nsid);
    if (!targetval) {
        log_error("\nError allocating a new RPC request");
        val_free_value(reqdata);
        return ERR_INTERNAL_MEM;
    } else {
        val_add_child(targetval, reqdata);
    }

    parmval = xml_val_new_flag(lockcb->config_name,
                               obj_nsid);
    if (!parmval) {
        val_free_value(reqdata);
        return ERR_INTERNAL_MEM;
    } else {
        val_add_child(parmval, targetval);
    }

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (!scb) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    } else {
        req = mgr_rpc_new_request(scb);
        if (!req) {
            res = ERR_INTERNAL_MEM;
            log_error("\nError allocating a new RPC request");
        } else {
            req->data = reqdata;
            req->rpc = rpc;
            req->timeout = server_cb->timeout;
        }
    }
        
    /* if all OK, send the RPC request */
    if (res == NO_ERR) {
        if (LOGDEBUG2) {
            log_debug2("\nabout to send RPC request with reqdata:");
            val_dump_value_max(reqdata, 
                               0,
                               server_cb->defindent,
                               DUMP_VAL_LOG,
                               server_cb->display_mode,
                               FALSE,
                               FALSE);
        }

        /* the request will be stored if this returns NO_ERR */
        res = mgr_rpc_send_request(scb, req, yangcli_reply_handler);
        if (res == NO_ERR) {
            if (islock) {
                lockcb->lock_state = LOCK_STATE_REQUEST_SENT;
            } else {
                lockcb->lock_state = LOCK_STATE_RELEASE_SENT;
            }
            (void)uptime(&lockcb->last_msg_time);
            server_cb->locks_cur_cfg = lockcb->config_id;
        }
    }

    /* cleanup and set next state */
    if (res != NO_ERR) {
        if (req) {
            mgr_rpc_free_request(req);
        } else if (reqdata) {
            val_free_value(reqdata);
        }
    } else {
        server_cb->state = MGR_IO_ST_CONN_RPYWAIT;
    }

    return res;

} /* send_lock_pdu_to_server */
コード例 #4
0
/********************************************************************
 * FUNCTION parse_node
 * (config mode input received)
 *  Parse the next word using the comstate and session_cb state
 *  Expecting this word to represent a datastore node, not a key or value
 *
 * e.g.,
 *  interface eth0 mtu 1500
 *      ^      ^    ^    ^
 *    node    key node  value
 *
 * INPUTS:
 *    tkc == token chain in progress
 *    session_cb == session control block to use
 *    done == address of return done flag
 *    gotexit == address of return gotexit flag
 *    gotapply == address of return gotapply flag
 *    gotdo == address of return do command flag
 *
 * OUTPUTS:
 *    *done == TRUE if parsing done; no more tokens;
 *             ignore unless return NO_ERR
 *    *gotexit == TRUE if got 'exit' command
 *             ignore unless return NO_ERR and *done == TRUE
 *    *gotapply == TRUE if got 'apply' command
 *             ignore unless return NO_ERR and *done == TRUE
 *    *gotdo == TRUE if got 'do' command
 * RETURNS:
 *   status
 *********************************************************************/
static status_t
    parse_node (tk_chain_t *tkc,
                session_cb_t *session_cb,
                boolean *done,
                boolean *gotexit,
                boolean *gotapply,
                boolean *gotdo)
{
    *done = FALSE;
    *gotexit = FALSE;
    *gotapply = FALSE;
    *gotdo = FALSE;

    /* get the next token to use */
    status_t res = TK_ADV(tkc);
    if (res != NO_ERR) {
        if (res == ERR_NCX_EOF) {
            *done = TRUE;
            return NO_ERR;
        } else {
            log_error("\nError: Expecting node identifier\n");
            return res;
        }
    }

    boolean first = tk_cur_is_first(tkc);

    /* check if the 'do' form of command was given */
    if (first && TK_CUR_TYP(tkc) == TK_TT_TSTRING &&
        !xml_strcmp(TK_CUR_VAL(tkc), NCX_EL_DO) &&
        tk_next_typ(tkc) != TK_TT_NONE) {

        *gotdo = TRUE;
        *done = TRUE;
        return NO_ERR;
    }

    /* check if the 'no' form of command was given */
    if (first && TK_CUR_TYP(tkc) == TK_TT_TSTRING &&
        !xml_strcmp(TK_CUR_VAL(tkc), NCX_EL_NO) &&
        tk_next_typ(tkc) != TK_TT_NONE) {

        /* get the next token to use as the first identifier */
        res = TK_ADV(tkc);
        if (res != NO_ERR) {
            log_error("\nError: Expecting identifier token after "
                      "'no' keyword\n");
            return res;
        }
        first = FALSE;
        session_cb->config_no_active = TRUE;
    }

    /* check if the current token is an identifier */
    if (!TK_CUR_ID(tkc)) {
        log_error("\nError: expecting a node identifier\n");
        res = ERR_NCX_WRONG_TKTYPE;
        return res;
    }

    /* check if the exit command was given */
    if (first && TK_CUR_TYP(tkc) == TK_TT_TSTRING &&
        !xml_strcmp(TK_CUR_VAL(tkc), NCX_EL_EXIT) &&
        tk_next_typ(tkc) == TK_TT_NONE) {
        *done = TRUE;
        *gotexit = TRUE;
        return NO_ERR;
    }

    /* check if the apply command was given */
    if (first && TK_CUR_TYP(tkc) == TK_TT_TSTRING &&
        !xml_strcmp(TK_CUR_VAL(tkc), NCX_EL_APPLY) &&
        tk_next_typ(tkc) == TK_TT_NONE) {
        *done = TRUE;
        *gotapply = TRUE;
        return NO_ERR;
    }

    obj_template_t *startobj = session_cb->config_curobj;
    obj_template_t *topobj = NULL;

    if (startobj == NULL) {
        /* getting top-level config object */
        topobj = find_top_obj(session_cb, TK_CUR_VAL(tkc));
        if (topobj && !(obj_is_data_db(topobj) && obj_is_config(topobj))) {
            topobj = NULL;
        }
    } else {
        /* getting child node config object */
        topobj = find_child_obj(session_cb, startobj, TK_CUR_VAL(tkc));
        if (topobj && !obj_is_config(topobj)) {
            topobj = NULL;
        }
    }
    
    if (topobj == NULL) {
        log_error("\nError: No config object found matching '%s'\n",
                  TK_CUR_VAL(tkc));
        return ERR_NCX_UNKNOWN_OBJECT;
    }

    /* got a top object (relative to the current context) */
    session_cb->config_curobj = topobj;

    /* make a template object for the edit operation for non-terminals */
    val_value_t *newval = NULL;
    if (!obj_is_leafy(topobj)) {
        newval = val_new_value();
        if (newval == NULL) {
            log_error("\nError: malloc failed for new value\n");
            return ERR_INTERNAL_MEM;
        }
        val_init_from_template(newval, topobj);
        add_enode(session_cb, newval);
    } else if (session_cb->config_no_active && obj_is_leaf(topobj)) {
        /* no ... foo-leaf */
        newval = xml_val_new_flag(obj_get_name(topobj), obj_get_nsid(topobj));
        if (newval == NULL) {
            log_error("\nError: malloc failed for new value\n");
            return ERR_INTERNAL_MEM;
        }
        add_enode(session_cb, newval);
    }

    if (obj_is_list(topobj)) {
        boolean anykeys = FALSE;
        obj_key_t *newkey = obj_first_key(topobj);
        while (newkey) {
            anykeys = TRUE;

            /* get the next token to use as the key value */
            res = TK_ADV(tkc);
            if (res != NO_ERR) {
                log_error("\nError: Expecting value for '%s' key leaf\n",
                          obj_get_name(newkey->keyobj));
                return res;
            }

            /* parse the value as a key value */
            /*** do something different if TK_CUR_MOD(tkc) is not NULL ***/
            val_value_t *keyval =
                val_make_simval_obj(newkey->keyobj, TK_CUR_VAL(tkc), &res);
            if (res != NO_ERR) {
                log_error("\nError: Invalid value for '%s' key leaf\n",
                          obj_get_name(newkey->keyobj));
                val_free_value(keyval);
                return res;
            }

            /* save keyval */
            if (newval) {
                val_add_child(keyval, newval);
            } else {
                val_free_value(keyval);
            }

            /* set up the next key in the list */
            newkey = obj_next_key(newkey);
        }
        if (anykeys) {
            res = val_gen_index_chain(topobj, newval);
        }
    }

    if (res == NO_ERR && obj_is_leafy(topobj)) {
        /* expecting a value node to follow or done if 'no' command */
        *done = TRUE;
    }

    return res;

}  /* parse_node */