예제 #1
0
/********************************************************************
 * FUNCTION add_alias
 * 
 * Add the alias record
 *
 * INPUTS:
 *   alias == alias to add
 *
 * RETURNS:
 *   status
 *********************************************************************/
static status_t
    add_alias (alias_cb_t *alias)
{
    dlq_hdr_t  *aliasQ = get_aliasQ();
    alias_cb_t *curalias;
    int         ret;

    if (aliasQ == NULL) {
        SET_ERROR(ERR_INTERNAL_VAL);
        free_alias(alias);
        return ERR_INTERNAL_VAL;
    }

    for (curalias = (alias_cb_t *)dlq_firstEntry(aliasQ);
         curalias != NULL;
         curalias = (alias_cb_t *)dlq_nextEntry(curalias)) {

        ret = xml_strcmp(curalias->name, alias->name);
        if (ret == 0) {
            SET_ERROR(ERR_NCX_DUP_ENTRY);
            free_alias(alias);
            return ERR_NCX_DUP_ENTRY;
        } else if (ret > 0) {
            dlq_insertAhead(alias, curalias);
            return NO_ERR;
        }
    }

    /* new last entry */
    dlq_enque(alias, aliasQ);
    return NO_ERR;

}  /* add_alias */
예제 #2
0
/********************************************************************
* FUNCTION y_simple_list_test_get_counter_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_simple_list_test_get_counter_invoke (
    ses_cb_t *scb,
    rpc_msg_t *msg,
    xml_node_t *methnode)
{
    status_t res = NO_ERR;
    val_value_t     *countVal;
    xmlChar          countBuff[100];

    /* remove the next line if scb is used */
    (void)scb;

    /* remove the next line if msg is used */
    (void)msg;

    /* remove the next line if methnode is used */
    (void)methnode;

    /* invoke your device instrumentation code here */
    snprintf((char *)countBuff, sizeof(countBuff), "%u", count_static);
    countVal = val_make_string(0,
                               (xmlChar*)"count",
                               countBuff);
    if (countVal == NULL) {
        val_free_value(countVal);
        return ERR_INTERNAL_MEM;
    }

    dlq_enque(countVal, &msg->rpc_dataQ);
    msg->rpc_data_type = RPC_DATA_STD;

    return res;

} /* y_simple_list_test_get_counter_invoke */
예제 #3
0
/********************************************************************
* FUNCTION get_my_session_invoke
*
* get-my-session : invoke params callback
*
* INPUTS:
*    see rpc/agt_rpc.h
* RETURNS:
*    status
*********************************************************************/
static status_t 
    get_my_session_invoke (ses_cb_t *scb,
                           rpc_msg_t *msg,
                           xml_node_t *methnode)
{
    val_value_t     *indentval, *linesizeval, *withdefval;
    xmlChar          numbuff[NCX_MAX_NUMLEN];

    (void)methnode;

    snprintf((char *)numbuff, sizeof(numbuff), "%u", scb->indent);
    indentval = val_make_string(mysesmod->nsid,
                                NCX_EL_INDENT,
                                numbuff);
    if (indentval == NULL) {
        return ERR_INTERNAL_MEM;
    }

    snprintf((char *)numbuff, sizeof(numbuff), "%u", scb->linesize);
    linesizeval = val_make_string(mysesmod->nsid,
                                  NCX_EL_LINESIZE,
                                  numbuff);
    if (linesizeval == NULL) {
        val_free_value(indentval);
        return ERR_INTERNAL_MEM;
    }

    withdefval = 
        val_make_string(mysesmod->nsid,
                        NCX_EL_WITH_DEFAULTS,
                        ncx_get_withdefaults_string(scb->withdef));
    if (withdefval == NULL) {
        val_free_value(indentval);
        val_free_value(linesizeval);
        return ERR_INTERNAL_MEM;
    }

    dlq_enque(indentval, &msg->rpc_dataQ);
    dlq_enque(linesizeval, &msg->rpc_dataQ);
    dlq_enque(withdefval, &msg->rpc_dataQ);
    msg->rpc_data_type = RPC_DATA_YANG;
    return NO_ERR;

} /* get_my_session_invoke */
예제 #4
0
/********************************************************************
* FUNCTION add_request
*
* Add an RPC request to the Q
* 
* INPUTS:
*   scb == session control block
*   req == mgr_rpc_req_t to add
*
* RETURNS:
*   none
*********************************************************************/
static void
    add_request (ses_cb_t *scb,
                 mgr_rpc_req_t  *req)
{
    mgr_scb_t *mscb;

    mscb = mgr_ses_get_mscb(scb);

    (void)uptime(&req->starttime);

    dlq_enque(req, &mscb->reqQ);

}  /* add_request */
예제 #5
0
/********************************************************************
* FUNCTION ncx_set_feature_code_entry
* 
* Create or set a feature_entry struct for the specified 
* feature code parameter
*
* !!! THIS FUNCTION IS DEPRECATED!!!
* !!! The --feature-code and --feature-code-default parameters are ignored
* !!! Feature code generation is not controlled by this parameter 
*
* INPUTS:
*   featstr == feature parameter string
*   featcode == ncx_feature_code_t enumeration to set
*
* RETURNS:
*   status
*********************************************************************/
status_t
    ncx_set_feature_code_entry (const xmlChar *featstr,
                                ncx_feature_code_t featcode)
{
    feature_entry_t  *fentry;
    status_t          res;
    uint32            cnt;

#ifdef DEBUG
    if (featstr == NULL) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

    res = NO_ERR;
    fentry = find_feature_entry(featstr, &feature_entryQ);
    if (fentry != NULL) {
        if (fentry->code_set) {
            if (fentry->code != featcode) {
                log_error("\nError: feature '%s' already set with "
                          "conflicting value",
                          featstr);
                res = ERR_NCX_INVALID_VALUE;
            } else {
                log_info("\nFeature '%s' already set with "
                          "same value",
                          featstr);
            }
        } else {
            fentry->code_set = TRUE;
            fentry->code = featcode;
        }
    } else {
        cnt = 0;
        res = split_feature_string(featstr, &cnt);
        if (res == NO_ERR) {
            fentry = new_feature_entry(featstr);
            if (fentry == NULL) {
                res = ERR_INTERNAL_MEM;
            } else {
                fentry->code_set = TRUE;
                fentry->code = featcode;
                dlq_enque(fentry, &feature_entryQ);
            }
        }
    }
    return res;

}  /* ncx_set_feature_code_entry */
예제 #6
0
/********************************************************************
* FUNCTION add_pmap
*
* Add a prefix mapping entry
*
* INPUTS:
*    msg  == message to search
*    newpmap == xmlns_pmap_t struct to add
*
* RETURNS:
*   none
*********************************************************************/
static void
add_pmap (xml_msg_hdr_t *msg,
          xmlns_pmap_t *newpmap)
{
    xmlns_pmap_t  *pmap;

    /* add the new prefix mapping */
    for (pmap = (xmlns_pmap_t *)dlq_firstEntry(&msg->prefixQ);
            pmap != NULL;
            pmap = (xmlns_pmap_t *)dlq_nextEntry(pmap)) {
        if (newpmap->nm_id < pmap->nm_id) {
            dlq_insertAhead(newpmap, pmap);
            return;
        }
    }
    dlq_enque(newpmap, &msg->prefixQ);

}  /* add_pmap */
예제 #7
0
/********************************************************************
* FUNCTION ncx_set_feature_enable
* 
* Create or set a feature_entry struct for the specified 
* feature enabled parameter
*
* Called from SIL init code
*
* INPUTS:
*   modname == name of module defining the feature
*   name == feature name
*   flag == feature enabled flag
*
* RETURNS:
*   status
*********************************************************************/
status_t
    ncx_set_feature_enable (const xmlChar *modname,
                            const xmlChar *name,
                            boolean flag)
{
    assert( modname && "modname is NULL!" );
    assert( name && "modname is NULL!" );

    status_t res = NO_ERR;
    feature_entry_t *fentry = 
        find_feature_entry2(modname, name, &feature_entryQ);
    if (fentry != NULL) {
        if (fentry->enable_set) {
            if (fentry->enable != flag) {
                if (flag) {
                    /* SIL enabled, so previous CLI disable is allowed */
                    log_debug("\nFeature '%s' already disabled from CLI, "
                             "ignoring SIL disable", name);
                } else {
                    /* SIL disabled so override CLI enable */
                    log_info("\nFeature '%s' disabled in SIL, "
                             "overriding CLI enable", name);
                    fentry->enable = FALSE;
                }
            } /* else same value so ignore */
        } else {
            fentry->enable_set = TRUE;
            fentry->enable = flag;
        }
    } else {
        fentry = new_feature_entry2(modname, name);
        if (fentry == NULL) {
            res = ERR_INTERNAL_MEM;
        } else {
            fentry->enable_set = TRUE;
            fentry->enable = flag;
            dlq_enque(fentry, &feature_entryQ);
        }
    }
    return res;

}  /* ncx_set_feature_enable */
status_t agt_not_queue_notification_cb_register( const xmlChar *modname,
                                       agt_not_queue_notification_cb_t cb )
{
    assert( modname );

    agt_cb_queue_notification_set_t* cbSet = find_callback_set( modname );

    if ( !cbSet )
    {
        cbSet = new_callback_set( modname );
        if ( !cbSet )
        {
            return ERR_INTERNAL_MEM;
        }

        dlq_enque( cbSet, &callbackQ );
    }

    cbSet->callback = cb;
    return NO_ERR;
}
예제 #9
0
/********************************************************************
 * FUNCTION add_edit
 * (config mode input received)
 *  Add an edit to the server config_editQ
 *
 * INPUTS:
 *    session_cb == session control block to use
 *
 * RETURNS:
 *   status
 *********************************************************************/
