From 1fcdcc0db6e859f501d4246e8c309c8a48137ed9 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Sat, 15 Jan 2022 19:50:29 +1100
Subject: [PATCH] split resolve.c file

---
 src/lib66/resolve/deps-lib/deps            |  21 +-
 src/lib66/resolve/resolve.c                | 561 ---------------------
 src/lib66/resolve/resolve_add_cdb.c        |  34 ++
 src/lib66/resolve/resolve_add_cdb_uint.c   |  38 ++
 src/lib66/resolve/resolve_add_string.c     |  48 ++
 src/lib66/resolve/resolve_append.c         |  62 +++
 src/lib66/resolve/resolve_check.c          |  41 ++
 src/lib66/resolve/resolve_cmp.c            |  59 +++
 src/lib66/resolve/resolve_deep_free.c      |  56 ++
 src/lib66/resolve/resolve_find_cdb.c       |  55 ++
 src/lib66/resolve/resolve_free.c           |  34 ++
 src/lib66/resolve/resolve_init.c           |  32 ++
 src/lib66/resolve/resolve_modify_field.c   |  68 +++
 src/lib66/resolve/resolve_modify_field_g.c |  65 +++
 src/lib66/resolve/resolve_read.c           |  36 ++
 src/lib66/resolve/resolve_read_cdb.c       |  68 +++
 src/lib66/resolve/resolve_rmfile.c         |  35 ++
 src/lib66/resolve/resolve_search.c         |  68 +++
 src/lib66/resolve/resolve_set_struct.c     |  32 ++
 src/lib66/resolve/resolve_write.c          |  36 ++
 src/lib66/resolve/resolve_write_cdb.c      |  94 ++++
 21 files changed, 981 insertions(+), 562 deletions(-)
 delete mode 100644 src/lib66/resolve/resolve.c
 create mode 100644 src/lib66/resolve/resolve_add_cdb.c
 create mode 100644 src/lib66/resolve/resolve_add_cdb_uint.c
 create mode 100644 src/lib66/resolve/resolve_add_string.c
 create mode 100644 src/lib66/resolve/resolve_append.c
 create mode 100644 src/lib66/resolve/resolve_check.c
 create mode 100644 src/lib66/resolve/resolve_cmp.c
 create mode 100644 src/lib66/resolve/resolve_deep_free.c
 create mode 100644 src/lib66/resolve/resolve_find_cdb.c
 create mode 100644 src/lib66/resolve/resolve_free.c
 create mode 100644 src/lib66/resolve/resolve_init.c
 create mode 100644 src/lib66/resolve/resolve_modify_field.c
 create mode 100644 src/lib66/resolve/resolve_modify_field_g.c
 create mode 100644 src/lib66/resolve/resolve_read.c
 create mode 100644 src/lib66/resolve/resolve_read_cdb.c
 create mode 100644 src/lib66/resolve/resolve_rmfile.c
 create mode 100644 src/lib66/resolve/resolve_search.c
 create mode 100644 src/lib66/resolve/resolve_set_struct.c
 create mode 100644 src/lib66/resolve/resolve_write.c
 create mode 100644 src/lib66/resolve/resolve_write_cdb.c

diff --git a/src/lib66/resolve/deps-lib/deps b/src/lib66/resolve/deps-lib/deps
index 2546d1bc..d4474c59 100644
--- a/src/lib66/resolve/deps-lib/deps
+++ b/src/lib66/resolve/deps-lib/deps
@@ -1,6 +1,25 @@
-resolve.o
+resolve_add_cdb.o
+resolve_add_cdb_uint.o
+resolve_add_string.o
+resolve_append.o
+resolve_check.o
+resolve_cmp.o
+resolve_deep_free.o
+resolve_find_cdb.o
+resolve_free.o
+resolve_init.o
+resolve_modify_field.o
+resolve_modify_field_g.o
+resolve_read.o
+resolve_read_cdb.o
+resolve_rmfile.o
+resolve_search.o
+resolve_set_struct.o
+resolve_write.o
+resolve_write_cdb.o
 -ls6rc
 -ls6
 -loblibs
 -lexecline
 -lskarnet
