/******************************************************************** * FUNCTION do_end (local RPC) * * Handle the end command; end an if or while block * * end * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the show command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_end (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { val_value_t *valset; status_t res; res = NO_ERR; valset = get_valset(server_cb, rpc, &line[len], &res); if (valset == NULL) { if (res != ERR_NCX_SKIPPED) { return res; } } else { val_free_value(valset); return ERR_NCX_INVALID_VALUE; } res = runstack_handle_end(server_cb->runstack_context); return res; } /* do_end */
/******************************************************************** * FUNCTION do_unset (local RPC) * * unset def * * Handle the unset command; remove the specified alias * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the unset command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ extern status_t do_unset (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { val_value_t *valset, *parm; status_t res = NO_ERR; valset = get_valset(server_cb, rpc, &line[len], &res); if (res == NO_ERR && valset) { parm = val_find_child(valset, YANGCLI_MOD, NCX_EL_NAME); if (parm) { const xmlChar *varstr = VAL_STR(parm); alias_cb_t *alias = find_alias(varstr, xml_strlen(varstr)); if (alias) { dlq_remove(alias); free_alias(alias); log_info("\nDeleted alias '%s'\n", varstr); } else { res = ERR_NCX_INVALID_VALUE; log_error("\nError: unknown alias '%s'\n", varstr); } } /* else missing parameter already reported */ } /* else no valset already reported */ if (valset) { val_free_value(valset); } return res; } /* do_unset */
/******************************************************************** * FUNCTION do_alias (local RPC) * * alias * alias def * alias def=def-value * * Handle the alias command, based on the parameter * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the alias command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_alias (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { val_value_t *valset, *parm; status_t res = NO_ERR; valset = get_valset(server_cb, rpc, &line[len], &res); if (res == NO_ERR && valset) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_VAR); if (parm) { const xmlChar *varstr = VAL_STR(parm); res = handle_alias_parm(varstr, FALSE, TRUE); if (res == NO_ERR) { update_yangcli_param_change_flag (ALIASES_FILE, TRUE); } } else { /* no parameter; show all aliases */ show_aliases(); } } if (valset) { val_free_value(valset); } return res; } /* do_alias */
/******************************************************************** * FUNCTION do_exit (local RPC) * * exit * * Exit the configuration mode * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the show command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_exit (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { status_t res = NO_ERR; val_value_t *valset = get_valset(server_cb, rpc, &line[len], &res); if (valset && res == NO_ERR) { ; } if (res == NO_ERR || res == ERR_NCX_SKIPPED) { session_cb_t *session_cb = server_cb->cur_session_cb; if (!session_cb->config_mode) { log_error("\nError: configure mode is not active\n"); res = ERR_NCX_OPERATION_FAILED; } else { exit_config_mode(session_cb); } } if (valset) { val_free_value(valset); } return res; } /* do_exit */
/******************************************************************** * FUNCTION do_release_locks (local RPC) * * release all the locks on the server * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the history command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_release_locks (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { ses_cb_t *scb; val_value_t *valset; uint32 locks_timeout, retry_interval; boolean cleanup, done, needed; status_t res; if (!server_cb->locks_active) { log_error("\nError: locks are not active"); return ERR_NCX_OPERATION_FAILED; } scb = mgr_ses_get_scb(server_cb->mysid); if (scb == NULL) { log_error("\nError: active session dropped, cannot lock"); return ERR_NCX_OPERATION_FAILED; } locks_timeout = server_cb->locks_timeout; retry_interval = server_cb->locks_retry_interval; cleanup = TRUE; res = NO_ERR; valset = get_valset(server_cb, rpc, &line[len], &res); if (res == NO_ERR || res == ERR_NCX_SKIPPED) { /* start the auto-unlock procedure */ server_cb->locks_timeout = locks_timeout; server_cb->locks_retry_interval = retry_interval; server_cb->locks_cleanup = cleanup; needed = setup_unlock_cbs(server_cb); if (LOGINFO && needed) { log_info("\nSending <unlock> operations for release-locks...\n"); } if (needed) { done = FALSE; res = handle_release_locks_request_to_server(server_cb, TRUE, &done); if (done) { /* need to close the session or report fatal error */ clear_lock_cbs(server_cb); } } } if (valset != NULL) { val_free_value(valset); } return res; } /* do_release_locks */
/******************************************************************** * FUNCTION do_config (local RPC) * * config term * * Enter the configuration mode * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the show command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_config (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { status_t res = NO_ERR; val_value_t *valset = get_valset(server_cb, rpc, &line[len], &res); if (valset && res == NO_ERR) { /* check if the 'brief' flag is set first */ val_value_t *parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_TERM); if (!parm || parm->res != NO_ERR) { log_error("\nError: 'terminal' parameter invalid\n"); if (parm) { res = parm->res; } else { res = ERR_NCX_MISSING_PARM; } } else { session_cb_t *session_cb = server_cb->cur_session_cb; if (session_cb->config_mode) { log_error("\nError: configure mode already active\n"); res = ERR_NCX_IN_USE; } else { res = start_config_mode(server_cb, session_cb); } } } if (valset) { val_free_value(valset); } return res; } /* do_config */
/******************************************************************** * FUNCTION do_get_locks (local RPC) * * get all the locks on the server * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the history command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_get_locks (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { ses_cb_t *scb; val_value_t *valset, *parm; uint32 locks_timeout, retry_interval; boolean cleanup, done; status_t res; if (server_cb->locks_active) { log_error("\nError: locks are already active"); return ERR_NCX_OPERATION_FAILED; } if (server_cb->state != MGR_IO_ST_CONN_IDLE) { log_error("\nError: no active session to lock"); return ERR_NCX_OPERATION_FAILED; } scb = mgr_ses_get_scb(server_cb->mysid); if (scb == NULL) { log_error("\nError: active session dropped, cannot lock"); return ERR_NCX_OPERATION_FAILED; } locks_timeout = server_cb->locks_timeout; retry_interval = server_cb->locks_retry_interval; cleanup = TRUE; res = NO_ERR; valset = get_valset(server_cb, rpc, &line[len], &res); if (valset && res == NO_ERR) { /* get the overall lock timeout */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_LOCK_TIMEOUT); if (parm && parm->res == NO_ERR) { locks_timeout = VAL_UINT(parm); } /* get the retry interval between failed locks */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_RETRY_INTERVAL); if (parm && parm->res == NO_ERR) { retry_interval = VAL_UINT(parm); } /* get the auto-cleanup flag */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_CLEANUP); if (parm && parm->res == NO_ERR) { cleanup = VAL_BOOL(parm); } } /* start the auto-lock procedure */ setup_lock_cbs(server_cb); server_cb->locks_timeout = locks_timeout; server_cb->locks_retry_interval = retry_interval; server_cb->locks_cleanup = cleanup; done = FALSE; if (LOGINFO) { log_info("\nSending <lock> operations for get-locks...\n"); } res = handle_get_locks_request_to_server(server_cb, TRUE, &done); if (res != NO_ERR && done) { /* need to undo the whole thing; whatever got done */ } if (valset != NULL) { val_free_value(valset); } return res; } /* do_get_locks */
/******************************************************************** * 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 */
/******************************************************************** * FUNCTION do_while (local RPC) * * Handle the while command; start a new loopcb context * * while expr='xpath-str' [docroot=$foo] * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the show command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_while (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { val_value_t *valset, *docroot, *expr, *dummydoc, *maxloops; xpath_pcb_t *pcb; status_t res; uint32 maxloopsval; docroot = NULL; expr = NULL; pcb = NULL; dummydoc = NULL; res = NO_ERR; maxloopsval = YANGCLI_DEF_MAXLOOPS; valset = get_valset(server_cb, rpc, &line[len], &res); if (valset == NULL) { return res; } if (res != NO_ERR) { val_free_value(valset); return res; } if (valset->res != NO_ERR) { res = valset->res; val_free_value(valset); return res; } /* get the expr parameter */ expr = val_find_child(valset, YANGCLI_MOD, YANGCLI_EXPR); if (expr == NULL) { res = ERR_NCX_MISSING_PARM; } else if (expr->res != NO_ERR) { res = expr->res; } if (res == NO_ERR) { /* get the optional docroot parameter */ docroot = val_find_child(valset, YANGCLI_MOD, YANGCLI_DOCROOT); if (docroot != NULL) { if (docroot->res != NO_ERR) { res = docroot->res; } else { val_remove_child(docroot); } } } if (res == NO_ERR && docroot == NULL) { dummydoc = xml_val_new_struct(NCX_EL_DATA, xmlns_nc_id()); if (dummydoc == NULL) { res = ERR_INTERNAL_MEM; } else { docroot = dummydoc; } } if (res == NO_ERR) { /* get the optional maxloops parameter */ maxloops = val_find_child(valset, YANGCLI_MOD, YANGCLI_MAXLOOPS); if (maxloops != NULL) { if (maxloops->res != NO_ERR) { res = maxloops->res; } else { maxloopsval = VAL_UINT(maxloops); } } } if (res == NO_ERR) { /* got all the parameters, and setup the XPath control block */ pcb = xpath_new_pcb_ex(VAL_STR(expr), xpath_getvar_fn, server_cb->runstack_context); if (pcb == NULL) { res = ERR_INTERNAL_MEM; } else { /* save these parameter and start a new while context block */ res = runstack_handle_while(server_cb->runstack_context, maxloopsval, pcb, /* hand off memory here */ docroot); /* hand off memory here */ if (res == NO_ERR) { /* hand off the pcb and docroot memory above */ pcb = NULL; docroot = NULL; } } } /* cleanup and exit */ if (valset) { val_free_value(valset); } if (pcb) { xpath_free_pcb(pcb); } if (docroot) { val_free_value(docroot); } return res; } /* do_while */
/******************************************************************** * FUNCTION do_elif (local RPC) * * Handle the if command; start a new ifcb context * * elif expr='xpath-str' [docroot=$foo] * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the show command * line == CLI input in progress * len == offset into line buffer to start parsing * isif == TRUE for if, FALSE for elif * RETURNS: * status *********************************************************************/ static status_t do_if_elif (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len, boolean isif) { val_value_t *valset, *docroot, *expr, *dummydoc; xpath_pcb_t *pcb; xpath_result_t *result; status_t res; boolean cond; docroot = NULL; expr = NULL; pcb = NULL; dummydoc = NULL; cond = FALSE; res = NO_ERR; valset = get_valset(server_cb, rpc, &line[len], &res); if (valset == NULL) { return res; } if (res != NO_ERR) { val_free_value(valset); return res; } if (valset->res != NO_ERR) { res = valset->res; val_free_value(valset); return res; } /* get the expr parameter */ expr = val_find_child(valset, YANGCLI_MOD, YANGCLI_EXPR); if (expr == NULL) { res = ERR_NCX_MISSING_PARM; } else if (expr->res != NO_ERR) { res = expr->res; } if (res == NO_ERR) { /* get the optional docroot parameter */ docroot = val_find_child(valset, YANGCLI_MOD, YANGCLI_DOCROOT); if (docroot && docroot->res != NO_ERR) { res = docroot->res; } } if (res == NO_ERR && docroot == NULL) { dummydoc = xml_val_new_struct(NCX_EL_DATA, xmlns_nc_id()); if (dummydoc == NULL) { res = ERR_INTERNAL_MEM; } else { docroot = dummydoc; } } if (res == NO_ERR) { /* got all the parameters, and setup the XPath control block */ pcb = xpath_new_pcb_ex(VAL_STR(expr), xpath_getvar_fn, server_cb->runstack_context); if (pcb == NULL) { res = ERR_INTERNAL_MEM; } else if ((isif && runstack_get_cond_state(server_cb->runstack_context)) || (!isif && !runstack_get_if_used(server_cb->runstack_context))) { /* figure out if this if or elif block is enabled or not */ result = xpath1_eval_expr(pcb, docroot, /* context */ docroot, TRUE, FALSE, &res); if (result != NULL && res == NO_ERR) { /* get new condition state for this loop */ cond = xpath_cvt_boolean(result); } xpath_free_result(result); } if (res == NO_ERR) { if (isif) { res = runstack_handle_if(server_cb->runstack_context, cond); } else { res = runstack_handle_elif(server_cb->runstack_context, cond); } } } /* cleanup and exit */ if (valset) { val_free_value(valset); } if (pcb) { xpath_free_pcb(pcb); } if (dummydoc) { val_free_value(dummydoc); } return res; } /* do_if_elif */
/******************************************************************** * FUNCTION do_show (local RPC) * * show module=mod-name * modules * def=def-nmae * * Get the specified parameter and show the internal info, * based on the parameter * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the show command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_show (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { val_value_t *valset, *parm; ncx_module_t *mod; status_t res; boolean imode, done; help_mode_t mode; xmlChar versionbuffer[NCX_VERSION_BUFFSIZE]; res = NO_ERR; imode = interactive_mode(); valset = get_valset(server_cb, rpc, &line[len], &res); if (valset && res == NO_ERR) { mode = HELP_MODE_NORMAL; /* check if the 'brief' flag is set first */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_BRIEF); if (parm && parm->res == NO_ERR) { mode = HELP_MODE_BRIEF; } else { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_FULL); if (parm && parm->res == NO_ERR) { mode = HELP_MODE_FULL; } } /* get the 1 of N 'showtype' choice */ done = FALSE; /* show cli */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_CLI); if (parm) { do_show_cli(server_cb); done = TRUE; } /* show local <foo> */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_LOCAL); if (parm) { res = do_show_var(server_cb, VAL_STR(parm), VAR_TYP_LOCAL, FALSE, mode); done = TRUE; } } /* show locals */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_LOCALS); if (parm) { res = do_show_vars(server_cb, mode, TRUE, FALSE, FALSE); done = TRUE; } } /* show objects */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_OBJECTS); if (parm) { res = do_show_objects(server_cb, mode); done = TRUE; } } /* show global */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_GLOBAL); if (parm) { res = do_show_var(server_cb, VAL_STR(parm), VAR_TYP_GLOBAL, FALSE, mode); done = TRUE; } } /* show globals */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_GLOBALS); if (parm) { res = do_show_vars(server_cb, mode, TRUE, TRUE, FALSE); done = TRUE; } } /* show session */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_SESSION); if (parm) { do_show_session(server_cb, mode); done = TRUE; } /* show system */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_SYSTEM); if (parm) { do_show_system(server_cb, mode); done = TRUE; } /* show var <foo> */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_VAR); if (parm) { res = do_show_var(server_cb, VAL_STR(parm), VAR_TYP_NONE, TRUE, mode); done = TRUE; } } /* show vars */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_VARS); if (parm) { res = do_show_vars(server_cb, mode, FALSE, FALSE, TRUE); done = TRUE; } } /* show module <foo> */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_MODULE); if (parm) { mod = find_module(server_cb, VAL_STR(parm)); if (mod) { res = do_show_module(mod, mode); } else { if (imode) { log_stdout("\nyangcli-pro: module (%s) not loaded", VAL_STR(parm)); } else { log_error("\nyangcli-pro: module (%s) not loaded", VAL_STR(parm)); } } done = TRUE; } } /* show modules */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_MODULES); if (parm) { res = do_show_modules(server_cb, mode); done = TRUE; } } /* show version */ if (!done) { parm = val_find_child(valset, YANGCLI_MOD, NCX_EL_VERSION); if (parm) { res = ncx_get_version(versionbuffer, NCX_VERSION_BUFFSIZE); if (res == NO_ERR) { if (imode) { log_stdout("\nyangcli version %s\n", versionbuffer); } else { log_write("\nyangcli version %s\n", versionbuffer); } } done = TRUE; } } } if (valset) { val_free_value(valset); } return res; } /* do_show */