From c725de2d4af67063a838fc92c162daa7ea764b2b Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Sat, 15 Oct 2022 20:54:51 +1100
Subject: [PATCH] revamp of the state file

---
 src/include/66/state.h            | 69 ++++++++++++++++++++-----------
 src/lib66/state/deps-lib/deps     |  5 ++-
 src/lib66/state/state_check.c     | 25 +++++------
 src/lib66/state/state_get_flags.c | 52 +++++++++++++++++++++++
 src/lib66/state/state_messenger.c | 37 +++++++++++++++++
 src/lib66/state/state_pack.c      | 15 ++++---
 src/lib66/state/state_read.c      | 20 +++++----
 src/lib66/state/state_rmfile.c    | 16 +++----
 src/lib66/state/state_set_flag.c  | 39 +++++++++++++++++
 src/lib66/state/state_unpack.c    | 56 ++++++++++++++++++-------
 src/lib66/state/state_write.c     | 29 ++++++++-----
 11 files changed, 277 insertions(+), 86 deletions(-)
 create mode 100644 src/lib66/state/state_get_flags.c
 create mode 100644 src/lib66/state/state_messenger.c
 create mode 100644 src/lib66/state/state_set_flag.c

diff --git a/src/include/66/state.h b/src/include/66/state.h
index 2ca93575..0d01733a 100644
--- a/src/include/66/state.h
+++ b/src/include/66/state.h
@@ -18,37 +18,58 @@
 #include <stddef.h>
 
 #include <skalibs/uint32.h>
-#include <skalibs/uint64.h>
 
-#define SS_FLAGS_FALSE (1 << 1)
-#define SS_FLAGS_TRUE (1 << 2)
-#define SS_FLAGS_UNKNOWN (1 << 3)
-#define SS_FLAGS_RELOAD (1 << 4)
-#define SS_FLAGS_INIT (1 << 5)
-#define SS_FLAGS_UNSUPERVISE (1 << 6)
-#define SS_FLAGS_STATE (1 << 7)
-#define SS_FLAGS_PID (1 << 8)
+#define STATE_STATE_SIZE 40
+
+#define STATE_FLAGS_FALSE (1 << 1) // 2
+#define STATE_FLAGS_TRUE (1 << 2) // 4
+#define STATE_FLAGS_UNKNOWN (1 << 3) // 8
+
+#define STATE_FLAGS_TOINIT (1 << 4) // 16
+#define STATE_FLAGS_TORELOAD (1 << 5) // ...
+#define STATE_FLAGS_TORESTART (1 << 6)
+#define STATE_FLAGS_TOUNSUPERVISE (1 << 7)
+#define STATE_FLAGS_ISDOWNFILE (1 << 8)
+#define STATE_FLAGS_ISEARLIER (1 << 9)
+#define STATE_FLAGS_ISENABLED (1 << 10)
+#define STATE_FLAGS_ISPARSED (1 << 11)
+#define STATE_FLAGS_ISSUPERVISED (1 << 12)
+#define STATE_FLAGS_ISUP (1 << 13)
+
+#define STATE_FLAGS_TOPROPAGATE (1 << 14)
+#define STATE_FLAGS_WANTUP (1 << 15)
+#define STATE_FLAGS_WANTDOWN (1 << 16)
+
 
 typedef struct ss_state_s ss_state_t, *ss_state_t_ref ;
 struct ss_state_s
 {
-    uint32_t reload ;
-    uint32_t init ;
-    uint32_t unsupervise ;
-    uint32_t state ;//0 down,1 up, 2 earlier
-    uint64_t pid ;
+    /** STATE_FLAGS_FALSE -> no,
+     * STATE_FLAGS_TRUE -> yes
+     * for all field */
+    uint32_t toinit ;
+    uint32_t toreload ;
+    uint32_t torestart ;
+    uint32_t tounsupervise ;
+    uint32_t isdownfile ;
+    uint32_t isearlier ;
+    uint32_t isenabled ;
+    uint32_t isparsed ;
+    uint32_t issupervised ;
+    uint32_t isup ;
 } ;
-#define STATE_ZERO { 0,0,0,0,0 }
-#define SS_STATE_SIZE 24
+
+#define STATE_ZERO { 2,2,2,2,2,2,2,2,2,2 }
 extern ss_state_t const ss_state_zero ;
 