static status_t
    add_edit (session_cb_t *session_cb)
{
    if (session_cb->config_etree) {
        op_editop_t delop = get_del_op(session_cb);
        op_editop_t op = (session_cb->config_no_active) ?
            delop : OP_EDITOP_MERGE;
        val_value_t *clone = val_clone(session_cb->config_etree);
        if (clone == NULL) {
            return ERR_INTERNAL_MEM;
        }
        config_edit_t *edit = new_config_edit(op, clone);
        if (edit == NULL) {
            val_free_value(clone);
            return ERR_INTERNAL_MEM;
        }
        session_cb->config_edit_dirty = TRUE;
        dlq_enque(edit, &session_cb->config_editQ);
    }
    return NO_ERR;

}  /* add_edit */
예제 #10
0
/********************************************************************
 * FUNCTION insert_event_cb
 * 
 * Insert a new event control block
 *
 * INPUTS:
 *   newcb == control block to insert
 *********************************************************************/
static void
    insert_event_cb (event_cb_t *newcb)
{
    /* insert sorted by module-name, event-name */
    event_cb_t *cb = (event_cb_t *)dlq_firstEntry(&event_cbQ);
    for (; cb; cb = (event_cb_t *)dlq_nextEntry(cb)) {
        int ret = xml_strcmp(newcb->modname, cb->modname);
        if (ret < 0) {
            dlq_insertAhead(newcb, cb);
            return;
        } else if (ret == 0) {
            int ret2 = xml_strcmp(newcb->event, cb->event);
            if (ret2 <= 0) {
                dlq_insertAhead(newcb, cb);
                return;
            }
        }
    }

    /* new last entry */
    dlq_enque(newcb, &event_cbQ);

} /* insert_event_cb */
예제 #11
0
/********************************************************************
* FUNCTION ncx_set_feature_enable_entry
* 
* Create or set a feature_entry struct for the specified 
* feature enabled parameter
*
* Called from CLI/conf handler code
*
* INPUTS:
*   featstr == feature parameter string
*   flag == enabled flag
*
* RETURNS:
*   status
*********************************************************************/
status_t
    ncx_set_feature_enable_entry (const xmlChar *featstr,
                                  boolean flag)
{
#ifdef DEBUG
    if (featstr == NULL) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

    status_t res = NO_ERR;
    feature_entry_t *fentry = find_feature_entry(featstr, &feature_entryQ);
    if (fentry != NULL) {
        if (fentry->enable_set) {
            if (fentry->enable != flag) {
                log_info("\nFeature '%s' already %s so ignoring new value",
                         (flag) ? "disabled" : "enabled", featstr);
                res = ERR_NCX_INVALID_VALUE;
            }
        } else {
            fentry->enable_set = TRUE;
            fentry->enable = flag;
        }
    } else {
        fentry = new_feature_entry(featstr);
        if (fentry == NULL) {
            res = ERR_INTERNAL_MEM;
        } else {
            fentry->enable_set = TRUE;
            fentry->enable = flag;
            dlq_enque(fentry, &feature_entryQ);
        }
    }
    return res;

}  /* ncx_set_feature_enable_entry */
예제 #12
0
/********************************************************************
* FUNCTION y_starter_starter_get_load_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_starter_starter_get_load_invoke (
    ses_cb_t *scb,
    rpc_msg_t *msg,
    xml_node_t *methnode)
{
    status_t res = NO_ERR;


    /* remove the next line if scb is used */
    (void)scb;

    /* remove the next line if msg is used */
    (void)msg;

    /* remove the next line if methnode is used */
    (void)methnode;

    /* invoke your device instrumentation code here */
    /*********************** THIS PART IS ADDED MANUALLY BY LEVI *************************/ 
	//--------- GET LOAD DATA ----------------
	//it looks like this: "0.01 0.14 0.12 1/309 6531"
	FILE *fp;
	int status;
	char load[30];
	
	//open the command for reading
	fp = popen("cat /proc/loadavg", "r");
	if(fp == NULL)
	{
		log_info("\nFailed to get LOAD\n");
			
	}
	else 
	{
		while(fgets(load, sizeof(load)-1, fp) != NULL)
		{
			log_info("\nRead data from cli: %s\n", load);		
		}	
		
		//closing
		pclose(fp);
	}
	//##########################################
	  
	  int numberOfLoadParams = 5;
	  char *load_params[numberOfLoadParams];
	  int n=0;
	  int nn;
	  
	  char *ds = strdup(load);
	  
	  load_params[n]=strtok(ds, " ");
	  //log_info("load_params[%d]:%s",n,load_params[n]);
	  while(load_params[n] && (n < (numberOfLoadParams-1)))
	  {
			load_params[++n] = strtok(NULL, " ");
//			log_info("[LOG]load_params[%d]:%s",n,load_params[n]);
	  }
	  
	  	
	 	
    
		val_value_t *childval = NULL;
    	childval = agt_make_list(
    				obj_find_child(starter_get_load_obj,y_starter_M_starter,"output"),
    				y_starter_N_load,
    				&res);
		if(childval != NULL)
		{
			log_info("\nList found and initialized");		
		}
		
		val_value_t *a = NULL;
