From 6715c89d9053f56e49b1f9236a680913858f2b27 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Wed, 6 Jul 2022 17:31:15 +1100
Subject: [PATCH] remove use of s6-rc. Split sanitize_system to new function.
 Revamp clone feature. Do not handle anymore backup directory at clone time.
 Pass to new graph_matrix_get_edge_g_sorted_sa() and
 graph_matrix_get_edge_g_sa() functions interface

---
 src/lib66/exec/ssexec_tree.c | 344 +++++++----------------------------
 1 file changed, 62 insertions(+), 282 deletions(-)

diff --git a/src/lib66/exec/ssexec_tree.c b/src/lib66/exec/ssexec_tree.c
index 5c08af21..5e9539db 100644
--- a/src/lib66/exec/ssexec_tree.c
+++ b/src/lib66/exec/ssexec_tree.c
@@ -38,16 +38,14 @@
 #include <66/config.h>
 #include <66/utils.h>
 #include <66/constants.h>
-#include <66/db.h>
 #include <66/enum.h>
 #include <66/state.h>
 #include <66/service.h>
 #include <66/resolve.h>
 #include <66/graph.h>
+#include <66/sanitize.h>
 
 #include <s6/supervise.h>
-#include <s6-rc/s6rc-servicedir.h>
-#include <s6-rc/s6rc-constants.h>
 
 #define TREE_COLON_DELIM ':'
 #define TREE_COMMA_DELIM ','
@@ -177,35 +175,6 @@ static void auto_dir(char const *dst,mode_t mode)
         log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"create directory: ",dst) ;
 }
 
-static void auto_create(char *strings,char const *str, size_t len)
-{
-    log_flow() ;
-
-    auto_strings(strings + len, str) ;
-    auto_dir(strings,0755) ;
-}
-
-static void auto_check(char *dst)
-{
-    log_flow() ;
-
-    int r = scan_mode(dst,S_IFDIR) ;
-
-    if (r == -1)
-        log_diesys_nclean(LOG_EXIT_SYS, &cleanup, "conflicting format for: ", dst) ;
-
-    if (!r)
-        auto_dir(dst,0755) ;
-}
-
-static void inline auto_stralloc(stralloc *sa,char const *str)
-{
-    log_flow() ;
-
-    if (!auto_stra(sa,str))
-        log_die_nomem("stralloc") ;
-}
-
 static ssize_t tree_get_key(char *table,char const *str)
 {
     ssize_t pos = -1 ;
@@ -224,97 +193,6 @@ static ssize_t tree_get_key(char *table,char const *str)
     return pos ;
 }
 