-extern void state_rmfile(char const *src,char const *name) ;
-extern void state_pack(char *pack,ss_state_t *sta) ;
-extern void state_unpack(char *pack,ss_state_t *sta) ;
-extern int state_write(ss_state_t *sta,char const *dst,char const *name) ;
-extern int state_read(ss_state_t *sta,char const *src,char const *name) ;
-extern int state_check(char const *src, char const *name) ;
-extern void state_setflag(ss_state_t *sta,int flags,int flags_val) ;
-extern int state_check_flags(char const *src, char const *name,int flags) ;
+extern int state_check(char const *base, char const *name) ;
+extern void state_rmfile(char const *base, char const *name) ;
+extern void state_pack(char *base, ss_state_t *sta) ;
+extern void state_unpack(char *pack, ss_state_t *sta) ;
+extern int state_write(ss_state_t *sta, char const *base, char const *name) ;
+extern int state_read(ss_state_t *sta, char const *base, char const *name) ;
+extern void state_set_flag(ss_state_t *sta, int flags,int flags_val) ;
+extern int state_get_flags(char const *base, char const *name, int flags) ;
+extern int state_messenger(char const *base, char const *name, uint32_t flag, uint32_t value) ;
 
 #endif
diff --git a/src/lib66/state/deps-lib/deps b/src/lib66/state/deps-lib/deps
index d897d6f5..8e957dc4 100644
--- a/src/lib66/state/deps-lib/deps
+++ b/src/lib66/state/deps-lib/deps
@@ -1,9 +1,10 @@
 state_check.o
-state_check_flags.o
+state_get_flags.o
+state_messenger.o
 state_pack.o
 state_read.o
 state_rmfile.o
-state_setflag.o
+state_set_flag.o
 state_unpack.o
 state_write.o
 -loblibs
diff --git a/src/lib66/state/state_check.c b/src/lib66/state/state_check.c
index 8f2cd210..502587f4 100644
--- a/src/lib66/state/state_check.c
+++ b/src/lib66/state/state_check.c
@@ -13,26 +13,27 @@
  */
 
 #include <string.h>
-#include <sys/stat.h>
+#include <unistd.h>
 
 #include <oblibs/log.h>
-#include <oblibs/types.h>
+#include <oblibs/string.h>
 
 #include <66/state.h>
+#include <66/constants.h>
+#include <66/resolve.h>
 
