From 8b61f655dad4037a5f5d3822b9c141feefabd367 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Sun, 29 Jan 2023 20:06:22 +1100
Subject: [PATCH] provide good help

---
 src/66/66-oneshot.c                     |   4 +-
 src/66/66.c                             | 331 +++++++----------
 src/include/66/ssexec.h                 | 121 ++++---
 src/lib66/exec/ssexec_boot.c            |   3 +-
 src/lib66/exec/ssexec_disable.c         |   9 +-
 src/lib66/exec/ssexec_enable.c          |  13 +-
 src/lib66/exec/ssexec_env.c             |  20 +-
 src/lib66/exec/ssexec_help.c            | 458 ++++++++++++++----------
 src/lib66/exec/ssexec_init.c            |   3 +-
 src/lib66/exec/ssexec_inservice.c       |  12 +-
 src/lib66/exec/ssexec_instate.c         |  16 +-
 src/lib66/exec/ssexec_intree.c          |   8 +-
 src/lib66/exec/ssexec_parse.c           |  13 +-
 src/lib66/exec/ssexec_reconfigure.c     |  25 +-
 src/lib66/exec/ssexec_reload.c          |  10 +-
 src/lib66/exec/ssexec_resolve_service.c |   2 +-
 src/lib66/exec/ssexec_resolve_tree.c    |   3 +-
 src/lib66/exec/ssexec_restart.c         |   9 +-
 src/lib66/exec/ssexec_scanctl.c         |   9 +-
 src/lib66/exec/ssexec_scandir.c         |  31 +-
 src/lib66/exec/ssexec_service_admin.c   |  29 +-
 src/lib66/exec/ssexec_service_wrapper.c |  56 ++-
 src/lib66/exec/ssexec_start.c           |   9 +-
 src/lib66/exec/ssexec_stop.c            |   9 +-
 src/lib66/exec/ssexec_svctl.c           |   9 +-
 src/lib66/exec/ssexec_tree.c            |   5 +-
 src/lib66/exec/ssexec_tree_wrapper.c    |  62 ++--
 src/lib66/exec/ssexec_treectl.c         |  10 +-
 src/lib66/svc/svc_send_wait.c           |   2 +-
 29 files changed, 664 insertions(+), 627 deletions(-)

diff --git a/src/66/66-oneshot.c b/src/66/66-oneshot.c
index 344e10be..87b5feab 100644
--- a/src/66/66-oneshot.c
+++ b/src/66/66-oneshot.c
@@ -30,7 +30,7 @@
 
 #define USAGE "66-oneshot [ -h ] [ -v verbosity ] up|down /var/lib/66/system/<tree>/servicedirs/svc/<service>"
 