-void sanitize_system(ssexec_t *info)
-{
-    log_flow() ;
-
-    log_trace("sanitize system..." ) ;
-
-    size_t baselen = info->base.len ;
-    uid_t log_uid ;
-    gid_t log_gid ;
-    char dst[baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + SS_MASTER_LEN + 1] ;
-    auto_strings(dst,info->base.s, SS_SYSTEM) ;
-
-    /** base is /var/lib/66 or $HOME/.66*/
-    /** this verification is made in case of
-     * first use of 66-*** tools */
-    auto_check(dst) ;
-    /** create extra directory for service part */
-    if (!info->owner) {
-
-        auto_check(SS_LOGGER_SYSDIR) ;
-
-        if (!youruid(&log_uid,SS_LOGGER_RUNNER) ||
-        !yourgid(&log_gid,log_uid))
-            log_dieusys(LOG_EXIT_SYS,"get uid and gid of: ",SS_LOGGER_RUNNER) ;
-
-        if (chown(SS_LOGGER_SYSDIR,log_uid,log_gid) == -1)
-            log_dieusys(LOG_EXIT_SYS,"chown: ",SS_LOGGER_RUNNER) ;
-
-        auto_check(SS_SERVICE_SYSDIR) ;
-        auto_check(SS_SERVICE_ADMDIR) ;
-        auto_check(SS_SERVICE_ADMCONFDIR) ;
-        auto_check(SS_MODULE_SYSDIR) ;
-        auto_check(SS_MODULE_ADMDIR) ;
-        auto_check(SS_SCRIPT_SYSDIR) ;
-        auto_check(SS_SEED_ADMDIR) ;
-        auto_check(SS_SEED_SYSDIR) ;
-
-    } else {
-
-        size_t extralen ;
-        stralloc extra = STRALLOC_ZERO ;
-        if (!set_ownerhome(&extra,info->owner))
-            log_dieusys(LOG_EXIT_SYS,"set home directory") ;
-
-        extralen = extra.len ;
-        if (!auto_stra(&extra, SS_USER_DIR, SS_SYSTEM))
-            log_die_nomem("stralloc") ;
-        auto_check(extra.s) ;
-
-        extra.len = extralen ;
-        auto_stralloc(&extra,SS_LOGGER_USERDIR) ;
-        auto_check(extra.s) ;
-
-        extra.len = extralen ;
-        auto_stralloc(&extra,SS_SERVICE_USERDIR) ;
-        auto_check(extra.s) ;
-
-        extra.len = extralen ;
-        auto_stralloc(&extra,SS_SERVICE_USERCONFDIR) ;
-        auto_check(extra.s) ;
-
-        extra.len = extralen ;
-        auto_stralloc(&extra,SS_MODULE_USERDIR) ;
-        auto_check(extra.s) ;
-
-        extra.len = extralen ;
-        auto_stralloc(&extra,SS_SCRIPT_USERDIR) ;
-        auto_check(extra.s) ;
-
-        extra.len = extralen ;
-        auto_stralloc(&extra,SS_SEED_USERDIR) ;
-        auto_check(extra.s) ;
-
-        stralloc_free(&extra) ;
-    }
-
-    auto_strings(dst,info->base.s, SS_SYSTEM, SS_RESOLVE) ;
-    auto_check(dst) ;
-
-    auto_strings(dst + baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN, SS_MASTER) ;
-
-    if (!scan_mode(dst, S_IFREG))
-        if (!tree_resolve_master_create(info->base.s, info->owner))
-            log_dieu(LOG_EXIT_SYS, "write Master resolve file of trees") ;
-
-    auto_strings(dst + baselen, SS_TREE_CURRENT) ;
-    auto_check(dst) ;
-    auto_strings(dst + baselen, SS_SYSTEM, SS_BACKUP) ;
-    auto_check(dst) ;
-}
-
 static void tree_parse_options_groups(char *store, char const *str)
 {
     log_flow() ;
@@ -440,7 +318,7 @@ static void tree_parse_options_depends(graph_t *g, ssexec_t *info, char const *s
 
             log_trace("launch 66-tree sub-process for tree: ", name) ;
 
-            if (ssexec_tree(nargc, newargv, (char const *const *)environ, &newinfo))
+            if (ssexec_tree(nargc, newargv, &newinfo))
                 log_dieusys(LOG_EXIT_SYS, "create tree: ", name) ;
 
             ssexec_free(&newinfo) ;
@@ -621,60 +499,19 @@ void create_tree(ssexec_t *info)
 {
     log_flow() ;
 
-    size_t newlen = 0, treelen = info->tree.len ;
+    size_t treelen = info->tree.len ;
     char const *tree = info->tree.s ;
-    char dst[treelen + SS_SVDIRS_LEN + SS_DB_LEN + SS_SRC_LEN + 16 + 1] ;
-    char sym[treelen + SS_SVDIRS_LEN + 1 + SS_SYM_SVC_LEN + 1] ;
-    char dstsym[treelen + SS_SVDIRS_LEN + SS_SVC_LEN + 1] ;
-
-    auto_strings(dst, tree) ;
-    newlen = treelen ;
-
-    auto_create(dst, SS_SVDIRS, newlen) ;
-    auto_create(dst, SS_RULES, newlen) ;
-    auto_strings(dst + newlen, SS_SVDIRS) ;
-    newlen = newlen + SS_SVDIRS_LEN ;
-    auto_create(dst, SS_DB, newlen) ;
-    auto_create(dst, SS_SVC, newlen) ;
-    auto_create(dst, SS_RESOLVE, newlen) ;
-    dst[newlen] = 0 ;
-
-    if (!service_resolve_master_create(info->base.s, info->treename.s))
-        log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"write Master resolve file of services") ;
-
-    auto_strings(sym,dst, "/", SS_SYM_SVC) ;
-    auto_strings(dstsym, dst, SS_SVC) ;
-
-    log_trace("point symlink: ", sym, " to ", dstsym) ;
-    if (symlink(dstsym,sym) < 0)
-        log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"symlink: ", sym) ;
-
-    auto_strings(sym + newlen + 1, SS_SYM_DB) ;
-    auto_strings(dstsym + newlen, SS_DB) ;
-
-    log_trace("point symlink: ", sym, " to ", dstsym) ;
-    if (symlink(dstsym, sym) < 0)
-        log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"symlink: ", sym) ;
-
-    auto_strings(dst + newlen, SS_DB) ;
-    newlen = newlen + SS_DB_LEN ;
-    auto_create(dst, SS_SRC, newlen) ;
-    auto_strings(dst + newlen, SS_SRC) ;
-    newlen = newlen + SS_SRC_LEN ;
-    auto_create(dst, SS_MASTER, newlen) ;
-    auto_strings(dst + newlen, SS_MASTER) ;
-    newlen = newlen + SS_MASTER_LEN ;
-
-    log_trace("create file: ", dst, "/contents") ;
-    if (!file_create_empty(dst, "contents", 0644))
-        log_dieusys_nclean(LOG_EXIT_SYS, &cleanup, "create: ", dst, "/contents") ;
-
-    auto_strings(dst + newlen, "/type") ;
+    char dst[treelen + SS_SVDIRS_LEN + SS_RESOLVE_LEN + 1] ;
 
