Ejemplo n.º 1
0
int
__wrap_sr_delete_item(sr_session_ctx_t *session, const char *xpath, const sr_edit_options_t opts)
{
    (void)session;
    struct ly_set *set;
    uint32_t i;

    set = lyd_find_path(data, xpath);
    assert_ptr_not_equal(set, NULL);

    if ((opts & SR_EDIT_STRICT) && !set->number) {
        ly_set_free(set);
        return SR_ERR_DATA_MISSING;
    }
    for (i = 0; i < set->number; ++i) {
        if ((opts & SR_EDIT_NON_RECURSIVE) && set->set.d[i]->child) {
            ly_set_free(set);
            return SR_ERR_UNSUPPORTED;
        }

        lyd_free(set->set.d[i]);
    }
    ly_set_free(set);

    return SR_ERR_OK;
}
Ejemplo n.º 2
0
static void
test_lys_find_path(void **state)
{
    (void) state; /* unused */
    LYS_INFORMAT yang_format = LYS_IN_YIN;
    const struct lys_module *module;
    struct ly_set *set;

    module = lys_parse_mem(ctx, lys_module_a, yang_format);
    assert_ptr_not_equal(module, NULL);

    set = lys_find_path(module, NULL, "/x/*");
    assert_ptr_not_equal(set, NULL);
    assert_int_equal(set->number, 5);
    ly_set_free(set);

    set = lys_find_path(module, NULL, "/x//*");
    assert_ptr_not_equal(set, NULL);
    assert_int_equal(set->number, 6);
    ly_set_free(set);

    set = lys_find_path(module, NULL, "/x//.");
    assert_ptr_not_equal(set, NULL);
    assert_int_equal(set->number, 7);
    ly_set_free(set);
}
Ejemplo n.º 3
0
static void
test_attributes(void **state)
{
    struct state *st = (*state);

    st->set = lyd_find_xpath(st->dt, "//*[@*]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 6);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//@*/..");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 6);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//*[@*[substring(local-name(.),1,2) = 'ip']]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 4);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//*[@*[substring(local-name(.),1,2) = 'ip']]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 4);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//*[@yang:ip_attr > '20']");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 2);
    ly_set_free(st->set);
    st->set = NULL;
}
Ejemplo n.º 4
0
static void
test_simple(void **state)
{
    struct state *st = (*state);

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 1);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces/interface");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 2);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces/interface[name='iface1']");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 1);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces/interface[name='iface1']/ietf-ip:ipv4/address");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 2);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces/interface[name='iface1']/ietf-ip:ipv4/address[ip='10.0.0.1']");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 1);
    ly_set_free(st->set);
    st->set = NULL;
}
Ejemplo n.º 5
0
int
__wrap_sr_move_item(sr_session_ctx_t *session, const char *xpath, const sr_move_position_t position, const char *relative_item)
{
    (void)session;
    struct ly_set *set, *set2 = NULL;
    struct lyd_node *node;

    set = lyd_find_path(data, xpath);
    assert_ptr_not_equal(set, NULL);
    assert_int_equal(set->number, 1);

    switch (position) {
    case SR_MOVE_BEFORE:
        set2 = lyd_find_path(data, relative_item);
        assert_ptr_not_equal(set2, NULL);
        assert_int_equal(set2->number, 1);

        assert_int_equal(lyd_insert_before(set2->set.d[0], set->set.d[0]), 0);
        break;
    case SR_MOVE_AFTER:
        set2 = lyd_find_path(data, relative_item);
        assert_ptr_not_equal(set2, NULL);
        assert_int_equal(set2->number, 1);

        assert_int_equal(lyd_insert_after(set2->set.d[0], set->set.d[0]), 0);
        break;
    case SR_MOVE_FIRST:
        node = set->set.d[0]->parent->child;

        assert_int_equal(lyd_insert_before(node, set->set.d[0]), 0);
        break;
    case SR_MOVE_LAST:
        node = set->set.d[0]->parent->child->prev;

        assert_int_equal(lyd_insert_after(node, set->set.d[0]), 0);
        break;
    }

    ly_set_free(set);
    ly_set_free(set2);
    return SR_ERR_OK;
}
Ejemplo n.º 6
0
static int
teardown_f(void **state)
{
    struct state *st = (*state);

    lyd_free_withsiblings(st->dt);
    ly_set_free(st->set);
    ly_ctx_destroy(st->ctx, NULL);
    free(st);
    (*state) = NULL;

    return 0;
}
Ejemplo n.º 7
0
std::vector<std::shared_ptr<ydk::path::DataNode>>
ydk::path::RootDataImpl::find(const std::string& path)
{
    populate_new_schemas_from_path(path);

    std::vector<std::shared_ptr<DataNode>> results;

    if(m_node == nullptr)
    {
        return results;
    }

    std::string schema_path{ this->get_path() };
    if(schema_path.size()!= 1)
    {
        schema_path+="/";
    }

    auto s = get_schema_node().get_statement();
    if(s.keyword == "rpc" || s.keyword == "action")
    {
        schema_path+="input/";
    }

    schema_path+=path;

    YLOG_DEBUG("Looking for schema nodes path in root: '{}'", schema_path);
    const struct lys_node* found_snode = ly_ctx_get_node(m_node->schema->module->ctx, nullptr, schema_path.c_str(), 1);

    if(found_snode)
    {
        struct ly_set* result_set = lyd_find_instance(m_node, found_snode);
        if( result_set )
        {
            if (result_set->number > 0)
            {
                for(size_t i=0; i < result_set->number; i++)
                {
                    struct lyd_node* node_result = result_set->set.d[i];
                    results.push_back(get_dn_for_desc_node(node_result));
                }
            }
            ly_set_free(result_set);
        }

    }

    return results;
}
Ejemplo n.º 8
0
int
__wrap_sr_get_item_next(sr_session_ctx_t *session, sr_val_iter_t *iter, sr_val_t **value)
{
    static struct ly_set *ietf_if_set = NULL;
    const char *xpath = (const char *)iter;
    char *path;
    (void)session;

    if (!strcmp(xpath, "/ietf-interfaces:*//.")) {
        if (!ietf_if_set) {
            ietf_if_set = lyd_find_path(data, xpath);
        }

        if (!ietf_if_set->number) {
            ly_set_free(ietf_if_set);
            ietf_if_set = NULL;
            return SR_ERR_NOT_FOUND;
        }

        path = lyd_path(ietf_if_set->set.d[0]);
        *value = calloc(1, sizeof **value);
        op_set_srval(ietf_if_set->set.d[0], path, 1, *value, NULL);
        (*value)->dflt = ietf_if_set->set.d[0]->dflt;
        free(path);

        --ietf_if_set->number;
        if (ietf_if_set->number) {
            memmove(ietf_if_set->set.d, ietf_if_set->set.d + 1, ietf_if_set->number * sizeof(void *));
        }
    } else {
        *value = NULL;
        return SR_ERR_NOT_FOUND;
    }

    return SR_ERR_OK;
}
Ejemplo n.º 9
0
static void
test_advanced(void **state)
{
    struct state *st = (*state);

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces/interface[name='iface1']/ietf-ip:ipv4/*[ip]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 3);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces//*[ietf-ip:ip]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 10);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces//*[ietf-ip:ip[.='10.0.0.1']]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 2);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//ietf-ip:ip[.='10.0.0.1']");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 2);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//*[../description]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 14);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//interface[name='iface1']/ipv4//*");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 12);
    ly_set_free(st->set);
    st->set = NULL;
}
Ejemplo n.º 10
0
struct nc_server_reply *
op_lock(struct lyd_node *rpc, struct nc_session *ncs)
{
    struct np2_sessions *sessions;
    sr_datastore_t ds = 0;
    struct nc_session **dsl = NULL;
    time_t *dst;
    struct ly_set *nodeset;
    struct nc_server_error *e;
    struct nc_server_reply *ereply = NULL;
    const char *dsname;

    /* get sysrepo connections for this session */
    sessions = (struct np2_sessions *)nc_session_get_data(ncs);

    if (np2srv_sr_check_exec_permission(sessions->srs, "/ietf-netconf:lock", &ereply)) {
        goto finish;
    }

    /* get know which datastore is being affected */
    nodeset = lyd_find_path(rpc, "/ietf-netconf:lock/target/*");
    dsname = nodeset->set.d[0]->schema->name;
    ly_set_free(nodeset);

    if (!strcmp(dsname, "running")) {
        /* TODO additional requirements in case of supporting confirmed-commit */
        ds = SR_DS_RUNNING;
        dsl = &dslock.running;
        dst = &dslock.running_time;
    } else if (!strcmp(dsname, "startup")) {
        ds = SR_DS_STARTUP;
        dsl = &dslock.startup;
        dst = &dslock.startup_time;
    } else if (!strcmp(dsname, "candidate")) {
        ds = SR_DS_CANDIDATE;
        dsl = &dslock.candidate;
        dst = &dslock.candidate_time;
    } else {
        EINT;
        e = nc_err(NC_ERR_OP_FAILED, NC_ERR_TYPE_PROT);
        nc_err_set_msg(e, np2log_lasterr(), "en");
        ereply = nc_server_reply_err(e);
        goto finish;
    }
    if (ds != sessions->ds) {
        /* update sysrepo session */
        if (np2srv_sr_session_switch_ds(sessions->srs, ds, &ereply)) {
            goto finish;
        }
        sessions->ds = ds;
    }

    pthread_rwlock_rdlock(&dslock_rwl);
    if (*dsl) {
lock_held:
        /* lock already held */
        pthread_rwlock_unlock(&dslock_rwl);
        ERR("Locking datastore %s by session %d failed (datastore is already locked by session %d).",
            dsname, nc_session_get_id(ncs), nc_session_get_id(*dsl));
        e = nc_err(NC_ERR_LOCK_DENIED, nc_session_get_id(*dsl));
        nc_err_set_msg(e, np2log_lasterr(), "en");
        ereply = nc_server_reply_err(e);
        goto finish;
    }
    pthread_rwlock_unlock(&dslock_rwl);

    pthread_rwlock_wrlock(&dslock_rwl);
    /* check again dsl, it could change between unlock and wrlock */
    if (*dsl) {
        goto lock_held;
    }

    if (np2srv_sr_lock_datastore(sessions->srs, &ereply)) {
        /* lock is held outside Netopeer */
        pthread_rwlock_unlock(&dslock_rwl);
        /* add lock denied error */
        ERR("Locking datastore %s by session %d failed.", dsname, nc_session_get_id(ncs));
        e = nc_err(NC_ERR_LOCK_DENIED, 0);
        nc_err_set_msg(e, np2log_lasterr(), "en");
        nc_server_reply_add_err(ereply, e);
        goto finish;
    }

    /* update local information about locks */
    *dsl = ncs;
    *dst = time(NULL);
    pthread_rwlock_unlock(&dslock_rwl);

    /* build positive RPC Reply */
    ereply = nc_server_reply_ok();

finish:
    return ereply;
}
Ejemplo n.º 11
0
struct nc_server_reply *
op_unlock(struct lyd_node *rpc, struct nc_session *ncs)
{
    struct np2_sessions *sessions;
    sr_datastore_t ds = 0;
    struct nc_session **dsl = NULL;
    time_t *dst;
    struct ly_set *nodeset;
    const char *dsname;
    struct nc_server_error *e;
    struct nc_server_reply *ereply = NULL;

    /* get sysrepo connections for this session */
    sessions = (struct np2_sessions *)nc_session_get_data(ncs);

    if (np2srv_sr_check_exec_permission(sessions->srs, "/ietf-netconf:unlock", &ereply)) {
        goto finish;
    }

    /* get know which datastore is being affected */
    nodeset = lyd_find_path(rpc, "/ietf-netconf:unlock/target/*");
    dsname = nodeset->set.d[0]->schema->name;
    ly_set_free(nodeset);

    if (!strcmp(dsname, "running")) {
        ds = SR_DS_RUNNING;
        dsl = &dslock.running;
        dst = &dslock.running_time;
    } else if (!strcmp(dsname, "startup")) {
        ds = SR_DS_STARTUP;
        dsl = &dslock.startup;
        dst = &dslock.startup_time;
    } else if (!strcmp(dsname, "candidate")) {
        ds = SR_DS_CANDIDATE;
        dsl = &dslock.candidate;
        dst = &dslock.candidate_time;
    } else {
        EINT;
        e = nc_err(NC_ERR_OP_FAILED, NC_ERR_TYPE_PROT);
        nc_err_set_msg(e, np2log_lasterr(), "en");
        ereply = nc_server_reply_err(e);
        goto finish;
    }
    if (ds != sessions->ds) {
        /* update sysrepo session */
        if (np2srv_sr_session_switch_ds(sessions->srs, ds, &ereply)) {
            goto finish;
        }
        sessions->ds = ds;
    }

    pthread_rwlock_rdlock(&dslock_rwl);
    if (!(*dsl)) {
        /* lock is not held */
        pthread_rwlock_unlock(&dslock_rwl);
        ERR("Unlocking datastore %s by session %d failed (lock is not active).",
            dsname, nc_session_get_id(ncs));
        e = nc_err(NC_ERR_OP_FAILED, NC_ERR_TYPE_PROT);
        nc_err_set_msg(e, np2log_lasterr(), "en");
        ereply = nc_server_reply_err(e);
        goto finish;
    } else {
        /* lock is held, but by who? */
        if ((*dsl) != ncs) {
            /* by someone else */
            pthread_rwlock_unlock(&dslock_rwl);
            ERR("Unlocking datastore %s by session %d failed (lock is held by session %d).",
                dsname, nc_session_get_id(ncs), nc_session_get_id(*dsl));
            e = nc_err(NC_ERR_LOCK_DENIED, nc_session_get_id(*dsl));
            nc_err_set_msg(e, np2log_lasterr(), "en");
            ereply = nc_server_reply_err(e);
            goto finish;
        }
    }
    pthread_rwlock_unlock(&dslock_rwl);
    pthread_rwlock_wrlock(&dslock_rwl);

    if (np2srv_sr_unlock_datastore(sessions->srs, &ereply)) {
        /* lock is held outside Netopeer */
        pthread_rwlock_unlock(&dslock_rwl);
        /* add lock denied error */
        ERR("Unlocking datastore %s by session %d failed.", dsname, nc_session_get_id(ncs));
        e = nc_err(NC_ERR_LOCK_DENIED, 0);
        nc_err_set_msg(e, np2log_lasterr(), "en");
        nc_server_reply_add_err(ereply, e);
        goto finish;
    }

    /* according to RFC 6241 8.3.5.2, discard changes */
    np2srv_sr_discard_changes(sessions->srs, NULL);

    /* update local information about locks */
    *dsl = NULL;
    *dst = 0;

    pthread_rwlock_unlock(&dslock_rwl);

    /* build positive RPC Reply */
    ereply = nc_server_reply_ok();

finish:
    return ereply;
}
Ejemplo n.º 12
0
static void
test_functions_operators(void **state)
{
    struct state *st = (*state);

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces/interface/name[true() and not(false()) and not(boolean(. != 'iface1'))]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 1);
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[0])->value_str, "iface1");
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces/interface/name[round(ceiling(1.8)+0.4)+floor(0.28)]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 1);
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[0])->value_str, "iface2");
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "/ietf-interfaces:interfaces/interface/type[string-length(substring-after(\"hello12hi\", '12')) != 2 or starts-with(.,'iana') and contains(.,'back') and .=substring-before(concat(string(.),'aab', \"abb\"),'aa')]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 1);
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[0])->value_str, "iana-if-type:softwareLoopback");
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//*[neighbor/link-layer-address = translate(normalize-space('\t\n01   .34    .56\t.78.9a\n\r.bc.de.f0  \t'), '. ', ':')]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 2);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//ip[position() = last()]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 1);
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[0])->value_str, "2001:abcd:ef01:2345:6789:0:1:1");
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//ip[count(//*[.='52'])]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 1);
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[0])->value_str, "10.0.0.1");
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//*[local-name()='autoconf' and namespace-uri()='urn:ietf:params:xml:ns:yang:ietf-ip']");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 2);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//interface[name='iface2']//. | //ip | //interface[number((1 mod (20 - 15)) div 1)]//.");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 68);
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//ip[position() mod 2 = 1] | //ip[position() mod 2 = 0]");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 10);
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[0])->value_str, "10.0.0.1");
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[1])->value_str, "172.0.0.1");
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[2])->value_str, "10.0.0.2");
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[7])->value_str, "10.0.0.1");
    assert_string_equal(((struct lyd_node_leaf_list *)st->set->set.d[9])->value_str, "2001:abcd:ef01:2345:6789:0:1:1");
    ly_set_free(st->set);
    st->set = NULL;

    st->set = lyd_find_xpath(st->dt, "//*[1] | //*[last()] | //*[10] | //*[8]//.");
    assert_ptr_not_equal(st->set, NULL);
    assert_int_equal(st->set->number, 15);
    ly_set_free(st->set);
    st->set = NULL;
}
Ejemplo n.º 13
0
struct nc_server_reply *
op_validate(struct lyd_node *rpc, struct nc_session *ncs)
{
    struct np2_sessions *sessions;
    struct ly_set *nodeset;
    struct nc_server_error *e = NULL;
    int rc;
    struct lyd_node *config = NULL;
    struct lyd_node_anyxml *axml;
    const char *dsname;
    sr_datastore_t ds = SR_DS_CANDIDATE;

    /* get sysrepo connections for this session */
    sessions = (struct np2_sessions *)nc_session_get_data(ncs);

    /* get know which datastore is being affected */
    nodeset = lyd_get_node(rpc, "/ietf-netconf:validate/source/*");
    dsname = nodeset->set.d[0]->schema->name;
    axml = (struct lyd_node_anyxml *)nodeset->set.d[0];
    ly_set_free(nodeset);
    if (!strcmp(dsname, "running")) {
        ds = SR_DS_RUNNING;
    } else if (!strcmp(dsname, "startup")) {
        ds = SR_DS_STARTUP;
    } else if (!strcmp(dsname, "candidate")) {
        ds = SR_DS_CANDIDATE;
    } else if (!strcmp(dsname, "config")) {
        /* get data tree to validate */
        config = lyd_parse_xml(rpc->schema->module->ctx, &axml->value.xml, LYD_OPT_CONFIG | LYD_OPT_DESTRUCT);
        if (ly_errno != LY_SUCCESS) {
            ly_set_free(nodeset);
            goto error;
        }
        rc = lyd_validate(&config, LYD_OPT_CONFIG, np2srv.ly_ctx);

        /* cleanup */
        lyd_free_withsiblings(config);

        goto done;
    }
    /* TODO support URL */

    if (ds != sessions->ds) {
        /* update sysrepo session */
        sr_session_switch_ds(sessions->srs, ds);
        sessions->ds = ds;
    }
    if (ds != SR_DS_CANDIDATE) {
        /* refresh datastore content */
        if (sr_session_refresh(sessions->srs) != SR_ERR_OK) {
            goto error;
        }
    }

    /* validate sysrepo's datastore */
    rc = sr_validate(sessions->srs);
    if (rc != SR_ERR_OK) {
        goto error;
    }

done:

    return nc_server_reply_ok();

error:
    /* handle error */
    if (!e) {
        e = nc_err(NC_ERR_OP_FAILED, NC_ERR_TYPE_APP);
        nc_err_set_msg(e, np2log_lasterr(), "en");
    }

    return nc_server_reply_err(e);
}