/*		char loadOne[40] = "load_One";*/
		a = agt_make_leaf(
			childval->obj,
			y_starter_N_loadOne,
			(const xmlChar*)load_params[0],
			&res);
		if(a!=NULL)
		{
			log_info("\nloadOne filled with ");
			log_info(load_params[0]);

			val_add_child(a,childval);		
		}
		else 
		{
			return res;		
		}
		
		
/*		char loadFive[40] = "load_Five";*/
		a = agt_make_leaf(
			childval->obj,
			y_starter_N_loadFive,
			(const xmlChar*)load_params[1],
			&res);
		if(a!=NULL)
		{
			log_info("\nloadFive filled with ");
			log_info(load_params[1]);

			val_add_child(a,childval);		
		}
		else 
		{
			return res;		
		}
		
		
/*		char loadFifteen[40] = "load_Fifteen";*/
		a = agt_make_leaf(
			childval->obj,
			y_starter_N_loadFifteen,
			(const xmlChar*)load_params[2],
			&res);
		if(a!=NULL)
		{
			log_info("\nloadFifteen filled with ");
			log_info(load_params[2]);

			val_add_child(a,childval);		
		}
		else 
		{
			return res;		
		}
		
/*		char processesCE[40] = "processesCurrentlyExists";*/
		a = agt_make_leaf(
			childval->obj,
			y_starter_N_processesCurrentlyExists,
			(const xmlChar*)load_params[3],
			&res);
		if(a!=NULL)
		{
			log_info("\nprocessesCE filled with ");
			log_info(load_params[3]);

			val_add_child(a,childval);		
		}
		else 
		{
			return res;		
		}
		
		/*log_info("PID: %s", load_params[4]);*/
		//we need to remove the trailing \n from the end
		char* pid = strtok(load_params[4],"\n");
		a = agt_make_leaf(
			childval->obj,
			y_starter_N_pid,
			(const xmlChar*)pid,
			&res);
		if(a!=NULL)
		{
			log_info("\npid filled with ");
			log_info(pid);

			val_add_child(a,childval);		
		}
		else 
		{
			return res;		
		}

		free(ds);

		dlq_enque((void*)childval,&(msg->rpc_dataQ));

