From a09e2fc4091805193550d5f0a258b452f4ab0856 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Sat, 15 Apr 2023 17:37:22 +1100
Subject: [PATCH] add graph_compute_visit function and make visit structure
 public

---
 src/include/66/graph.h                |  4 ++-
 src/include/66/utils.h                | 14 +++++---
 src/lib66/exec/ssexec_disable.c       | 14 ++++++--
 src/lib66/exec/ssexec_enable.c        |  9 +++++-
 src/lib66/exec/ssexec_reconfigure.c   | 38 +++++++---------------
 src/lib66/exec/ssexec_start.c         | 46 +--------------------------
 src/lib66/exec/ssexec_stop.c          | 22 ++-----------
 src/lib66/exec/ssexec_tree_admin.c    | 38 ++++++----------------
 src/lib66/graph/deps-lib/deps         |  1 +
 src/lib66/graph/graph_compute_visit.c | 45 ++++++++++++++++++++++++++
 src/lib66/utils/deps-lib/deps         |  4 +--
 src/lib66/utils/visit.c               | 29 +++++++++++++++++
 12 files changed, 135 insertions(+), 129 deletions(-)
 create mode 100644 src/lib66/graph/graph_compute_visit.c
 create mode 100644 src/lib66/utils/visit.c

diff --git a/src/include/66/graph.h b/src/include/66/graph.h
index d47c1a53..14d96598 100644
--- a/src/include/66/graph.h
+++ b/src/include/66/graph.h
@@ -29,10 +29,12 @@
 extern void graph_build_tree(graph_t *g,char const *base, resolve_tree_master_enum_t field) ;
 extern void graph_build_service(graph_t *g, resolve_service_t *ares, unsigned int *areslen, ssexec_t *info, uint32_t flag) ;
 extern int graph_compute_dependencies(graph_t *g, char const *vertex, char const *edge, uint8_t requiredby) ;
-
+extern void graph_compute_visit(char const *name, unsigned int *visit, unsigned int *list, graph_t *graph, unsigned int *nservice, uint8_t requiredby) ;
 
 extern int graph_build_service_bytree(graph_t *g, char const *tree, uint8_t what,  uint8_t is_supervised) ;
 extern int graph_build_service_bytree_from_src(graph_t *g, char const *src, uint8_t what) ;
+
+
 /** possible remove of it */
 extern int graph_build_service_from_sastr(graph_t *graph, stralloc *sa, char const *base) ;
 
diff --git a/src/include/66/utils.h b/src/include/66/utils.h
index c2c55d32..48ab09a9 100644
--- a/src/include/66/utils.h
+++ b/src/include/66/utils.h
@@ -24,13 +24,22 @@
 #include <skalibs/genalloc.h>
 
 #include <66/ssexec.h>
-#include <66/service.h>
 
 #define MYUID getuid()
 #define YOURUID(passto,owner) youruid(passto,owner)
 #define MYGID getgid()
 #define YOURGID(passto,owner) yourgid(passto,owner)
 
+typedef enum visit_e visit_t ;
+enum visit_e
+{
+    VISIT_WHITE = 0,
+    VISIT_GRAY,
+    VISIT_BLACK
+} ;
+
+extern void visit_init(visit_t *visit, size_t len) ;
+
 /** ss_utils.c file */
 extern char const *get_userhome(uid_t myuid) ;
 extern int youruid(uid_t *passto,char const *owner) ;
@@ -42,10 +51,7 @@ extern int set_livestate(stralloc *live,uid_t owner) ;
 extern int set_ownerhome(stralloc *base,uid_t owner) ;
 extern int set_ownersysdir(stralloc *base,uid_t owner) ;
 extern int read_svfile(stralloc *sasv,char const *name,char const *src) ;
-extern int module_in_cmdline(genalloc *gares, resolve_service_t *res, char const *dir) ;
-extern int module_search_service(char const *src, genalloc *gares, char const *name,uint8_t *found, char module_name[256]) ;
 
