From 49203b605d712a504be30fe2c51a5c4d3fec8fdf Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Mon, 10 Jan 2022 18:49:24 +1100
Subject: [PATCH] add tree_resolve_create_master, tree_resolve_modify_field,
 tree_resolve_field_tosa, tree_iscurrent, tree_isinitialized, tree_isenabled
 and tree_ongroups function

---
 src/include/66/tree.h         | 106 ++++++++++++++---
 src/lib66/tree.c              | 207 ++++++++++++++++++++++++++++++++++
 src/lib66/tree_find_current.c |  58 ----------
 src/lib66/tree_isvalid.c      |  39 -------
 4 files changed, 300 insertions(+), 110 deletions(-)
 create mode 100644 src/lib66/tree.c
 delete mode 100644 src/lib66/tree_find_current.c
 delete mode 100644 src/lib66/tree_isvalid.c

diff --git a/src/include/66/tree.h b/src/include/66/tree.h
index e2398bab..ca1a5830 100644
--- a/src/include/66/tree.h
+++ b/src/include/66/tree.h
@@ -22,8 +22,17 @@
 #include <skalibs/cdbmake.h>
 
 #include <66/ssexec.h>
+#include <66/resolve.h>
+
+
+#define DATA_TREE 1
+#define TREE_GROUPS_BOOT "boot"
+#define TREE_GROUPS_BOOT_LEN (sizeof TREE_GROUPS_BOOT - 1)
+#define TREE_GROUPS_ADM "admin"
+#define TREE_GROUPS_ADM_LEN (sizeof TREE_GROUPS_ADM - 1)
+#define TREE_GROUPS_USER "user"
+#define TREE_GROUPS_USER_LEN (sizeof TREE_GROUPS_USER - 1)
 
-#define TREE_STRUCT 1
 
 typedef struct resolve_tree_s resolve_tree_t, *resolve_tree_t_ref ;
 struct resolve_tree_s
@@ -35,35 +44,103 @@ struct resolve_tree_s
     uint32_t depends ;
     uint32_t requiredby ;
     uint32_t allow ;
+    uint32_t groups ;
     uint32_t contents ;
+    // for the master
+    uint32_t enabled ; //string of all enabled tree
+    uint32_t current ;//name of the current tree, only available and used on Master resolve file
 
     uint32_t ndepends ;
     uint32_t nrequiredby ;
+    uint32_t nallow ;
+    uint32_t ngroups ; //not really useful for now, we accept only one group
     uint32_t ncontents ;
-    uint32_t current ;//no->0, yes->1
+
     uint32_t init ;//not initialized->0, initialized->1
     uint32_t disen ;//disable->0, enable->1
+    // for the master
+    uint32_t nenabled ; //nbre of enabled tree
+} ;
+#define RESOLVE_TREE_ZERO { 0,STRALLOC_ZERO,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
+
+typedef enum resolve_tree_enum_e resolve_tree_enum_t, *resolve_tree_enum_t_ref;
+enum resolve_tree_enum_e
+{
+    TREE_ENUM_NAME = 0,
+    TREE_ENUM_DEPENDS,
+    TREE_ENUM_REQUIREDBY,
+    TREE_ENUM_ALLOW,
+    TREE_ENUM_GROUPS,
+    TREE_ENUM_CONTENTS,
+    TREE_ENUM_ENABLED,
+    TREE_ENUM_CURRENT,
+    TREE_ENUM_NDEPENDS,
+    TREE_ENUM_NREQUIREDBY,
+    TREE_ENUM_NALLOW,
+    TREE_ENUM_NGROUPS,
+    TREE_ENUM_NCONTENTS,
+    TREE_ENUM_INIT,
+    TREE_ENUM_DISEN,
+    TREE_ENUM_NENABLED,
+    TREE_ENUM_ENDOFKEY
 } ;
-#define RESOLVE_TREE_ZERO { 0,STRALLOC_ZERO,0,0,0,0,0,0,0,0,0,0,0 }
 