+
diff --git a/src/lib66/resolve/resolve.c b/src/lib66/resolve/resolve.c
deleted file mode 100644
index 2fc670d7..00000000
--- a/src/lib66/resolve/resolve.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * resolve.c
- *
- * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
- *
- * All rights reserved.
- *
- * This file is part of Obarun. It is subject to the license terms in
- * the LICENSE file found in the top-level directory of this
- * distribution.
- * This file may not be copied, modified, propagated, or distributed
- * except according to the terms contained in the LICENSE file./
- */
-
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>//close, fsync
-#include <stdlib.h>//mkstemp, malloc, free
-#include <sys/types.h>//ssize_t
-#include <stdio.h>//rename
-
-#include <oblibs/log.h>
-#include <oblibs/string.h>
-#include <oblibs/types.h>
-#include <oblibs/sastr.h>
-
-#include <skalibs/stralloc.h>
-#include <skalibs/genalloc.h>
-#include <skalibs/cdb.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/cdbmake.h>
-#include <skalibs/posixplz.h>//unlink
-#include <skalibs/types.h>//uint##_pack
-
-#include <66/resolve.h>
-#include <66/service.h>
-#include <66/tree.h>
-#include <66/constants.h>
-#include <66/graph.h>
-
-/**
- *
- * MAIN API
- *
- * */
-
-resolve_wrapper_t *resolve_set_struct(uint8_t type, void *s)
-{
-    log_flow() ;
-
-    resolve_wrapper_t *wres = malloc(sizeof(resolve_wrapper_t)) ;
-
-    wres->obj = s ;
-    wres->type = type ;
-    return wres ;
-} ;
-
-
-int resolve_init(resolve_wrapper_t *wres)
-{
-    log_flow() ;
-
-    RESOLVE_SET_SAWRES(wres) ;
-
-    sawres->len = 0 ;
-
-    return resolve_add_string(wres,"") ;
-}
-
-int resolve_read(resolve_wrapper_t *wres, char const *src, char const *name)
-{
-    log_flow() ;
-
-    size_t srclen = strlen(src) ;
-    size_t namelen = strlen(name) ;
-
-    char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen + 1] ;
-    auto_strings(tmp,src,SS_RESOLVE,"/",name) ;
-
-    if (!resolve_read_cdb(wres,tmp))
-        return 0 ;
-
-    return 1 ;
-}
-
-int resolve_write(resolve_wrapper_t *wres, char const *dst, char const *name)
-{
-    log_flow() ;
-
-    size_t dstlen = strlen(dst) ;
-    size_t namelen = strlen(name) ;
-
-    char tmp[dstlen + SS_RESOLVE_LEN + 1 + namelen + 1] ;
-    auto_strings(tmp,dst,SS_RESOLVE,"/") ;
-
-    if (!resolve_write_cdb(wres,tmp,name))
-        return 0 ;
-
-    return 1 ;
-}
-
-int resolve_check(char const *src, char const *name)
-{
-    log_flow() ;
-
-    int r ;
-    size_t srclen = strlen(src) ;
-    size_t namelen = strlen(name) ;
-
-    char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen + 1] ;
-    auto_strings(tmp, src, SS_RESOLVE, "/", name) ;
-
-    r = scan_mode(tmp,S_IFREG) ;
-    if (r <= 0)
-        return 0 ;
-
-    return 1 ;
-}
-
-int resolve_append(genalloc *ga, resolve_wrapper_t *wres)
-{
-    log_flow() ;
-
-    int e = 0 ;
-
-    if (wres->type == DATA_SERVICE) {
-
-        resolve_service_t cp = RESOLVE_SERVICE_ZERO ;
-        if (!service_resolve_copy(&cp, ((resolve_service_t *)wres->obj)))
-            goto err ;
-
-        if (!genalloc_append(resolve_service_t, ga, &cp))
-            goto err ;
-
-    } else if (wres->type == DATA_TREE) {
-
-        resolve_tree_t cp = RESOLVE_TREE_ZERO ;
-        if (!tree_resolve_copy(&cp, ((resolve_tree_t *)wres->obj)))
-            goto err ;
-
-        if (!genalloc_append(resolve_tree_t, ga, &cp))
-            goto err ;
-
-    } else if (wres->type == DATA_TREE_MASTER) {
-
-            resolve_tree_master_t cp = RESOLVE_TREE_MASTER_ZERO ;
-
-            if (!tree_resolve_master_copy(&cp, ((resolve_tree_master_t *)wres->obj)))
-                goto err ;
-
-            if (!genalloc_append(resolve_tree_master_t, ga, &cp))
-                goto err ;
-    }
-
-    e = 1 ;
-    err:
-        return e ;
-}
-
-int resolve_search(genalloc *ga, char const *name, uint8_t type)
-{
-    log_flow() ;
-
-    size_t len, pos = 0 ;
-
-    if (type == DATA_SERVICE) {
-
-        len = genalloc_len(resolve_service_t, ga) ;
-
-        for (;pos < len ; pos++) {
-
-            char *s = genalloc_s(resolve_service_t,ga)[pos].sa.s + genalloc_s(resolve_service_t,ga)[pos].name ;
-            if (!strcmp(name,s))
-                return pos ;
-        }
-
-    } else if (type == DATA_TREE) {
-
-        len = genalloc_len(resolve_tree_t, ga) ;
-
-        for (;pos < len ; pos++) {
-
-            char *s = genalloc_s(resolve_tree_t,ga)[pos].sa.s + genalloc_s(resolve_tree_t,ga)[pos].name ;
-            if (!strcmp(name,s))
-                return pos ;
-        }
-    }
-
-    return -1 ;
-}
-
-int resolve_cmp(genalloc *ga, char const *name, uint8_t type)
-{
-    log_flow() ;
-
-    size_t len, pos = 0 ;
-
-    if (type == DATA_SERVICE) {
-
-        len = genalloc_len(resolve_service_t, ga) ;
-
-        for (;pos < len ; pos++) {
-
-            char *str = genalloc_s(resolve_service_t, ga)[pos].sa.s ;
-            char *s = str + genalloc_s(resolve_service_t, ga)[pos].name ;
-            if (!strcmp(name,s))
-                return 1 ;
-        }
-
-    } else if (type == DATA_TREE) {
-
-        len = genalloc_len(resolve_tree_t, ga) ;
-
-        for (;pos < len ; pos++) {
-
-            char *str = genalloc_s(resolve_tree_t, ga)[pos].sa.s ;
-            char *s = str + genalloc_s(resolve_tree_t, ga)[pos].name ;
-            if (!strcmp(name,s))
-                return 1 ;
-        }
-    }
-
-    return 0 ;
-}
-
-void resolve_rmfile(char const *src,char const *name)
-{
-    log_flow() ;
-
-    size_t srclen = strlen(src) ;
-    size_t namelen = strlen(name) ;
-
-    char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen +1] ;
-    auto_strings(tmp, src, SS_RESOLVE, "/", name) ;
-
-    unlink_void(tmp) ;
-}
-
-ssize_t resolve_add_string(resolve_wrapper_t *wres, char const *data)
-{
-    log_flow() ;
-
-    RESOLVE_SET_SAWRES(wres) ;
-
-    ssize_t baselen = sawres->len ;
-
-    if (!data) {
-
-        if (!stralloc_catb(sawres,"",1))
-            log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ;
-
-        return baselen ;
-    }
-
-    size_t datalen = strlen(data) ;
-
-    if (!stralloc_catb(sawres,data,datalen + 1))
-        log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ;
-
-    return baselen ;
-}
-
-int resolve_modify_field(resolve_wrapper_t_ref wres, uint8_t field, char const *by)
-{
-    log_flow() ;
-
-    int e = 0 ;
-
-    resolve_wrapper_t_ref mwres = 0 ;
-
-    if (wres->type == DATA_SERVICE) {
-
-        resolve_service_t_ref res = (resolve_service_t *)wres->obj  ;
-        mwres = resolve_set_struct(DATA_SERVICE, res) ;
-
-        log_trace("modify field ", resolve_service_field_table[field].field," of service ", res->sa.s + res->name, " with value: ", by) ;
-
-        if (!service_resolve_modify_field(res, field, by))
-            goto err ;
-
-    } else if (wres->type == DATA_TREE) {
-
-        resolve_tree_t_ref res = (resolve_tree_t *)wres->obj  ;
-        mwres = resolve_set_struct(DATA_TREE, res) ;
-
-        log_trace("modify field ", resolve_tree_field_table[field].field," of tree ", res->sa.s + res->name, " with value: ", by) ;
-
-        if (!tree_resolve_modify_field(res, field, by))
-            goto err ;
-
-    } else if (wres->type == DATA_TREE_MASTER) {
-
-        resolve_tree_master_t_ref res = (resolve_tree_master_t *)wres->obj  ;
-        mwres = resolve_set_struct(DATA_TREE_MASTER, res) ;
-
-        log_trace("modify field ", resolve_tree_master_field_table[field].field," of inner resolve file of trees with value: ", by) ;
-
-        if (!tree_resolve_master_modify_field(res, field, by))
-            goto err ;
-    }
-
-    e = 1 ;
-    err:
-        free(mwres) ;
-        return e ;
-}
-
-int resolve_modify_field_g(resolve_wrapper_t_ref wres, char const *base, char const *element, uint8_t field, char const *value)
-{
-
-    log_flow() ;
-
-    size_t baselen = strlen(base), tot = baselen + SS_SYSTEM_LEN + 1, treelen = 0 ;
-    char *treename = 0 ;
-
-    if (wres->type == DATA_SERVICE) {
-        treename = ((resolve_service_t *)wres->obj)->sa.s + ((resolve_service_t *)wres->obj)->treename ;
-        treelen = strlen(treename) ;
-        tot += treelen + SS_SVDIRS_LEN + 1 ;
-
-    }
-
-    char solve[tot] ;
-
-    if (wres->type == DATA_SERVICE) {
-
-        auto_strings(solve, base, SS_SYSTEM, "/", treename, SS_SVDIRS) ;
-
-    } else if (wres->type == DATA_TREE || wres->type == DATA_TREE_MASTER) {
-
-        auto_strings(solve, base, SS_SYSTEM) ;
-    }
-
-    if (!resolve_read(wres, solve, element))
-        log_warnusys_return(LOG_EXIT_ZERO, "read resolve file of: ", solve, "/", element) ;
-
-    if (!resolve_modify_field(wres, field, value))
-        log_warnusys_return(LOG_EXIT_ZERO, "modify resolve file of: ", solve, "/", element) ;
-
-    if (!resolve_write(wres, solve, element))
-        log_warnusys_return(LOG_EXIT_ZERO, "write resolve file of :", solve, "/", element) ;
-
-    return 1 ;
-
-}
-
-/**
- *
- * FREED
- *
- * */
-
-void resolve_free(resolve_wrapper_t *wres)
-{
-    log_flow() ;
-
-    RESOLVE_SET_SAWRES(wres) ;
-
-    stralloc_free(sawres) ;
-
-    free(wres) ;
-}
-
-void resolve_deep_free(uint8_t type, genalloc *g)
-{
-    log_flow() ;
-
-    size_t pos = 0 ;
-
-    if (type == DATA_SERVICE) {
-
-        for (; pos < genalloc_len(resolve_service_t, g) ; pos++)
-            stralloc_free(&genalloc_s(resolve_service_t, g)[pos].sa) ;
-
-        genalloc_free(resolve_service_t, g) ;
-
-    } else if (type == DATA_TREE) {
-
-        for (; pos < genalloc_len(resolve_tree_t, g) ; pos++)
-            stralloc_free(&genalloc_s(resolve_tree_t, g)[pos].sa) ;
-
-         genalloc_free(resolve_tree_t, g) ;
-
-    } else if (type == DATA_TREE_MASTER) {
-
-        for (; pos < genalloc_len(resolve_tree_master_t, g) ; pos++)
-            stralloc_free(&genalloc_s(resolve_tree_master_t, g)[pos].sa) ;
-
-         genalloc_free(resolve_tree_master_t, g) ;
-    }
-
-}
-
-/**
- *
- * CDB
- *
- * */
-
-int resolve_read_cdb(resolve_wrapper_t *wres, char const *name)
-{
-    log_flow() ;
-
-    int fd, e = 0 ;
-    cdb c = CDB_ZERO ;
-
-    fd = open_readb(name) ;
-    if (fd < 0) {
-        log_warnusys("open: ",name) ;
-        goto err_fd ;
-    }
-
-    if (!cdb_init_fromfd(&c, fd)) {
-        log_warnusys("cdb_init: ", name) ;
-        goto err ;
-    }
-
-    if (wres->type == DATA_SERVICE) {
-
-        if (!service_read_cdb(&c, ((resolve_service_t *)wres->obj)))
-            goto err ;
-
-    } else if (wres->type == DATA_TREE){
-
-        if (!tree_read_cdb(&c, ((resolve_tree_t *)wres->obj)))
-            goto err ;
-
-    } else if (wres->type == DATA_TREE_MASTER) {
-
-        if (!tree_read_master_cdb(&c, ((resolve_tree_master_t *)wres->obj)))
-            goto err ;
-    }
-
-    e = 1 ;
-
-    err:
-        close(fd) ;
-    err_fd:
-        cdb_free(&c) ;
-        return e ;
-}
-
-int resolve_write_cdb(resolve_wrapper_t *wres, char const *dst, char const *name)
-{
-    log_flow() ;
-
-    int fd ;
-    size_t dstlen = strlen(dst), namelen = strlen(name);
-    cdbmaker c = CDBMAKER_ZERO ;
-    char tfile[dstlen + 1 + namelen + namelen + 9] ;
-    char dfile[dstlen + 1 + namelen + 1] ;
-
-    auto_strings(dfile,dst,"/",name) ;
-
-    auto_strings(tfile,dst,"/",name,":",name,":","XXXXXX") ;
-
-    fd = mkstemp(tfile) ;
-    if (fd < 0 || ndelay_off(fd)) {
-        log_warnusys("mkstemp: ", tfile) ;
-        goto err_fd ;
-    }
-
-    if (!cdbmake_start(&c, fd)) {
-        log_warnusys("cdbmake_start") ;
-        goto err ;
-    }
-
-    if (wres->type == DATA_SERVICE) {
-
-        if (!service_write_cdb(&c, ((resolve_service_t *)wres->obj)))
-            goto err ;
-
-    } else if (wres->type == DATA_TREE) {
-
-        if (!tree_write_cdb(&c, ((resolve_tree_t *)wres->obj)))
-            goto err ;
-
-    } else if (wres->type == DATA_TREE_MASTER) {
-
-        if (!tree_write_master_cdb(&c, ((resolve_tree_master_t *)wres->obj)))
-            goto err ;
-
-    }
-
-    if (!cdbmake_finish(&c) || fsync(fd) < 0) {
-        log_warnusys("write to: ", tfile) ;
-        goto err ;
-    }
-
-    close(fd) ;
-
-    if (rename(tfile, dfile) < 0) {
-        log_warnusys("rename ", tfile, " to ", dfile) ;
-        goto err_fd ;
-    }
-
-    return 1 ;
-
-    err:
-        close(fd) ;
-    err_fd:
-        unlink_void(tfile) ;
-        return 0 ;
-}
-
-int resolve_add_cdb(cdbmaker *c, char const *key, char const *data)
-{
-    log_flow() ;
-
-    size_t klen = strlen(key) ;
-    size_t dlen = strlen(data) ;
-
-    if (!cdbmake_add(c,key,klen,dlen ? data : 0,dlen))
-        log_warnsys_return(LOG_EXIT_ZERO,"cdb_make_add: ",key) ;
-
-    return 1 ;
-}
-
-int resolve_add_cdb_uint(cdbmaker *c, char const *key, uint32_t data)
-{
-    log_flow() ;
-
-    char pack[4] ;
-    size_t klen = strlen(key) ;
-
-    uint32_pack_big(pack, data) ;
-    if (!cdbmake_add(c,key,klen,pack,4))
-        log_warnsys_return(LOG_EXIT_ZERO,"cdb_make_add: ",key) ;
-
-    return 1 ;
-}
-
-int resolve_find_cdb(stralloc *result, cdb const *c, char const *key)
-{
-    log_flow() ;
-
-    uint32_t x = 0 ;
-    size_t klen = strlen(key) ;
-    cdb_data cdata ;
-
-    result->len = 0 ;
-
-    int r = cdb_find(c, &cdata, key, klen) ;
-    if (r == -1)
-        log_warnusys_return(LOG_EXIT_LESSONE,"search on cdb key: ",key) ;
-
-    if (!r)
-        log_warn_return(LOG_EXIT_ZERO,"unknown cdb key: ",key) ;
-
-    char pack[cdata.len + 1] ;
-    memcpy(pack,cdata.s, cdata.len) ;
-    pack[cdata.len] = 0 ;
-
-    uint32_unpack_big(pack, &x) ;
-
-    if (!auto_stra(result,pack))
-        log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ;
-
-    return x ;
-}
-
diff --git a/src/lib66/resolve/resolve_add_cdb.c b/src/lib66/resolve/resolve_add_cdb.c
new file mode 100644
index 00000000..41e75e0b
--- /dev/null
+++ b/src/lib66/resolve/resolve_add_cdb.c
@@ -0,0 +1,34 @@
+/*
+ * resolve_add_cdb.c
+ *
+ * Copyright (c) 2018-2022 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+
+#include <oblibs/log.h>
+
+#include <skalibs/cdbmake.h>
+
+#include <66/resolve.h>
+
+int resolve_add_cdb(cdbmaker *c, char const *key, char const *data)
+{
+    log_flow() ;
+
+    size_t klen = strlen(key) ;
+    size_t dlen = strlen(data) ;
+
+    if (!cdbmake_add(c,key,klen,dlen ? data : 0,dlen))
+        log_warnsys_return(LOG_EXIT_ZERO,"cdb_make_add: ",key) ;
+
+    return 1 ;
+}
diff --git a/src/lib66/resolve/resolve_add_cdb_uint.c b/src/lib66/resolve/resolve_add_cdb_uint.c
new file mode 100644
index 00000000..215cacf7
--- /dev/null
+++ b/src/lib66/resolve/resolve_add_cdb_uint.c
@@ -0,0 +1,38 @@
+/*
+ * resolve_add_cdb_uint.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <skalibs/cdbmake.h>
+#include <skalibs/types.h>//uint##_pack
+
+#include <66/resolve.h>
+
+int resolve_add_cdb_uint(cdbmaker *c, char const *key, uint32_t data)
+{
+    log_flow() ;
+
+    char pack[4] ;
+    size_t klen = strlen(key) ;
+
+    uint32_pack_big(pack, data) ;
+    if (!cdbmake_add(c,key,klen,pack,4))
+        log_warnsys_return(LOG_EXIT_ZERO,"cdb_make_add: ",key) ;
+
+    return 1 ;
+}
diff --git a/src/lib66/resolve/resolve_add_string.c b/src/lib66/resolve/resolve_add_string.c
new file mode 100644
index 00000000..6f497d2b
--- /dev/null
+++ b/src/lib66/resolve/resolve_add_string.c
@@ -0,0 +1,48 @@
+/*
+ * resolve_add_string.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <sys/types.h>//ssize_t
+
+#include <oblibs/log.h>
+
+#include <skalibs/stralloc.h>
+
+#include <66/resolve.h>
+#include <66/service.h>
+#include <66/tree.h>
+
+ssize_t resolve_add_string(resolve_wrapper_t *wres, char const *data)
+{
+    log_flow() ;
+
+    RESOLVE_SET_SAWRES(wres) ;
+
+    ssize_t baselen = sawres->len ;
+
+    if (!data) {
+
+        if (!stralloc_catb(sawres,"",1))
+            log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ;
+
+        return baselen ;
+    }
+
+    size_t datalen = strlen(data) ;
+
+    if (!stralloc_catb(sawres,data,datalen + 1))
+        log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ;
+
+    return baselen ;
+}
diff --git a/src/lib66/resolve/resolve_append.c b/src/lib66/resolve/resolve_append.c
new file mode 100644
index 00000000..15dd80ab
--- /dev/null
+++ b/src/lib66/resolve/resolve_append.c
@@ -0,0 +1,62 @@
+/*
+ * resolve_append.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <oblibs/log.h>
+
+#include <skalibs/genalloc.h>
+
+#include <66/resolve.h>
+#include <66/graph.h>
+#include <66/service.h>
+#include <66/tree.h>
+
+int resolve_append(genalloc *ga, resolve_wrapper_t *wres)
+{
+    log_flow() ;
+
+    int e = 0 ;
+
+    if (wres->type == DATA_SERVICE) {
+
+        resolve_service_t cp = RESOLVE_SERVICE_ZERO ;
+        if (!service_resolve_copy(&cp, ((resolve_service_t *)wres->obj)))
+            goto err ;
+
+        if (!genalloc_append(resolve_service_t, ga, &cp))
+            goto err ;
+
+    } else if (wres->type == DATA_TREE) {
+
+        resolve_tree_t cp = RESOLVE_TREE_ZERO ;
+        if (!tree_resolve_copy(&cp, ((resolve_tree_t *)wres->obj)))
+            goto err ;
+
+        if (!genalloc_append(resolve_tree_t, ga, &cp))
+            goto err ;
+
+    } else if (wres->type == DATA_TREE_MASTER) {
+
+            resolve_tree_master_t cp = RESOLVE_TREE_MASTER_ZERO ;
+
+            if (!tree_resolve_master_copy(&cp, ((resolve_tree_master_t *)wres->obj)))
+                goto err ;
+
+            if (!genalloc_append(resolve_tree_master_t, ga, &cp))
+                goto err ;
+    }
+
+    e = 1 ;
+    err:
+        return e ;
+}
diff --git a/src/lib66/resolve/resolve_check.c b/src/lib66/resolve/resolve_check.c
new file mode 100644
index 00000000..497773bc
--- /dev/null
+++ b/src/lib66/resolve/resolve_check.c
@@ -0,0 +1,41 @@
+/*
+ * resolve_check.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <sys/stat.h>
+
+#include <oblibs/log.h>
+#include <oblibs/types.h>
+#include <oblibs/string.h>
+
+#include <66/resolve.h>
+#include <66/constants.h>
+
+int resolve_check(char const *src, char const *name)
+{
+    log_flow() ;
+
+    int r ;
+    size_t srclen = strlen(src) ;
+    size_t namelen = strlen(name) ;
+
+    char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen + 1] ;
+    auto_strings(tmp, src, SS_RESOLVE, "/", name) ;
+
+    r = scan_mode(tmp,S_IFREG) ;
+    if (r <= 0)
+        return 0 ;
+
+    return 1 ;
+}
diff --git a/src/lib66/resolve/resolve_cmp.c b/src/lib66/resolve/resolve_cmp.c
new file mode 100644
index 00000000..f175563a
--- /dev/null
+++ b/src/lib66/resolve/resolve_cmp.c
@@ -0,0 +1,59 @@
+/*
+ * resolve_cmp.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+#include <oblibs/log.h>
+
+#include <skalibs/genalloc.h>
+
+#include <66/resolve.h>
+#include <66/graph.h>
+#include <66/service.h>
+#include <66/tree.h>
+
+int resolve_cmp(genalloc *ga, char const *name, uint8_t type)
+{
+    log_flow() ;
+
+    size_t len, pos = 0 ;
+
+    if (type == DATA_SERVICE) {
+
+        len = genalloc_len(resolve_service_t, ga) ;
+
+        for (;pos < len ; pos++) {
+
+            char *str = genalloc_s(resolve_service_t, ga)[pos].sa.s ;
+            char *s = str + genalloc_s(resolve_service_t, ga)[pos].name ;
+            if (!strcmp(name,s))
+                return 1 ;
+        }
+
+    } else if (type == DATA_TREE) {
+
+        len = genalloc_len(resolve_tree_t, ga) ;
+
+        for (;pos < len ; pos++) {
+
+            char *str = genalloc_s(resolve_tree_t, ga)[pos].sa.s ;
+            char *s = str + genalloc_s(resolve_tree_t, ga)[pos].name ;
+            if (!strcmp(name,s))
+                return 1 ;
+        }
+    }
+
+    return 0 ;
+}
diff --git a/src/lib66/resolve/resolve_deep_free.c b/src/lib66/resolve/resolve_deep_free.c
new file mode 100644
index 00000000..cdab670c
--- /dev/null
+++ b/src/lib66/resolve/resolve_deep_free.c
@@ -0,0 +1,56 @@
+/*
+ * resolve_deep_free.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include <oblibs/log.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+
+#include <66/resolve.h>
+#include <66/service.h>
+#include <66/tree.h>
+#include <66/graph.h>
+
+void resolve_deep_free(uint8_t type, genalloc *g)
+{
+    log_flow() ;
+
+    size_t pos = 0 ;
+
+    if (type == DATA_SERVICE) {
+
+        for (; pos < genalloc_len(resolve_service_t, g) ; pos++)
+            stralloc_free(&genalloc_s(resolve_service_t, g)[pos].sa) ;
+
+        genalloc_free(resolve_service_t, g) ;
+
+    } else if (type == DATA_TREE) {
+
+        for (; pos < genalloc_len(resolve_tree_t, g) ; pos++)
+            stralloc_free(&genalloc_s(resolve_tree_t, g)[pos].sa) ;
+
+         genalloc_free(resolve_tree_t, g) ;
+
+    } else if (type == DATA_TREE_MASTER) {
+
+        for (; pos < genalloc_len(resolve_tree_master_t, g) ; pos++)
+            stralloc_free(&genalloc_s(resolve_tree_master_t, g)[pos].sa) ;
+
+         genalloc_free(resolve_tree_master_t, g) ;
+    }
+
+}
diff --git a/src/lib66/resolve/resolve_find_cdb.c b/src/lib66/resolve/resolve_find_cdb.c
new file mode 100644
index 00000000..188fe0a0
--- /dev/null
+++ b/src/lib66/resolve/resolve_find_cdb.c
@@ -0,0 +1,55 @@
+/*
+ * resolve_find_cdb.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/cdb.h>
+#include <skalibs/types.h>
+
+#include <66/resolve.h>
+
+int resolve_find_cdb(stralloc *result, cdb const *c, char const *key)
+{
+    log_flow() ;
+
+    uint32_t x = 0 ;
+    size_t klen = strlen(key) ;
+    cdb_data cdata ;
+
+    result->len = 0 ;
+
+    int r = cdb_find(c, &cdata, key, klen) ;
+    if (r == -1)
+        log_warnusys_return(LOG_EXIT_LESSONE,"search on cdb key: ",key) ;
+
+    if (!r)
+        log_warn_return(LOG_EXIT_ZERO,"unknown cdb key: ",key) ;
+
+    char pack[cdata.len + 1] ;
+    memcpy(pack,cdata.s, cdata.len) ;
+    pack[cdata.len] = 0 ;
+
+    uint32_unpack_big(pack, &x) ;
+
+    if (!auto_stra(result,pack))
+        log_warnusys_return(LOG_EXIT_LESSONE,"stralloc") ;
+
+    return x ;
+}
+
diff --git a/src/lib66/resolve/resolve_free.c b/src/lib66/resolve/resolve_free.c
new file mode 100644
index 00000000..32b04054
--- /dev/null
+++ b/src/lib66/resolve/resolve_free.c
@@ -0,0 +1,34 @@
+/*
+ * resolve_free.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <stdlib.h>
+
+#include <oblibs/log.h>
+
+#include <skalibs/stralloc.h>
+
+#include <66/resolve.h>
+#include <66/service.h>
+#include <66/tree.h>
+
+void resolve_free(resolve_wrapper_t *wres)
+{
+    log_flow() ;
+
+    RESOLVE_SET_SAWRES(wres) ;
+
+    stralloc_free(sawres) ;
+
+    free(wres) ;
+}
diff --git a/src/lib66/resolve/resolve_init.c b/src/lib66/resolve/resolve_init.c
new file mode 100644
index 00000000..cd1168a5
--- /dev/null
+++ b/src/lib66/resolve/resolve_init.c
@@ -0,0 +1,32 @@
+/*
+ * resolve_init.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <oblibs/log.h>
+
+#include <skalibs/stralloc.h>
+
+#include <66/resolve.h>
+#include <66/tree.h>
+#include <66/service.h>
+
+int resolve_init(resolve_wrapper_t *wres)
+{
+    log_flow() ;
+
+    RESOLVE_SET_SAWRES(wres) ;
+
+    sawres->len = 0 ;
+
+    return resolve_add_string(wres,"") ;
+}
diff --git a/src/lib66/resolve/resolve_modify_field.c b/src/lib66/resolve/resolve_modify_field.c
new file mode 100644
index 00000000..b40c5c17
--- /dev/null
+++ b/src/lib66/resolve/resolve_modify_field.c
@@ -0,0 +1,68 @@
+/*
+ * resolve_modify_field.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <oblibs/log.h>
+
+#include <66/resolve.h>
+#include <66/service.h>
+#include <66/tree.h>
+#include <66/graph.h>
+
+int resolve_modify_field(resolve_wrapper_t_ref wres, uint8_t field, char const *by)
+{
+    log_flow() ;
+
+    int e = 0 ;
+
+    resolve_wrapper_t_ref mwres = 0 ;
+
+    if (wres->type == DATA_SERVICE) {
+
+        resolve_service_t_ref res = (resolve_service_t *)wres->obj  ;
+        mwres = resolve_set_struct(DATA_SERVICE, res) ;
+
+        log_trace("modify field ", resolve_service_field_table[field].field," of service ", res->sa.s + res->name, " with value: ", by) ;
+
+        if (!service_resolve_modify_field(res, field, by))
+            goto err ;
+
+    } else if (wres->type == DATA_TREE) {
+
+        resolve_tree_t_ref res = (resolve_tree_t *)wres->obj  ;
+        mwres = resolve_set_struct(DATA_TREE, res) ;
+
+        log_trace("modify field ", resolve_tree_field_table[field].field," of tree ", res->sa.s + res->name, " with value: ", by) ;
+
+        if (!tree_resolve_modify_field(res, field, by))
+            goto err ;
+
+    } else if (wres->type == DATA_TREE_MASTER) {
+
+        resolve_tree_master_t_ref res = (resolve_tree_master_t *)wres->obj  ;
+        mwres = resolve_set_struct(DATA_TREE_MASTER, res) ;
+
+        log_trace("modify field ", resolve_tree_master_field_table[field].field," of inner resolve file of trees with value: ", by) ;
+
+        if (!tree_resolve_master_modify_field(res, field, by))
+            goto err ;
+    }
+
+    e = 1 ;
+    err:
+        free(mwres) ;
+        return e ;
+}
diff --git a/src/lib66/resolve/resolve_modify_field_g.c b/src/lib66/resolve/resolve_modify_field_g.c
new file mode 100644
index 00000000..7f06301c
--- /dev/null
+++ b/src/lib66/resolve/resolve_modify_field_g.c
@@ -0,0 +1,65 @@
+/*
+ * resolve_modify_field_g.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <66/resolve.h>
+#include <66/service.h>
+#include <66/tree.h>
+#include <66/constants.h>
+#include <66/graph.h>
+
+
+int resolve_modify_field_g(resolve_wrapper_t_ref wres, char const *base, char const *element, uint8_t field, char const *value)
+{
+
+    log_flow() ;
+
+    size_t baselen = strlen(base), tot = baselen + SS_SYSTEM_LEN + 1, treelen = 0 ;
+    char *treename = 0 ;
+
+    if (wres->type == DATA_SERVICE) {
+        treename = ((resolve_service_t *)wres->obj)->sa.s + ((resolve_service_t *)wres->obj)->treename ;
+        treelen = strlen(treename) ;
+        tot += treelen + SS_SVDIRS_LEN + 1 ;
+
+    }
+
+    char solve[tot] ;
+
+    if (wres->type == DATA_SERVICE) {
+
+        auto_strings(solve, base, SS_SYSTEM, "/", treename, SS_SVDIRS) ;
+
+    } else if (wres->type == DATA_TREE || wres->type == DATA_TREE_MASTER) {
+
+        auto_strings(solve, base, SS_SYSTEM) ;
+    }
+
+    if (!resolve_read(wres, solve, element))
+        log_warnusys_return(LOG_EXIT_ZERO, "read resolve file of: ", solve, "/", element) ;
+
+    if (!resolve_modify_field(wres, field, value))
+        log_warnusys_return(LOG_EXIT_ZERO, "modify resolve file of: ", solve, "/", element) ;
+
+    if (!resolve_write(wres, solve, element))
+        log_warnusys_return(LOG_EXIT_ZERO, "write resolve file of :", solve, "/", element) ;
+
+    return 1 ;
+
+}
diff --git a/src/lib66/resolve/resolve_read.c b/src/lib66/resolve/resolve_read.c
new file mode 100644
index 00000000..2b32fde4
--- /dev/null
+++ b/src/lib66/resolve/resolve_read.c
@@ -0,0 +1,36 @@
+/*
+ * resolve_read.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <66/resolve.h>
+
+int resolve_read(resolve_wrapper_t *wres, char const *src, char const *name)
+{
+    log_flow() ;
+
+    size_t srclen = strlen(src) ;
+    size_t namelen = strlen(name) ;
+
+    char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen + 1] ;
+    auto_strings(tmp,src,SS_RESOLVE,"/",name) ;
+
+    if (!resolve_read_cdb(wres,tmp))
+        return 0 ;
+
+    return 1 ;
+}
diff --git a/src/lib66/resolve/resolve_read_cdb.c b/src/lib66/resolve/resolve_read_cdb.c
new file mode 100644
index 00000000..9a7bd2b4
--- /dev/null
+++ b/src/lib66/resolve/resolve_read_cdb.c
@@ -0,0 +1,68 @@
+/*
+ * resolve_read_cdb.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <unistd.h>
+
+#include <oblibs/log.h>
+
+#include <skalibs/cdb.h>
+#include <skalibs/djbunix.h>
+
+#include <66/resolve.h>
+#include <66/graph.h>
+#include <66/service.h>
+#include <66/tree.h>
+
+int resolve_read_cdb(resolve_wrapper_t *wres, char const *name)
+{
+    log_flow() ;
+
+    int fd, e = 0 ;
+    cdb c = CDB_ZERO ;
+
+    fd = open_readb(name) ;
+    if (fd < 0) {
+        log_warnusys("open: ",name) ;
+        goto err_fd ;
+    }
+
+    if (!cdb_init_fromfd(&c, fd)) {
+        log_warnusys("cdb_init: ", name) ;
+        goto err ;
+    }
+
+    if (wres->type == DATA_SERVICE) {
+
+        if (!service_read_cdb(&c, ((resolve_service_t *)wres->obj)))
+            goto err ;
+
+    } else if (wres->type == DATA_TREE){
+
+        if (!tree_read_cdb(&c, ((resolve_tree_t *)wres->obj)))
+            goto err ;
+
+    } else if (wres->type == DATA_TREE_MASTER) {
+
+        if (!tree_read_master_cdb(&c, ((resolve_tree_master_t *)wres->obj)))
+            goto err ;
+    }
+
+    e = 1 ;
+
+    err:
+        close(fd) ;
+    err_fd:
+        cdb_free(&c) ;
+        return e ;
+}
diff --git a/src/lib66/resolve/resolve_rmfile.c b/src/lib66/resolve/resolve_rmfile.c
new file mode 100644
index 00000000..71cf85e3
--- /dev/null
+++ b/src/lib66/resolve/resolve_rmfile.c
@@ -0,0 +1,35 @@
+/*
+ * resolve_rmfile.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <skalibs/posixplz.h>
+
+#include <66/resolve.h>
+
+void resolve_rmfile(char const *src,char const *name)
+{
+    log_flow() ;
+
+    size_t srclen = strlen(src) ;
+    size_t namelen = strlen(name) ;
+
+    char tmp[srclen + SS_RESOLVE_LEN + 1 + namelen +1] ;
+    auto_strings(tmp, src, SS_RESOLVE, "/", name) ;
+
+    unlink_void(tmp) ;
+}
diff --git a/src/lib66/resolve/resolve_search.c b/src/lib66/resolve/resolve_search.c
new file mode 100644
index 00000000..912ca31e
--- /dev/null
+++ b/src/lib66/resolve/resolve_search.c
@@ -0,0 +1,68 @@
+/*
+ * resolve_search.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <stdint.h>
+
+#include <oblibs/log.h>
+
+#include <skalibs/genalloc.h>
+
+#include <66/resolve.h>
+#include <66/service.h>
+#include <66/tree.h>
+#include <66/graph.h>
+
+int resolve_search(genalloc *ga, char const *name, uint8_t type)
+{
+    log_flow() ;
+
+    size_t len, pos = 0 ;
+
+    if (type == DATA_SERVICE) {
+
+        len = genalloc_len(resolve_service_t, ga) ;
+
+        for (;pos < len ; pos++) {
+
+            char *s = genalloc_s(resolve_service_t,ga)[pos].sa.s + genalloc_s(resolve_service_t,ga)[pos].name ;
+            if (!strcmp(name,s))
+                return pos ;
+        }
+
+    } else if (type == DATA_TREE) {
+
+        len = genalloc_len(resolve_tree_t, ga) ;
+
+        for (;pos < len ; pos++) {
+
+            char *s = genalloc_s(resolve_tree_t,ga)[pos].sa.s + genalloc_s(resolve_tree_t,ga)[pos].name ;
+            if (!strcmp(name,s))
+                return pos ;
+        }
+
+    } else if (type == DATA_TREE_MASTER) {
+
+        len = genalloc_len(resolve_tree_master_t, ga) ;
+
+        for (;pos < len ; pos++) {
+
+            char *s = genalloc_s(resolve_tree_master_t,ga)[pos].sa.s + genalloc_s(resolve_tree_master_t,ga)[pos].name ;
+            if (!strcmp(name,s))
+                return pos ;
+        }
+    }
+
+    return -1 ;
+}
diff --git a/src/lib66/resolve/resolve_set_struct.c b/src/lib66/resolve/resolve_set_struct.c
new file mode 100644
index 00000000..8d8f2af3
--- /dev/null
+++ b/src/lib66/resolve/resolve_set_struct.c
@@ -0,0 +1,32 @@
+/*
+ * resolve_set_struct.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <oblibs/log.h>
+
+#include <66/resolve.h>
+
+resolve_wrapper_t *resolve_set_struct(uint8_t type, void *s)
+{
+    log_flow() ;
+
+    resolve_wrapper_t *wres = malloc(sizeof(resolve_wrapper_t)) ;
+
+    wres->obj = s ;
+    wres->type = type ;
+    return wres ;
+} ;
+
diff --git a/src/lib66/resolve/resolve_write.c b/src/lib66/resolve/resolve_write.c
new file mode 100644
index 00000000..830f09a9
--- /dev/null
+++ b/src/lib66/resolve/resolve_write.c
@@ -0,0 +1,36 @@
+/*
+ * resolve_write.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <66/resolve.h>
+
+int resolve_write(resolve_wrapper_t *wres, char const *dst, char const *name)
+{
+    log_flow() ;
+
+    size_t dstlen = strlen(dst) ;
+    size_t namelen = strlen(name) ;
+
+    char tmp[dstlen + SS_RESOLVE_LEN + 1 + namelen + 1] ;
+    auto_strings(tmp,dst,SS_RESOLVE,"/") ;
+
+    if (!resolve_write_cdb(wres,tmp,name))
+        return 0 ;
+
+    return 1 ;
+}
diff --git a/src/lib66/resolve/resolve_write_cdb.c b/src/lib66/resolve/resolve_write_cdb.c
new file mode 100644
index 00000000..02ed4906
--- /dev/null
+++ b/src/lib66/resolve/resolve_write_cdb.c
@@ -0,0 +1,94 @@
+/*
+ * resolve_write_cdb.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <skalibs/djbunix.h>
+#include <skalibs/cdbmake.h>
+#include <skalibs/posixplz.h>//unlink
+
+#include <66/resolve.h>
+#include <66/service.h>
+#include <66/tree.h>
+#include <66/graph.h>
+
+int resolve_write_cdb(resolve_wrapper_t *wres, char const *dst, char const *name)
+{
+    log_flow() ;
+
+    int fd ;
+    size_t dstlen = strlen(dst), namelen = strlen(name);
+    cdbmaker c = CDBMAKER_ZERO ;
+    char tfile[dstlen + 1 + namelen + namelen + 9] ;
+    char dfile[dstlen + 1 + namelen + 1] ;
+
+    auto_strings(dfile,dst,"/",name) ;
+
+    auto_strings(tfile,dst,"/",name,":",name,":","XXXXXX") ;
+
+    fd = mkstemp(tfile) ;
+    if (fd < 0 || ndelay_off(fd)) {
+        log_warnusys("mkstemp: ", tfile) ;
+        goto err_fd ;
+    }
+
+    if (!cdbmake_start(&c, fd)) {
+        log_warnusys("cdbmake_start") ;
+        goto err ;
+    }
+
+    if (wres->type == DATA_SERVICE) {
+
+        if (!service_write_cdb(&c, ((resolve_service_t *)wres->obj)))
+            goto err ;
+
+    } else if (wres->type == DATA_TREE) {
+
+        if (!tree_write_cdb(&c, ((resolve_tree_t *)wres->obj)))
+            goto err ;
+
+    } else if (wres->type == DATA_TREE_MASTER) {
+
+        if (!tree_write_master_cdb(&c, ((resolve_tree_master_t *)wres->obj)))
+            goto err ;
+
+    }
+
+    if (!cdbmake_finish(&c) || fsync(fd) < 0) {
+        log_warnusys("write to: ", tfile) ;
+        goto err ;
+    }
+
+    close(fd) ;
+
+    if (rename(tfile, dfile) < 0) {
+        log_warnusys("rename ", tfile, " to ", dfile) ;
+        goto err_fd ;
+    }
+
+    return 1 ;
+
+    err:
+        close(fd) ;
+    err_fd:
+        unlink_void(tfile) ;
+        return 0 ;
+}
-- 
GitLab