-    log_trace("create file: ", dst) ;
-    if(!openwritenclose_unsafe(dst, "bundle\n",7))
-        log_dieusys_nclean(LOG_EXIT_SYS, &cleanup, "write: ", dst) ;
+    auto_strings(dst, tree, SS_SVDIRS, SS_SVC) ;
+    auto_dir(dst, 0755) ;
+    auto_strings(dst + treelen + SS_SVDIRS_LEN, SS_RESOLVE) ;
+    auto_dir(dst, 0755) ;
+    auto_strings(dst + treelen, SS_RULES) ;
+    auto_dir(dst, 0755) ;
 
+    if (!service_resolve_master_create(info->base.s, info->treename.s))
+        log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"write Master resolve file of services for tree: ", info->treename.s) ;
 }
 
 void tree_groups(char const *base, char const *treename, char const *value)
@@ -784,7 +621,7 @@ void tree_master_modify_contents(char const *base, char const *treename)
     resolve_free(wres) ;
 }
 
-void tree_create(graph_t *g, ssexec_t *info, tree_what_t *what, char const *const *envp)
+void tree_create(graph_t *g, ssexec_t *info, tree_what_t *what)
 {
     log_flow() ;
 
@@ -807,6 +644,9 @@ void tree_create(graph_t *g, ssexec_t *info, tree_what_t *what, char const *cons
     log_trace("creating: ", info->tree.s, "..." ) ;
     create_tree(info) ;
 
+    char svdir[info->tree.len + SS_SVDIRS_LEN + SS_SVC_LEN + 2] ;
+    auto_strings(svdir, info->tree.s, SS_SVDIRS, SS_SVC, "/") ;
+
     log_trace("creating backup directory of tree: ", info->treename.s, "...") ;
     create_backupdir(info->base.s, info->treename.s) ;
 
@@ -816,15 +656,6 @@ void tree_create(graph_t *g, ssexec_t *info, tree_what_t *what, char const *cons
     // set permissions
     what->allow = 1 ;
 
-    // compilation of the db
-    size_t dblen = info->tree.len ;
-    char newdb[dblen + SS_SVDIRS_LEN + 1] ;
-    auto_strings(newdb, info->tree.s, SS_SVDIRS) ;
-
-    log_trace("compile: ",newdb, "/db/", info->treename.s, "..." ) ;
-    if (!db_compile(newdb, info->tree.s, info->treename.s, envp))
-        log_dieu_nclean(LOG_EXIT_SYS,&cleanup, "compile ", newdb, "/db/", info->treename.s) ;
-
     tres.name = resolve_add_string(wres, info->treename.s) ;
     tres.groups = resolve_add_string(wres, info->owner ? TREE_GROUPS_USER : TREE_GROUPS_ADM) ;
     tres.ngroups = 1 ;
@@ -836,7 +667,7 @@ void tree_create(graph_t *g, ssexec_t *info, tree_what_t *what, char const *cons
     /** check of the seed.sa.len: if the seed file is not parse at this point
      * the seed.sa.s + seed.depends is empty which produce a segmentation fault
      * when the -o options is passed at commandline. We have already passed
-     * through the tree_parse_options_depends anyway when it's the case */
+     * through the tree_parse_options_depends anyway when it's the case. */
     if (what->depends && seed.sa.len)
         tree_parse_options_depends(g, info, seed.sa.s + seed.depends, 0, what) ;
 
@@ -852,10 +683,8 @@ void tree_create(graph_t *g, ssexec_t *info, tree_what_t *what, char const *cons
 }
 
 /**
- *
  * WARNING: The order of the trees are not sorted by dependencies order
  *
- *
  * !action -> disable
  * action -> disable */
 void tree_master_enable_disable(char const *base, char const *treename, uint8_t action)
@@ -942,7 +771,7 @@ void tree_enable_disable_deps(graph_t *g,char const *base, char const *treename,
     size_t pos = 0, element = 0 ;
     stralloc sa = STRALLOC_ZERO ;
 
-    if (graph_matrix_get_edge_g_sa(&sa, g, treename, action ? 0 : 1) < 0)
+    if (graph_matrix_get_edge_g_sa(&sa, g, treename, action ? 0 : 1, 0) < 0)
         log_dieu(LOG_EXIT_SYS, "get ", action ? "dependencies" : "required by" ," of: ", treename) ;
 
     size_t len = sastr_nelement(&sa) ;
@@ -1031,7 +860,7 @@ void tree_depends_requiredby(graph_t *g, char const *base, char const *treename,
 
     auto_strings(solve, base, SS_SYSTEM) ;
 
-    if (graph_matrix_get_edge_g_sorted_sa(&sa, g, treename, requiredby) < 0)
+    if (graph_matrix_get_edge_g_sorted_sa(&sa, g, treename, requiredby, 0) < 0)
         log_dieu(LOG_EXIT_SYS,"get sorted ", requiredby ? "required by" : "dependency", " list of tree: ", treename) ;
 
     size_t vlen = sastr_nelement(&sa) ;
@@ -1126,7 +955,7 @@ void tree_depends_requiredby_deps(graph_t *g, char const *base, char const *tree
     stralloc sa = STRALLOC_ZERO ;
     char solve[baselen + SS_SYSTEM_LEN + 1] ;
 
-    if (graph_matrix_get_edge_g_sorted_sa(&sa, g, treename, requiredby) < 0)
+    if (graph_matrix_get_edge_g_sorted_sa(&sa, g, treename, requiredby, 0) < 0)
         log_dieu(LOG_EXIT_SYS,"get sorted ", requiredby ? "required by" : "dependency", " list of tree: ", treename) ;
 
     size_t vlen = sastr_nelement(&sa) ;
@@ -1368,48 +1197,36 @@ void tree_clone(char const *clone, ssexec_t *info)
 
     int r ;
     resolve_service_t res = RESOLVE_SERVICE_ZERO ;
-    resolve_tree_master_t mres = RESOLVE_TREE_MASTER_ZERO ;
+    resolve_tree_t tres = RESOLVE_TREE_ZERO ;
     resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
     stralloc sa = STRALLOC_ZERO ;
-    char const *exclude[1] = { 0 } ;
+    char const *exclude[2] = { SS_MASTER + 1, 0 } ;
 
     size_t syslen = info->base.len + SS_SYSTEM_LEN ;
-    size_t treelen = info->treename.len, clonelen = strlen(clone) ;
+    size_t clonelen = strlen(clone) ;
     size_t pos = 0 ;
 
     char system[syslen + 1] ;
-    auto_strings(system,info->base.s,SS_SYSTEM) ;
+    auto_strings(system, info->base.s, SS_SYSTEM) ;
 
     size_t clone_target_len = syslen + 1 + clonelen ;
     char clone_target[clone_target_len + 1] ;
-    auto_strings(clone_target,system,"/",clone) ;
+    auto_strings(clone_target, system, "/", clone) ;
 
     r = scan_mode(clone_target,S_IFDIR) ;
-    if ((r < 0) || r) log_die(LOG_EXIT_SYS,clone_target,": already exist") ;
+    if ((r < 0) || r) log_die(LOG_EXIT_USER,clone_target,": already exist") ;
 
     // clone main directory
-    log_trace("clone: ",info->treename.s," as: ",clone,"..." ) ;
-    if (!hiercopy(info->tree.s,clone_target))
+    log_trace("clone: ", info->treename.s, " as: ", clone, "..." ) ;
+    if (!hiercopy(info->tree.s, clone_target))
         log_dieusys(LOG_EXIT_SYS,"copy: ",info->tree.s," to: ",clone_target) ;
 
-    // clone backup directory
-    size_t clone_backup_len = syslen + SS_BACKUP_LEN + 1 + clonelen ;
-    char clone_backup[clone_backup_len + 1] ;
-    auto_strings(clone_backup,system,SS_BACKUP,"/",clone) ;
-
-    char tree_backup[syslen + SS_BACKUP_LEN + 1 + treelen + 1] ;
-    auto_strings(tree_backup,system,SS_BACKUP,"/",info->treename.s) ;
-
-    /* make cleantree pointing to the clone to be able to remove it
-     * in case of crach */
     cleantree = clone_target ;
 
-    log_trace("clone backup of: ",info->treename.s," as: ",clone,"..." ) ;
-    if (!hiercopy(tree_backup,clone_backup))
-        log_dieu_nclean(LOG_EXIT_SYS,&cleanup,"copy: ",tree_backup," to: ",clone_backup) ;
-
-    // modify the resolve file to match the new name
-    // main directory first
+    /**
+     * modify the resolve files of all services inside the clone
+     * to match the new name of the tree.
+     * */
     char src_resolve[clone_target_len + SS_SVDIRS_LEN + SS_RESOLVE_LEN + 1] ;
     auto_strings(src_resolve,clone_target,SS_SVDIRS,SS_RESOLVE) ;
 
@@ -1426,93 +1243,56 @@ void tree_clone(char const *clone, ssexec_t *info)
         if (!resolve_read(wres,clone_res,name))
             log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"read resolve file of: ",src_resolve,"/",name) ;
 
-        if (!resolve_modify_field(wres, SERVICE_ENUM_RUNAT, clone)  ||
+        char status[info->base.len + SS_SYSTEM_LEN + 1 + clonelen + SS_SVDIRS_LEN + SS_SVC_LEN + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
+        auto_strings(status, info->base.s, SS_SYSTEM, "/", clone, SS_SVDIRS, SS_SVC, SS_STATE, "/", SS_STATUS) ;
+
+        if (!resolve_modify_field(wres, SERVICE_ENUM_TREE, clone_target) ||
             !resolve_modify_field(wres, SERVICE_ENUM_TREENAME, clone) ||
-            !resolve_modify_field(wres, SERVICE_ENUM_TREE, clone) ||
-            !resolve_modify_field(wres, SERVICE_ENUM_STATE, clone))
+            !resolve_modify_field(wres, SERVICE_ENUM_STATUS, status))
                 log_dieusys_nclean(LOG_EXIT_SYS, &cleanup, "modify resolve file of: ", name) ;
 
         if (!resolve_write(wres,clone_res,name))
             log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"write resolve file of: ",src_resolve,"/",name) ;
     }
 
-    // rename db
-    char clone_db_old[clone_target_len + SS_SVDIRS_LEN + SS_DB_LEN + 1 + treelen + 1] ;
-    auto_strings(clone_db_old,clone_target,SS_SVDIRS,SS_DB,"/",info->treename.s) ;
-
-    char clone_db_new[clone_target_len + SS_SVDIRS_LEN + SS_DB_LEN + 1 + clonelen + 1] ;
-    auto_strings(clone_db_new,clone_target,SS_SVDIRS,SS_DB,"/",clone) ;
-
-    log_trace("rename tree db: ",info->treename.s," as: ",clone,"..." ) ;
-    if (rename(clone_db_old,clone_db_new) == -1)
-        log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"rename: ",clone_db_old," to: ",clone_db_new) ;
-
-    // backup directory
-    char src_resolve_backup[clone_backup_len + SS_RESOLVE_LEN + 1] ;
-    auto_strings(src_resolve_backup,clone_backup,SS_RESOLVE) ;
-
-    sa.len = 0 ;
-
-    /** main and backup can be different,so rebuild the list
-     * Also, a backup directory can be empty, check it first */
-    r = scan_mode(src_resolve_backup,S_IFDIR) ;
-    if (r == 1) {
-
-        if (!sastr_dir_get(&sa,src_resolve_backup,exclude,S_IFREG))
-            log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"get resolve file at: ",src_resolve_backup) ;
-
-        pos = 0 ;
-        FOREACH_SASTR(&sa, pos) {
-
-            char *name = sa.s + pos ;
+    resolve_free(wres) ;
 
-            if (!resolve_read(wres,clone_backup,name))
-                log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"read resolve file of: ",src_resolve_backup,"/",name) ;
+    /** copy tree resolve file */
+    struct stat st ;
+    char src[syslen + SS_RESOLVE_LEN + 1 + info->treename.len + 1] ;
+    char dst[syslen + SS_RESOLVE_LEN + 1 + clonelen + 1] ;
+    auto_strings(src, system, SS_RESOLVE, "/", info->treename.s) ;
+    auto_strings(dst, system, SS_RESOLVE, "/", clone) ;
 
-            if (!resolve_modify_field(wres, SERVICE_ENUM_RUNAT, clone) ||
-                !resolve_modify_field(wres, SERVICE_ENUM_TREENAME, clone) ||
-                !resolve_modify_field(wres, SERVICE_ENUM_TREE, clone) ||
-                !resolve_modify_field(wres, SERVICE_ENUM_STATE, clone))
-                    log_dieusys_nclean(LOG_EXIT_SYS, &cleanup, "modify resolve file of: ", name) ;
+    if (stat(src, &st) < 0)
+        log_dieusys_nclean(LOG_EXIT_SYS, &cleanup, "stat: ", src) ;
 
-            if (!resolve_write(wres,clone_backup,name))
-                log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"write resolve file of: ",src_resolve,"/",name) ;
-        }
-        // rename db
-        char clone_db_backup_old[clone_backup_len + SS_DB_LEN + 1 + treelen + 1] ;
-        auto_strings(clone_db_backup_old,clone_backup,SS_DB,"/",info->treename.s) ;
+    if (!filecopy_unsafe(src, dst, st.st_mode))
+        log_dieusys_nclean(LOG_EXIT_SYS, &cleanup, "copy: ", src, " to: ", dst) ;
 
-        char clone_db_backup_new[clone_backup_len + SS_DB_LEN + 1 + clonelen + 1] ;
-        auto_strings(clone_db_backup_new,clone_backup,SS_DB,"/",clone) ;
+    lchown(dst, st.st_uid, st.st_gid) ;
 
-        log_trace("rename tree backup db: ",info->treename.s," as: ",clone,"..." ) ;
-        if (rename(clone_db_backup_old,clone_db_backup_new) == -1)
-            log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"rename: ",clone_db_backup_old," to: ",clone_db_backup_new) ;
-    }
     /** tree resolve file */