-static inline void info_help (void)
+static inline void help_oneshot (void)
 {
     DEFAULT_MSG = 0 ;
 
@@ -62,7 +62,7 @@ int main(int argc, char const *const *argv)
             if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
             switch (opt)
             {
-                case 'h' :  info_help(); return 0 ;
+                case 'h' :  help_oneshot(); return 0 ;
                 case 'v' :  if (!uint0_scan(l.arg, &VERBOSITY)) log_usage(USAGE) ; break ;
                 default :   log_usage(USAGE) ;
             }
diff --git a/src/66/66.c b/src/66/66.c
index 3e767dfb..2d8b62b3 100644
--- a/src/66/66.c
+++ b/src/66/66.c
@@ -26,15 +26,6 @@
 #include <66/sanitize.h>
 #include <66/tree.h>
 
-static inline void info_help (char const *help,char const *usage)
-{
-    log_flow() ;
-
-    DEFAULT_MSG = 0 ;
-
-    log_info(usage,"\n", help) ;
-}
-
 void set_treeinfo(ssexec_t *info)
 {
     log_flow() ;
@@ -95,19 +86,12 @@ int main(int argc, char const *const *argv)
 
     if (!argv[1]) {
         PROG = "66" ;
-        log_usage(usage_66) ;
-
-    } else if (!strcmp(argv[1], "version")) {
-
-        PROG = "version" ;
-        log_info(SS_VERSION) ;
+        log_usage( usage_66, "\n", help_66) ;
         return 0 ;
     }
 
     int r, n = 0, i = 0 ;
     uint8_t sanitize = 0 ;
-    /** 30 options should be large enough */
-    char opts[30] ;
     char const *main = "hv:l:t:T:z" ;
     char str[UINT_FMT] ;
     char const *nargv[argc + 1] ;
@@ -125,7 +109,116 @@ int main(int argc, char const *const *argv)
     if (!set_ownersysdir(&info.base, info.owner))
         log_dieusys(LOG_EXIT_SYS, "set owner directory") ;
 
-    if (!strcmp(argv[1], "boot")) {
+    {
+        subgetopt l = SUBGETOPT_ZERO ;
+
+        int f = 0 ;
+        for (;;)
+        {
+            int opt = subgetopt_r(argc, argv, main, &l) ;
+
+            if (opt == -1) break ;
+            switch (opt)
+            {
+                case 'h' :
+
+                    info_help(help_66, usage_66) ;
+                    return 0 ;
+
+                case 'v' :
+
+                    if (!uint0_scan(l.arg, &VERBOSITY))
+                        log_usage(info.usage) ;
+                    info.opt_verbo = 1 ;
+                    break ;
+
+                case 'l' :
+
+                    str[uint_fmt(str, SS_MAX_PATH)] = 0 ;
+
+                    if (strlen(l.arg) > SS_MAX_PATH)
+                        log_die(LOG_EXIT_USER, "live path is too long -- it can not exceed ", str) ;
+
+                    if (!auto_stra(&info.live, l.arg))
+                        log_die_nomem("stralloc") ;
+
+                    info.opt_live = 1 ;
+                    break ;
+
+                case 't' :
+
+                    str[uint_fmt(str, SS_MAX_TREENAME)] = 0 ;
+
+                    if (strlen(l.arg) > SS_MAX_TREENAME)
+                        log_die(LOG_EXIT_USER, "tree name is too long -- it can not exceed ", str) ;
+
+                    if (!auto_stra(&info.treename, l.arg))
+                        log_die_nomem("stralloc") ;
+
+                    info.opt_tree = 1 ;
+                    break ;
+
+                case 'T' :
+
+                    if (!uint0_scan(l.arg, &info.timeout))
+                        log_usage(info.usage) ;
+                    info.opt_timeout = 1 ;
+                    break ;
+
+                case 'z' :
+
+                    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++) {
+
+                        if (!argv[l.ind])
+                            log_usage(info.usage) ;
+
+                        if (l.arg) {
+
+                            if (!strcmp(nargv[i],argv[l.ind - 2]) || !strcmp(nargv[i],l.arg))
+                                f = 1 ;
+
+                        } else {
+
+                            if (!strcmp(nargv[i],argv[l.ind]))
+                                f = 1 ;
+                        }
+                    }
+
+                    if (!f) {
+
+                        if (l.arg) {
+                            // distinction between e.g -enano and -e nano
+                            if (argv[l.ind - 1][0] != '-')
+                                nargv[n++] = argv[l.ind - 2] ;
+
+                            nargv[n++] = argv[l.ind - 1] ;
+
+                        } else {
+
+                            nargv[n++] = argv[l.ind] ;
+                        }
+                    }
+                    f = 0 ;
+                    break ;
+            }
+        }
+        argc -= l.ind ; argv += l.ind ;
+    }
+
+    if (!strcmp(argv[1], "version")) {
+
+        PROG = "version" ;
+        log_info(SS_VERSION) ;
+        return 0 ;
+
+    } else if (!strcmp(argv[0], "boot")) {
 
         PROG = "boot" ;
         nargv[n++] = PROG ;
@@ -136,9 +229,7 @@ int main(int argc, char const *const *argv)
 
         sanitize++ ;
 
-        auto_strings(opts, main, OPTS_BOOT) ;
-
-    } else if (!strcmp(argv[1], "enable")) {
+    } else if (!strcmp(argv[0], "enable")) {
 
         PROG = "enable" ;
         nargv[n++] = PROG ;
@@ -147,9 +238,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_enable ;
         func = &ssexec_enable ;
 
-        auto_strings(opts, main, OPTS_ENABLE) ;
-
-    } else if (!strcmp(argv[1], "disable")) {
+    } else if (!strcmp(argv[0], "disable")) {
 
         PROG = "disable" ;
         nargv[n++] = PROG ;
@@ -158,9 +247,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_disable ;
         func = &ssexec_disable ;
 
-        auto_strings(opts, main, OPTS_DISABLE) ;
-
-    } else if (!strcmp(argv[1], "start")) {
+    } else if (!strcmp(argv[0], "start")) {
 
         PROG = "start" ;
         nargv[n++] = PROG ;
@@ -169,9 +256,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_start ;
         func = &ssexec_start ;
 
-        auto_strings(opts, main, OPTS_START) ;
-
-    } else if (!strcmp(argv[1], "stop")) {
+    } else if (!strcmp(argv[0], "stop")) {
 
         PROG = "stop" ;
         nargv[n++] = PROG ;
@@ -180,9 +265,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_stop ;
         func = &ssexec_stop ;
 
-        auto_strings(opts, main, OPTS_STOP) ;
-
-    } else if (!strcmp(argv[1], "env")) {
+    } else if (!strcmp(argv[0], "env")) {
 
         PROG = "env" ;
         nargv[n++] = PROG ;
@@ -191,9 +274,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_env ;
         func = &ssexec_env ;
 
-        auto_strings(opts, main, OPTS_ENV) ;
-
-    } else if (!strcmp(argv[1], "init")) {
+    } else if (!strcmp(argv[0], "init")) {
 
         PROG = "init" ;
         nargv[n++] = PROG ;
@@ -202,9 +283,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_init ;
         func = &ssexec_init ;
 
-        auto_strings(opts, main, OPTS_INIT) ;
-
-    } else if (!strcmp(argv[1], "parse")) {
+    } else if (!strcmp(argv[0], "parse")) {
 
         PROG = "parse" ;
         nargv[n++] = PROG ;
@@ -213,9 +292,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_parse ;
         func = &ssexec_parse ;
 
-        auto_strings(opts, main, OPTS_PARSE) ;
-
-    } else if (!strcmp(argv[1], "reconfigure")) {
+    } else if (!strcmp(argv[0], "reconfigure")) {
 
         PROG = "reconfigure" ;
         nargv[n++] = PROG ;
@@ -224,9 +301,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_reconfigure ;
         func = &ssexec_reconfigure ;
 
-        auto_strings(opts, main, OPTS_SUBSTART) ;
-
-    } else if (!strcmp(argv[1], "reload")) {
+    } else if (!strcmp(argv[0], "reload")) {
 
         PROG = "reload" ;
         nargv[n++] = PROG ;
@@ -235,9 +310,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_reload ;
         func = &ssexec_reload ;
 
-        auto_strings(opts, main, OPTS_SUBSTART) ;
-
-    } else if (!strcmp(argv[1], "restart")) {
+    } else if (!strcmp(argv[0], "restart")) {
 
         PROG = "restart" ;
         nargv[n++] = PROG ;
@@ -246,21 +319,17 @@ int main(int argc, char const *const *argv)
         info.usage = usage_restart ;
         func = &ssexec_restart ;
 
-        auto_strings(opts, main, OPTS_SUBSTART) ;
-
-    } else if (!strcmp(argv[1], "unsupervise")) {
+    } else if (!strcmp(argv[0], "unsupervise")) {
 
         PROG = "stop" ;
         nargv[n++] = PROG ;
         nargv[n++] = "-u" ;
         info.prog = PROG ;
-        info.help = help_stop ;
-        info.usage = usage_stop ;
+        info.help = help_unsupervise ;
+        info.usage = usage_unsupervise ;
         func = &ssexec_stop ;
 
-        auto_strings(opts, main, OPTS_STOP) ;
-
-    } else if (!strcmp(argv[1], "svctl")) {
+    } else if (!strcmp(argv[0], "signal")) {
 
         PROG = "svctl" ;
         nargv[n++] = PROG ;
@@ -269,47 +338,19 @@ int main(int argc, char const *const *argv)
         info.usage = usage_svctl ;
         func = &ssexec_svctl ;
 
-        auto_strings(opts, main, OPTS_SVCTL) ;
-
-    } else if (!strcmp(argv[1], "tree")) {
+    } else if (!strcmp(argv[0], "tree")) {
 
         PROG = "tree" ;
         nargv[n++] = PROG ;
         func = &ssexec_tree_wrapper ;
 
-        auto_strings(opts, main) ;
-
-    } else if (!strcmp(argv[1], "service")) {
+    } else if (!strcmp(argv[0], "service")) {
 
         PROG = "service" ;
         nargv[n++] = PROG ;
         func = &ssexec_service_wrapper ;
 
-        auto_strings(opts, main) ;
-
-    } else if (!strcmp(argv[1], "intree")) {
-
-        PROG = "intree" ;
-        nargv[n++] = PROG ;
-        info.prog = PROG ;
-        info.help = help_intree ;
-        info.usage = usage_intree ;
-        func = &ssexec_intree ;
-
-        auto_strings(opts, main, OPTS_INTREE) ;
-
-    } else if (!strcmp(argv[1], "inservice")) {
-
-        PROG = "inservice" ;
-        nargv[n++] = PROG ;
-        info.prog = PROG ;
-        info.help = help_inservice ;
-        info.usage = usage_inservice ;
-        func = &ssexec_inservice ;
-
-        auto_strings(opts, main, OPTS_INSERVICE) ;
-
-    } else if (!strcmp(argv[1], "scanctl")) {
+    } else if (!strcmp(argv[0], "scanctl")) {
 
         PROG = "scanctl" ;
         nargv[n++] = PROG ;
@@ -318,9 +359,7 @@ int main(int argc, char const *const *argv)
         info.usage = usage_scanctl ;
         func = &ssexec_scanctl ;
 
-        auto_strings(opts, main, OPTS_SCANCTL) ;
-
-    } else if (!strcmp(argv[1], "scandir")) {
+    } else if (!strcmp(argv[0], "scandir")) {
 
         PROG = "scandir" ;
         nargv[n++] = PROG ;
@@ -329,118 +368,20 @@ int main(int argc, char const *const *argv)
         info.usage = usage_scandir ;
         func = &ssexec_scandir ;
 
-        auto_strings(opts, main, OPTS_SCANDIR) ;
-
     } else {
 
-        log_usage(usage_66) ;
+        PROG = "66" ;
+        if (!strcmp(argv[0], "-h")) {
+            info_help(help_66, usage_66) ;
+            return 0 ;
+        }
+
+        log_usage(usage_66, "\n", help_66) ;
     }
 
     argc-- ;
     argv++ ;
 
-    {
-        subgetopt l = SUBGETOPT_ZERO ;
-
-        int f = 0 ;
-        for (;;)
-        {
-            int opt = subgetopt_r(argc, argv, opts, &l) ;
-
-            if (opt == -1) break ;
-            switch (opt)
-            {
-                case 'h' :
-
-                    info_help(info.help, info.usage) ;
-                    return 0 ;
-
-                case 'v' :
-
-                    if (!uint0_scan(l.arg, &VERBOSITY))
-                        log_usage(info.usage) ;
-                    info.opt_verbo = 1 ;
-                    break ;
-
-                case 'l' :
-
-                    str[uint_fmt(str, SS_MAX_PATH)] = 0 ;
-
-                    if (strlen(l.arg) > SS_MAX_PATH)
-                        log_die(LOG_EXIT_USER, "live path is too long -- it can not exceed ", str) ;
-
-                    if (!auto_stra(&info.live, l.arg))
-                        log_die_nomem("stralloc") ;
-
-                    info.opt_live = 1 ;
-                    break ;
-
-                case 't' :
-
-                    str[uint_fmt(str, SS_MAX_TREENAME)] = 0 ;
-
-                    if (strlen(l.arg) > SS_MAX_TREENAME)
-                        log_die(LOG_EXIT_USER, "tree name is too long -- it can not exceed ", str) ;
-
-                    if (!auto_stra(&info.treename, l.arg))
-                        log_die_nomem("stralloc") ;
-
-                    info.opt_tree = 1 ;
-                    break ;
-
-                case 'T' :
-
-                    if (!uint0_scan(l.arg, &info.timeout))
-                        log_usage(info.usage) ;
-                    info.opt_timeout = 1 ;
-                    break ;
-
-                case 'z' :
-
-                    log_color = !isatty(1) ? &log_color_disable : &log_color_enable ;
-                    info.opt_color = 1 ;
-                    break ;
-
-                default :
-
-                    for (i = 0 ; i < n ; i++) {
-
-                        if (!argv[l.ind])
-                            log_usage(info.usage) ;
-
-                        if (l.arg) {
-
-                            if (!strcmp(nargv[i],argv[l.ind - 2]) || !strcmp(nargv[i],l.arg))
-                                f = 1 ;
-
-                        } else {
-
-                            if (!strcmp(nargv[i],argv[l.ind]))
-                                f = 1 ;
-                        }
-                    }
-
-                    if (!f) {
-
-                        if (l.arg) {
-                            // distinction between e.g -enano and -e nano
-                            if (argv[l.ind - 1][0] != '-')
-                                nargv[n++] = argv[l.ind - 2] ;
-
-                            nargv[n++] = argv[l.ind - 1] ;
-
-                        } else {
-
-                            nargv[n++] = argv[l.ind] ;
-                        }
-                    }
-                    f = 0 ;
-                    break ;
-            }
-        }
-        argc -= l.ind ; argv += l.ind ;
-    }
-
     if (!sanitize)
         sanitize_system(&info) ;
 
diff --git a/src/include/66/ssexec.h b/src/include/66/ssexec.h
index 696dfaaf..e1dc6c2c 100644
--- a/src/include/66/ssexec.h
+++ b/src/include/66/ssexec.h
@@ -128,95 +128,126 @@ extern ssexec_func_t ssexec_tree_wrapper ;
 extern ssexec_func_t ssexec_service_wrapper ;
 extern ssexec_func_t ssexec_service_admin ;
 
-extern char const *usage_parse ;
-extern char const *help_parse ;
+extern void info_help (char const *help,char const *usage) ;
+
+extern char const *usage_66 ;
+extern char const *help_66 ;
+
+extern char const *usage_boot ;
+extern char const *help_boot ;
+
 extern char const *usage_enable ;
 extern char const *help_enable ;
+
 extern char const *usage_disable ;
 extern char const *help_disable ;
-extern char const *usage_svctl ;
-extern char const *help_svctl ;
+
 extern char const *usage_start ;
 extern char const *help_start ;
+
 extern char const *usage_stop ;
 extern char const *help_stop ;
-extern char const *usage_init ;
-extern char const *help_init ;
+
 extern char const *usage_env ;
 extern char const *help_env ;
-extern char const *usage_treectl ;
-extern char const *help_treectl ;
-extern char const *usage_tree ;
-extern char const *help_tree ;
+
+extern char const *usage_init ;
+extern char const *help_init ;
+
+extern char const *usage_parse ;
+extern char const *help_parse ;
+
 extern char const *usage_reconfigure ;
 extern char const *help_reconfigure ;
+
 extern char const *usage_reload ;
 extern char const *help_reload ;
+
 extern char const *usage_restart ;
 extern char const *help_restart ;
+
 extern char const *usage_unsupervise ;
 extern char const *help_unsupervise ;
-extern char const *usage_inresolve ;
-extern char const *help_inresolve ;
-extern char const *usage_instate ;
-extern char const *help_instate ;
-extern char const *usage_intree ;
-extern char const *help_intree ;
-extern char const *usage_inservice ;
-extern char const *help_inservice ;
-extern char const *usage_boot ;
-extern char const *help_boot ;
+
+extern char const *usage_svctl ;
+extern char const *help_svctl ;
+
+extern char const *usage_tree_wrapper ;
+extern char const *help_tree_wrapper ;
+extern char const *usage_tree_create ;
+extern char const *help_tree_create ;
+extern char const *usage_tree_admin ;
+extern char const *help_tree_admin ;
+extern char const *usage_tree_remove ;
+extern char const *help_tree_remove ;
+extern char const *usage_tree_enable ;
+extern char const *help_tree_enable ;
+extern char const *usage_tree_disable ;
+extern char const *help_tree_disable ;
+extern char const *usage_tree_current ;
+extern char const *help_tree_current ;
+extern char const *usage_tree_resolve ;
+extern char const *help_tree_resolve ;
+extern char const *usage_tree_status ;
+extern char const *help_tree_status ;
+extern char const *usage_tree_up ;
+extern char const *help_tree_up ;
+extern char const *usage_tree_down ;
+extern char const *help_tree_down ;
+extern char const *usage_tree_unsupervise ;
+extern char const *help_tree_unsupervise ;
+
+extern char const *usage_service_wrapper ;
+extern char const *help_service_wrapper ;
+extern char const *usage_service_status ;
+extern char const *help_service_status ;
+extern char const *usage_service_resolve ;
+extern char const *help_service_resolve ;
+extern char const *usage_service_state ;
+extern char const *help_service_state ;
+extern char const *usage_service_remove ;
+extern char const *help_service_remove ;
+
 extern char const *usage_scanctl ;
 extern char const *help_scanctl ;
+
 extern char const *usage_scandir ;
 extern char const *help_scandir ;
-extern char const *usage_service_wrapper ;
-extern char const *help_service_wrapper ;
-extern char const *usage_service_admin ;
-extern char const *help_service_admin ;
-extern char const *usage_66 ;
 
-#define OPTS_SUBSTART "P"
+#define OPTS_SUBSTART "hP"
 #define OPTS_SUBSTART_LEN (sizeof OPTS_SUBSTART - 1)
-#define OPTS_PARSE "fFcmCI"
+#define OPTS_PARSE "hfFcmCI"
 #define OPTS_PARSE_LEN (sizeof OPTS_PARSE - 1)
-#define OPTS_INIT ""
-#define OPTS_INIT_LEN (sizeof OPTS_INIT - 1)
-#define OPTS_ENABLE "fFSI"
+#define OPTS_ENABLE "hfFSI"
 #define OPTS_ENABLE_LEN (sizeof OPTS_ENABLE - 1)
-#define OPTS_DISABLE "S"
+#define OPTS_DISABLE "hS"
 #define OPTS_DISABLE_LEN (sizeof OPTS_DISABLE - 1)
-#define OPTS_START "P"
+#define OPTS_START "hP"
 #define OPTS_START_LEN (sizeof OPTS_START - 1)
-#define OPTS_STOP "uP"
+#define OPTS_STOP "huP"
 #define OPTS_STOP_LEN (sizeof OPTS_STOP - 1)
-#define OPTS_SVCTL "abqHkti12pcyroduxOw:P"
+#define OPTS_SVCTL "habqHkti12pcyroduxOw:P"
 #define OPTS_SVCTL_LEN (sizeof OPTS_SVCTL - 1)
-#define OPTS_ENV "c:s:VLr:e:i:"
+#define OPTS_ENV "hc:s:VLr:e:i:"
 #define OPTS_ENV_LEN (sizeof OPTS_ENV - 1)
 #define OPTS_TREECTL "f"
 #define OPTS_TREECTL_LEN (sizeof OPTS_TREECTL - 1)
-#define OPTS_TREE "co:EDRnadC:S:"
+#define OPTS_TREE "hco:EDRnadC:S:"
 #define OPTS_TREE_LEN (sizeof OPTS_TREE - 1)
-#define OPTS_INRESOLVE ""
-#define OPTS_INRESOLVE_LEN (sizeof OPTS_INRESOLVE - 1)
-#define OPTS_INSTATE ""
-#define OPTS_INSTATE_LEN (sizeof OPTS_INSTATE - 1)
 #define OPTS_INTREE "no:grd:l:"
 #define OPTS_INTREE_LEN (sizeof OPTS_INTREE - 1)
 #define OPTS_INSERVICE "no:grd:t:p:"
 #define OPTS_INSERVICE_LEN (sizeof OPTS_INSERVICE - 1)
-#define OPTS_BOOT "ms:e:d:b:l:"
+#define OPTS_BOOT "hms:e:d:b:l:"
 #define OPTS_BOOT_LEN (sizeof OPTS_BOOT - 1)
-#define OPTS_SCANCTL "o:d:t:e:"
+#define OPTS_SCANCTL "ho:d:t:e:"
 #define OPTS_SCANCTL_LEN (sizeof OPTS_SCANCTL - 1)
-#define OPTS_SCANDIR "bl:s:o:L:cB"
+#define OPTS_SCANDIR "hbl:s:o:L:cB"
 #define OPTS_SCANDIR_LEN (sizeof OPTS_SCANDIR - 1)
+
 #define OPTS_SERVICE_WRAPPER ""
 #define OPTS_SERVICE_WRAPPER_LEN (sizeof OPTS_SERVICE_WRAPPER - 1)
 #define OPTS_SERVICE_ADMIN ""
 #define OPTS_SERVICE_ADMIN_LEN (sizeof OPTS_SERVICE_ADMIN - 1)
 
-
-
 #endif
diff --git a/src/lib66/exec/ssexec_boot.c b/src/lib66/exec/ssexec_boot.c
index d25a3306..05d787bb 100644
--- a/src/lib66/exec/ssexec_boot.c
+++ b/src/lib66/exec/ssexec_boot.c
@@ -479,13 +479,14 @@ int ssexec_boot(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt)
             {
+                case 'h' : info_help(info->help, info->usage) ; return 0 ;
                 case 'm' : tmpfs = 1 ; break ;
                 case 's' : skel = l.arg ; break ;
                 case 'e' : envdir = l.arg ; break ;
                 case 'd' : slashdev = l.arg ; break ;
                 case 'b' : banner = l.arg ; break ;
                 case 'l' : log_user = l.arg ; break ;
-                default :  log_usage(usage_boot) ;
+                default :  log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
diff --git a/src/lib66/exec/ssexec_disable.c b/src/lib66/exec/ssexec_disable.c
index e5be6345..0a8ec0b2 100644
--- a/src/lib66/exec/ssexec_disable.c
+++ b/src/lib66/exec/ssexec_disable.c
@@ -67,6 +67,11 @@ int ssexec_disable(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
 
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'S' :
 
                     stop = 1 ;
@@ -83,14 +88,14 @@ int ssexec_disable(int argc, char const *const *argv, ssexec_t *info)
                     break ;
 
                 default :
-                    log_usage(usage_disable) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_disable) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     /** build the graph of the entire system */
     graph_build_service(&graph, ares, &areslen, info, flag) ;
diff --git a/src/lib66/exec/ssexec_enable.c b/src/lib66/exec/ssexec_enable.c
index 73b617dc..7cb84ee4 100644
--- a/src/lib66/exec/ssexec_enable.c
+++ b/src/lib66/exec/ssexec_enable.c
@@ -89,11 +89,16 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
 
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'f' :
 
                     /** only rewrite the service itself */
                     if (force)
-                        log_usage(usage_enable) ;
+                        log_usage(info->usage, "\n", info->help) ;
                     force = 1 ;
                     break ;
 
@@ -101,7 +106,7 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
 
                      /** force to rewrite it dependencies */
                     if (force)
-                        log_usage(usage_enable) ;
+                        log_usage(info->usage, "\n", info->help) ;
                     force = 2 ;
                     break ;
 
@@ -116,14 +121,14 @@ int ssexec_enable(int argc, char const *const *argv, ssexec_t *info)
                     break ;
 
                 default :
-                    log_usage(usage_enable) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_enable) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     for(; n < argc ; n++) {
         check_identifier(argv[n]) ;
diff --git a/src/lib66/exec/ssexec_env.c b/src/lib66/exec/ssexec_env.c
index 6954937f..888df723 100644
--- a/src/lib66/exec/ssexec_env.c
+++ b/src/lib66/exec/ssexec_env.c
@@ -16,7 +16,6 @@
 #include <stdlib.h>//getenv
 #include <unistd.h>//_exit,access
 
-#include <oblibs/obgetopt.h>
 #include <oblibs/log.h>
 #include <oblibs/files.h>
 #include <oblibs/string.h>
@@ -24,6 +23,7 @@
 #include <oblibs/sastr.h>
 #include <oblibs/environ.h>
 
+#include <skalibs/sgetopt.h>
 #include <skalibs/stralloc.h>
 #include <skalibs/genalloc.h>
 #include <skalibs/buffer.h>
@@ -229,12 +229,16 @@ int ssexec_env(int argc, char const *const *argv, ssexec_t *info)
 
         for (;;)
         {
-            int opt = getopt_args(argc,argv, ">" OPTS_ENV, &l) ;
+            int opt = subgetopt_r(argc, argv, OPTS_ENV, &l) ;
             if (opt == -1) break ;
-            if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
 
             switch (opt)
             {
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'c' :
 
                         if (env_check_version(&saversion,l.arg) <= 0)
@@ -251,13 +255,13 @@ int ssexec_env(int argc, char const *const *argv, ssexec_t *info)
 
                 case 'V' :
 
-                        if (todo != T_UNSET) log_usage(usage_env) ;
+                        if (todo != T_UNSET) log_usage(info->usage, "\n", info->help) ;
                         todo = T_VLIST ;
 
                         break ;
                 case 'L' :
 
-                        if (todo != T_UNSET) log_usage(usage_env) ;
+                        if (todo != T_UNSET) log_usage(info->usage, "\n", info->help) ;
                         todo = T_LIST ;
 
                         break ;
@@ -267,7 +271,7 @@ int ssexec_env(int argc, char const *const *argv, ssexec_t *info)
                         if (!sastr_add_string(&savar,l.arg))
                             log_die_nomem("stralloc") ;
 
-                        if (todo != T_UNSET && todo != T_REPLACE) log_usage(usage_env) ;
+                        if (todo != T_UNSET && todo != T_REPLACE) log_usage(info->usage, "\n", info->help) ;
                         todo = T_REPLACE ;
 
                         break ;
@@ -285,13 +289,13 @@ int ssexec_env(int argc, char const *const *argv, ssexec_t *info)
 
                 default :
 
-                    log_usage(usage_env) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
-    if (argc < 1) log_usage(usage_env) ;
+    if (argc < 1) log_usage(info->usage, "\n", info->help) ;
     sv = argv[0] ;
 
     if (todo == T_UNSET && !import && !saversion.len && !eversion.len) todo = T_EDIT ;
diff --git a/src/lib66/exec/ssexec_help.c b/src/lib66/exec/ssexec_help.c
index 5f8de4de..12ebe70c 100644
--- a/src/lib66/exec/ssexec_help.c
+++ b/src/lib66/exec/ssexec_help.c
@@ -12,145 +12,253 @@
  * except according to the terms contained in the LICENSE file./
  */
 
+#include <oblibs/log.h>
 #include <66/ssexec.h>
 
-char const *usage_parse = "66 parse [ -h ] [ -z ] [ -v verbosity ] [ -t tree ] [ -f|F ] [ -I ] service" ;
+inline void info_help (char const *help,char const *usage)
+{
+    DEFAULT_MSG = 0 ;
 
-char const *help_parse =
+    log_info(usage,"\n", help) ;
+}
+
+
+char const *usage_66 = "66 [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -T timeout ] start|stop|reload|restart|unsupervise|reconfigure|enable|disable|env|service|tree|init|parse|signal|scanctl|scandir|boot|version [<command options>] service...|tree" ;
+
+char const *help_66 =
+"\nmain tool to init a system, control and manage services\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
 "   -z: use color\n"
 "   -v: increase/decrease verbosity\n"
-"   -f: force to overwrite existing destination\n"
-"   -F: also force to overwrite its dependencies\n"
-"   -I: do not import modified configuration files from previous version\n"
+"   -l: live directory\n"
+"   -T: timeout\n"
+"\n"
+"command:\n"
+"   start: bring up service\n"
+"   stop: bring down service\n"
+"   reload: send a SIGHUP signal to service\n"
+"   restart: bring down service then bring it up\n"
+"   unsupervise: bring down service and remove it from scandir\n"
+"   reconfigure: bring down, unsupervise, parse it again and bring up service\n"
+"   enable: activate service for the next boot\n"
+"   disable: deactivate service for the next boot\n"
+"   env: manage service environment variable\n"
+"   service: manage/see service information\n"
+"   tree: manage/see tree information\n"
+"   init: initiate to scandir all service declared inside tree\n"
+"   parse: parse the service frontend file\n"
+"   signal: send signal to service\n"
+"   scanctl: send signal to scandir\n"
+"   scandir: manage scandir\n"
+"   boot: boot the system with 66\n"
+"   version: display 66 version\n"
+"\n"
+"Use '66 <command> -h' to see command options\n"
 ;
 
-char const *usage_enable = "66 enable [ -h ] [ -z ] [ -v verbosity ] [ - l live ] [ -t tree ] [ -f|F ] [ -I ] [ -S ] service(s)" ;
+char const *usage_boot = "66 boot [ -h ] [ -m ] [ -s skel ] [ -l log_user ] [ -e environment ] [ -d dev ] [ -b banner ]" ;
+
+char const *help_boot =
+"\nboot a system with 66. Generally used at /bin/init script\n"
+"\n"
+"options :\n"
+"   -h: print this help\n"
+"   -m: mount parent live directory\n"
+"   -s: skeleton directory\n"
+"   -l: run catch-all logger as log_user user\n"
+"   -e: environment directory or file\n"
+"   -d: dev directory\n"
+"   -b: banner to display\n"
+;
+
+char const *usage_enable = "66 enable [ -h ] [ -f|F ] [ -I ] [ -S ] service..." ;
 
 char const *help_enable =
+"\nactivate services at the next boot\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -t: name of the tree to use\n"
 "   -f: force to overwrite the service(s)\n"
 "   -F: force to overwrite the service(s) and its dependencies\n"
 "   -I: do not import modified configuration files from previous version\n"
 "   -S: enable and start the service\n"
 ;
 
-char const *usage_disable = "66 disable [ -h ] [ -z ] [ -v verbosity ] [ - l live ] [ -t tree ] [ -S ] service(s)" ;
+char const *usage_disable = "66 disable [ -h ] [ -S ] service..." ;
 
 char const *help_disable =
+"\ndeactivate services at the next boot\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -t: name of the tree to use\n"
-"   -S: disable and stop/unsupervice the service if needed\n"
+"   -S: disable and stop/unsupervice service if needed\n"
+;
+
+char const *usage_start = "66 start [ -h ] [ -P ] service..." ;
+
+char const *help_start =
+"\nbring up services\n"
+"\n"
+"options:\n"
+"   -h: print this help\n"
+"   -P: do not propagate signal to its dependencies\n"
+;
+
+char const *usage_stop = "66 stop [ -h ] [ -P ] [ -u ] service..." ;
+
+char const *help_stop =
+"\nbring down services\n"
+"\n"
+"options:\n"
+"   -h: print this help\n"
+"   -P: do not propagate signal to its requiredby\n"
+"   -u: unsupervise service(s)\n"
 ;
 
-char const *usage_init = "66 init [ -h ] [ -z ] [ -v verbosity ] [ -l live ] tree" ;
+char const *usage_env = "66 env [ -h ] [ -c version ] [ -s version ] [ -V|L ] [ -r key=value ] [ -i src,dst ] [ -e editor ] service" ;
+
+char const *help_env =
+"\nmanage environment service files and its contents\n"
+"\n"
+"options:\n"
+"   -h: print this help\n"
+"   -c: set version as default\n"
+"   -s: specifies the version to handle\n"
+"   -V: lists available versioned configuration directories of the service\n"
+"   -L: lists the environment variables of the service\n"
+"   -r: replace the value of the key\n"
+"   -i: import configuration files from src version to dst version\n"
+"   -e: edit the file with editor\n"
+;
+
+char const *usage_init = "66 init [ -h ] tree" ;
 
 char const *help_init =
+"\ninitiate all services present in tree to a scandir already running\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
 ;
 
-char const *usage_start = "66 start [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -t tree ] [ -T timeout ] service(s)" ;
+char const *usage_parse = "66 parse [ -h ] [ -f|F ] [ -I ] service..." ;
 
-char const *help_start =
+char const *help_parse =
+"\nparse a frontend service file and install its result to resolve files\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -t: tree to use\n"
-"   -T: timeout\n"
+"   -f: force to overwrite existing destination\n"
+"   -F: also force to overwrite its dependencies\n"
+"   -I: do not import modified configuration files from previous version\n"
 ;
 
-char const *usage_stop = "66 stop [ -h ] [ -z ] [ -v verbosity ] [ -T timeout ] [ -l live ] [ -t tree ] [ -u ] service(s)" ;
+char const *usage_reconfigure = "66 reconfigure [ -h ] [ -P ] service..." ;
 
-char const *help_stop =
+char const *help_reconfigure =
+"\nconvenient tool to bring down, unsupervise, parse again and bring up services in one pass\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -T: timeout\n"
-"   -t: tree to use\n"
-"   -u: unsupervise service(s)\n"
+"   -P: do not propagate signal to its dependencies\n"
 ;
 
-char const *usage_svctl = "66 svctl [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -t tree ] [ -T timeout ] [ -wu | -wU | -wd | -wD | -wr | -wR ] [ -abqHkti12pcyoduxOr ] service(s)" ;
+char const *usage_reload = "66 reload [ -h ] [ -P ] service..." ;
 
-char const *help_svctl =
+char const *help_reload =
+"\nconvenient tool to send a SIGHUP signal to services\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -t: tree to use\n"
-"   -T: service timeout\n"
+"   -P: do not propagate signal to its dependencies\n"
 ;
 
-char const *usage_env = "66 env [ -h ] [ -z ] [ -v verbosity ] [ -t tree ] [ -c version ] [ -s version ] [ -V|L ] [ -r key=value ] [ -i src,dst ] [ -e editor ] service" ;
+char const *usage_restart = "66 restart [ -h ] [ -P ] service..." ;
 
-char const *help_env =
+char const *help_restart =
+"\nconvenient tool to bring down then bring up services in one pass\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -t: tree to use\n"
-"   -c: set version as default\n"
-"   -s: specifies the version to handle\n"
-"   -V: lists available versioned configuration directories of the service\n"
-"   -L: lists the environment variables of the service\n"
-"   -r: replace the value of the key\n"
-"   -i: import configuration files from src version to dst version\n"
-"   -e: edit the file with editor\n"
+"   -P: do not propagate signal to its dependencies\n"
 ;
 
-char const *usage_treectl = "66 treectl [ -h ] [ -z ] [ -v verbosity ] [ -T timeout ] [ -l live ] [ -t tree ] [ -f ] up|down|unsupervise" ;
+char const *usage_unsupervise = "66 unsupervise [ -h ] [ -P ] service..." ;
 
-char const *help_treectl =
+char const *help_unsupervise =
+"\nbring down services and remove it from the scandir\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -T: timeout\n"
-"   -l: live directory\n"
-"   -t: tree to use\n"
-"   -f: fork the process\n"
+"   -P: do not propagate signal to its dependencies\n"
 ;
 
-char const *usage_tree = "66 tree [ -h ] [ -z ] [ -v verbosity ] [ -T timeout ] [ -l live ] create|admin|remove|enable|disable|current|up|down|unsupervise [ -f ] [ -o depends=:... ] tree" ;
+char const *usage_svctl = "66 signal [ -h ] [ -wu | -wU | -wd | -wD | -wr | -wR ] [ -abqHkti12pcyodDuUxOr ] service..." ;
 
-char const *help_tree =
+char const *help_svctl =
+"\nsend a signal to services\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -T: timeout\n"
-"   -f: fork the process\n"
-"   -o: colon separated list of options\n"
+"   -wu: do not exit until the service is up"
+"   -wU: do not exit until the service is up and ready as notified by the daemon itself"
+"   -wd: do not exit until the service is down"
+"   -wD: do not exit until the service is down and ready to be brought up"
+"   -wr: do not exit until the service has been started or restarted"
+"   -wR: do not exit until the service has been started or restarted and has notified readiness"
+"   -a: send a SIGALRM signal"
+"   -b: send a SIGABRT signal"
+"   -q: send a SIGQUIT signal"
+"   -H: send a SIGHUP signal"
+"   -k: send a SIGKILL signal"
+"   -t: send a SIGTERM signal"
+"   -i: send a SIGINT signal"
+"   -1: send a SIGUSR1 signal"
+"   -2: send a SIGUSR2 signal"
+"   -p: send a SIGSTOP signal"
+"   -c: send a SIGCONT signal"
+"   -y: send a SIGWINCH signal"
+"   -o: once. Equivalent to '-uO'."
+"   -d: send a SIGTERM signal then a SIGCONT signal."
+"   -D: bring down service and avoid to be bring it up automatically"
+"   -u: bing up service"
+"   -U: bring up service and ensure that service can be restarted automatically"
+"   -x: bring down the service and propagate to its supervisor"
+"   -O : mark the service to run once at most"
+"   -r : restart service by sending it a signal(default SIGTERM)"
+;
+
+char const *usage_tree_wrapper = "66 tree [ -h ] create|admin|remove|enable|disable|current|up|down|unsupervise [<command options>] tree" ;
 
+char const *help_tree_wrapper =
+"\nmain sub tools to manages trees\n"
+"\n"
+"options:\n"
+"   -h: print this help\n"
+"\n"
+"command:"
+"   create: create tree\n"
+"   admin: manage tree\n"
+"   remove: remove tree\n"
+"   enable: activate tree for the next boot\n"
+"   disable: deactivate tree for the next boot\n"
+"   current: mark tree as current\n"
+"   up: bring up all services from tree\n"
+"   down: bring down all services from tree\n"
+"   unsupervise: bring down and unsupervise all services from tree\n"
+"\n"
+"Use '66 tree <command> -h' to see command options\n"
+;
+
+char const *usage_tree_create = "66 tree create [ -h ] [ -o depends=,requiredby=,... ] tree" ;
+
+char const *help_tree_create =
+"\ncreate a tree\n"
+"\n"
+"options:\n"
+"   -h: print this help\n"
+"   -o: colon separated list of options\n"
 "\n"
 "valid fields for -o options are:\n"
 "\n"
@@ -163,94 +271,78 @@ char const *help_tree =
 "   noseed: do not use seed file to build the tree\n"
 ;
 
-char const *usage_reconfigure = "66 reconfigure [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -t tree ] [ -T timeout ] [ -P ] service(s)" ;
+char const *usage_tree_admin = "66 tree admin [ -h ] [ -o depends=,requiredby=,... ] tree" ;
 
-char const *help_reconfigure =
+char const *help_tree_admin =
+"\nadministrate an existing tree\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -t: tree to use\n"
-"   -T: timeout\n"
-"   -P: do not propagate signal to its dependencies\n"
+"   -o: colon separated list of options\n"
+"\n"
+"valid fields for -o options are:\n"
+"\n"
+"   depends=: comma separated list of dependencies for tree or none\n"
+"   requiredby=: comma separated list of trees required by tree or none\n"
+"   groups=: add tree to the specified groups\n"
+"   allow=: comma separated list of account to allow at tree\n"
+"   deny=: comma separated list of account to deny at tree\n"
+"   clone=: make a clone of tree\n"
+"   noseed: do not use seed file to build the tree\n"
 ;
 
-char const *usage_reload = "66 reload [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -t tree ] [ -T timeout ] [ -P ] service(s)" ;
+char const *usage_tree_remove = "66 tree remove [ -h ] tree" ;
 
-char const *help_reload =
+char const *help_tree_remove =
+"\nremove a tree\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -t: tree to use\n"
-"   -T: timeout\n"
-"   -P: do not propagate signal to its dependencies\n"
 ;
 
-char const *usage_restart = "66 restart [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -t tree ] [ -T timeout ] [ -P ] service(s)" ;
+char const *usage_tree_enable = "66 tree enable [ -h ] tree" ;
 
-char const *help_restart =
+char const *help_tree_enable =
+"\nactivate tree at next boot\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -t: tree to use\n"
-"   -T: timeout\n"
-"   -P: do not propagate signal to its dependencies\n"
 ;
 
-char const *usage_unsupervise = "66 unsupervise [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -t tree ] [ -T timeout ] [ -P ] service(s)" ;
+char const *usage_tree_disable = "66 tree disable [ -h ] tree" ;
 
-char const *help_unsupervise =
+char const *help_tree_disable =
+"\ndeactivate tree at next boot\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -t: tree to use\n"
-"   -T: timeout\n"
-"   -P: do not propagate signal to its dependencies\n"
 ;
 
-char const *usage_inresolve = "66 inresolve [ -h ] [ -z ] [ -v verbosity ] [ -t tree ] tree|service name" ;
+char const *usage_tree_current = "66 tree current [ -h ] tree" ;
 
-char const *help_inresolve =
+char const *help_tree_current =
+"\nmark tree as current\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -t: only search at the specified tree\n"
-"   tree: search for tree name\n"
-"   service: search for service name\n"
 ;
 
-char const *usage_instate = "66 instate [ -h ] [ -z ] [ -v verbosity ] service" ;
+char const *usage_tree_resolve = "66 tree resolve [ -h ] tree" ;
 
-char const *help_instate =
+char const *help_tree_resolve =
+"\ndisplay the resolve files contents of tree\n"
 "\n"
 "options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
 ;
 
-char const *usage_intree = "66 intree [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -n ] [ -o name,init,enabled,... ] [ -g ] [ -d depth ] [ -r ] tree" ;
+char const *usage_tree_status = "66 tree status [ -h ] [ -n ] [ -o name,init,enabled,... ] [ -g ] [ -d depth ] [ -r ] tree" ;
 
-char const *help_intree =
+char const *help_tree_status =
+"\ndisplay information about tree\n"
 "\n"
 "options :\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
 "   -n: do not display the names of fields\n"
 "   -o: comma separated list of field to display\n"
 "   -g: displays the contents field as graph\n"
@@ -270,66 +362,65 @@ char const *help_intree =
 "   contents: displays the contents of the tree\n"
 ;
 
-char const *usage_inservice = "66 inservice [ -h ] [ -z ] [ -v verbosity ] [ -n ] [ -o name,intree,status,... ] [ -g ] [ -d depth ] [ -r ] [ -t tree ] [ -p nline ] service" ;
+char const *usage_tree_up = "66 tree up [ -h ] [ -f ] tree" ;
 
-char const *help_inservice =
+char const *help_tree_up =
+"\nbring up all enabled services of tree\n"
 "\n"
-"options :\n"
+"options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -n: do not display the field name\n"
-"   -o: comma separated list of field to display\n"
-"   -g: displays the contents field as graph\n"
-"   -d: limit the depth of the contents field recursion\n"
-"   -r: reverse the contents field\n"
-"   -t: only search service at the specified tree\n"
-"   -p: print n last lines of the log file\n"
+"   -f: fork the process\n"
+;
+
+char const *usage_tree_down = "66 tree down [ -h ] [ -f ] tree" ;
+
+char const *help_tree_down =
+"\nbring down all services of tree\n"
 "\n"
-"valid fields for -o options are:\n"
+"options:\n"
+"   -h: print this help\n"
+"   -f: fork the process\n"
+;
+
+char const *usage_tree_unsupervise = "66 tree unsupervise [ -h ] [ -f ] tree" ;
+
+char const *help_tree_unsupervise =
+"\nbring down and unsupervise all services of tree\n"
 "\n"
-"   name: displays the name\n"
-"   version: displays the version of the service\n"
-"   intree: displays the service's tree name\n"
-"   status: displays the status\n"
-"   type: displays the service type\n"
-"   description: displays the description\n"
-"   source: displays the source of the service's frontend file\n"
-"   live: displays the service's live directory\n"
-"   depends: displays the service's dependencies\n"
-"   requiredby: displays the service(s) which depends on service\n"
-"   extdepends: displays the service's external dependencies\n"
-"   optsdepends: displays the service's optional dependencies\n"
-"   start: displays the service's start script\n"
-"   stop: displays the service's stop script\n"
-"   envat: displays the source of the environment file\n"
-"   envfile: displays the contents of the environment file\n"
-"   logname: displays the logger's name\n"
-"   logdst: displays the logger's destination\n"
-"   logfile: displays the contents of the log file\n"
+"options:\n"
+"   -h: print this help\n"
+"   -f: fork the process\n"
 ;
 
-/**
- *
- * pass -g as default
- * -d -g -p become -o depth=,graph=none,reverse=,nline=
- *
- *
- * */
-char const *usage_service_wrapper = "66 service [ -h ] [ -z ] [ -v verbosity ] [ -t tree ] status|resolve|state|remove [ -n ] [ -o name,intree,status,... ] [ -g ] [ -d depth ] [ -r ]  [ -p nline ] service" ;
+char const *usage_service_wrapper = "66 service [ -h ] status|resolve|state|remove [<command options>] service..." ;
 
 char const *help_service_wrapper =
+"\nmain sub tools to view and manages services\n"
+"\n"
+"options :\n"
+"   -h: print this help\n"
+"\n"
+"command:\n"
+"   status: displays information of the service\n"
+"   resolve: displays the resolve file of the service\n"
+"   state: displays the state file of the service\n"
+"   remove: remove and cleanup the service\n"
+"\n"
+"Use '66 service <command> -h' to see command options\n"
+;
+
+char const *usage_service_status = "66 service status [ -h ] [ -n ] [ -o name,intree,status,... ] [ -g ] [ -d depth ] [ -r ] [ -p nline ] service..." ;
+
+char const *help_service_status =
+"\ndisplay services informations\n"
 "\n"
 "options :\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
 "   -n: do not display the field name\n"
-"   -o: comma separated list of field to display\n"
+"   -o: comma separated list of options\n"
 "   -g: displays the contents field as graph\n"
 "   -d: limit the depth of the contents field recursion\n"
 "   -r: reverse the contents field\n"
-"   -t: only search service at the specified tree\n"
 "   -p: print n last lines of the log file\n"
 "\n"
 "valid fields for -o options are:\n"
@@ -344,7 +435,6 @@ char const *help_service_wrapper =
 "   live: displays the service's live directory\n"
 "   depends: displays the service's dependencies\n"
 "   requiredby: displays the service(s) which depends on service\n"
-"   extdepends: displays the service's external dependencies\n"
 "   optsdepends: displays the service's optional dependencies\n"
 "   start: displays the service's start script\n"
 "   stop: displays the service's stop script\n"
@@ -355,53 +445,53 @@ char const *help_service_wrapper =
 "   logfile: displays the contents of the log file\n"
 ;
 
-char const *usage_service_admin = "66 service remove [ -h ] service" ;
+char const *usage_service_resolve = "66 service resolve [ -h ] service" ;
 
-char const *help_service_admin =
+char const *help_service_resolve =
+"\ndisplay the resolve files contents of services\n"
 "\n"
-"options :\n"
+"options:\n"
 "   -h: print this help\n"
 ;
 
-char const *usage_boot = "66 boot [ -h ] [ -z ] [ -m ] [ -s skel ] [ -l log_user ] [ -e environment ] [ -d dev ] [ -b banner ]" ;
+char const *usage_service_state = "66 service state [ -h ] service" ;
 
-char const *help_boot =
+char const *help_service_state =
+"\ndisplay state files contents of services\n"
+"\n"
+"options:\n"
+"   -h: print this help\n"
+;
+
+char const *usage_service_remove = "66 service remove [ -h ] service" ;
+
+char const *help_service_remove =
+"\nremove services and cleanup all files belong to it from the system\n"
 "\n"
 "options :\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -m: mount parent live directory\n"
-"   -s: skeleton directory\n"
-"   -l: run catch-all logger as log_user user\n"
-"   -e: environment directory or file\n"
-"   -d: dev directory\n"
-"   -b: banner to display\n"
 ;
 
-char const *usage_scanctl = "66 scanctl [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -d notif ] [ -t rescan ] [ -e environment ] [ -o owner ] start|stop|reload|quit|nuke|zombies or any s6-svscanctl options" ;
+char const *usage_scanctl = "66 scanctl [ -d notif ] [ -t rescan ] [ -e environment ] [ -o owner ] start|stop|reload|quit|nuke|zombies or any s6-svscanctl options" ;
 
 char const *help_scanctl =
+"\nsend signal to scandir\n"
 "\n"
 "options :\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
 "   -d: notify readiness on file descriptor\n"
 "   -t: rescan scandir every milliseconds\n"
 "   -e: environment directory\n"
 "   -o: handles scandir of owner\n"
 ;
 
-char const *usage_scandir = "66 scandir [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -b|B ] [ -c ] [ -L log_user ] [ -s skel ] [ -o owner ] create|remove" ;
+char const *usage_scandir = "66 scandir [ -h ] [ -b|B ] [ -c ] [ -L log_user ] [ -s skel ] [ -o owner ] create|remove" ;
 
 char const *help_scandir =
+"\nmanage a scandir\n"
 "\n"
-"options :\n"
+"options:\n"
 "   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
 "   -b: create scandir for a boot process\n"
 "   -B: create scandir for a boot process inside a container\n"
 "   -c: do not catch log\n"
@@ -409,5 +499,3 @@ char const *help_scandir =
 "   -s: skeleton directory\n"
 "   -o: handles owner scandir\n"
 ;
-
-char const *usage_66 = "66 start|stop|reload|restart|unsupervise|reconfigure|enable|disable|env|service|tree|init|parse|svctl|scanctl|scandir|boot|version service(s)|tree" ;
diff --git a/src/lib66/exec/ssexec_init.c b/src/lib66/exec/ssexec_init.c
index 3e65fbbc..68bf2156 100644
--- a/src/lib66/exec/ssexec_init.c
+++ b/src/lib66/exec/ssexec_init.c
@@ -143,11 +143,10 @@ int ssexec_init(int argc, char const *const *argv, ssexec_t *info)
     uint8_t earlier = 0 ;
     char const *treename = 0 ;
 
-
     stralloc sa = STRALLOC_ZERO ;
 
     if (argc < 2 || !argv[1])
-        log_usage(usage_init) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     treename = argv[1] ;
     size_t treenamelen = strlen(treename) ;
diff --git a/src/lib66/exec/ssexec_inservice.c b/src/lib66/exec/ssexec_inservice.c
index 732d4d06..549a7245 100644
--- a/src/lib66/exec/ssexec_inservice.c
+++ b/src/lib66/exec/ssexec_inservice.c
@@ -879,21 +879,21 @@ int ssexec_inservice(int argc, char const *const *argv, ssexec_t *info)
             int opt = subgetopt_r(argc,argv, OPTS_INSERVICE, &l) ;
             if (opt == -1) break ;
 
-            switch (opt)
-            {
+            switch (opt) {
+
                 case 'n' :  NOFIELD = 0 ; break ;
                 case 'o' :  legacy = 0 ; info_parse_options(l.arg,what) ; break ;
                 case 'g' :  GRAPH = 1 ; break ;
                 case 'r' :  REVERSE = 1 ; break ;
-                case 'd' :  if (!uint0_scan(l.arg, &MAXDEPTH)) log_usage(usage_inservice) ; break ;
-                case 'p' :  if (!uint0_scan(l.arg, &nlog)) log_usage(usage_inservice) ; break ;
-                default :   log_usage(usage_inservice) ;
+                case 'd' :  if (!uint0_scan(l.arg, &MAXDEPTH)) log_usage(usage_service_status, "\n", help_service_status) ; break ;
+                case 'p' :  if (!uint0_scan(l.arg, &nlog)) log_usage(usage_service_status, "\n", help_service_status) ; break ;
+                default :   log_usage(usage_service_status, "\n", help_service_status) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
-    if (!argc) log_usage(usage_inservice) ;
+    if (!argc) log_usage(usage_service_status, "\n", help_service_status) ;
     svname = *argv ;
 
     if (legacy)
diff --git a/src/lib66/exec/ssexec_instate.c b/src/lib66/exec/ssexec_instate.c
index 312794e9..105682c8 100644
--- a/src/lib66/exec/ssexec_instate.c
+++ b/src/lib66/exec/ssexec_instate.c
@@ -41,20 +41,6 @@ static char fields[INFO_NKEY][INFO_FIELD_MAXLEN] = {{ 0 }} ;
 
 #define USAGE "66-instate [ -h ] [ -v verbosity ] [ -z ] service"
 
-static inline void info_help (void)
-{
-    DEFAULT_MSG = 0 ;
-
-    static char const *help =
-"\n"
-"options :\n"
-"   -h: print this help\n"
-"   -z: use color\n"
-"   -t: only search service at the specified tree\n"
-;
-
-    log_info(USAGE,"\n",help) ;
-}
 
 static void info_display_string(char const *field,char const *str)
 {
@@ -110,7 +96,7 @@ int ssexec_instate(int argc, char const *const *argv, ssexec_t *info)
     argc-- ;
     argv++ ;
 
-    if (!argc) log_usage(usage_instate) ;
+    if (!argc) log_usage(usage_service_state, "\n", help_service_state) ;
     svname = *argv ;
 
     if (!set_ownersysdir_stack(base, getuid()))
diff --git a/src/lib66/exec/ssexec_intree.c b/src/lib66/exec/ssexec_intree.c
index 8208a16a..c6ea85c6 100644
--- a/src/lib66/exec/ssexec_intree.c
+++ b/src/lib66/exec/ssexec_intree.c
@@ -530,11 +530,11 @@ int ssexec_intree(int argc, char const *const *argv, ssexec_t *info)
                 case 'o' :  legacy = 0 ; info_parse_options(l.arg,what) ; break ;
                 case 'g' :  GRAPH = 1 ; break ;
                 case 'r' :  REVERSE = 1 ; break ;
-                case 'd' :  if (!uint0_scan(l.arg, &MAXDEPTH)) log_usage(usage_intree) ; break ;
-                case 'l' :  if (!stralloc_cats(&live,l.arg)) log_usage(usage_intree) ;
-                            if (!stralloc_0(&live)) log_usage(usage_intree) ;
+                case 'd' :  if (!uint0_scan(l.arg, &MAXDEPTH)) log_usage(info->usage, "\n", info->help) ; break ;
+                case 'l' :  if (!stralloc_cats(&live,l.arg)) log_usage(info->usage, "\n", info->help) ;
+                            if (!stralloc_0(&live)) log_usage(info->usage, "\n", info->help) ;
                             break ;
-                default :   log_usage(usage_intree) ;
+                default :   log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
diff --git a/src/lib66/exec/ssexec_parse.c b/src/lib66/exec/ssexec_parse.c
index 7cacac78..d5478253 100644
--- a/src/lib66/exec/ssexec_parse.c
+++ b/src/lib66/exec/ssexec_parse.c
@@ -44,11 +44,16 @@ int ssexec_parse(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt)
             {
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'f' :
 
                     /** only rewrite the service itself */
                     if (force)
-                        log_usage(usage_enable) ;
+                        log_usage(info->usage, "\n", info->help) ;
                     force = 1 ;
                     break ;
 
@@ -56,7 +61,7 @@ int ssexec_parse(int argc, char const *const *argv, ssexec_t *info)
 
                      /** force to rewrite it dependencies */
                      if (force)
-                        log_usage(usage_enable) ;
+                        log_usage(info->usage, "\n", info->help) ;
                     force = 2 ;
                     break ;
 
@@ -70,14 +75,14 @@ int ssexec_parse(int argc, char const *const *argv, ssexec_t *info)
                 case 'C' :  log_1_warn("deprecated option -- ignoring") ; break ;
 
                 default :
-                    log_usage(usage_parse) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_parse) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     for (; *argv ; argv++) {
 
diff --git a/src/lib66/exec/ssexec_reconfigure.c b/src/lib66/exec/ssexec_reconfigure.c
index 036105f1..cac1601e 100644
--- a/src/lib66/exec/ssexec_reconfigure.c
+++ b/src/lib66/exec/ssexec_reconfigure.c
@@ -29,21 +29,7 @@
 #include <66/service.h>
 
 #include <stdio.h>
-/**
- *
- *
- * ./66 reconfigure consolekit provoque une erreur
- *
- *
- *
- *
- * reconfigure(src/lib66/svc/svc_scandir_send.c: svc_scandir_send(): 34): tracing: send signal: an to scandir: /run/66/state/0/dbus-log/scandir
- * reconfigure(src/lib66/svc/svc_scandir_send.c: svc_scandir_send(): 37): warning: unable to control: /run/66/state/0/dbus-log/scandir: No such file or directory
- * reconfigure(src/lib66/sanitize/sanitize_scandir.c: sanitize_scandir(): 150): fatal: unable to reload scandir: /run/66/state/0/dbus-log/scandir
- *
- *
- *
- * */
+
 int ssexec_reconfigure(int argc, char const *const *argv, ssexec_t *info)
 {
     log_flow() ;
@@ -69,6 +55,11 @@ int ssexec_reconfigure(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
 
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'P' :
 
                     siglen++ ;
@@ -76,14 +67,14 @@ int ssexec_reconfigure(int argc, char const *const *argv, ssexec_t *info)
 
                 default :
 
-                    log_usage(usage_start) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_start) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     if ((svc_scandir_ok(info->scandir.s)) !=  1 )
         log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s, " is not running") ;
diff --git a/src/lib66/exec/ssexec_reload.c b/src/lib66/exec/ssexec_reload.c
index 0aa20c07..54f666fe 100644
--- a/src/lib66/exec/ssexec_reload.c
+++ b/src/lib66/exec/ssexec_reload.c
@@ -54,6 +54,12 @@ int ssexec_reload(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
 
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
+
                 case 'P' :
 
                     FLAGS_CLEAR(flag, STATE_FLAGS_TOPROPAGATE) ;
@@ -62,14 +68,14 @@ int ssexec_reload(int argc, char const *const *argv, ssexec_t *info)
 
                 default :
 
-                    log_usage(usage_start) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_start) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     if ((svc_scandir_ok(info->scandir.s)) !=  1 )
         log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s, " is not running") ;
diff --git a/src/lib66/exec/ssexec_resolve_service.c b/src/lib66/exec/ssexec_resolve_service.c
index adec8d4a..e50af0bf 100644
--- a/src/lib66/exec/ssexec_resolve_service.c
+++ b/src/lib66/exec/ssexec_resolve_service.c
@@ -170,7 +170,7 @@ int ssexec_resolve_service(int argc, char const *const *argv, ssexec_t *info)
     argv++ ;
 
     if (argc < 1)
-        log_usage(usage_inresolve) ;
+        log_usage(usage_service_resolve, "\n", help_service_resolve) ;
 
     svname = *argv ;
 
diff --git a/src/lib66/exec/ssexec_resolve_tree.c b/src/lib66/exec/ssexec_resolve_tree.c
index 3298d712..b632554f 100644
--- a/src/lib66/exec/ssexec_resolve_tree.c
+++ b/src/lib66/exec/ssexec_resolve_tree.c
@@ -80,7 +80,6 @@ int ssexec_resolve_tree(int argc, char const *const *argv, ssexec_t *info)
     uint8_t master = 0 ;
 
     char const *svname = 0 ;
-    char const *treename = info->treename.s ;
 
     resolve_wrapper_t_ref wres = 0 ;
     resolve_tree_t tres = RESOLVE_TREE_ZERO ;
@@ -90,7 +89,7 @@ int ssexec_resolve_tree(int argc, char const *const *argv, ssexec_t *info)
     argv++ ;
 
     if (argc < 1)
-        log_usage(usage_inresolve) ;
+        log_usage(usage_tree_resolve, "\n", help_tree_resolve) ;
 
     svname = *argv ;
 
diff --git a/src/lib66/exec/ssexec_restart.c b/src/lib66/exec/ssexec_restart.c
index d8f6ac43..604b3b55 100644
--- a/src/lib66/exec/ssexec_restart.c
+++ b/src/lib66/exec/ssexec_restart.c
@@ -54,6 +54,11 @@ int ssexec_restart(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
 
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'P' :
 
                     FLAGS_CLEAR(flag, STATE_FLAGS_TOPROPAGATE) ;
@@ -62,14 +67,14 @@ int ssexec_restart(int argc, char const *const *argv, ssexec_t *info)
 
                 default :
 
-                    log_usage(usage_start) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_start) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     if ((svc_scandir_ok(info->scandir.s)) !=  1 )
         log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s, " is not running") ;
diff --git a/src/lib66/exec/ssexec_scanctl.c b/src/lib66/exec/ssexec_scanctl.c
index d706a21a..76c69201 100644
--- a/src/lib66/exec/ssexec_scanctl.c
+++ b/src/lib66/exec/ssexec_scanctl.c
@@ -177,6 +177,11 @@ int ssexec_scanctl(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
 
+                 case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'o' :
 
                     if (MYUID)
@@ -216,13 +221,13 @@ int ssexec_scanctl(int argc, char const *const *argv, ssexec_t *info)
 
                 default :
 
-                    log_usage(usage_scanctl) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
-    if (argc < 1) log_usage(usage_scanctl) ;
+    if (argc < 1) log_usage(info->usage, "\n", info->help) ;
     signal = argv[0] ;
     r = set_livedir(&scandir) ;
     if (r < 0) log_die(LOG_EXIT_USER,"live: ",scandir.s," must be an absolute path") ;
diff --git a/src/lib66/exec/ssexec_scandir.c b/src/lib66/exec/ssexec_scandir.c
index f870ac2b..8d57f2c4 100644
--- a/src/lib66/exec/ssexec_scandir.c
+++ b/src/lib66/exec/ssexec_scandir.c
@@ -75,28 +75,6 @@ static int BUF_FD ; // general buffer fd
 
 #define USAGE "66-scandir [ -h ] [ -z ] [ -v verbosity ] [ -l live ] [ -b|B ] [ -c ] [ -L log_user ] [ -s skel ] [ -o owner ] create|remove"
 
-static inline void info_help (void)
-{
-    DEFAULT_MSG = 0 ;
-
-    static char const *help =
-"\n"
-"options :\n"
-"   -h: print this help\n"
-"   -z: use color\n"
-"   -v: increase/decrease verbosity\n"
-"   -l: live directory\n"
-"   -b: create scandir for a boot process\n"
-"   -B: create scandir for a boot process inside a container\n"
-"   -c: do not catch log\n"
-"   -L: run catch-all logger as log_user user\n"
-"   -s: skeleton directory\n"
-"   -o: handles owner scandir\n"
-;
-
-    log_info(USAGE,"\n",help) ;
-}
-
 static inline unsigned int lookup (char const *const *table, char const *signal)
 {
     log_flow() ;
@@ -788,6 +766,11 @@ int ssexec_scandir(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt)
             {
+                 case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'b' :
 
                     BOOT = 1 ;
@@ -832,14 +815,14 @@ int ssexec_scandir(int argc, char const *const *argv, ssexec_t *info)
 
                 default :
 
-                    log_usage(usage_scandir) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (!argc)
-        log_usage(usage_scandir) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     cmd = parse_command(argv[0]) ;
 
diff --git a/src/lib66/exec/ssexec_service_admin.c b/src/lib66/exec/ssexec_service_admin.c
index 4e6dadb0..d54fb548 100644
--- a/src/lib66/exec/ssexec_service_admin.c
+++ b/src/lib66/exec/ssexec_service_admin.c
@@ -21,26 +21,17 @@
 #include <66/ssexec.h>
 #include <66/config.h>
 
-static inline void info_help (char const *help,char const *usage)
-{
-    log_flow() ;
-
-    DEFAULT_MSG = 0 ;
-
-    log_info(usage,"\n", help) ;
-}
-
 int ssexec_service_admin(int argc, char const *const *argv, ssexec_t *info)
 {
     log_flow() ;
 
     if (!argv[1]) {
         PROG = "service" ;
-        log_usage(usage_service_wrapper) ;
+        log_usage(usage_service_remove, "\n", help_service_remove) ;
     }
 
     int r, n = 0, i = 0 ;
-    uint8_t ctl = 0 ;
+/*    uint8_t ctl = 0 ;
     ssexec_func_t_ref func = 0 ;
     char const *nargv[argc + 1] ;
 
@@ -94,7 +85,7 @@ int ssexec_service_admin(int argc, char const *const *argv, ssexec_t *info)
 
     } else {
 
-        log_usage(usage_tree) ;
+        log_usage(usage_service_admin, "\n", help_service_admin) ;
     }
 
     {
@@ -103,15 +94,10 @@ int ssexec_service_admin(int argc, char const *const *argv, ssexec_t *info)
         int f = 0 ;
         for (;;) {
 
-            int opt = subgetopt_r(argc, argv, "-h", &l) ;
+            int opt = subgetopt_r(argc, argv, "", &l) ;
             if (opt == -1) break ;
             switch (opt) {
 
-                case 'h' :
-
-                    info_help(info->help, info->usage) ;
-                    return 0 ;
-
                 default:
 
                     for (i = 0 ; i < n ; i++) {
@@ -159,10 +145,10 @@ int ssexec_service_admin(int argc, char const *const *argv, ssexec_t *info)
 
     if (ctl) {
         /* swap the command and options e.g.
-         * down -f <treename> <-> -f down <treename> */
+         * down -f <treename> <-> -f down <treename>
         if (n > 2) {
             /* swap the command and options e.g.
-             * down -f <-> -f down */
+             * down -f <-> -f down
             nargv[n] = nargv[n-1] ;
             nargv[n-1] = nargv[0] ;
             nargv[++n] = 0 ;
@@ -179,6 +165,7 @@ int ssexec_service_admin(int argc, char const *const *argv, ssexec_t *info)
     }
 
     r = (*func)(n, nargv, info) ;
-
+*/
+r = 0 ;
     return r ;
 }
diff --git a/src/lib66/exec/ssexec_service_wrapper.c b/src/lib66/exec/ssexec_service_wrapper.c
index 26e8407d..0c5605c5 100644
--- a/src/lib66/exec/ssexec_service_wrapper.c
+++ b/src/lib66/exec/ssexec_service_wrapper.c
@@ -21,22 +21,13 @@
 #include <66/ssexec.h>
 #include <66/config.h>
 
-static inline void info_help (char const *help,char const *usage)
-{
-    log_flow() ;
-
-    DEFAULT_MSG = 0 ;
-
-    log_info(usage,"\n", help) ;
-}
-
 int ssexec_service_wrapper(int argc, char const *const *argv, ssexec_t *info)
 {
     log_flow() ;
 
     if (!argv[1]) {
         PROG = "service" ;
-        log_usage(usage_service_wrapper) ;
+        log_usage(usage_service_wrapper, "\n", help_service_wrapper) ;
     }
 
     int r, n = 0, i = 0 ;
@@ -47,56 +38,48 @@ int ssexec_service_wrapper(int argc, char const *const *argv, ssexec_t *info)
     if (!strcmp(argv[1], "status")) {
 
         nargv[n++] = PROG ;
-
         info->prog = PROG ;
-        info->help = help_inservice ;
-        info->usage = usage_inservice ;
+        info->help = help_service_status ;
+        info->usage = usage_service_status ;
         func = &ssexec_inservice ;
 
-        argc-- ;
-        argv++ ;
-
     } else if (!strcmp(argv[1], "resolve")) {
 
         nargv[n++] = PROG ;
-
         info->prog = PROG ;
-        info->help = help_inresolve ;
-        info->usage = usage_inresolve ;
+        info->help = help_service_resolve ;
+        info->usage = usage_service_resolve ;
         func = &ssexec_resolve_service ;
 
-        argc-- ;
-        argv++ ;
-
     } else if (!strcmp(argv[1], "state")) {
 
         nargv[n++] = PROG ;
-
         info->prog = PROG ;
-        info->help = help_instate ;
-        info->usage = usage_instate ;
+        info->help = help_service_state ;
+        info->usage = usage_service_state ;
         func = &ssexec_instate ;
 
-        argc-- ;
-        argv++ ;
-
     } else if (!strcmp(argv[1], "remove")) {
 
         nargv[n++] = PROG ;
-
         info->prog = PROG ;
-        info->help = help_instate ;
-        info->usage = usage_instate ;
+        info->help = help_service_remove ;
+        info->usage = usage_service_remove ;
         func = &ssexec_service_admin ;
 
-        argc-- ;
-        argv++ ;
-
     } else {
 
-        log_usage(usage_tree) ;
+        if (!strcmp(argv[1], "-h")) {
+            info_help(help_service_wrapper, usage_service_wrapper) ;
+            return 0 ;
+        }
+
+        log_usage(usage_service_wrapper, "\n", help_service_wrapper) ;
     }
 
+    argc-- ;
+    argv++ ;
+
     {
         subgetopt l = SUBGETOPT_ZERO ;
 
@@ -152,6 +135,9 @@ int ssexec_service_wrapper(int argc, char const *const *argv, ssexec_t *info)
         argc -= l.ind ; argv += l.ind ;
     }
 
+    if (argc < 1)
+        log_usage(info->usage, "\n", info->help) ;
+
     for (i = 0 ; i < argc ; i++ , argv++)
         nargv[n++] = *argv ;
 
diff --git a/src/lib66/exec/ssexec_start.c b/src/lib66/exec/ssexec_start.c
index 7268b8ce..82d4df67 100644
--- a/src/lib66/exec/ssexec_start.c
+++ b/src/lib66/exec/ssexec_start.c
@@ -52,6 +52,11 @@ int ssexec_start(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
 
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'P' :
 
                     FLAGS_CLEAR(flag, STATE_FLAGS_TOPROPAGATE) ;
@@ -60,14 +65,14 @@ int ssexec_start(int argc, char const *const *argv, ssexec_t *info)
 
                 default :
 
-                    log_usage(usage_start) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_start) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     if ((svc_scandir_ok(info->scandir.s)) !=  1 )
         log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s, " is not running") ;
diff --git a/src/lib66/exec/ssexec_stop.c b/src/lib66/exec/ssexec_stop.c
index ce2ceb0d..b632b6d3 100644
--- a/src/lib66/exec/ssexec_stop.c
+++ b/src/lib66/exec/ssexec_stop.c
@@ -53,6 +53,11 @@ int ssexec_stop(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
 
+                case 'h' :
+
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
+
                 case 'P' :
 
                     FLAGS_CLEAR(flag, STATE_FLAGS_TOPROPAGATE) ;
@@ -75,14 +80,14 @@ int ssexec_stop(int argc, char const *const *argv, ssexec_t *info)
                     return 0 ;
 
                 default :
-                    log_usage(usage_stop) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_stop) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     if ((svc_scandir_ok(info->scandir.s)) != 1)
         log_diesys(LOG_EXIT_SYS,"scandir: ", info->scandir.s," is not running") ;
diff --git a/src/lib66/exec/ssexec_svctl.c b/src/lib66/exec/ssexec_svctl.c
index 4ef157b6..6ca3f14f 100644
--- a/src/lib66/exec/ssexec_svctl.c
+++ b/src/lib66/exec/ssexec_svctl.c
@@ -838,6 +838,9 @@ int ssexec_svctl(int argc, char const *const *argv, ssexec_t *info)
             if (opt == -1) break ;
 
             switch (opt) {
+                case 'h' :
+                    info_help(info->help, info->usage) ;
+                    return 0 ;
 
                 case 'a' :
                 case 'b' :
@@ -867,7 +870,7 @@ int ssexec_svctl(int argc, char const *const *argv, ssexec_t *info)
                 case 'w' :
 
                     if (!memchr("dDuUrR", l.arg[0], 6))
-                        log_usage(usage_svctl) ;
+                        log_usage(info->usage, "\n", info->help) ;
 
                     updown[2] = l.arg[0] ;
                     opt_updown = 1 ;
@@ -878,14 +881,14 @@ int ssexec_svctl(int argc, char const *const *argv, ssexec_t *info)
                     break ;
 
                 default :
-                    log_usage(usage_svctl) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1 || datalen < 2)
-        log_usage(usage_svctl) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     if (info->timeout)
         tain_from_millisecs(&deadline, info->timeout) ;
diff --git a/src/lib66/exec/ssexec_tree.c b/src/lib66/exec/ssexec_tree.c
index f54591ae..6e9c6cce 100644
--- a/src/lib66/exec/ssexec_tree.c
+++ b/src/lib66/exec/ssexec_tree.c
@@ -1331,13 +1331,14 @@ int ssexec_tree(int argc, char const *const *argv, ssexec_t *info)
 
                 default :
 
-                    log_usage(usage_tree) ;
+                    log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
-    if (argc < 1) log_usage(usage_tree) ;
+    if (argc < 1)
+        log_usage(info->usage, "\n", info->help) ;
 
     check_identifier(argv[0]) ;
 
diff --git a/src/lib66/exec/ssexec_tree_wrapper.c b/src/lib66/exec/ssexec_tree_wrapper.c
index bc323524..f7abc149 100644
--- a/src/lib66/exec/ssexec_tree_wrapper.c
+++ b/src/lib66/exec/ssexec_tree_wrapper.c
@@ -21,22 +21,13 @@
 #include <66/ssexec.h>
 #include <66/config.h>
 
-static inline void info_help (char const *help,char const *usage)
-{
-    log_flow() ;
-
-    DEFAULT_MSG = 0 ;
-
-    log_info(usage,"\n", help) ;
-}
-
 int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
 {
     log_flow() ;
 
     if (!argv[1]) {
         PROG = "tree" ;
-        log_usage(usage_tree) ;
+        log_usage(usage_tree_wrapper, "\n", help_tree_wrapper) ;
     }
 
     int r, n = 0, i = 0 ;
@@ -49,8 +40,8 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
         nargv[n++] = PROG ;
 
         info->prog = PROG ;
-        info->help = help_tree ;
-        info->usage = usage_tree ;
+        info->help = help_tree_create ;
+        info->usage = usage_tree_create ;
         func = &ssexec_tree ;
 
         argc-- ;
@@ -61,8 +52,8 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
         nargv[n++] = PROG ;
 
         info->prog = PROG ;
-        info->help = help_tree ;
-        info->usage = usage_tree ;
+        info->help = help_tree_admin ;
+        info->usage = usage_tree_admin ;
         func = &ssexec_tree ;
 
         argc-- ;
@@ -74,8 +65,8 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
         nargv[n++] = "-R" ;
 
         info->prog = PROG ;
-        info->help = help_tree ;
-        info->usage = usage_tree ;
+        info->help = help_tree_remove ;
+        info->usage = usage_tree_remove ;
         func = &ssexec_tree ;
 
         argc-- ;
@@ -87,8 +78,8 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
         nargv[n++] = "-E" ;
 
         info->prog = PROG ;
-        info->help = help_tree ;
-        info->usage = usage_tree ;
+        info->help = help_tree_enable ;
+        info->usage = usage_tree_enable ;
         func = &ssexec_tree ;
 
         argc-- ;
@@ -100,8 +91,8 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
         nargv[n++] = "-D" ;
 
         info->prog = PROG ;
-        info->help = help_tree ;
-        info->usage = usage_tree ;
+        info->help = help_tree_disable ;
+        info->usage = usage_tree_disable ;
 
         func = &ssexec_tree ;
 
@@ -114,8 +105,8 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
         nargv[n++] = "-c" ;
 
         info->prog = PROG ;
-        info->help = help_tree ;
-        info->usage = usage_tree ;
+        info->help = help_tree_current ;
+        info->usage = usage_tree_current ;
 
         func = &ssexec_tree ;
 
@@ -127,8 +118,8 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
         nargv[n++] = PROG ;
 
         info->prog = PROG ;
-        info->help = help_inresolve ;
-        info->usage = usage_inresolve ;
+        info->help = help_tree_resolve ;
+        info->usage = usage_tree_resolve ;
 
         func = &ssexec_resolve_tree ;
 
@@ -140,8 +131,8 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
         nargv[n++] = PROG ;
 
         info->prog = PROG ;
-        info->help = help_intree ;
-        info->usage = usage_intree ;
+        info->help = help_tree_status ;
+        info->usage = usage_tree_status ;
 
         func = &ssexec_intree ;
 
@@ -151,30 +142,35 @@ int ssexec_tree_wrapper(int argc, char const *const *argv, ssexec_t *info)
     } else if (!strcmp(argv[1], "up")) {
 
         info->prog = PROG ;
-        info->help = help_treectl ;
-        info->usage = usage_treectl ;
+        info->help = help_tree_up ;
+        info->usage = usage_tree_up ;
         func = &ssexec_treectl ;
         ctl++ ;
 
     } else if (!strcmp(argv[1], "down")) {
 
         info->prog = PROG ;
-        info->help = help_treectl ;
-        info->usage = usage_treectl ;
+        info->help = help_tree_down ;
+        info->usage = usage_tree_down ;
         func = &ssexec_treectl ;
         ctl++ ;
 
     } else if (!strcmp(argv[1], "unsupervise")) {
 
         info->prog = PROG ;
-        info->help = help_treectl ;
-        info->usage = usage_treectl ;
+        info->help = help_tree_unsupervise ;
+        info->usage = usage_tree_unsupervise ;
         func = &ssexec_treectl ;
         ctl++ ;
 
     } else {
 
-        log_usage(usage_tree) ;
+        if (!strcmp(argv[1], "-h")) {
+            info_help(help_tree_wrapper, usage_tree_wrapper) ;
+            return 0 ;
+        }
+
+        log_usage(usage_tree_wrapper, "\n", help_tree_wrapper) ;
     }
 
     {
diff --git a/src/lib66/exec/ssexec_treectl.c b/src/lib66/exec/ssexec_treectl.c
index 31d9da9f..4c86ffb8 100644
--- a/src/lib66/exec/ssexec_treectl.c
+++ b/src/lib66/exec/ssexec_treectl.c
@@ -139,7 +139,7 @@ static inline unsigned int lookup (char const *const *table, char const *signal)
     return i ;
 }
 
-static inline unsigned int parse_signal (char const *signal)
+static inline unsigned int parse_signal (char const *signal, ssexec_t *info)
 {
     log_flow() ;
 
@@ -150,7 +150,7 @@ static inline unsigned int parse_signal (char const *signal)
         0
     } ;
     unsigned int i = lookup(signal_table, signal) ;
-    if (!signal_table[i]) log_usage(usage_treectl) ;
+    if (!signal_table[i]) log_usage(info->usage, "\n", info->help) ;
     return i ;
 }
 
@@ -872,14 +872,14 @@ int ssexec_treectl(int argc, char const *const *argv, ssexec_t *info)
 
             switch (opt) {
                 case 'f' :  shut = 1 ; break ;
-                default :   log_usage(usage_treectl) ;
+                default :   log_usage(info->usage, "\n", info->help) ;
             }
         }
         argc -= l.ind ; argv += l.ind ;
     }
 
     if (argc < 1)
-        log_usage(usage_treectl) ;
+        log_usage(info->usage, "\n", info->help) ;
 
     info->treename.len = 0 ;
 
@@ -893,7 +893,7 @@ int ssexec_treectl(int argc, char const *const *argv, ssexec_t *info)
     else
         deadline = tain_infinite_relative ;
 
-    what = parse_signal(*argv) ;
+    what = parse_signal(*argv, info) ;
 
     reloadmsg = what ;
 
diff --git a/src/lib66/svc/svc_send_wait.c b/src/lib66/svc/svc_send_wait.c
index 36e9e6b3..13cd9d18 100644
--- a/src/lib66/svc/svc_send_wait.c
+++ b/src/lib66/svc/svc_send_wait.c
@@ -34,11 +34,11 @@ int svc_send_wait(char const *const *list, unsigned int nservice, char **sig, un
     verbo[uint_fmt(verbo, VERBOSITY)] = 0 ;
 
     newargv[m++] = "66" ;
-    newargv[m++] = "svctl" ;
     if (info->opt_color)
         newargv[m++] = "-z" ;
     newargv[m++] = "-v" ;
     newargv[m++] = verbo ;
+    newargv[m++] = "signal" ;
 
     for (; *sig ; sig++)
         newargv[m++] = *sig ;
-- 
GitLab