-extern int module_path(stralloc *sdir, stralloc *mdir, char const *sv,char const *frontend_src, uid_t owner) ;
 extern int sa_pointo(stralloc *sa, ssexec_t *info, int type, unsigned int where) ;
 extern int create_live_state(ssexec_t *info, char const *treename) ;
 extern int create_live_tree(ssexec_t *info) ;
diff --git a/src/lib66/exec/ssexec_disable.c b/src/lib66/exec/ssexec_disable.c
index 3a5549ad..d0313c08 100644
--- a/src/lib66/exec/ssexec_disable.c
+++ b/src/lib66/exec/ssexec_disable.c
@@ -30,6 +30,7 @@
 #include <66/graph.h>
 #include <66/resolve.h>
 #include <66/utils.h>
+#include <66/state.h>
 
 int ssexec_disable(int argc, char const *const *argv, ssexec_t *info)
 {
@@ -45,6 +46,9 @@ int ssexec_disable(int argc, char const *const *argv, ssexec_t *info)
     unsigned int areslen = 0 ;
     resolve_service_t ares[SS_MAX_SERVICE] ;
 
+    visit_t visit[SS_MAX_SERVICE] ;
+    visit_init(visit, SS_MAX_SERVICE) ;
+
     FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ;
 
     {
@@ -74,7 +78,7 @@ int ssexec_disable(int argc, char const *const *argv, ssexec_t *info)
 
                 case 'R' :
 
-                    log_1_warn("options -F is deprecated -- use instead 66 service remove <service>") ;
+                    log_1_warn("options -F is deprecated -- use instead 66 remove <service>") ;
                     break ;
 
                 default :
@@ -94,8 +98,14 @@ int ssexec_disable(int argc, char const *const *argv, ssexec_t *info)
         log_die(LOG_EXIT_USER, "services selection is not available -- try to parse it first") ;
 
     for (; n < argc ; n++) {
+
         name_isvalid(argv[n]) ;
-        service_enable_disable(&graph, info->base.s, argv[n], 0) ;
+
+        int aresid = service_resolve_array_search(ares, areslen, argv[n]) ;
+        if (aresid < 0)
+            log_die(LOG_EXIT_USER, "service: ", argv[n], " not available -- did you parsed it?") ;
+
+        service_enable_disable(&graph, &ares[aresid], ares, areslen, 0, visit) ;
 
         if (!sastr_add_string(&sa, argv[n]))
             log_dieu(LOG_EXIT_SYS, "add string") ;
diff --git a/src/lib66/exec/ssexec_enable.c b/src/lib66/exec/ssexec_enable.c
index 44207ae3..8c8f54a3 100644
--- a/src/lib66/exec/ssexec_enable.c
+++ b/src/lib66/exec/ssexec_enable.c
@@ -67,6 +67,9 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
     unsigned int areslen = 0 ;
     resolve_service_t ares[SS_MAX_SERVICE] ;
 
+    visit_t visit[SS_MAX_SERVICE] ;
+    visit_init(visit, SS_MAX_SERVICE) ;
+
     FLAGS_SET(flag, STATE_FLAGS_TOPROPAGATE|STATE_FLAGS_WANTUP) ;
 
     {
@@ -125,7 +128,11 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
 
     for (n = 0 ; n < argc ; n++) {
 
-        service_enable_disable(&graph, info->base.s, argv[n], 1) ;
+        int aresid = service_resolve_array_search(ares, areslen, argv[n]) ;
+        if (aresid < 0)
+            log_die(LOG_EXIT_USER, "service: ", argv[n], " not available -- did you parsed it?") ;
+
+        service_enable_disable(&graph, &ares[aresid], ares, areslen, 1, visit) ;
 
         if (!sastr_add_string(&sa, argv[n]))
             log_dieu(LOG_EXIT_SYS, "add string") ;
diff --git a/src/lib66/exec/ssexec_reconfigure.c b/src/lib66/exec/ssexec_reconfigure.c
index bf337d20..6fc61df6 100644
--- a/src/lib66/exec/ssexec_reconfigure.c
+++ b/src/lib66/exec/ssexec_reconfigure.c
@@ -119,25 +119,9 @@ int ssexec_reconfigure(int argc, char const *const *argv, ssexec_t *info)
         if (aresid < 0)
             log_die(LOG_EXIT_USER, "service: ", argv[n], " not available -- did you parsed it?") ;
 
-        unsigned int l[graph.mlen], c = 0, pos = 0, idx = 0 ;
-
-        idx = graph_hash_vertex_get_id(&graph, argv[n]) ;
-
-        if (!visit[idx]) {
-            list[nservice++] = idx ;
-            visit[idx] = 1 ;
-        }
-        /** find dependencies of the service from the graph, do it recursively */
-        c = graph_matrix_get_edge_g_list(l, &graph, argv[n], 1, 1) ;
-
-        /** append to the list to deal with */
-        for (; pos < c ; pos++) {
-            if (!visit[l[pos]]) {
-                list[nservice++] = l[pos] ;
-                visit[l[pos]] = 1 ;
-            }
-        }
+        graph_compute_visit(argv[n], visit, list, &graph, &nservice, 1) ;
     }
+
     /** keep list of already running service */
     char const *exclude[4] = { SS_FDHOLDER, SS_ONESHOTD, SS_SVSCAN_LOG, 0 } ;
     if (!sastr_dir_get(&sa, info->scandir.s, exclude, S_IFDIR))
@@ -147,6 +131,7 @@ int ssexec_reconfigure(int argc, char const *const *argv, ssexec_t *info)
         /** stop service and unsupervise it */
         unsigned int m = 0 ;
         int nargc = 2 + argc + siglen ;
+        char const *prog = PROG ;
         char const *newargv[nargc] ;
 
         newargv[m++] = "stop" ;
@@ -158,7 +143,9 @@ int ssexec_reconfigure(int argc, char const *const *argv, ssexec_t *info)
 
         newargv[m++] = 0 ;
 
+        PROG = "stop" ;
         e = ssexec_stop(nargc, newargv, info) ;
+        PROG = prog ;
         if (e)
             goto freed ;
     }
@@ -170,23 +157,22 @@ int ssexec_reconfigure(int argc, char const *const *argv, ssexec_t *info)
     {
         /** start service */
         unsigned int m = 0 ;
-        int nargc = 2 + nservice + siglen ;
+        int nargc = 2 + argc + siglen ;
+        char const *prog = PROG ;
         char const *newargv[nargc] ;
 
         newargv[m++] = "start" ;
         if (siglen)
             newargv[m++] = "-P" ;
 
-        for (n = 0 ; n < nservice ; n++) {
-            char *name = graph.data.s + genalloc_s(graph_hash_t,&graph.hash)[list[n]].vertex ;
-            if (sastr_cmp(&sa, name) >= 0)
-                newargv[m++] = name ;
-        }
+        for (n = 0 ; n < argc ; n++)
+            newargv[m++] = argv[n] ;
 
         newargv[m++] = 0 ;
 
-        e = ssexec_start(m - 1, newargv, info) ;
-
+        PROG= "start" ;
+        e = ssexec_start(--m, newargv, info) ;
+        PROG = prog ;
     }
 
     freed:
diff --git a/src/lib66/exec/ssexec_start.c b/src/lib66/exec/ssexec_start.c
index 30f604dc..64145968 100644
--- a/src/lib66/exec/ssexec_start.c
+++ b/src/lib66/exec/ssexec_start.c
@@ -102,52 +102,8 @@ int ssexec_start(int argc, char const *const *argv, ssexec_t *info)
         if (aresid < 0)
             log_die(LOG_EXIT_USER, "service: ", argv[n], " not available -- did you parsed it?") ;
 
-        unsigned int l[graph.mlen], c = 0, pos = 0, idx = 0 ;
+        graph_compute_visit(argv[n], visit, list, &graph, &nservice, 0) ;
 
-        idx = graph_hash_vertex_get_id(&graph, argv[n]) ;
-
-        if (!visit[idx]) {
-            list[nservice++] = idx ;
-            visit[idx] = 1 ;
-        }
-
-        /** find dependencies of the service from the graph, do it recursively */
-        c = graph_matrix_get_edge_g_list(l, &graph, argv[n], 0, 1) ;
-
-        /** append to the list to deal with */
-        for (; pos < c ; pos++) {
-            if (!visit[l[pos]]) {
-                list[nservice++] = l[pos] ;
-                visit[l[pos]] = 1 ;
-            }
-        }
-        if (ares[aresid].type == TYPE_MODULE) {
-
-            if (ares[aresid].regex.ncontents) {
-
-                stralloc sa = STRALLOC_ZERO ;
-                if (!sastr_clean_string(&sa, ares[aresid].sa.s + ares[aresid].regex.contents))
-                    log_dieu(LOG_EXIT_SYS, "clean string") ;
-
-                {
-                    size_t idx = 0 ;
-                    FOREACH_SASTR(&sa, idx) {
-
-
-                        /** find dependencies of the service from the graph, do it recursively */
-                        c = graph_matrix_get_edge_g_list(l, &graph, sa.s + idx, 0, 1) ;
-
-                        /** append to the list to deal with */
-                        for (pos = 0 ; pos < c ; pos++) {
-                            if (!visit[l[pos]]) {
-                                list[nservice++] = l[pos] ;
-                                visit[l[pos]] = 1 ;
-                            }
-                        }
-                    }
-                }
-            }
-        }
     }
 
     /** initiate services at the corresponding scandir */
diff --git a/src/lib66/exec/ssexec_stop.c b/src/lib66/exec/ssexec_stop.c
index 9de73113..f2971dcd 100644
--- a/src/lib66/exec/ssexec_stop.c
+++ b/src/lib66/exec/ssexec_stop.c
@@ -17,6 +17,7 @@
 #include <oblibs/log.h>
 #include <oblibs/types.h>
 #include <oblibs/graph.h>
+#include <oblibs/sastr.h>
 
 #include <skalibs/sgetopt.h>
 #include <skalibs/djbunix.h>
@@ -28,6 +29,7 @@
 #include <66/state.h>
 #include <66/svc.h>
 #include <66/service.h>
+#include <66/enum.h>
 
 int ssexec_stop(int argc, char const *const *argv, ssexec_t *info)
 {
@@ -106,25 +108,7 @@ int ssexec_stop(int argc, char const *const *argv, ssexec_t *info)
         if (aresid < 0)
             log_die(LOG_EXIT_USER, "service: ", argv[n], " not available -- did you started it?") ;
 
-        unsigned int l[graph.mlen], c = 0, pos = 0, idx = 0 ;
-
-        idx = graph_hash_vertex_get_id(&graph, argv[n]) ;
-
-        if (!visit[idx]) {
-            list[nservice++] = idx ;
-            visit[idx] = 1 ;
-        }
-
-        /** find requiredby of the service from the graph, do it recursively */
-        c = graph_matrix_get_edge_g_list(l, &graph, argv[n], 1, 1) ;
-
-        /** append to the list to deal with */
-        for (; pos < c ; pos++) {
-            if (!visit[l[pos]]) {
-                list[nservice++] = l[pos] ;
-                visit[l[pos]] = 1 ;
-            }
-        }
+        graph_compute_visit(argv[n], visit, list, &graph, &nservice, 1) ;
     }
 
     char *sig[siglen] ;
diff --git a/src/lib66/exec/ssexec_tree_admin.c b/src/lib66/exec/ssexec_tree_admin.c
index 6ede0c5f..49ca0bf3 100644
--- a/src/lib66/exec/ssexec_tree_admin.c
+++ b/src/lib66/exec/ssexec_tree_admin.c
@@ -52,14 +52,6 @@
 #define TREE_MAXOPTS 9
 #define tree_checkopts(n) if (n >= TREE_MAXOPTS) log_die(LOG_EXIT_USER, "too many -o options")
 
-typedef enum visit_e visit ;
-enum visit_e
-{
-    SS_WHITE = 0,
-    SS_GRAY,
-    SS_BLACK
-} ;
-
 typedef struct tree_opts_map_s tree_opts_map_t ;
 struct tree_opts_map_s
 {
@@ -135,16 +127,6 @@ tree_what_t what_init(void)
     return what ;
 }
 
-void visit_init(visit *v, size_t len)
-{
-    log_flow() ;
-
-    size_t pos = 0 ;
-    for (; pos < len; pos++)
-        v[pos] = SS_WHITE ;
-
-}
-
 void tree_enable_disable(graph_t *g, char const *base, char const *treename, uint8_t action) ;
 
 static void check_identifier(char const *name)
@@ -695,7 +677,7 @@ void tree_enable_disable_deps(graph_t *g,char const *base, char const *treename,
         log_dieu(LOG_EXIT_SYS, "get ", action ? "dependencies" : "required by" ," of: ", treename) ;
 
     size_t len = sastr_nelement(&sa) ;
-    visit v[len] ;
+    visit_t v[len] ;
 
     visit_init(v, len) ;
 
@@ -703,13 +685,13 @@ void tree_enable_disable_deps(graph_t *g,char const *base, char const *treename,
 
         FOREACH_SASTR(&sa, pos) {
 
-            if (v[element] == SS_WHITE) {
+            if (v[element] == VISIT_WHITE) {
 
                 char *name = sa.s + pos ;
 
                 tree_enable_disable(g, base, name, action) ;
 
-                v[element] = SS_GRAY ;
+                v[element] = VISIT_GRAY ;
             }
             element++ ;
         }
@@ -773,7 +755,7 @@ void tree_depends_requiredby(graph_t *g, char const *base, char const *treename,
         log_dieu(LOG_EXIT_SYS,"get sorted ", requiredby ? "required by" : "dependency", " list of tree: ", treename) ;
 
     size_t vlen = sastr_nelement(&sa) ;
-    visit v[vlen] ;
+    visit_t v[vlen] ;
 
     visit_init(v, vlen) ;
 
@@ -787,7 +769,7 @@ void tree_depends_requiredby(graph_t *g, char const *base, char const *treename,
 
         for(; pos < len ; pos += strlen(t + pos) + 1, element++) {
 
-            if (v[element] == SS_WHITE) {
+            if (v[element] == VISIT_WHITE) {
 
                 char *name = t + pos ;
 
@@ -800,7 +782,7 @@ void tree_depends_requiredby(graph_t *g, char const *base, char const *treename,
 
                     if (deps) {
                         if (!strcmp(name, deps)) {
-                            v[element] = SS_GRAY ;
+                            v[element] = VISIT_GRAY ;
                             continue ;
                         }
                     }
@@ -811,7 +793,7 @@ void tree_depends_requiredby(graph_t *g, char const *base, char const *treename,
                     nb++ ;
                 }
 
-                v[element] = SS_GRAY ;
+                v[element] = VISIT_GRAY ;
             }
         }
     }
@@ -868,7 +850,7 @@ void tree_depends_requiredby_deps(graph_t *g, char const *base, char const *tree
         log_dieu(LOG_EXIT_SYS,"get sorted ", requiredby ? "required by" : "dependency", " list of tree: ", treename) ;
 
     size_t vlen = sastr_nelement(&sa) ;
-    visit v[vlen] ;
+    visit_t v[vlen] ;
 
     visit_init(v, vlen) ;
 
@@ -881,13 +863,13 @@ void tree_depends_requiredby_deps(graph_t *g, char const *base, char const *tree
 
     for(; pos < len ; pos += strlen(t + pos) + 1, element++) {
 
-        if (v[element] == SS_WHITE) {
+        if (v[element] == VISIT_WHITE) {
 
             char *name = t + pos ;
 
             tree_depends_requiredby(g, base, name, !requiredby, none, deps) ;
 
-            v[element] = SS_GRAY ;
+            v[element] = VISIT_GRAY ;
         }
     }
 
diff --git a/src/lib66/graph/deps-lib/deps b/src/lib66/graph/deps-lib/deps
index 021c9492..1449b9ff 100644
--- a/src/lib66/graph/deps-lib/deps
+++ b/src/lib66/graph/deps-lib/deps
@@ -1,6 +1,7 @@
 graph_build_service.o
 graph_build_tree.o
 graph_compute_dependencies.o
+graph_compute_visit.o
 graph_remove_deps.o
 -loblibs
 -lskarnet
diff --git a/src/lib66/graph/graph_compute_visit.c b/src/lib66/graph/graph_compute_visit.c
new file mode 100644
index 00000000..3940cab5
--- /dev/null
+++ b/src/lib66/graph/graph_compute_visit.c
@@ -0,0 +1,45 @@
+/*
+ * graph_compute_visit_g.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 <stdint.h>
+
+#include <oblibs/log.h>
+
+#include <66/graph.h>
+
+
+void graph_compute_visit(char const *name, unsigned int *visit, unsigned int *list, graph_t *graph, unsigned int *nservice, uint8_t requiredby)
+{
+    log_flow() ;
+
+    unsigned int l[graph->mlen], c = 0, pos = 0, idx = 0 ;
+
+    idx = graph_hash_vertex_get_id(graph, name) ;
+
+    if (!visit[idx]) {
+        list[(*nservice)++] = idx ;
+        visit[idx] = 1 ;
+    }
+
+    /** find dependencies of the service from the graph, do it recursively */
+    c = graph_matrix_get_edge_g_list(l, graph, name, requiredby, 1) ;
+
+    /** append to the list to deal with */
+    for (; pos < c ; pos++) {
+        if (!visit[l[pos]]) {
+            list[(*nservice)++] = l[pos] ;
+            visit[l[pos]] = 1 ;
+        }
+    }
+}
diff --git a/src/lib66/utils/deps-lib/deps b/src/lib66/utils/deps-lib/deps
index e23a2bec..014c51bb 100644
--- a/src/lib66/utils/deps-lib/deps
+++ b/src/lib66/utils/deps-lib/deps
@@ -1,7 +1,4 @@
 get_userhome.o
-module_in_cmdline.o
-module_path.o
-module_search_service.o
 name_isvalid.o
 read_svfile.o
 set_livedir.o
@@ -9,6 +6,7 @@ set_livescan.o
 set_livestate.o
 set_ownerhome.o
 set_ownersysdir.o
+visit.o
 yourgid.o
 youruid.o
 -ls6
diff --git a/src/lib66/utils/visit.c b/src/lib66/utils/visit.c
new file mode 100644
index 00000000..af29a1d9
--- /dev/null
+++ b/src/lib66/utils/visit.c
@@ -0,0 +1,29 @@
+/*
+ * visit.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 <stddef.h>
+
+#include <oblibs/log.h>
+
+#include <66/utils.h>
+
+void visit_init(visit_t *visit, size_t len)
+{
+    log_flow() ;
+
+    size_t pos = 0 ;
+    for (; pos < len; pos++)
+        visit[pos] = VISIT_WHITE ;
+
+}
-- 
GitLab