-int state_check(char const *src, char const *name)
+int state_check(char const *base, char const *name)
 {
     log_flow() ;
 
-    int r ;
-    size_t srclen = strlen(src) ;
+    size_t baselen = strlen(base) ;
     size_t namelen = strlen(name) ;
-    char tmp[srclen + 1 + namelen + 1] ;
-    memcpy(tmp,src,srclen) ;
-    tmp[srclen] = '/' ;
-    memcpy(tmp + srclen + 1, name, namelen) ;
-    tmp[srclen + 1 + namelen] = 0 ;
-    r = scan_mode(tmp,S_IFREG) ;
-    if (r <= 0) return 0 ;
+    char target[baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + 1 + SS_SERVICE_LEN + 1 + namelen + SS_SVC_LEN + 1 + namelen + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
+
+    auto_strings(target, base, SS_SYSTEM, SS_RESOLVE, "/", SS_SERVICE, "/", name, SS_SVC, "/", name, SS_STATE, "/", SS_STATUS) ;
+
+    if (access(target, F_OK) < 0)
+        return 0 ;
+
     return 1 ;
 }
diff --git a/src/lib66/state/state_get_flags.c b/src/lib66/state/state_get_flags.c
new file mode 100644
index 00000000..a3768c10
--- /dev/null
+++ b/src/lib66/state/state_get_flags.c
@@ -0,0 +1,52 @@
+/*
+ * state_get_flags.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 <66/state.h>
+
+int state_get_flags(char const *base, char const *name, int flags)
+{
+    log_flow() ;
+
+    /** not parsed.
+     * Return -1 to make a distinction between
+     * file absent and flag == 0. */
+    if (!state_check(base, name))
+        return -1 ;
+
+    ss_state_t sta = STATE_ZERO ;
+
+    if (!state_read(&sta, base, name))
+        // should not happen
+        return -1 ;
+
+    switch (flags)
+    {
+        case STATE_FLAGS_TOINIT: return sta.toinit ;
+        case STATE_FLAGS_TORELOAD: return sta.toreload ;
+        case STATE_FLAGS_TORESTART: return sta.torestart ;
+        case STATE_FLAGS_TOUNSUPERVISE: return sta.tounsupervise ;
+        case STATE_FLAGS_ISDOWNFILE: return sta.isdownfile ;
+        case STATE_FLAGS_ISEARLIER: return sta.isearlier ;
+        case STATE_FLAGS_ISENABLED: return sta.isenabled ;
+        case STATE_FLAGS_ISPARSED: return sta.isparsed ;
+        case STATE_FLAGS_ISSUPERVISED: return sta.issupervised ;
+        case STATE_FLAGS_ISUP: return sta.isup ;
+        default:
+            // should never happen
+            return -1 ;
+    }
+
+}
diff --git a/src/lib66/state/state_messenger.c b/src/lib66/state/state_messenger.c
new file mode 100644
index 00000000..876887e6
--- /dev/null
+++ b/src/lib66/state/state_messenger.c
@@ -0,0 +1,37 @@
+/*
+ * state_messenger.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 <oblibs/log.h>
+#include <66/state.h>
+
+int state_messenger(char const *base, char const *name, uint32_t flag, uint32_t value)
+{
+    log_flow() ;
+
+    ss_state_t sta = STATE_ZERO ;
+
+    if (!state_read(&sta, base, name))
+        log_warnusys_return(LOG_EXIT_ZERO, "read status file of: ", name) ;
+
+    state_set_flag(&sta, flag, value) ;
+
+    if (!state_write(&sta, base, name))
+        log_warnusys_return(LOG_EXIT_ZERO, "write status file of: ", name) ;
+
+
+    return 1 ;
+}
+
diff --git a/src/lib66/state/state_pack.c b/src/lib66/state/state_pack.c
index 6479adfc..1a63ff8d 100644
--- a/src/lib66/state/state_pack.c
+++ b/src/lib66/state/state_pack.c
@@ -22,9 +22,14 @@ void state_pack(char *pack, ss_state_t *sta)
 {
     log_flow() ;
 
-    uint32_pack_big(pack,sta->reload) ;
-    uint32_pack_big(pack+4,sta->init) ;
-    uint32_pack_big(pack+8,sta->unsupervise) ;
-    uint32_pack_big(pack+12,sta->state) ;
-    uint64_pack_big(pack+16,sta->pid) ;
+    uint32_pack_big(pack, sta->toinit) ;
+    uint32_pack_big(pack + 4, sta->toreload) ;
+    uint32_pack_big(pack + 8, sta->torestart) ;
+    uint32_pack_big(pack + 12, sta->tounsupervise) ;
+    uint32_pack_big(pack + 16, sta->isdownfile) ;
+    uint32_pack_big(pack + 20, sta->isearlier) ;
+    uint32_pack_big(pack + 24, sta->isenabled) ;
+    uint32_pack_big(pack + 28, sta->isparsed) ;
+    uint32_pack_big(pack + 32, sta->issupervised) ;
+    uint32_pack_big(pack + 36, sta->isup) ;
 }
diff --git a/src/lib66/state/state_read.c b/src/lib66/state/state_read.c
index b2bb622a..6a836491 100644
--- a/src/lib66/state/state_read.c
+++ b/src/lib66/state/state_read.c
@@ -15,26 +15,28 @@
 #include <string.h>
 
 #include <oblibs/log.h>
+#include <oblibs/string.h>
 
 #include <skalibs/djbunix.h>
 
 #include <66/state.h>
+#include <66/constants.h>
+#include <66/resolve.h>
 
-int state_read(ss_state_t *sta, char const *src, char const *name)
+int state_read(ss_state_t *sta, char const *base, char const *name)
 {
     log_flow() ;
 
-    char pack[SS_STATE_SIZE] ;
-    size_t srclen = strlen(src) ;
+    size_t baselen = strlen(base) ;
     size_t namelen = strlen(name) ;
+    char pack[STATE_STATE_SIZE] ;
+    char target[baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + 1 + SS_SERVICE_LEN + 1 + namelen + SS_SVC_LEN + 1 + namelen + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
 
-    char tmp[srclen + 1 + namelen + 1] ;
-    memcpy(tmp,src,srclen) ;
-    tmp[srclen] = '/' ;
-    memcpy(tmp + srclen + 1, name, namelen) ;
-    tmp[srclen + 1 + namelen] = 0 ;
+    auto_strings(target, base, SS_SYSTEM, SS_RESOLVE, "/", SS_SERVICE, "/", name, SS_SVC, "/", name, SS_STATE, "/", SS_STATUS) ;
+
+    if (openreadnclose(target, pack, STATE_STATE_SIZE) < STATE_STATE_SIZE)
+        return 0 ;
 
-    if (openreadnclose(tmp, pack, SS_STATE_SIZE) < SS_STATE_SIZE) return 0 ;
     state_unpack(pack, sta) ;
 
     return 1 ;
diff --git a/src/lib66/state/state_rmfile.c b/src/lib66/state/state_rmfile.c
index 84f860b9..4c94d6b2 100644
--- a/src/lib66/state/state_rmfile.c
+++ b/src/lib66/state/state_rmfile.c
@@ -15,23 +15,23 @@
 #include <string.h>
 
 #include <oblibs/log.h>
+#include <oblibs/string.h>
 
 #include <skalibs/posixplz.h>
 
 #include <66/state.h>
+#include <66/constants.h>
+#include <66/resolve.h>
 
-void state_rmfile(char const *src,char const *name)
+void state_rmfile(char const *base, char const *name)
 {
     log_flow() ;
 
-    size_t srclen = strlen(src) ;
+    size_t baselen = strlen(base) ;
     size_t namelen = strlen(name) ;
+    char target[baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + 1 + SS_SERVICE_LEN + 1 + namelen + SS_SVC_LEN + 1 + namelen + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
 
-    char tmp[srclen + 1 + namelen + 1] ;
-    memcpy(tmp,src,srclen) ;
-    tmp[srclen] = '/' ;
-    memcpy(tmp + srclen + 1, name, namelen) ;
-    tmp[srclen + 1 + namelen] = 0 ;
+    auto_strings(target, base, SS_SYSTEM, SS_RESOLVE, "/", SS_SERVICE, "/", name, SS_SVC, "/", name, SS_STATE, "/", SS_STATUS) ;
 
-    unlink_void(tmp) ;
+    unlink_void(target) ;
 }
diff --git a/src/lib66/state/state_set_flag.c b/src/lib66/state/state_set_flag.c
new file mode 100644
index 00000000..fc343e38
--- /dev/null
+++ b/src/lib66/state/state_set_flag.c
@@ -0,0 +1,39 @@
+/*
+ * state_set_flag.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 <oblibs/log.h>
+
+#include <66/state.h>
+
+void state_set_flag(ss_state_t *sta, int flags, int flags_val)
+{
+    log_flow() ;
+
+    switch (flags)
+    {
+        case STATE_FLAGS_TOINIT: sta->toinit = flags_val ; break ;
+        case STATE_FLAGS_TORELOAD: sta->toreload = flags_val ; break ;
+        case STATE_FLAGS_TORESTART: sta->torestart = flags_val ; break ;
+        case STATE_FLAGS_TOUNSUPERVISE: sta->tounsupervise = flags_val ; break ;
+        case STATE_FLAGS_ISDOWNFILE: sta->isdownfile = flags_val ; break ;
+        case STATE_FLAGS_ISEARLIER: sta->isearlier = flags_val ; break ;
+        case STATE_FLAGS_ISENABLED: sta->isenabled = flags_val ; break ;
+        case STATE_FLAGS_ISPARSED: sta->isparsed = flags_val ; break ;
+        case STATE_FLAGS_ISSUPERVISED: sta->issupervised = flags_val ; break ;
+        case STATE_FLAGS_ISUP: sta->isup = flags_val ; break ;
+        default: return ;
+    }
+}
diff --git a/src/lib66/state/state_unpack.c b/src/lib66/state/state_unpack.c
index 3d385f8c..4fe575b3 100644
--- a/src/lib66/state/state_unpack.c
+++ b/src/lib66/state/state_unpack.c
@@ -24,20 +24,44 @@ void state_unpack(char *pack,ss_state_t *sta)
 {
     log_flow() ;
 
-    uint32_t reload ;
-    uint32_t init ;
-    uint32_t unsupervise ;
-    uint32_t state ;
-    uint64_t pid ;
-
-    uint32_unpack_big(pack,&reload) ;
-    sta->reload = reload ;
-    uint32_unpack_big(pack+4,&init) ;
-    sta->init = init ;
-    uint32_unpack_big(pack+8,&unsupervise) ;
-    sta->unsupervise = unsupervise ;
-    uint32_unpack_big(pack+12,&state) ;
-    sta->state = state ;
-    uint64_unpack_big(pack+16,&pid) ;
-    sta->pid = pid ;
+    uint32_t toinit ;
+    uint32_t toreload ;
+    uint32_t torestart ;
+    uint32_t tounsupervise ;
+    uint32_t isdownfile ;
+    uint32_t isearlier ;
+    uint32_t isenabled ;
+    uint32_t isparsed ;
+    uint32_t issupervised ;
+    uint32_t isup ;
+
+    uint32_unpack_big(pack, &toinit) ;
+    sta->toinit = toinit ;
+
+    uint32_unpack_big(pack + 4, &toreload) ;
+    sta->toreload = toreload ;
+
+    uint32_unpack_big(pack + 8, &torestart) ;
+    sta->torestart = torestart ;
+
+    uint32_unpack_big(pack + 12, &tounsupervise) ;
+    sta->tounsupervise = tounsupervise ;
+
+    uint32_unpack_big(pack + 16, &isdownfile) ;
+    sta->isdownfile = isdownfile ;
+
+    uint32_unpack_big(pack + 20, &isearlier) ;
+    sta->isearlier = isearlier ;
+
+    uint32_unpack_big(pack + 24, &isenabled) ;
+    sta->isenabled = isenabled ;
+
+    uint32_unpack_big(pack + 28, &isparsed) ;
+    sta->isparsed = isparsed ;
+
+    uint32_unpack_big(pack + 32, &issupervised) ;
+    sta->issupervised = issupervised ;
+
+    uint32_unpack_big(pack + 36, &isup) ;
+    sta->isup = isup ;
 }
diff --git a/src/lib66/state/state_write.c b/src/lib66/state/state_write.c
index c5a5de61..4a29cb5c 100644
--- a/src/lib66/state/state_write.c
+++ b/src/lib66/state/state_write.c
@@ -13,29 +13,38 @@
  */
 
 #include <string.h>
