Esempio n. 1
0
/********************************************************************
 * 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 */
Esempio n. 2
0
/********************************************************************
 * 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 */
Esempio n. 3
0
/********************************************************************
 * 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 */
Esempio n. 5
0
/********************************************************************
 * 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 */
Esempio n. 7
0
/********************************************************************
 * 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 */
Esempio n. 8
0
/********************************************************************
 * 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 */
Esempio n. 9
0
/********************************************************************
 * FUNCTION do_while (local RPC)
 * 
 * Handle the while command; start a new loopcb context
 *
 * while expr='xpath-str' [docroot=$foo]
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the show command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    do_while (server_cb_t *server_cb,
              obj_template_t *rpc,
              const xmlChar *line,
              uint32  len)
{
    val_value_t        *valset, *docroot, *expr, *dummydoc, *maxloops;
    xpath_pcb_t        *pcb;
    status_t            res;
    uint32              maxloopsval;

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

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

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

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

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

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

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

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

}  /* do_while */
Esempio n. 10
0
/********************************************************************
 * 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 */
Esempio n. 11
0
/********************************************************************
 * 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 */