-extern stralloc saseed ;
+typedef struct resolve_tree_field_table_s resolve_tree_field_table_t, *resolve_tree_field_table_t_ref ;
+struct resolve_tree_field_table_s
+{
+    char *field ;
+} ;
+
+extern resolve_tree_field_table_t resolve_tree_field_table[] ;
 
 typedef struct tree_seed_s tree_seed_t, tree_seed_t_ref ;
 struct tree_seed_s
 {
+    stralloc sa ;
+
     int name ;
     int depends ;
     int requiredby ;
-    uint8_t enabled ;
     int allow ;
     int deny ;
+    int groups ;
+    int contents ;
+
     uint8_t current ;
-    int group ;
-    int services ;
-    uint8_t nopts ;
+    uint8_t disen ;
 
+    uint8_t nopts ;
 } ;
-#define TREE_SEED_ZERO { -1, -1, -1, 0, -1, -1, 0, -1, -1, 0 }
+#define TREE_SEED_ZERO { STRALLOC_ZERO, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0 }
+
+/** @Return 1 on success
+ * @Return 0 if not valid
+ * @Return -1 on system error */
+extern int tree_isvalid(char const *base, char const *treename) ;
+
+/** Append @tree with the name of the current tree
+ * @Return 1 on success
+ * @Return 0 on fail */
+extern int tree_find_current(stralloc *tree, char const *base, uid_t owner) ;
+
+/** @Return 1 on success
+ * @Return 0 if not valid
+ * @Return -1 on system error */
+extern int tree_iscurrent(char const *base, char const *treename) ;
+
+/** @Return 1 on success
+ * @Return 0 on fail */
+extern int tree_isinitialized(char const *live, char const *treename, uid_t owner) ;
+
+/** @Return 1 on success
+ * @Return 0 if not valid
+ * @Return -1 on system error */
+extern int tree_isenabled(char const *base, char const *treename) ;
+
+/** @Return 1 on success
+ * @Return 0 if not valid
+ * @Return -1 on system error */
+extern int tree_ongroups(char const *base, char const *treename, char const *group) ;
 
 extern int tree_cmd_state(unsigned int verbosity,char const *cmd,char const *tree) ;
 extern int tree_state(int argc, char const *const *argv) ;
@@ -78,7 +155,7 @@ extern int tree_copy_tmp(char const *workdir, ssexec_t *info) ;
  * with the path.
  * @Return 1 on success
  * @Return 0 on fail */
-extern int tree_find_current(stralloc *tree, char const *base,uid_t owner) ;
+extern int tree_find_current(stralloc *tree, char const *base, uid_t owner) ;
 
 extern int tree_get_permissions(char const *tree, uid_t owner) ;
 
@@ -88,7 +165,7 @@ extern char tree_setname(stralloc *sa, char const *tree) ;
 
 extern int tree_switch_current(char const *base, char const *tree) ;
 
-extern int tree_isvalid(ssexec_t *info) ;
+
 
 /**
  *
@@ -99,6 +176,9 @@ extern int tree_isvalid(ssexec_t *info) ;
 extern int tree_read_cdb(cdb *c, resolve_tree_t *tres) ;
 extern int tree_write_cdb(cdbmaker *c, resolve_tree_t *tres) ;
 extern int tree_resolve_copy(resolve_tree_t *dst, resolve_tree_t *tres) ;
+extern int tree_resolve_create_master(char const *base, uid_t owner) ;
+extern int tree_resolve_modify_field(resolve_tree_t *tres, uint8_t field, char const *data) ;
+extern int tree_resolve_field_tosa(stralloc *sa, resolve_tree_t *tres, resolve_tree_enum_t field) ;
 
 /**
  *
@@ -106,8 +186,8 @@ extern int tree_resolve_copy(resolve_tree_t *dst, resolve_tree_t *tres) ;
  *
  * */
 
-extern void tree_seed_free(void) ;
-extern int tree_seed_setseed(tree_seed_t *seed, char const *treename, uint8_t check_service) ;
+extern void tree_seed_free(tree_seed_t *seed) ;
+extern int tree_seed_setseed(tree_seed_t *seed, char const *treename, uint8_t check_contents) ;
 extern int tree_seed_isvalid(char const *seed) ;
 
 #endif
