From 9f097519e8ff5fac7f6e307ead753984ebd2646a Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Fri, 17 Feb 2023 21:15:47 +1100
Subject: [PATCH] remove the tree path. This commit sign the end of the "[WIP]
 allow to switch between trees" works. The tree directory was used with s6-rc.
 Tree are now completely handled by resolve file. That's means that services
 are not independent of a tree. Again earn of flexibility.

---
 src/66/66.c                                   |  18 ++-
 src/include/66/resolve.h                      |  10 --
 src/lib66/exec/ssexec_copy.c                  |   2 -
 src/lib66/exec/ssexec_free.c                  |   1 -
 src/lib66/exec/ssexec_init.c                  |  11 +-
 src/lib66/exec/ssexec_service_resolve.c       | 136 +++++++++---------
 src/lib66/exec/ssexec_service_signal.c        |   8 +-
 src/lib66/parse/parse_compute_resolve.c       |  37 ++---
 src/lib66/parse/parse_module.c                |   1 -
 src/lib66/sanitize/sanitize_livestate.c       |   6 +-
 src/lib66/sanitize/sanitize_scandir.c         |   7 +-
 src/lib66/sanitize/sanitize_system.c          |   7 +-
 src/lib66/service/service_resolve_copy.c      |   1 -
 .../service/service_resolve_get_field_tosa.c  |   4 -
 .../service/service_resolve_modify_field.c    |   5 -
 src/lib66/service/service_resolve_read_cdb.c  |   2 -
 src/lib66/service/service_resolve_write.c     |   4 +-
 src/lib66/service/service_resolve_write_cdb.c |   1 -
 src/lib66/tree/tree_switch_current.c          |  36 +----
 19 files changed, 113 insertions(+), 184 deletions(-)

diff --git a/src/66/66.c b/src/66/66.c
index be6a6526..224a09d2 100644
--- a/src/66/66.c
+++ b/src/66/66.c
@@ -31,17 +31,13 @@ void set_treeinfo(ssexec_t *info)
     log_flow() ;
 
     int r = tree_sethome(info) ;
-    if (r == -3)
-        log_dieu(LOG_EXIT_USER, "find the current tree. You must use the -t options") ;
-    if (r == -2)
-        log_dieu(LOG_EXIT_USER, "set the tree name") ;
     if (r == -1)
-        log_dieu(LOG_EXIT_USER, "parse seed file") ;
+        log_dieu(LOG_EXIT_USER, "set the tree name") ;
     if (!r)
-        log_dieusys(LOG_EXIT_SYS, "find tree: ", info->treename.s) ;
+        log_dieu(LOG_EXIT_USER, "parse seed file") ;
 
-    if (!tree_get_permissions(info->tree.s, info->owner))
-        log_die(LOG_EXIT_USER,"You're not allowed to use the tree: ",info->tree.s) ;
+    if (!tree_get_permissions(info->base.s, info->treename.s))
+        log_die(LOG_EXIT_USER,"You're not allowed to use the tree: ",info->treename.s) ;
 
     info->treeallow = 1 ;
 }
@@ -75,7 +71,6 @@ static void info_clean(ssexec_t *info)
 
     info->base.len = 0 ;
     info->live.len = 0 ;
-    info->tree.len = 0 ;
     info->scandir.len = 0 ;
     info->treename.len = 0 ;
 
@@ -170,8 +165,11 @@ int main(int argc, char const *const *argv)
                     log_color = !isatty(1) ? &log_color_disable : &log_color_enable ;
                     info.opt_color = 1 ;
                     break ;
+
                 case '?' :
+
                     log_usage(usage_66, "\n", help_66) ;