/*	 // ------------------------ CREATING A CUSTOM RPC REPLY -------------------------------
	
	 //declare a val_value_t * paramter   
    val_value_t *rpc_output = NULL;
    //making a leaf
    //	1.param -> we need to find the corresponding output element defined in the yang
    //		starter_get_load_obj is created automatically, since we have a get_load rpc in our module called starter -> starter_get_load_obj
    //		y_starter_M_starter corresponds to the module (you need to modify both strings 'starter' to your module name)
    //		"output" -> is the output part of the rpc (leave unmodified)
    //	2.param -> y_yourModuleName_N_leafNodeInYourRPCOUTPUT
    //	3.param -> the message you want to send (should be xmlChar*, char, char*)
    //	4. param -> the res variable which is returned by default 
	 rpc_output = agt_make_leaf(
	 		obj_find_child(starter_get_load_obj,y_starter_M_starter,"output"),
	 		y_starter_N_load,	
	 		load,
	 		&res);
	
	 //check that we could create correctly our RPC reply message
	 if (rpc_output!=NULL)
    {
    	//if yes -> put that to the rpc-reply (only rpc_output variable should be modified)
		dlq_enque((void*)rpc_output,&(msg->rpc_dataQ));
    }
    //if, however, something went wrong during creating rpc-reply, we print it into the log
    else 
    {
        log_error(
            "\nError: make leaf failed (%s), cannot send "
            "<load> rpc_reply",
            get_error_string(res));
    } 
    //======================================================================================   */
   
    /********************************** END OF LEVI **************************************/
    return res;

} /* y_starter_starter_get_load_invoke */
예제 #13
0
/********************************************************************
 * FUNCTION yangcli_notification_handler
 * 
 * matches callback template mgr_not_cbfn_t
 *
 * INPUTS:
 *   scb == session receiving RPC reply
 *   msg == notification msg that was parsed
 *   consumed == address of return consumed message flag
 *
 *  OUTPUTS:
 *     *consumed == TRUE if msg has been consumed so
 *                  it will not be freed by mgr_not_dispatch
 *               == FALSE if msg has been not consumed so
 *                  it will be freed by mgr_not_dispatch
 *********************************************************************/