diff --git a/src/lib66/tree.c b/src/lib66/tree.c
new file mode 100644
index 00000000..5b4f4b82
--- /dev/null
+++ b/src/lib66/tree.c
@@ -0,0 +1,207 @@
+/*
+ * tree.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 <66/tree.h>
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/unistd.h>//access
+#include <sys/errno.h>
+
+#include <oblibs/types.h>
+#include <oblibs/string.h>
+#include <oblibs/log.h>
+#include <oblibs/files.h>
+#include <oblibs/sastr.h>
+
+#include <skalibs/types.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+#include <66/constants.h>
+#include <66/resolve.h>
+
+int tree_isvalid(char const *base, char const *treename)
+{
+    log_flow() ;
+
+    int r ;
+    size_t baselen = strlen(base), treelen = strlen(treename) ;
+    char t[baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + 1 + treelen + 1] ;
+    auto_strings(t, base, SS_SYSTEM, SS_RESOLVE, "/", treename) ;
+
+    r = scan_mode(t, S_IFREG) ;
+    if (r < 0)
+        return -1 ;
+    else if (!r)
+        return 0 ;
+
+    return 1 ;
+}
+
+int tree_find_current(stralloc *tree, char const *base, uid_t owner)
+{
+    log_flow() ;
+
+    ssize_t r ;
+    size_t baselen = strlen(base) ;
+    char pack[UID_FMT] ;
+
+    uint32_pack(pack,owner) ;
+    size_t packlen = uint_fmt(pack,owner) ;
+    pack[packlen] = 0 ;
+
+    char t[baselen + SS_TREE_CURRENT_LEN + 1 + packlen + 1 + SS_TREE_CURRENT_LEN + 1] ;
+    auto_strings(t, base, SS_TREE_CURRENT, "/", pack, "/", SS_TREE_CURRENT) ;
+
+    r = scan_mode(t,S_IFDIR) ;
+    if(r <= 0)
+        return 0 ;
+
+    r = sarealpath(tree,t) ;
+    if (r < 0 )
+        return 0 ;
+
+    if (!stralloc_0(tree))
+        return 0 ;
+
+    tree->len--;
+
+    return 1 ;
+}
+
+int tree_iscurrent(char const *base, char const *treename)
+{
+    log_flow() ;
+
+    int e = -1 ;
+    size_t baselen = strlen(base) ;
+    resolve_tree_t tres = RESOLVE_TREE_ZERO ;
+    resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ;
+    char t[baselen + SS_SYSTEM_LEN + 1] ;
+
+    auto_strings(t, base, SS_SYSTEM) ;
+
+    if (!resolve_read(wres, t, SS_MASTER + 1))
+        goto err ;
+
+    if (!strcmp(tres.sa.s + tres.current, treename))
+        e = 1 ;
+    else
+        e = 0 ;
+
+    err:
+        resolve_free(wres) ;
+        return e ;
+}
+
+int tree_isinitialized(char const *live, char const *treename, uid_t owner)
+{
+    log_flow() ;
+
+    int init = 0 ;
+
+    size_t livelen = strlen(live), treelen = strlen(treename) ;
+
+    char pack[UID_FMT] ;
+    uint32_pack(pack,owner) ;
+    size_t packlen = uint_fmt(pack,owner) ;
+    pack[packlen] = 0 ;
+
+    char t[livelen + SS_STATE_LEN + 1 + packlen + 1 + treelen + 6] ;
+    auto_strings(t, live, SS_STATE + 1, "/", pack, "/", treename, "/init") ;
+
+    if (!access(t, F_OK))
+        init = 1 ;
+
+    return init ;
+}
+
+int tree_isenabled(char const *base, char const *treename)
+{
+    log_flow() ;
+
+    int e = -1 ;
+    size_t baselen = strlen(base), pos = 0 ;
+    stralloc sa = STRALLOC_ZERO ;
+    resolve_tree_t tres = RESOLVE_TREE_ZERO ;
+    resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ;
+    char solve[baselen + SS_SYSTEM_LEN + 1] ;
+
+    auto_strings(solve, base, SS_SYSTEM) ;
+
+    if (!resolve_read(wres, solve, SS_MASTER + 1))
+        goto err ;
+
+    if (tres.nenabled) {
+
+        if (!sastr_clean_string(&sa, tres.sa.s + tres.enabled))
+            goto err ;
+
+        e = 0 ;
+
+        FOREACH_SASTR(&sa, pos) {
+
+            if (!strcmp(treename, sa.s + pos)) {
+                e = 1 ;
+                break ;
+            }
+        }
+    }
+    else e = 0 ;
+
+    err:
+        resolve_free(wres) ;
+        stralloc_free(&sa) ;
+        return e ;
+}
+
+int tree_ongroups(char const *base, char const *treename, char const *group)
+{
+    log_flow() ;
+
+    int e = -1 ;
+    size_t baselen = strlen(base), pos = 0 ;
+    stralloc sa = STRALLOC_ZERO ;
+    resolve_tree_t tres = RESOLVE_TREE_ZERO ;
+    resolve_wrapper_t_ref wres = resolve_set_struct(DATA_TREE, &tres) ;
+    char solve[baselen + SS_SYSTEM_LEN + 1] ;
+
+    auto_strings(solve, base, SS_SYSTEM) ;
+
+    if (!resolve_read(wres, solve, treename))
+        goto err ;
+
+    if (tres.ngroups) {
+
+        if (!sastr_clean_string(&sa, tres.sa.s + tres.groups))
+            goto err ;
+
+        e = 0 ;
+
+        FOREACH_SASTR(&sa, pos) {
+
+            if (!strcmp(group, sa.s + pos)) {
+                e = 1 ;
+                break ;
+            }
+        }
+    }
+    else e = 0 ;
+
+    err:
+       resolve_free(wres) ;
+       stralloc_free(&sa) ;
+       return e ;
+}
diff --git a/src/lib66/tree_find_current.c b/src/lib66/tree_find_current.c
deleted file mode 100644
index 35d95936..00000000
--- a/src/lib66/tree_find_current.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * tree_find_current.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 <66/utils.h>
-
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <string.h>
-
-#include <oblibs/log.h>
-#include <oblibs/types.h>
-
-#include <skalibs/types.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
-
-#include <66/constants.h>
-
-int tree_find_current(stralloc *tree, char const *base,uid_t owner)
-{
-    log_flow() ;
-
-    ssize_t r ;
-    size_t baselen = strlen(base) ;
-    char pack[UID_FMT] ;
-
-    uint32_pack(pack,owner) ;
-    size_t packlen = uint_fmt(pack,owner) ;
-    pack[packlen] = 0 ;
-
-    char sa[baselen + SS_TREE_CURRENT_LEN + 1 + packlen + 1 + SS_TREE_CURRENT_LEN + 1] ;
-    memcpy(sa,base,baselen) ;
-    memcpy(sa + baselen, SS_TREE_CURRENT, SS_TREE_CURRENT_LEN) ;
-    sa[baselen + SS_TREE_CURRENT_LEN] = '/' ;
-    memcpy(sa + baselen + SS_TREE_CURRENT_LEN + 1, pack,packlen) ;
-    sa[baselen + SS_TREE_CURRENT_LEN + 1 + packlen] = '/' ;
-    memcpy(sa + baselen + SS_TREE_CURRENT_LEN + 1 + packlen + 1,SS_TREE_CURRENT,SS_TREE_CURRENT_LEN) ;
-    sa[baselen + SS_TREE_CURRENT_LEN + 1 + packlen + 1 + SS_TREE_CURRENT_LEN] = 0 ;
-
-    r = scan_mode(sa,S_IFDIR) ;
-    if(r <= 0) return 0 ;
-    r = sarealpath(tree,sa) ;
-    if (r < 0 ) return 0 ;
-    if (!stralloc_0(tree)) log_warnsys_return(LOG_EXIT_ZERO,"stralloc") ;
-    tree->len--;
-    return 1 ;
-}
diff --git a/src/lib66/tree_isvalid.c b/src/lib66/tree_isvalid.c
deleted file mode 100644
index 0a5ea461..00000000
--- a/src/lib66/tree_isvalid.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * tree_isvalid.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 <66/tree.h>
-
-#include <sys/types.h>
-
-#include <oblibs/types.h>
-#include <oblibs/string.h>
-
-#include <66/constants.h>
-#include <66/ssexec.h>
-
-int tree_isvalid(ssexec_t *info)
-{
-    int r ;
-
-    char treename[info->base.len + SS_SYSTEM_LEN + 1 + info->treename.len + 1] ;
-    auto_strings(treename, info->base.s, SS_SYSTEM, "/", info->treename.s) ;
-
-    r = scan_mode(treename, S_IFDIR) ;
-    if (r < 0)
-        return -1 ;
-    else if (!r)
-        return 0 ;
-
-    return 1 ;
-}
-- 
GitLab