+
                 default :
 
                     for (i = 0 ; i < n ; i++) {
@@ -194,7 +192,7 @@ int main(int argc, char const *const *argv)
                     if (!f) {
 
                         if (l.arg) {
-                            // distinction between e.g -enano and -e nano
+                            // distinction between e.g -e<value> and -e <value>
                             if (argv[l.ind - 1][0] != '-')
                                 nargv[n++] = argv[l.ind - 2] ;
 
diff --git a/src/include/66/resolve.h b/src/include/66/resolve.h
index 7503d2b7..ea38f647 100644
--- a/src/include/66/resolve.h
+++ b/src/include/66/resolve.h
@@ -22,18 +22,9 @@
 #include <skalibs/cdb.h>
 #include <skalibs/cdbmake.h>
 
-
-#define SS_RESOLVE_LIVE 0
-#define SS_RESOLVE_SRC 1
-#define SS_RESOLVE_STATE 2
-#define SS_NOTYPE -1
-#define SS_SIMPLE 0
-#define SS_DOUBLE 1
-
 #define DATA_TREE 1
 #define DATA_TREE_MASTER 2
 #define DATA_SERVICE 0
-#define DATA_SERVICE_MASTER 3
 
 typedef struct resolve_wrapper_s resolve_wrapper_t, *resolve_wrapper_t_ref ;
 struct resolve_wrapper_s
@@ -46,7 +37,6 @@ struct resolve_wrapper_s
 #define RESOLVE_SET_SAWRES(wres) \
     stralloc_ref sawres = 0 ; \
     if (wres->type == DATA_SERVICE) sawres = (&((resolve_service_t *)wres->obj)->sa) ; \
-    else if (wres->type == DATA_SERVICE_MASTER) sawres = (&((resolve_service_master_t *)wres->obj)->sa) ; \
     else if (wres->type == DATA_TREE) sawres = (&((resolve_tree_t *)wres->obj)->sa) ; \
     else if (wres->type == DATA_TREE_MASTER) sawres = (&((resolve_tree_master_t *)wres->obj)->sa) ;
 #endif
diff --git a/src/lib66/exec/ssexec_copy.c b/src/lib66/exec/ssexec_copy.c
index 26a21e0f..3c511473 100644
--- a/src/lib66/exec/ssexec_copy.c
+++ b/src/lib66/exec/ssexec_copy.c
@@ -25,7 +25,6 @@ void ssexec_copy(ssexec_t *dest, ssexec_t *src)
 
     auto_stra(&dest->base, src->base.s) ;
     auto_stra(&dest->live, src->live.s) ;
-    auto_stra(&dest->tree, src->tree.s) ;
     auto_stra(&dest->scandir, src->scandir.s) ;
     auto_stra(&dest->treename, src->treename.s) ;
 
@@ -39,7 +38,6 @@ void ssexec_copy(ssexec_t *dest, ssexec_t *src)
     dest->usage = src->usage ;
     dest->opt_verbo = src->opt_verbo ;
     dest->opt_live = src->opt_live ;
-    dest->opt_tree = src->opt_tree ;
     dest->opt_timeout = src->opt_timeout ;
     dest->opt_color = src->opt_color ;
     dest->skip_opt_tree = src->skip_opt_tree ;
diff --git a/src/lib66/exec/ssexec_free.c b/src/lib66/exec/ssexec_free.c
index 9091563c..201e4950 100644
--- a/src/lib66/exec/ssexec_free.c
+++ b/src/lib66/exec/ssexec_free.c
@@ -28,7 +28,6 @@ void ssexec_free(ssexec_t *info)
 
     stralloc_free(&info->base) ;
     stralloc_free(&info->live) ;
-    stralloc_free(&info->tree) ;
     stralloc_free(&info->scandir) ;
     stralloc_free(&info->treename) ;
 }
diff --git a/src/lib66/exec/ssexec_init.c b/src/lib66/exec/ssexec_init.c
index 68bf2156..28159faa 100644
--- a/src/lib66/exec/ssexec_init.c
+++ b/src/lib66/exec/ssexec_init.c
@@ -145,21 +145,16 @@ int ssexec_init(int argc, char const *const *argv, ssexec_t *info)
 
     stralloc sa = STRALLOC_ZERO ;
 
-    if (argc < 2 || !argv[1])
+    if (!argc)
         log_usage(info->usage, "\n", info->help) ;
 
     treename = argv[1] ;
-    size_t treenamelen = strlen(treename) ;
-    size_t treelen = info->base.len + SS_SYSTEM_LEN + 1 + treenamelen + 1 ;
-    char tree[treelen + 1] ;
-
-    auto_strings(tree, info->base.s, SS_SYSTEM, "/", treename) ;
 
     if (!tree_isvalid(info->base.s, treename))
         log_diesys(LOG_EXIT_USER, "invalid tree name: ", treename) ;
 
-    if (!tree_get_permissions(tree, info->owner))
-        log_die(LOG_EXIT_USER, "You're not allowed to use the tree: ", tree) ;
+    if (!tree_get_permissions(info->base.s, treename))
+        log_die(LOG_EXIT_USER, "You're not allowed to use the tree: ", treename) ;
 
     r = scan_mode(info->scandir.s, S_IFDIR) ;
     if (r < 0) log_die(LOG_EXIT_SYS,info->scandir.s, " conflicted format") ;
diff --git a/src/lib66/exec/ssexec_service_resolve.c b/src/lib66/exec/ssexec_service_resolve.c
index 9e887175..25df686a 100644
--- a/src/lib66/exec/ssexec_service_resolve.c
+++ b/src/lib66/exec/ssexec_service_resolve.c
@@ -34,7 +34,7 @@
 #include <66/config.h>
 #include <66/state.h>
 
-#define MAXOPTS 70
+#define MAXOPTS 69
 
 static wchar_t const field_suffix[] = L" :" ;
 static char fields[INFO_NKEY][INFO_FIELD_MAXLEN] = {{ 0 }} ;
@@ -93,66 +93,65 @@ static void info_display_service_field(resolve_service_t *res)
 
     info_display_string(fields[14], res->sa.s, res->path.home, 1) ;
     info_display_string(fields[15], res->sa.s, res->path.frontend, 1) ;
-    info_display_string(fields[16], res->sa.s, res->path.tree, 1) ;
-    info_display_string(fields[17], res->sa.s, res->path.status, 1) ;
-
-    info_display_string(fields[18], res->sa.s, res->dependencies.depends, 1) ;
-    info_display_string(fields[19], res->sa.s, res->dependencies.requiredby, 1) ;
-    info_display_string(fields[20], res->sa.s, res->dependencies.optsdeps, 1) ;
-    info_display_int(fields[21], res->dependencies.ndepends) ;
-    info_display_int(fields[22], res->dependencies.nrequiredby) ;
-    info_display_int(fields[23], res->dependencies.noptsdeps) ;
-
-    info_display_string(fields[24], res->sa.s, res->execute.run.run, 1) ;
-    info_display_string(fields[25], res->sa.s, res->execute.run.run_user, 1) ;
-    info_display_string(fields[26], res->sa.s, res->execute.run.build, 1) ;
-    info_display_string(fields[27], res->sa.s, res->execute.run.shebang, 1) ;
-    info_display_string(fields[28], res->sa.s, res->execute.run.runas, 1) ;
-    info_display_string(fields[29], res->sa.s, res->execute.finish.run, 1) ;
-    info_display_string(fields[30], res->sa.s, res->execute.finish.run_user, 1) ;
-    info_display_string(fields[31], res->sa.s, res->execute.finish.build, 1) ;
-    info_display_string(fields[32], res->sa.s, res->execute.finish.shebang, 1) ;
-    info_display_string(fields[33], res->sa.s, res->execute.finish.runas, 1) ;
-    info_display_int(fields[34], res->execute.timeout.kill) ;
-    info_display_int(fields[35], res->execute.timeout.finish) ;
-    info_display_int(fields[36], res->execute.timeout.up) ;
-    info_display_int(fields[37], res->execute.timeout.down) ;
-    info_display_int(fields[38], res->execute.down) ;
-    info_display_int(fields[39], res->execute.downsignal) ;
-
-    info_display_string(fields[40], res->sa.s, res->live.livedir, 1) ;
-    info_display_string(fields[41], res->sa.s, res->live.scandir, 1) ;
-    info_display_string(fields[42], res->sa.s, res->live.statedir, 1) ;
-    info_display_string(fields[43], res->sa.s, res->live.eventdir, 1) ;
-    info_display_string(fields[44], res->sa.s, res->live.notifdir, 1) ;
-    info_display_string(fields[45], res->sa.s, res->live.supervisedir, 1) ;
-    info_display_string(fields[46], res->sa.s, res->live.fdholderdir, 1) ;
-    info_display_string(fields[47], res->sa.s, res->live.oneshotddir, 1) ;
-
-    info_display_string(fields[48], res->sa.s, res->logger.name, 1) ;
-    info_display_string(fields[49], res->sa.s, res->logger.destination, 1) ;
-    info_display_int(fields[50], res->logger.backup) ;
-    info_display_int(fields[51], res->logger.maxsize) ;
-    info_display_int(fields[52], res->logger.timestamp) ;
-    info_display_string(fields[53], res->sa.s, res->logger.execute.run.run, 1) ;
-    info_display_string(fields[54], res->sa.s, res->logger.execute.run.run_user, 1) ;
-    info_display_string(fields[55], res->sa.s, res->logger.execute.run.build, 1) ;
-    info_display_string(fields[56], res->sa.s, res->logger.execute.run.shebang, 1) ;
-    info_display_string(fields[57], res->sa.s, res->logger.execute.run.runas, 1) ;
-    info_display_int(fields[58], res->logger.execute.timeout.kill) ;
-    info_display_int(fields[59], res->logger.execute.timeout.finish) ;
-
-    info_display_string(fields[60], res->sa.s, res->environ.env, 1) ;
-    info_display_string(fields[61], res->sa.s, res->environ.envdir, 1) ;
-    info_display_int(fields[62], res->environ.env_overwrite) ;
-
-    info_display_string(fields[63], res->sa.s, res->regex.configure, 1) ;
-    info_display_string(fields[64], res->sa.s, res->regex.directories, 1) ;
-    info_display_string(fields[65], res->sa.s, res->regex.files, 1) ;
-    info_display_string(fields[66], res->sa.s, res->regex.infiles, 1) ;
-    info_display_int(fields[67], res->regex.ndirectories) ;
-    info_display_int(fields[68], res->regex.nfiles) ;
-    info_display_int(fields[69], res->regex.ninfiles) ;
+    info_display_string(fields[16], res->sa.s, res->path.status, 1) ;
+
+    info_display_string(fields[17], res->sa.s, res->dependencies.depends, 1) ;
+    info_display_string(fields[18], res->sa.s, res->dependencies.requiredby, 1) ;
+    info_display_string(fields[19], res->sa.s, res->dependencies.optsdeps, 1) ;
+    info_display_int(fields[20], res->dependencies.ndepends) ;
+    info_display_int(fields[21], res->dependencies.nrequiredby) ;
+    info_display_int(fields[22], res->dependencies.noptsdeps) ;
+
+    info_display_string(fields[23], res->sa.s, res->execute.run.run, 1) ;
+    info_display_string(fields[24], res->sa.s, res->execute.run.run_user, 1) ;
+    info_display_string(fields[25], res->sa.s, res->execute.run.build, 1) ;
+    info_display_string(fields[26], res->sa.s, res->execute.run.shebang, 1) ;
+    info_display_string(fields[27], res->sa.s, res->execute.run.runas, 1) ;
+    info_display_string(fields[28], res->sa.s, res->execute.finish.run, 1) ;
+    info_display_string(fields[29], res->sa.s, res->execute.finish.run_user, 1) ;
+    info_display_string(fields[30], res->sa.s, res->execute.finish.build, 1) ;
+    info_display_string(fields[31], res->sa.s, res->execute.finish.shebang, 1) ;
+    info_display_string(fields[32], res->sa.s, res->execute.finish.runas, 1) ;
+    info_display_int(fields[33], res->execute.timeout.kill) ;
+    info_display_int(fields[34], res->execute.timeout.finish) ;
+    info_display_int(fields[35], res->execute.timeout.up) ;
+    info_display_int(fields[36], res->execute.timeout.down) ;
+    info_display_int(fields[37], res->execute.down) ;
+    info_display_int(fields[38], res->execute.downsignal) ;
+
+    info_display_string(fields[39], res->sa.s, res->live.livedir, 1) ;
+    info_display_string(fields[40], res->sa.s, res->live.scandir, 1) ;
+    info_display_string(fields[41], res->sa.s, res->live.statedir, 1) ;
+    info_display_string(fields[42], res->sa.s, res->live.eventdir, 1) ;
+    info_display_string(fields[43], res->sa.s, res->live.notifdir, 1) ;
+    info_display_string(fields[44], res->sa.s, res->live.supervisedir, 1) ;
+    info_display_string(fields[45], res->sa.s, res->live.fdholderdir, 1) ;
+    info_display_string(fields[46], res->sa.s, res->live.oneshotddir, 1) ;
+
+    info_display_string(fields[47], res->sa.s, res->logger.name, 1) ;
+    info_display_string(fields[48], res->sa.s, res->logger.destination, 1) ;
+    info_display_int(fields[49], res->logger.backup) ;
+    info_display_int(fields[50], res->logger.maxsize) ;
+    info_display_int(fields[51], res->logger.timestamp) ;
+    info_display_string(fields[52], res->sa.s, res->logger.execute.run.run, 1) ;
+    info_display_string(fields[53], res->sa.s, res->logger.execute.run.run_user, 1) ;
+    info_display_string(fields[54], res->sa.s, res->logger.execute.run.build, 1) ;
+    info_display_string(fields[55], res->sa.s, res->logger.execute.run.shebang, 1) ;
+    info_display_string(fields[56], res->sa.s, res->logger.execute.run.runas, 1) ;
+    info_display_int(fields[57], res->logger.execute.timeout.kill) ;
+    info_display_int(fields[58], res->logger.execute.timeout.finish) ;
+
+    info_display_string(fields[59], res->sa.s, res->environ.env, 1) ;
+    info_display_string(fields[60], res->sa.s, res->environ.envdir, 1) ;
+    info_display_int(fields[61], res->environ.env_overwrite) ;
+
+    info_display_string(fields[62], res->sa.s, res->regex.configure, 1) ;
+    info_display_string(fields[63], res->sa.s, res->regex.directories, 1) ;
+    info_display_string(fields[64], res->sa.s, res->regex.files, 1) ;
+    info_display_string(fields[65], res->sa.s, res->regex.infiles, 1) ;
+    info_display_int(fields[66], res->regex.ndirectories) ;
+    info_display_int(fields[67], res->regex.nfiles) ;
+    info_display_int(fields[68], res->regex.ninfiles) ;
 
 }
 
@@ -192,15 +191,14 @@ int ssexec_service_resolve(int argc, char const *const *argv, ssexec_t *info)
 
         "home",
         "frontend",
-        "tree",
-        "status", //18
+        "status", //17
 
         "depends",
         "requiredby",
         "optsdeps",
         "ndepends",
         "nrequiredby",
-        "noptsdeps", // 24
+        "noptsdeps", // 23
 
         "run",
         "run_user",
@@ -217,7 +215,7 @@ int ssexec_service_resolve(int argc, char const *const *argv, ssexec_t *info)
         "timeoutup",
         "timeoutdown",
         "down",
-        "downsignal", // 40
+        "downsignal", // 39
 
         "livedir",
         "scandir",
@@ -226,7 +224,7 @@ int ssexec_service_resolve(int argc, char const *const *argv, ssexec_t *info)
         "notifdir",
         "supervisedir",
         "fdholderdir",
-        "oneshotddir", //48
+        "oneshotddir", //47
 
         "logname" ,
         "logdestination" ,
@@ -239,11 +237,11 @@ int ssexec_service_resolve(int argc, char const *const *argv, ssexec_t *info)
         "logrun_shebang" ,
         "logrun_runas" ,
         "logtimeoutkill",
-        "logtimeoutfinish", // 60
+        "logtimeoutfinish", // 59
 
         "env",
         "envdir",
-        "env_overwrite", // 63
+        "env_overwrite", // 62
 
         "configure",
         "directories",
@@ -251,7 +249,7 @@ int ssexec_service_resolve(int argc, char const *const *argv, ssexec_t *info)
         "infiles",
         "ndirectories",
         "nfiles",
-        "ninfiles" // 70
+        "ninfiles" // 69
 
     } ;
 