+    wres = resolve_set_struct(DATA_TREE, &tres) ;
 
-    resolve_free(wres) ;
-
-    wres = resolve_set_struct(DATA_TREE_MASTER, &mres) ;
-
-    if (!resolve_read(wres, system, info->treename.s))
-        log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"read inner resolve file of trees") ;
+    if (!resolve_read(wres, system, clone))
+        log_dieusys_nclean(LOG_EXIT_SYS,&cleanup,"read resolve file of tree: ", clone) ;
 
-    if (!resolve_modify_field(wres, TREE_ENUM_MASTER_ENABLED, 0) ||
-        !resolve_modify_field(wres, TREE_ENUM_MASTER_NAME, clone))
-            log_dieusys(LOG_EXIT_SYS, "modify inner resolve file of trees") ;
-
-    mres.nenabled = 0 ;
+    if(!resolve_modify_field(wres, TREE_ENUM_DISEN, 0))
+        log_dieusys(LOG_EXIT_SYS, "modify resolve file of tree: ", clone) ;
 
     if (!resolve_write(wres, system, clone))
-        log_dieusys_nclean(LOG_EXIT_SYS, &cleanup, "write inner resolve file of trees") ;
+        log_dieusys_nclean(LOG_EXIT_SYS, &cleanup, "write resolve file of tree: ", clone) ;
 
     resolve_free(wres) ;
 