void
    yangcli_notification_handler (ses_cb_t *scb,
                                  mgr_not_msg_t *msg,
                                  boolean *consumed)
{
    assert(scb && "scb is NULL!");
    assert(msg && "msg is NULL!");
    assert(consumed && "consumed is NULL!");

    *consumed = FALSE;

    mgr_scb_t *mgrcb = scb->mgrcb;
    server_cb_t *server_cb = get_cur_server_cb();
    session_cb_t *save_session_cb = server_cb->cur_session_cb;
    session_cb_t *session_cb = NULL;

    if (mgrcb) {
        session_cb = mgrcb->session_cb;
    }

    if (session_cb == NULL) {
        log_error("\nError: session no longer valid; dropping notification");
        return;
    }

    const xmlChar *sesname = get_session_name(session_cb);
    if (session_cb != save_session_cb) {
        set_cur_session_cb(server_cb, session_cb);
    }

    /* check the contents of the notification */
    if (msg && msg->notification) {

        /* dispatch this event to any handler registered for
         * this event;  !!! not session-specific !!!     */
        uint32 retcnt = dispatch_notif_event(session_cb, msg);
         
        /* display only unhandled notifications, and only if
         * the session is configured to show them         */
        log_debug_t loglevel = log_get_debug_level();
        log_debug_t base_loglevel = loglevel + 1;
        if (loglevel == LOG_DEBUG_INFO) {
            base_loglevel++;
        }
        if (retcnt == 0 && session_cb->echo_notifs &&
            base_loglevel >= session_cb->echo_notif_loglevel) {

            gl_normal_io(server_cb->cli_gl);
            if (loglevel >= session_cb->echo_notif_loglevel) {
                log_write("\n\nIncoming notification for session %u [%s]:",
                          scb->sid, sesname);
                val_dump_value_max(msg->notification, 
                                   0, session_cb->defindent,
                                   DUMP_VAL_LOG,
                                   session_cb->display_mode,
                                   FALSE, FALSE);
                log_write_append("\n\n");
            } else if (msg->eventType) {
                log_write("\n\nIncoming <%s> notification for session "
                          "%u [%s]\n\n", msg->eventType->name,
                          scb->sid, sesname);
            }
        }

        /* store msg in the session notification log */
        dlq_enque(msg, &session_cb->notificationQ);
        *consumed = TRUE;
    }
    
    if (session_cb != save_session_cb) {
        set_cur_session_cb(server_cb, save_session_cb);
    }

}  /* yangcli_notification_handler */
예제 #14
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 */
예제 #15
0
/********************************************************************
* FUNCTION yang_ext_consume_extension
* 
* Parse the next N tokens as an extension-stmt
* Create an ext_template_t struct and add it to the specified Q
*
* Error messages are printed by this function!!
* Do not duplicate error messages upon error return
*
* Current token is the 'extension' keyword
*
* INPUTS:
*   tkc == token chain
*   mod == module in progress
*
* RETURNS:
*   status of the operation
*********************************************************************/
status_t 
    yang_ext_consume_extension (tk_chain_t *tkc,
                                ncx_module_t  *mod)
{
    ext_template_t  *ext, *testext;
    const xmlChar   *val;
    const char      *expstr;
    yang_stmt_t     *stmt;
    tk_type_t        tktyp;
    boolean          done, arg, stat, desc, ref;
    status_t         res, retres;

#ifdef DEBUG
    if (!tkc || !mod) {
        return SET_ERROR(ERR_INTERNAL_PTR);
    }
#endif

    val = NULL;
    expstr = "keyword";
    done = FALSE;
    arg = FALSE;
    stat = FALSE;
    desc = FALSE;
    ref = FALSE;
    res = NO_ERR;
    retres = NO_ERR;

    /* Get a new ext_template_t to fill in */
    ext = ext_new_template();
    if (!ext) {
        res = ERR_INTERNAL_MEM;
        ncx_print_errormsg(tkc, mod, res);
        return res;
    }

    ncx_set_error(&ext->tkerr,
                  mod,
                  TK_CUR_LNUM(tkc),
                  TK_CUR_LPOS(tkc));

    /* Get the mandatory extension name */
    res = yang_consume_id_string(tkc, mod, &ext->name);
    CHK_EXT_EXIT;

    /* Get the starting left brace for the sub-clauses
     * or a semi-colon to end the extension-stmt
     */
    res = TK_ADV(tkc);
    if (res != NO_ERR) {
        ncx_print_errormsg(tkc, mod, res);
        ext_free_template(ext);
        return res;
    }
    switch (TK_CUR_TYP(tkc)) {
    case TK_TT_SEMICOL:
        done = TRUE;
        break;
    case TK_TT_LBRACE:
        break;
    default:
        retres = ERR_NCX_WRONG_TKTYPE;
        expstr = "semi-colon or left brace";
        ncx_mod_exp_err(tkc, mod, retres, expstr);
        done = TRUE;
    }

    /* get the extension statements and any appinfo extensions */
    while (!done) {
        /* get the next token */
        res = TK_ADV(tkc);
        if (res != NO_ERR) {
            ncx_print_errormsg(tkc, mod, res);
            ext_free_template(ext);
            return res;
        }

        tktyp = TK_CUR_TYP(tkc);
        val = TK_CUR_VAL(tkc);

        /* check the current token type */
        switch (tktyp) {
        case TK_TT_NONE:
            res = ERR_NCX_EOF;
            ncx_print_errormsg(tkc, mod, res);
            ext_free_template(ext);
            return res;
        case TK_TT_MSTRING:
            /* vendor-specific clause found instead */
            res = ncx_consume_appinfo(tkc, mod, &ext->appinfoQ);
            CHK_EXT_EXIT;
            continue;
        case TK_TT_RBRACE:
            done = TRUE;
            continue;
        case TK_TT_TSTRING:
            break;  /* YANG clause assumed */
        default:
            retres = ERR_NCX_WRONG_TKTYPE;
            ncx_mod_exp_err(tkc, mod, retres, expstr);
            continue;
        }

        /* Got a token string so check the value */
        if (!xml_strcmp(val, YANG_K_ARGUMENT)) {
            res = consume_yang_arg(tkc, mod, ext, &arg);
        } else if (!xml_strcmp(val, YANG_K_STATUS)) {
            res = yang_consume_status(tkc, 
                                      mod, 
                                      &ext->status,
                                      &stat, 
                                      &ext->appinfoQ);
        } else if (!xml_strcmp(val, YANG_K_DESCRIPTION)) {
            res = yang_consume_descr(tkc, 
                                     mod, 
                                     &ext->descr,
                                     &desc, 
                                     &ext->appinfoQ);
        } else if (!xml_strcmp(val, YANG_K_REFERENCE)) {
            res = yang_consume_descr(tkc, 
                                     mod, 
                                     &ext->ref,
                                     &ref, 
                                     &ext->appinfoQ);
        } else {
            res = ERR_NCX_WRONG_TKVAL;
            ncx_mod_exp_err(tkc, mod, res, expstr);
        }
        CHK_EXT_EXIT;
    }

    /* save or delete the ext_template_t struct */
    if (ext->name && ncx_valid_name2(ext->name)) {
        testext = ext_find_extension_all(mod, ext->name);
        if (testext) {
            log_error("\nError: extension '%s' already defined "
                      "in '%s' at line %u",
                      ext->name, 
                      testext->tkerr.mod->name,
                      testext->tkerr.linenum);
            retres = ERR_NCX_DUP_ENTRY;
            ncx_print_errormsg(tkc, mod, retres);
            ext_free_template(ext);
        } else {
            dlq_enque(ext, &mod->extensionQ);  /* may have some errors */
            if (mod->stmtmode) {
                stmt = yang_new_ext_stmt(ext);
                if (stmt) {
                    dlq_enque(stmt, &mod->stmtQ);
                } else {
                    log_error("\nError: malloc failure for ext_stmt");
                    retres = ERR_INTERNAL_MEM;
                    ncx_print_errormsg(tkc, mod, retres);
                }
            }
        }
    } else {
        ext_free_template(ext);
    }

    return retres;

}  /* yang_ext_consume_extension */