diff --git a/src/lib66/exec/ssexec_service_signal.c b/src/lib66/exec/ssexec_service_signal.c
index ce8344ce..6249a522 100644
--- a/src/lib66/exec/ssexec_service_signal.c
+++ b/src/lib66/exec/ssexec_service_signal.c
@@ -498,11 +498,11 @@ static int doit(pidservice_t *sv, unsigned int what, tain *deadline)
     char *sa = pares[sv->aresid].sa.s ;
     char *name = sa + pares[sv->aresid].name ;
     size_t namelen = strlen(name) ;
-    char *tree = pares[sv->aresid].sa.s + pares[sv->aresid].path.tree ;
-    size_t treelen = strlen(tree) ;
+    char *home = pares[sv->aresid].sa.s + pares[sv->aresid].path.home ;
+    size_t homelen = strlen(home) ;
 
-    char script[treelen + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + namelen + 7 + 1] ;
-    auto_strings(script, tree, SS_SVDIRS, SS_SVC, "/", name) ;
+    char script[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 7 + 1] ;
+    auto_strings(script, home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name) ;
 
     char *oneshotdir = pares[sv->aresid].sa.s + pares[sv->aresid].live.oneshotddir ;
     char *scandir = pares[sv->aresid].sa.s + pares[sv->aresid].live.scandir ;