+    /** tree Master resolve file */
+    tree_master_modify_contents(info->base.s, clone) ;
+
     log_info("Cloned successfully: ", info->treename.s, " to: ", clone) ;
 }
 
-int ssexec_tree(int argc, char const *const *argv, char const *const *envp, ssexec_t *info)
+int ssexec_tree(int argc, char const *const *argv, ssexec_t *info)
 {
     int r ;
 
@@ -1628,12 +1408,12 @@ int ssexec_tree(int argc, char const *const *argv, char const *const *envp, ssex
     }
 
     if(!r && what.create)
-        tree_create(&graph, info, &what, envp) ;
+        tree_create(&graph, info, &what) ;
 
     if (!r && what.remove)
         log_dieusys(LOG_EXIT_SYS,"find tree: ", info->treename.s) ;
 
-    if (!graph_build_g(&graph, info->base.s, info->treename.s, DATA_TREE, 0))
+    if (!graph_build_g(&graph, info->base.s, 0, DATA_TREE, 0))
         log_dieu(LOG_EXIT_SYS,"build the graph") ;
 
     if (what.remove) {
@@ -1641,7 +1421,7 @@ int ssexec_tree(int argc, char const *const *argv, char const *const *envp, ssex
         goto freed ;
     }
 
-    /** groups influence on enable. Apply it first */
+    /** groups influence on enable. Apply it first. */
     if (what.groups)
         tree_groups(info->base.s, info->treename.s, what.gr) ;
 
-- 
GitLab