summaryrefslogtreecommitdiff
path: root/src/lib/rib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/rib.c')
-rw-r--r--src/lib/rib.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/lib/rib.c b/src/lib/rib.c
index 4d1ae884..6b27ad27 100644
--- a/src/lib/rib.c
+++ b/src/lib/rib.c
@@ -95,6 +95,7 @@ struct rnode {
struct rnode * parent;
+ size_t chlen;
struct list_head children;
struct list_head subs;
@@ -248,6 +249,8 @@ static int rnode_add_child(struct rnode * node,
c->node = child;
list_add(&c->next, &node->children);
+ ++node->chlen;
+
return 0;
}
@@ -265,6 +268,7 @@ static void rnode_remove_child(struct rnode * node,
if (c->node == child) {
list_del(&c->next);
free(c);
+ --node->chlen;
return;
}
}
@@ -321,6 +325,8 @@ static struct rnode * rnode_create(struct rnode * parent,
node->parent = parent;
+ node->chlen = 0;
+
branch_hash(node);
rnode_throw_event(node, RO_CREATE);
@@ -606,6 +612,13 @@ ssize_t rib_read(const char * path,
return -EFBIG;
}
+ if (node->data == NULL) {
+ pthread_rwlock_unlock(&rib.lock);
+ return 0;
+ }
+
+ assert(node->len > 0);
+
memcpy(data, node->data, node->len);
rlen = node->len;
@@ -681,6 +694,60 @@ bool rib_has(const char * path)
return node != NULL;
}
+ssize_t rib_children(const char * path,
+ char *** children)
+{
+ struct list_head * p;
+
+ struct rnode * node;
+
+ ssize_t i = 0;
+
+ assert(path);
+ assert(children);
+
+ pthread_rwlock_rdlock(&rib.lock);
+
+ node = find_rnode_by_path(path);
+ if (node == NULL) {
+ pthread_rwlock_unlock(&rib.lock);
+ return -EPERM;
+ }
+
+ if (node->chlen == 0) {
+ pthread_rwlock_unlock(&rib.lock);
+ *children = NULL;
+ return 0;
+ }
+
+ *children = malloc(sizeof(**children) * node->chlen);
+ if (*children == NULL) {
+ pthread_rwlock_unlock(&rib.lock);
+ return -ENOMEM;
+ }
+
+ list_for_each(p, &node->children) {
+ struct child * c = list_entry(p, struct child, next);
+ (*children)[i] = strdup(c->node->name);
+ if ((*children)[i] == NULL) {
+ ssize_t j;
+ pthread_rwlock_unlock(&rib.lock);
+ for (j = 0; j < i; ++j)
+ free((*children)[j]);
+ free(*children);
+ return -ENOMEM;
+ }
+ ++i;
+ }
+
+ assert(i > 0);
+ assert((size_t) i == node->chlen);
+
+ pthread_rwlock_unlock(&rib.lock);
+
+ return i;
+}
+
static struct rib_sub * rib_get_sub(uint32_t sid)
{
struct list_head * p;