+#include <unistd.h>
 
 #include <oblibs/log.h>
+#include <oblibs/string.h>
+#include <oblibs/directory.h>
 
 #include <skalibs/djbunix.h>
 
 #include <66/state.h>
+#include <66/constants.h>
+#include <66/resolve.h>
 
-int state_write(ss_state_t *sta, char const *dst, char const *name)
+int state_write(ss_state_t *sta, char const *base, char const *name)
 {
     log_flow() ;
 
-    char pack[SS_STATE_SIZE] ;
-    size_t dstlen = strlen(dst) ;
+    size_t baselen = strlen(base) ;
     size_t namelen = strlen(name) ;
+    char target[baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + 1 + SS_SERVICE_LEN + 1 + namelen + SS_SVC_LEN + 1 + namelen + SS_STATE_LEN + 1 + SS_STATUS_LEN + 1] ;
 
-    char tmp[dstlen + 1 + namelen + 1] ;
-    memcpy(tmp,dst,dstlen) ;
-    tmp[dstlen] = '/' ;
-    memcpy(tmp + dstlen + 1, name, namelen) ;
-    tmp[dstlen + 1 + namelen] = 0 ;
+    auto_strings(target, base, SS_SYSTEM, SS_RESOLVE, "/", SS_SERVICE, "/", name, SS_SVC, "/", name, SS_STATE) ;
 
-    state_pack(pack,sta) ;
-    if (!openwritenclose_unsafe(tmp,pack,SS_STATE_SIZE)) return 0 ;
+    if (access(target, F_OK) < 0)
+        if (!dir_create_parent(target, 0755))
+            log_warnusys_return(LOG_EXIT_ZERO, "create directory: ", target) ;
+
+    auto_strings(target + baselen + SS_SYSTEM_LEN + SS_RESOLVE_LEN + 1 + SS_SERVICE_LEN + 1 + namelen + SS_SVC_LEN + 1 + namelen + SS_STATE_LEN, "/", SS_STATUS) ;
+
+    char pack[STATE_STATE_SIZE] ;
+
+    state_pack(pack, sta) ;
+    if (!openwritenclose_unsafe(target, pack, STATE_STATE_SIZE)) return 0 ;
 
     return 1 ;
 }
-- 
GitLab