diff --git a/src/lib66/parse/parse_compute_resolve.c b/src/lib66/parse/parse_compute_resolve.c
index 0138002e..b32b31f1 100644
--- a/src/lib66/parse/parse_compute_resolve.c
+++ b/src/lib66/parse/parse_compute_resolve.c
@@ -340,11 +340,10 @@ static void compute_log(resolve_service_t *res, ssexec_t *info)
 
     lres.path.home = resolve_add_string(wres, str + res->path.home) ;
     lres.path.frontend = resolve_add_string(wres, str + res->path.frontend) ;
-    lres.path.tree = resolve_add_string(wres, str + res->path.tree) ;
 
     {
-        char status[strlen(res->sa.s + res->path.tree) + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + strlen(name) + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
-        auto_strings(status, res->sa.s + res->path.tree, SS_SVDIRS, SS_SVC, "/", name, SS_STATE, "/" SS_STATUS) ;
+        char status[strlen(res->sa.s + res->path.home) + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + strlen(name) + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
+        auto_strings(status, res->sa.s + res->path.home, SS_SYSTEM, SS_SYSTEM, SS_SVC, "/", name, SS_STATE, "/" SS_STATUS) ;
         lres.path.status = resolve_add_string(wres, status) ;
 
     }
@@ -390,32 +389,22 @@ void parse_compute_resolve(resolve_service_t *res, ssexec_t *info)
 
     resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
     char name[strlen(res->sa.s + res->name) + 1] ;
-    char tree[info->base.len + SS_SYSTEM_LEN + 1 + SS_MAX_TREENAME + 1] ;
-    char status[info->base.len + SS_SYSTEM_LEN + 1 + SS_MAX_TREENAME + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + strlen(name) + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
+    char status[info->base.len + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + strlen(name) + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
 
     auto_strings(name, res->sa.s + res->name) ;
+    auto_strings(status, info->base.s, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name, SS_STATE, "/" SS_STATUS) ;
 
-    res->path.home = resolve_add_string(wres, info->base.s) ;
-
-    if (res->intree) {
-
-        auto_strings(tree, info->base.s, SS_SYSTEM, "/", res->sa.s + res->intree) ;
-        res->treename = resolve_add_string(wres,res->sa.s + res->intree) ;
-        res->path.tree = resolve_add_string(wres, tree) ;
-
-        auto_strings(status, res->sa.s + res->path.tree, SS_SVDIRS, SS_SVC, "/", name, SS_STATE, "/" SS_STATUS) ;
-        res->path.status = resolve_add_string(wres, status) ;
-
+    res->path.status = resolve_add_string(wres, status) ;
 
-    } else {
-
-        auto_strings(tree, info->base.s, SS_SYSTEM, "/", info->treename.s) ;
-        res->treename = resolve_add_string(wres,info->treename.s) ;
-        res->path.tree = resolve_add_string(wres, tree) ;
+    res->path.home = resolve_add_string(wres, info->base.s) ;
 
-        auto_strings(status, res->sa.s + res->path.tree, SS_SVDIRS, SS_SVC, "/", name, SS_STATE, "/" SS_STATUS) ;
-        res->path.status = resolve_add_string(wres, status) ;
-    }
+    /** Command line precede frontend file which precede the default tree name*/
+    if (info->opt_tree)
+        res->treename = resolve_add_string(wres, info->treename.s) ;
+    else if (res->intree)
+        res->treename = resolve_add_string(wres, res->sa.s + res->intree) ;
+    else
+        res->treename = resolve_add_string(wres, info->treename.s) ;
 
     /* live */
     res->live.livedir = resolve_add_string(wres, info->live.s) ;
diff --git a/src/lib66/parse/parse_module.c b/src/lib66/parse/parse_module.c
index 3a841b98..9b871e68 100644
--- a/src/lib66/parse/parse_module.c
+++ b/src/lib66/parse/parse_module.c
@@ -373,7 +373,6 @@ static void regex_configure(resolve_service_t *res, ssexec_t *info, char const *
             "MOD_NAME=", name, "\n", \
             "MOD_BASE=", res->sa.s + res->path.home, "\n", \
             "MOD_LIVE=", res->sa.s + res->live.livedir, "\n", \
-            "MOD_TREE=", res->sa.s + res->path.tree, "\n", \
             "MOD_SCANDIR=", res->sa.s + res->live.scandir, "\n", \
             "MOD_TREENAME=", res->sa.s + res->treename, "\n", \
             "MOD_OWNER=", res->sa.s + res->ownerstr, "\n", \
diff --git a/src/lib66/sanitize/sanitize_livestate.c b/src/lib66/sanitize/sanitize_livestate.c
index 7f5964a7..10557366 100644
--- a/src/lib66/sanitize/sanitize_livestate.c
+++ b/src/lib66/sanitize/sanitize_livestate.c
@@ -71,14 +71,14 @@ static void sanitize_livestate_service_symlink(resolve_service_t *res)
     size_t namelen = strlen(name) ;
     size_t livelen = strlen(res->sa.s + res->live.livedir) ;
     size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
-    size_t treelen = strlen(res->sa.s + res->path.tree) ;
+    size_t homelen = strlen(res->sa.s + res->path.home) ;
 
     char sym[livelen + SS_STATE_LEN + 1 + ownerlen + 1 + namelen + 1] ;
-    char dst[treelen + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
+    char dst[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1] ;
 
     auto_strings(sym, res->sa.s + res->live.livedir, SS_STATE + 1, "/", res->sa.s + res->ownerstr, "/", name) ;
 
-    auto_strings(dst, res->sa.s + res->path.tree, SS_SVDIRS, SS_SVC, "/", name) ;
+    auto_strings(dst, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE, SS_SVC, "/", name) ;
 
     if (!atomic_symlink(dst, sym, "livestate"))
        log_dieu(LOG_EXIT_SYS, "symlink: ", sym, " to: ", dst) ;
diff --git a/src/lib66/sanitize/sanitize_scandir.c b/src/lib66/sanitize/sanitize_scandir.c
index 5e02fead..4a3be020 100644
--- a/src/lib66/sanitize/sanitize_scandir.c
+++ b/src/lib66/sanitize/sanitize_scandir.c
@@ -54,14 +54,15 @@ static void scandir_service_to_scandir(resolve_service_t *res)
 {
     char *name = res->sa.s + res->name ;
     size_t namelen = strlen(name) ;
-    size_t treelen = strlen(res->sa.s + res->path.tree) ;
+    size_t homelen = strlen(res->sa.s + res->path.home) ;
     size_t livelen = strlen(res->sa.s + res->live.livedir) ;
     size_t ownerlen = strlen(res->sa.s + res->ownerstr) ;
 
-    char sym[treelen + SS_SVDIRS_LEN + SS_SVC_LEN + 1 + namelen + 1 + SS_SCANDIR_LEN + 1] ;
+    char sym[homelen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_SVC_LEN + 1 + namelen + 1 + SS_SCANDIR_LEN + 1] ;
     char dst[livelen + SS_SCANDIR_LEN + 1 + ownerlen + 1] ;
 
-    auto_strings(sym, res->sa.s + res->path.tree, SS_SVDIRS, SS_SVC, "/", name, "/", SS_SCANDIR) ;
+    auto_strings(sym, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE
+    , SS_SVC, "/", name, "/", SS_SCANDIR) ;
 
     auto_strings(dst, res->sa.s + res->live.livedir, SS_SCANDIR, "/", res->sa.s + res->ownerstr) ;
 
diff --git a/src/lib66/sanitize/sanitize_system.c b/src/lib66/sanitize/sanitize_system.c
index 06a37c82..88a543a7 100644
--- a/src/lib66/sanitize/sanitize_system.c
+++ b/src/lib66/sanitize/sanitize_system.c
@@ -70,7 +70,7 @@ int sanitize_system(ssexec_t *info)
     size_t baselen = info->base.len ;
     uid_t log_uid ;
     gid_t log_gid ;
-    char dst[baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + SS_SERVICE_LEN + 1] ;
+    char dst[baselen + SS_SYSTEM_LEN + SS_SERVICE_LEN + SS_RESOLVE_LEN + SS_SERVICE_LEN + 1] ;
     auto_strings(dst,info->base.s, SS_SYSTEM) ;
 
     /** base is /var/lib/66 or $HOME/.66*/
@@ -146,7 +146,10 @@ int sanitize_system(ssexec_t *info)
         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_strings(dst + baselen + SS_SYSTEM_LEN, SS_SERVICE, SS_RESOLVE) ;
+    auto_check(dst) ;
+
+    auto_strings(dst + baselen + SS_SYSTEM_LEN + SS_SERVICE_LEN, SS_SVC) ;
     auto_check(dst) ;
 
     /** create the default tree if it doesn't exist yet */
diff --git a/src/lib66/service/service_resolve_copy.c b/src/lib66/service/service_resolve_copy.c
index 737767a4..41466bf1 100644
--- a/src/lib66/service/service_resolve_copy.c
+++ b/src/lib66/service/service_resolve_copy.c
@@ -53,7 +53,6 @@ int service_resolve_copy(resolve_service_t *dst, resolve_service_t *res)
     // path
     dst->path.home = res->path.home ;
     dst->path.frontend = res->path.frontend ;
-    dst->path.tree = res->path.tree ;
     dst->path.status = res->path.status ;
 
     // dependencies
diff --git a/src/lib66/service/service_resolve_get_field_tosa.c b/src/lib66/service/service_resolve_get_field_tosa.c
index f6a6e0e8..f06686e1 100644
--- a/src/lib66/service/service_resolve_get_field_tosa.c
+++ b/src/lib66/service/service_resolve_get_field_tosa.c
@@ -106,10 +106,6 @@ int service_resolve_get_field_tosa(stralloc *sa, resolve_service_t *res, resolve
             str = res->sa.s + res->path.frontend ;
             break ;
 
-        case E_RESOLVE_SERVICE_TREE:
-            str = res->sa.s + res->path.tree ;
-            break ;
-
         case E_RESOLVE_SERVICE_STATUS:
             str = res->sa.s + res->path.status ;
 
diff --git a/src/lib66/service/service_resolve_modify_field.c b/src/lib66/service/service_resolve_modify_field.c
index 3ce7e42b..b930a458 100644
--- a/src/lib66/service/service_resolve_modify_field.c
+++ b/src/lib66/service/service_resolve_modify_field.c
@@ -40,7 +40,6 @@ resolve_field_table_t resolve_service_field_table[] = {
     // path
     [E_RESOLVE_SERVICE_HOME] = { .field = "home" },
     [E_RESOLVE_SERVICE_FRONTEND] = { .field = "frontend" },
-    [E_RESOLVE_SERVICE_TREE] = { .field = "tree" },
     [E_RESOLVE_SERVICE_STATUS] = { .field = "status" },
 
     // dependencies
@@ -198,10 +197,6 @@ int service_resolve_modify_field(resolve_service_t *res, resolve_service_enum_t
             res->path.frontend = resolve_add_string(wres, data) ;
             break ;
 
-        case E_RESOLVE_SERVICE_TREE:
-            res->path.tree = resolve_add_string(wres, data) ;
-            break ;
-
         case E_RESOLVE_SERVICE_STATUS:
             res->path.status = resolve_add_string(wres, data) ;
             break ;
diff --git a/src/lib66/service/service_resolve_read_cdb.c b/src/lib66/service/service_resolve_read_cdb.c
index 4d6fa15b..3c87f9ff 100644
--- a/src/lib66/service/service_resolve_read_cdb.c
+++ b/src/lib66/service/service_resolve_read_cdb.c
@@ -68,8 +68,6 @@ int service_resolve_read_cdb(cdb *c, resolve_service_t *res)
     res->path.home = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ;
     resolve_find_cdb(&tmp,c,"frontend") ;
     res->path.frontend = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ;
-    resolve_find_cdb(&tmp,c,"tree") ;
-    res->path.tree = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ;
     resolve_find_cdb(&tmp,c,"status") ;
     res->path.status = tmp.len ? resolve_add_string(wres,tmp.s) : 0 ;
 
diff --git a/src/lib66/service/service_resolve_write.c b/src/lib66/service/service_resolve_write.c
index 76a69142..65355b85 100644
--- a/src/lib66/service/service_resolve_write.c
+++ b/src/lib66/service/service_resolve_write.c
@@ -32,12 +32,12 @@ int service_resolve_write(resolve_service_t *res)
     char *name = res->sa.s + res->name ;
     size_t namelen = strlen(name) ;
     char sym[strlen(res->sa.s + res->path.home) + SS_SYSTEM_LEN + SS_RESOLVE_LEN + SS_SERVICE_LEN + 1 + namelen + 1] ;
-    char dst[strlen(res->sa.s + res->path.tree) + SS_SVDIRS_LEN + 1] ;
+    char dst[strlen(res->sa.s + res->path.home) + SS_SYSTEM_LEN + SS_SERVICE_LEN + 1] ;
     resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, res) ;
 
     auto_strings(sym, res->sa.s + res->path.home, SS_SYSTEM, SS_RESOLVE, SS_SERVICE, "/", name) ;
 
-    auto_strings(dst, res->sa.s + res->path.tree, SS_SVDIRS) ;
+    auto_strings(dst, res->sa.s + res->path.home, SS_SYSTEM, SS_SERVICE) ;
 
     if (!resolve_write(wres, dst, name))
         goto err ;
diff --git a/src/lib66/service/service_resolve_write_cdb.c b/src/lib66/service/service_resolve_write_cdb.c
index b89057cb..46f082e1 100644
--- a/src/lib66/service/service_resolve_write_cdb.c
+++ b/src/lib66/service/service_resolve_write_cdb.c
@@ -45,7 +45,6 @@ int service_resolve_write_cdb(cdbmaker *c, resolve_service_t *sres)
     // path
     !resolve_add_cdb(c, "home", str + sres->path.home) ||
     !resolve_add_cdb(c, "frontend", str + sres->path.frontend) ||
-    !resolve_add_cdb(c, "tree", str + sres->path.tree) ||
     !resolve_add_cdb(c, "status", str + sres->path.status) ||
 
     // dependencies
diff --git a/src/lib66/tree/tree_switch_current.c b/src/lib66/tree/tree_switch_current.c
index cde9a995..371d1fa6 100644
--- a/src/lib66/tree/tree_switch_current.c
+++ b/src/lib66/tree/tree_switch_current.c
@@ -12,53 +12,25 @@
  * except according to the terms contained in the LICENSE file./
  */
 
-#include <string.h>
-
-#include <oblibs/string.h>
 #include <oblibs/log.h>
-#include <oblibs/types.h>
-#include <oblibs/directory.h>
-
-#include <skalibs/unix-transactional.h>
-#include <skalibs/types.h>
 
 #include <66/constants.h>
 #include <66/resolve.h>
 #include <66/tree.h>
-#include <66/utils.h>
 
 int tree_switch_current(char const *base, char const *treename)
 {
     log_flow() ;
 
-    int r = 0, e = 0 ;
-    size_t baselen = strlen(base) ;
-    size_t treelen = strlen(treename) ;
+    int e = 0 ;
 
     resolve_tree_master_t mres = RESOLVE_TREE_MASTER_ZERO ;
     resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE_MASTER, &mres) ;
 
-    char pack[UID_FMT] ;
-    size_t packlen = uint_fmt(pack, MYUID) ;
-    pack[packlen] = 0 ;
-    char dst[baselen + SS_SYSTEM_LEN + SS_TREE_CURRENT_LEN + 1 + packlen + treelen + 2 + 1] ;
-    char sym[baselen + SS_TREE_CURRENT_LEN + 1 + packlen + 1 + SS_TREE_CURRENT_LEN + 1] ;
-
-    auto_strings(dst, base, SS_TREE_CURRENT, "/" , pack) ;
-
-    r = scan_mode(dst,S_IFDIR) ;
-    if (!r){
-        if (!dir_create_parent(dst,0755))
-            goto freed ;
-    } else if(r == -1)
-        goto freed ;
-
-    auto_strings(dst, base, SS_SYSTEM, "/", treename) ;
-
-    auto_strings(sym, base, SS_TREE_CURRENT, "/", pack, "/", SS_TREE_CURRENT) ;
-
-    if (!atomic_symlink(dst, sym,"tree_switch_current"))
+    if (tree_ongroups(base, treename, TREE_GROUPS_BOOT)) {
+        log_1_warn("you can't mark a tree current if it is part of the boot group") ;
         goto freed ;
+    }
 
     if (!resolve_modify_field_g(wres, base, SS_MASTER + 1, E_RESOLVE_TREE_MASTER_CURRENT,  treename)) {
         log_warnu("modify field: ", resolve_tree_master_field_table[E_RESOLVE_TREE_MASTER_CURRENT].field," of inner resolve file with value: ", treename) ;
-- 
GitLab