diff --git a/src/66/66-inservice.c b/src/66/66-inservice.c
index 8280fab02a97695b25b380e04ad685dbac6734d3..334155f3560f5bac3b457718e7c8a8dd418c14be 100644
--- a/src/66/66-inservice.c
+++ b/src/66/66-inservice.c
@@ -21,7 +21,6 @@
 
 #include <oblibs/sastr.h>
 #include <oblibs/log.h>
-#include <oblibs/obgetopt.h>
 #include <oblibs/types.h>
 #include <oblibs/string.h>
 #include <oblibs/files.h>
@@ -33,6 +32,7 @@
 #include <skalibs/bytestr.h>
 #include <skalibs/djbunix.h>
 #include <skalibs/buffer.h>
+#include <skalibs/sgetopt.h>
 
 #include <66/info.h>
 #include <66/utils.h>
@@ -65,6 +65,7 @@ static void info_display_version(char const *field, ss_resolve_t *res) ;
 static void info_display_source(char const *field, ss_resolve_t *res) ;
 static void info_display_live(char const *field, ss_resolve_t *res) ;
 static void info_display_deps(char const *field, ss_resolve_t *res) ;
+static void info_display_requiredby(char const *field, ss_resolve_t *res) ;
 static void info_display_optsdeps(char const *field, ss_resolve_t *res) ;
 static void info_display_extdeps(char const *field, ss_resolve_t *res) ;
 static void info_display_start(char const *field, ss_resolve_t *res) ;
@@ -77,6 +78,356 @@ static void info_display_logfile(char const *field, ss_resolve_t *res) ;
 
 ss_resolve_graph_style *STYLE = &graph_default ;
 
+
+
+
+#include <stdlib.h> //a garder
+
+#include <stdio.h>// a effacer
+
+
+
+#include <oblibs/graph.h>
+
+
+
+
+
+
+typedef int ss_info_graph_func(char const *name, char const *obj) ;
+typedef ss_info_graph_func *ss_info_graph_func_t_ref ;
+
+int ss_info_graph_display_service(char const *name, char const *obj)
+{
+    stralloc tree = STRALLOC_ZERO ;
+    ss_resolve_t res = RESOLVE_ZERO ;
+
+    int r = ss_resolve_svtree(&tree, name, obj), err = 0 ;
+
+    if (r != 2) {
+        if (r == 1)
+            log_warnu("find: ", name, " at tree: ", !obj ? tree.s : obj) ;
+        if (r > 2)
+            log_1_warn(name, " is set on different tree -- please use -t options") ;
+
+        goto freed ;
+    }
+
+    if (!ss_resolve_check(tree.s, name))
+        goto freed ;
+
+    if (!ss_resolve_read(&res, tree.s, name))
+        goto freed ;
+
+    char str_pid[UINT_FMT] ;
+    uint8_t pid_color = 0 ;
+    char *ppid ;
+    ss_state_t sta = STATE_ZERO ;
+    s6_svstatus_t status = S6_SVSTATUS_ZERO ;
+
+    if (res.type == TYPE_CLASSIC || res.type == TYPE_LONGRUN) {
+
+        s6_svstatus_read(res.sa.s + res.runat ,&status) ;
+        pid_color = !status.pid ? 1 : 2 ;
+        str_pid[uint_fmt(str_pid, status.pid)] = 0 ;
+        ppid = &str_pid[0] ;
+
+    } else {
+
+        char *ste = res.sa.s + res.state ;
+        char *name = res.sa.s + res.name ;
+        if (!ss_state_check(ste,name)) {
+
+            ppid = "unitialized" ;
+            goto dis ;
+        }
+
+        if (!ss_state_read(&sta,ste,name)) {
+
+            log_warnu("read state of: ",name) ;
+            goto freed ;
+        }
+        if (sta.init) {
+
+            ppid = "unitialized" ;
+            goto dis ;
+
+        } else if (!sta.state) {
+
+            ppid = "down" ;
+            pid_color = 1 ;
+
+        } else if (sta.state) {
+
+            ppid = "up" ;
+            pid_color = 2 ;
+        }
+    }
+
+    dis:
+
+    if (!bprintf(buffer_1,"(%s%s%s,%s%s%s,%s) %s", \
+
+                pid_color > 1 ? log_color->valid : pid_color ? log_color->error : log_color->warning, \
+                ppid, \
+                log_color->off, \
+
+                res.disen ? log_color->off : log_color->error, \
+                res.disen ? "Enabled" : "Disabled", \
+                log_color->off, \
+
+                get_key_by_enum(ENUM_TYPE,res.type), \
+
+                name))
+                    goto freed ;
+
+    err = 1 ;
+
+    freed:
+        ss_resolve_free(&res) ;
+        stralloc_free(&tree) ;
+
+    return err ;
+
+}
+
+int ss_info_graph_display(char const *name, char const *obj, ss_info_graph_func *func, depth_t *depth, int last, int padding, ss_resolve_graph_style *style)
+{
+    log_flow() ;
+
+    int level = 1 ;
+
+    const char *tip = "" ;
+
+    tip = last ? style->last : style->tip ;
+
+    while(depth->prev)
+        depth = depth->prev ;
+
+    while(depth->next)
+    {
+        if (!bprintf(buffer_1,"%*s%-*s",style->indent * (depth->level - level) + (level == 1 ? padding : 0), "", style->indent, style->limb))
+            return 0 ;
+
+        level = depth->level + 1 ;
+        depth = depth->next ;
+    }
+
+    if (!bprintf(buffer_1,"%*s%*s%s", \
+                level == 1 ? padding : 0,"", \
+                style->indent * (depth->level - level), "", \
+                tip)) return 0 ;
+
+    int r = (*func)(name, obj) ;
+    if (!r) return 0 ;
+    if (buffer_putsflush(buffer_1,"\n") < 0)
+        return 0 ;
+
+    return 1 ;
+}
+
+/** make a list of edge ordered by start order
+ * Return the number of edge on success
+ * Return -1 on fail */
+int ss_info_walk_edge(stralloc *sa, graph_t *g, char const *name, uint8_t requiredby)
+{
+
+    size_t pos = 0 ;
+    int count = -1 ;
+
+    stralloc tmp = STRALLOC_ZERO ;
+    stralloc vertex = STRALLOC_ZERO ;
+    graph_t gc = GRAPH_ZERO ;
+
+    count = graph_matrix_get_edge_g(&vertex, g, name, requiredby) ;
+
+    if (count <= 0) {
+        count = 0 ;
+        goto freed ;
+    }
+
+    FOREACH_SASTR(&vertex, pos) {
+
+        char *ename = vertex.s + pos ;
+
+        if (!graph_vertex_add(&gc, ename)) {
+
+            log_warnu("add vertex: ",ename) ;
+            goto freed ;
+        }
+
+        sa->len = 0 ;
+
+        unsigned int c = graph_matrix_get_edge_g(sa, g, ename, requiredby) ;
+
+        if (c == -1)
+            { count = -1 ; goto freed ; }
+
+        {
+            size_t bpos = 0 ;
+
+            FOREACH_SASTR(sa, bpos) {
+
+                char *edge = sa->s + bpos ;
+
+                if (!graph_vertex_add_with_edge(&gc, ename, edge)) {
+
+                    log_warnu("add edge: ",ename," to vertex: ", edge) ;
+                    goto freed ;
+                }
+
+                if (!graph_vertex_add(&gc, edge)) {
+
+                    log_warnu("add vertex: ",edge) ;
+                    goto freed ;
+                }
+            }
+        }
+
+        if (!sastr_add_string(&tmp, ename))
+            { count = -1 ; goto freed ; } ;
+    }
+
+    if (!graph_matrix_build(&gc)) {
+
+        log_warnu("build the matrix") ;
+        goto freed ;
+    }
+
+    if (!graph_matrix_analyze_cycle(&gc)) {
+        log_warnu("found cycle") ;
+        goto freed ;
+    }
+    if (!graph_matrix_sort(&gc)) {
+
+        log_warnu("sort the matrix") ;
+        goto freed ;
+    }
+
+    count = sa->len = pos = 0 ;
+
+    for(; pos < gc.sort_count ; pos++) {
+
+        char *name = gc.data.s + genalloc_s(graph_hash_t,&gc.hash)[gc.sort[pos]].vertex ;
+
+        if (sastr_find(&tmp, name) >= 0) {
+            count++ ;
+            if (!sastr_add_string(sa, name))
+                { count = -1 ; goto freed ; }
+        }
+    }
+
+    freed:
+        stralloc_free(&vertex) ;
+        stralloc_free(&tmp) ;
+        graph_free_all(&gc) ;
+
+        return count ;
+}
+
+int ss_info_walk(graph_t *g, char const *name, char const *obj, ss_info_graph_func *func, uint8_t requiredby, uint8_t reverse, depth_t *depth, int padding, ss_resolve_graph_style *style)
+{
+    log_flow() ;
+
+    uint8_t e = 0 ;
+
+    if ((unsigned int) depth->level > MAXDEPTH)
+        return 1 ;
+
+    stralloc vertex = STRALLOC_ZERO ;
+    stralloc edge = STRALLOC_ZERO ;
+
+    int count = ss_info_walk_edge(&vertex, g, name, requiredby) ;
+
+    if (count == -1) goto err ;
+
+    if (!vertex.len)
+        goto freed ;
+
+    size_t pos = 0 ;
+    int idx = 0;
+
+    if (reverse)
+        if (!sastr_reverse(&vertex))
+            goto err ;
+
+    for (; pos < vertex.len ; pos += strlen(vertex.s + pos) + 1, idx++ ) {
+
+        int last =  idx + 1 < count  ? 0 : 1 ;
+        char *name = vertex.s + pos ;
+
+        if (!ss_info_graph_display(name, obj, func, depth, last, padding, style))
+            goto err ;
+
+        edge.len = 0 ;
+
+        if (ss_info_walk_edge(&edge, g, name, requiredby) == -1)
+            goto err ;
+
+        if (edge.len)
+        {
+            depth_t d =
+            {
+                depth,
+                NULL,
+                depth->level + 1
+            } ;
+            depth->next = &d;
+
+            if(last)
+            {
+                if(depth->prev)
+                {
+                    depth->prev->next = &d;
+                    d.prev = depth->prev;
+                    depth = &d;
+
+                }
+                else
+                    d.prev = NULL;
+            }
+            if (!ss_info_walk(g, name, obj, func, requiredby, reverse, &d, padding, style))
+                goto err ;
+            depth->next = NULL ;
+        }
+    }
+
+    freed:
+        e = 1 ;
+
+    err:
+        stralloc_free(&vertex) ;
+        stralloc_free(&edge) ;
+
+    return e ;
+
+}
+
+depth_t ss_info_graph_init(void)
+{
+    log_flow() ;
+
+    depth_t d = {
+        NULL,
+        NULL,
+        1
+    } ;
+
+    return d ;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
 info_opts_map_t const opts_sv_table[] =
 {
     { .str = "name", .svfunc = &info_display_name, .id = 0 },
@@ -88,19 +439,20 @@ info_opts_map_t const opts_sv_table[] =
     { .str = "source", .svfunc = &info_display_source, .id = 6 },
     { .str = "live", .svfunc = &info_display_live, .id = 7 },
     { .str = "depends", .svfunc = &info_display_deps, .id = 8 },
-    { .str = "extdepends", .svfunc = &info_display_extdeps, .id = 9 },
-    { .str = "optsdepends", .svfunc = &info_display_optsdeps, .id = 10 },
-    { .str = "start", .svfunc = &info_display_start, .id = 11 },
-    { .str = "stop", .svfunc = &info_display_stop, .id = 12 },
-    { .str = "envat", .svfunc = &info_display_envat, .id = 13 },
-    { .str = "envfile", .svfunc = &info_display_envfile, .id = 14 },
-    { .str = "logname", .svfunc = &info_display_logname, .id = 15 },
-    { .str = "logdst", .svfunc = &info_display_logdst, .id = 16 },
-    { .str = "logfile", .svfunc = &info_display_logfile, .id = 17 },
+    { .str = "requiredby", .svfunc = &info_display_requiredby, .id = 9 },
+    { .str = "extdepends", .svfunc = &info_display_extdeps, .id = 10 },
+    { .str = "optsdepends", .svfunc = &info_display_optsdeps, .id = 11 },
+    { .str = "start", .svfunc = &info_display_start, .id = 12 },
+    { .str = "stop", .svfunc = &info_display_stop, .id = 13 },
+    { .str = "envat", .svfunc = &info_display_envat, .id = 14 },
+    { .str = "envfile", .svfunc = &info_display_envfile, .id = 15 },
+    { .str = "logname", .svfunc = &info_display_logname, .id = 16 },
+    { .str = "logdst", .svfunc = &info_display_logdst, .id = 17 },
+    { .str = "logfile", .svfunc = &info_display_logfile, .id = 18 },
     { .str = 0, .svfunc = 0, .id = -1 }
 } ;
 
-#define MAXOPTS 19
+#define MAXOPTS 20
 #define checkopts(n) if (n >= MAXOPTS) log_die(LOG_EXIT_USER, "too many options")
 #define DELIM ','
 
@@ -124,7 +476,7 @@ static inline void info_help (void)
 "   -t: only search service at the specified tree\n"
 "   -p: print n last lines of the log file\n"
 "\n"
-"valid field for -o options are:\n"
+"valid fields for -o options are:\n"
 "\n"
 "   name: displays the name\n"
 "   version: displays the version of the service\n"
@@ -135,6 +487,7 @@ static inline void info_help (void)
 "   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"
@@ -320,74 +673,371 @@ static void info_display_live(char const *field,ss_resolve_t *res)
     info_display_string(res->sa.s + res->runat) ;
 }
 
-static void info_display_deps(char const *field, ss_resolve_t *res)
+
+/*
+int graph_service_compute_deps(stralloc *deps, char const *str)
 {
-    int r ;
-    size_t padding = 1, pos = 0, el ;
-    ss_resolve_t gres = RESOLVE_ZERO ;
-    ss_resolve_graph_t graph = RESOLVE_GRAPH_ZERO ;
-    stralloc salist = STRALLOC_ZERO ;
+    stralloc tmp = STRALLOC_ZERO ;
+    size_t pos = 0 ;
+
+    if (!sastr_clean_string(&tmp,str))
+        log_warnu_return(LOG_EXIT_ZERO,"rebuild dependencies list") ;
+
+    FOREACH_SASTR(&tmp,pos) {
+
+            if (!sastr_add_string(deps, tmp.s + pos))
+                return 0 ;
+    }
+
+    stralloc_free(&tmp) ;
+
+    return 1 ;
+}
+*/
+
+int graph_service_add_deps(graph_t *g, char const *service, char const *sdeps)
+{
+    stralloc deps = STRALLOC_ZERO ;
+    uint8_t e = 0 ;
+    if (!sastr_clean_string(&deps,sdeps)) {
+        log_warnu("rebuild dependencies list") ;
+        goto freed ;
+    }
+
+    if (!graph_vertex_add_with_nedge(g, service, &deps)) {
+        log_warnu("add edges at vertex: ", service) ;
+        goto freed ;
+    }
+
+    e = 1 ;
+    freed:
+    stralloc_free(&deps) ;
+
+    return e ;
+}
+
+
+void ss_graph_matrix_add_classic(graph_t *g, genalloc *gares)
+{
+    size_t pos = 0, bpos = 0, ccount = 0 ;
+    size_t cl[SS_MAX_SERVICE] ;
+
+    for (; pos < genalloc_len(ss_resolve_t, gares) ; pos++) {
+
+        ss_resolve_t_ref res = &genalloc_s(ss_resolve_t, gares)[pos] ;
+
+        if (res->type == TYPE_CLASSIC) {
+
+            cl[ccount++] = pos ;
+
+        }
+    }
+
+    if (ccount) {
+
+        for (pos = 0 ; pos < ccount ; pos++)  {
+
+            char *str = genalloc_s(ss_resolve_t, gares)[cl[pos]].sa.s ;
+            char *sv = str + genalloc_s(ss_resolve_t, gares)[cl[pos]].name ;
+
+            graph_array_reverse(g->sort, g->sort_count) ;
+
+            for (bpos = 0 ; bpos < g->sort_count ; bpos++) {
+
+                char *service = g->data.s + genalloc_s(graph_hash_t,&g->hash)[g->sort[bpos]].vertex ;
+
+                int idx = ss_resolve_search(gares, service) ;
+                if (genalloc_s(ss_resolve_t, gares)[idx].type == TYPE_CLASSIC ||
+                    !strcmp(service, sv))
+                        continue ;
+
+                if (!graph_edge_add_g(g, service, sv))
+                    log_die(LOG_EXIT_SYS,"add edge: ", sv, " at vertex: ", service) ;
+
+                graph_free_matrix(g) ;
+                graph_free_sort(g) ;
+
+                if (!graph_matrix_build(g)) {
+                    graph_free_all(g) ;
+                    log_dieu(LOG_EXIT_SYS,"build the graph") ;
+                }
+
+                if (!graph_matrix_analyze_cycle(g))
+                    log_die(LOG_EXIT_SYS,"found cycle") ;
+            }
+
+            graph_array_reverse(g->sort, g->sort_count) ;
+        }
+    }
+
+}
+
+/** what = 0 -> only classic
+ * what = 1 -> only atomic
+ * what = 2 -> both
+ * @Return 0 on fail
+ *
+ * This function append the logger to @gares is case of classic service. */
+int ss_tree_get_sv_resolve(genalloc *gares, char const *dir, uint8_t what)
+{
+    log_flow() ;
+
+    stralloc sa = STRALLOC_ZERO ;
+    ss_resolve_t res = RESOLVE_ZERO ;
+    ss_resolve_t reslog = RESOLVE_ZERO ;
+
+    int e = 0 ;
+    size_t dirlen = strlen(dir), pos = 0 ;
+
+    char solve[dirlen + SS_RESOLVE_LEN + 1] ;
+
+    auto_strings(solve, dir, SS_RESOLVE) ;
+
+    char const *exclude[2] = { SS_MASTER + 1, 0 } ;
+    if (!sastr_dir_get(&sa,solve,exclude,S_IFREG))
+        goto err ;
+
+    FOREACH_SASTR(&sa, pos) {
+
+        char *name = sa.s + pos ;
+
+        if (!ss_resolve_check(dir,name))
+            goto err ;
+
+        if (!ss_resolve_read(&res,dir,name))
+            goto err ;
+
+        if (ss_resolve_search(gares,name) == -1) {
+
+            if ((!what || what == 2) && (res.type == TYPE_CLASSIC)) {
+
+                if (res.logger) {
+
+                    if (!ss_resolve_read(&reslog, dir, res.sa.s + res.logger))
+                        goto err ;
+
+                    if (ss_resolve_search(gares,res.sa.s + res.logger) == -1) {
+
+                        if (!ss_resolve_append(gares,&reslog))
+                            goto err ;
+                    }
+                }
+
+                if (!ss_resolve_append(gares,&res))
+                    goto err ;
+
+                continue ;
+            }
+
+            if (what) {
+
+                if (!ss_resolve_append(gares,&res))
+                    goto err ;
+            }
+        }
+    }
+
+    e = 1 ;
+    err:
+        stralloc_free(&sa) ;
+        ss_resolve_free(&res) ;
+        ss_resolve_free(&reslog) ;
+        return e ;
+}
+
+/** @tree: absolute path of the tree*/
+static void ss_graph_matrix_build_bytree(graph_t *g, char const *tree, uint8_t what)
+{
+    stralloc services = STRALLOC_ZERO ;
+    stralloc deps = STRALLOC_ZERO ;
     genalloc gares = GENALLOC_ZERO ;
 
+    size_t treelen = strlen(tree), pos = 0 ;
+    char src[treelen + SS_SVDIRS_LEN + 1] ;
+
+    auto_strings(src, tree, SS_SVDIRS) ;
+
+    if (!ss_tree_get_sv_resolve(&gares, src, what))
+        log_dieu(LOG_EXIT_SYS,"get resolve files of tree: ", tree) ;
+
+    if (genalloc_len(ss_resolve_t, &gares) >= SS_MAX_SERVICE)
+        log_die(LOG_EXIT_SYS, "too many services to handle") ;
+
+    pos = 0 ;
+
+    for (; pos < genalloc_len(ss_resolve_t, &gares) ; pos++) {
+
+        ss_resolve_t_ref res = &genalloc_s(ss_resolve_t, &gares)[pos] ;
+
+        char *str = res->sa.s ;
+
+        char *service = str + res->name ;
+
+        if (!graph_vertex_add(g, service))
+            log_dieu(LOG_EXIT_SYS,"add vertex: ", service) ;
+
+        deps.len = 0 ;
+
+        if (res->ndeps > 0) {
+
+            if (res->type == TYPE_MODULE || res->type == TYPE_BUNDLE) {
+
+                uint32_t tdeps = res->type == TYPE_MODULE ? what > 1 ? res->contents : res->deps : res->deps ;
+
+                if (!graph_service_add_deps(g, service, str + tdeps))
+                    log_dieu(LOG_EXIT_ZERO,"add dependencies of service: ",service) ;
+
+            } else {
+
+                if (!graph_service_add_deps(g, service,str + res->deps))
+                    log_dieu(LOG_EXIT_ZERO,"add dependencies of service: ",service) ;
+
+            }
+        }
+    }
+
+
+    if (!graph_matrix_build(g))
+        log_dieu(LOG_EXIT_SYS,"build the graph") ;
+
+    if (!graph_matrix_analyze_cycle(g))
+        log_die(LOG_EXIT_SYS,"found cycle") ;
+
+    if (!graph_matrix_sort(g))
+        log_dieu(LOG_EXIT_SYS,"sort the graph") ;
+
+    if (!what || what == 2)
+        ss_graph_matrix_add_classic(g, &gares) ;
+
+    stralloc_free(&services) ;
+    stralloc_free(&deps) ;
+}
+
+
+
+static void info_display_requiredby(char const *field, ss_resolve_t *res)
+{
+    size_t padding = 1 ;
+    int r ;
+    graph_t graph = GRAPH_ZERO ;
+
     if (NOFIELD) padding = info_display_field_name(field) ;
     else { field = 0 ; padding = 0 ; }
 
-    if (!res->ndeps) goto empty ;
+    /**
+     *
+     *
+     * ATTENTION A LA SORTIE D ERREUR
+     *
+     * */
 
-    if (res->type == TYPE_MODULE)
-    {
-        if (!sastr_clean_string(&salist,res->sa.s + res->contents))
-            log_dieu(LOG_EXIT_SYS,"rebuild dependencies list") ;
+    ss_graph_matrix_build_bytree(&graph, res->sa.s + res->tree, 2) ;
 
-        if (!ss_resolve_sort_bytype(&gares,&salist,src.s))
-            log_dieu(LOG_EXIT_SYS,"sort list by type") ;
 
-        for (pos = 0 ; pos < genalloc_len(ss_resolve_t,&gares) ; pos++)
-            if (!ss_resolve_graph_build(&graph,&genalloc_s(ss_resolve_t,&gares)[pos],src.s,REVERSE))
-                log_dieu(LOG_EXIT_SYS,"build the graph from: ",src.s) ;
+    unsigned int list[graph.mlen] ;
+
+    int count = graph_matrix_get_requiredby(list, &graph, res->sa.s + res->name , 0) ;
+
+    if (count == -1)
+        log_dieu(LOG_EXIT_SYS,"get requiredby for service: ", res->sa.s + res->name) ;
+
+    if (!count) goto empty ;
+
+    if (GRAPH) {
+
+        if (!bprintf(buffer_1,"%s\n","/"))
+            log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
+
+        depth_t d = ss_info_graph_init() ;
+
+        if (!ss_info_walk(&graph, res->sa.s + res->name, res->sa.s + res->treename, &ss_info_graph_display_service, 1, REVERSE, &d, padding, STYLE))
+            log_dieu(LOG_EXIT_SYS,"display the requiredby graphic") ;
+
+        return ;
 
-        r = ss_resolve_graph_publish(&graph,0) ;
-        if (r < 0) log_die(LOG_EXIT_USER,"cyclic graph detected") ;
-        else if (!r) log_dieusys(LOG_EXIT_SYS,"publish service graph") ;
+    } else {
 
-        salist.len = 0 ;
-        for (pos = 0 ; pos < genalloc_len(ss_resolve_t,&graph.sorted) ; pos++)
+        deps.len = 0 ;
+        r = ss_info_walk_edge(&deps,&graph, res->sa.s + res->name, 1) ;
+        if (r == -1)
+            log_dieu(LOG_EXIT_SYS, "get requiredby list") ;
+
+        if (!r)
+            goto empty ;
+
+        if (REVERSE)
+            if (!sastr_reverse(&deps))
+                log_dieu(LOG_EXIT_SYS,"reverse dependencies list") ;
+
+        info_display_list(field,&deps) ;
+
+        return ;
+    }
+
+    empty:
+        if (GRAPH)
         {
-            char *string = genalloc_s(ss_resolve_t,&graph.sorted)[pos].sa.s ;
-            char *name = string + genalloc_s(ss_resolve_t,&graph.sorted)[pos].name ;
-            if (!stralloc_catb(&salist,name,strlen(name)+1)) log_die_nomem("stralloc") ;
+            if (!bprintf(buffer_1,"%s\n","/"))
+                log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
+            if (!bprintf(buffer_1,"%*s%s%s%s%s\n",padding, "", STYLE->last, log_color->warning,"None",log_color->off))
+                log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
         }
-        genalloc_deepfree(ss_resolve_t,&gares,ss_resolve_free) ;
-        ss_resolve_graph_free(&graph) ;
-    }
-    else {
-        if (!sastr_clean_string(&salist,res->sa.s + res->deps))
-            log_dieu(LOG_EXIT_SYS,"rebuild dependencies list") ;
-    }
+        else
+        {
+            if (!bprintf(buffer_1,"%s%s%s\n",log_color->warning,"None",log_color->off))
+                log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
+        }
+}
+
+static void info_display_deps(char const *field, ss_resolve_t *res)
+{
+    int r ;
+    size_t padding = 1 ;
+    graph_t graph = GRAPH_ZERO ;
+
+    stralloc deps = STRALLOC_ZERO ;
+
+    if (NOFIELD) padding = info_display_field_name(field) ;
+    else { field = 0 ; padding = 0 ; }
+
+    ss_graph_matrix_build_bytree(&graph, res->sa.s + res->tree, 2) ;
+
+    unsigned int list[graph.mlen] ;
+
+    int count = graph_matrix_get_edge(list, &graph, res->sa.s + res->name , 0) ;
+
+    if (count == -1)
+        log_dieu(LOG_EXIT_SYS,"get requiredby for service: ", res->sa.s + res->name) ;
+
+    if (!count) goto empty ;
 
     if (GRAPH)
     {
         if (!bprintf(buffer_1,"%s\n","/"))
             log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
 
-        el = sastr_len(&salist) ;
-        if (!sastr_rebuild_in_oneline(&salist)) log_dieu(LOG_EXIT_SYS,"rebuild dependencies list") ;
+        depth_t d = ss_info_graph_init() ;
 
-        ss_resolve_init(&gres) ;
-        gres.ndeps = el ;
-        gres.deps = ss_resolve_add_string(&gres,salist.s) ;
-
-        if (!info_graph_init(&gres,src.s,REVERSE, padding, STYLE))
-            log_dieu(LOG_EXIT_SYS,"display graph of: ",gres.sa.s + gres.name) ;
+        if (!ss_info_walk(&graph, res->sa.s + res->name, res->sa.s + res->treename, &ss_info_graph_display_service, 0, REVERSE, &d, padding, STYLE))
+            log_dieu(LOG_EXIT_SYS,"display the dependencies graphic") ;
 
         goto freed ;
     }
     else
     {
+        deps.len = 0 ;
+        r = ss_info_walk_edge(&deps,&graph, res->sa.s + res->name, 0) ;
+        if (r == -1)
+            log_dieu(LOG_EXIT_SYS, "get requiredby list") ;
+
+        if (!r)
+            goto empty ;
+
         if (REVERSE)
-            if (!sastr_reverse(&salist))
+            if (!sastr_reverse(&deps))
                 log_dieu(LOG_EXIT_SYS,"reverse dependencies list") ;
-        info_display_list(field,&salist) ;
+        info_display_list(field,&deps) ;
+
         goto freed ;
     }
     empty:
@@ -395,6 +1045,7 @@ static void info_display_deps(char const *field, ss_resolve_t *res)
         {
             if (!bprintf(buffer_1,"%s\n","/"))
                 log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
+
             if (!bprintf(buffer_1,"%*s%s%s%s%s\n",padding, "", STYLE->last, log_color->warning,"None",log_color->off))
                 log_dieusys(LOG_EXIT_SYS,"write to stdout") ;
         }
@@ -405,8 +1056,7 @@ static void info_display_deps(char const *field, ss_resolve_t *res)
         }
 
     freed:
-        ss_resolve_free(&gres) ;
-        stralloc_free(&salist) ;
+        stralloc_free(&deps) ;
 }
 
 static void info_display_with_source_tree(stralloc *list,ss_resolve_t *res)
@@ -416,12 +1066,14 @@ static void info_display_with_source_tree(stralloc *list,ss_resolve_t *res)
     stralloc ntree = STRALLOC_ZERO ;
     stralloc src = STRALLOC_ZERO ;
     stralloc tmp = STRALLOC_ZERO ;
+    char const *exclude[3] = { SS_BACKUP + 1, SS_RESOLVE + 1, 0 } ;
     char *treename = 0 ;
 
     if (!auto_stra(&src,home.s)) log_die_nomem("stralloc") ;
     newlen = src.len ;
 
-    if (!sastr_dir_get(&ntree,home.s,SS_BACKUP + 1,S_IFDIR))
+
+    if (!sastr_dir_get(&ntree,home.s,exclude,S_IFDIR))
         log_dieu(LOG_EXIT_SYS,"get list of trees of: ",home.s) ;
 
     for (pos = 0 ; pos < ntree.len ; pos += strlen(ntree.s + pos) + 1)
@@ -433,7 +1085,9 @@ static void info_display_with_source_tree(stralloc *list,ss_resolve_t *res)
         if (!auto_stra(&src,treename,SS_SVDIRS,SS_RESOLVE))
             log_die_nomem("stralloc") ;
 
-        if (!sastr_dir_get(&svlist,src.s,SS_MASTER + 1,S_IFREG))
+        exclude[0] = SS_MASTER + 1 ;
+        exclude[1] = 0 ;
+        if (!sastr_dir_get(&svlist,src.s,exclude,S_IFREG))
             log_dieu(LOG_EXIT_SYS,"get contents of tree: ",src.s) ;
 
         for (lpos = 0 ; lpos < list->len ; lpos += strlen(list->s + lpos) + 1)
@@ -596,6 +1250,7 @@ static void info_display_envfile(char const *field,ss_resolve_t *res)
     stralloc sa = STRALLOC_ZERO ;
     stralloc salink = STRALLOC_ZERO ;
     stralloc list = STRALLOC_ZERO ;
+    char const *exclude[1] = { 0 } ;
 
     if (res->srconf)
     {
@@ -613,7 +1268,7 @@ static void info_display_envfile(char const *field,ss_resolve_t *res)
 
         newlen = salink.len - 1 ;
 
-        if (!sastr_dir_get(&list,salink.s,"",S_IFREG))
+        if (!sastr_dir_get(&list,salink.s,exclude,S_IFREG))
             log_dieusys(LOG_EXIT_SYS,"get list of environment file from: ",src) ;
 
         if (!sastr_sort(&list))
@@ -852,6 +1507,7 @@ int main(int argc, char const *const *argv, char const *const *envp)
         "Source",
         "Live",
         "Dependencies",
+        "Required by",
         "External dependencies" ,
         "Optional dependencies" ,
         "Start script",
@@ -868,9 +1524,9 @@ int main(int argc, char const *const *argv, char const *const *envp)
 
         for (;;)
         {
-            int opt = getopt_args(argc,argv, ">hzv:cno:grd:t:p:", &l) ;
+            int opt = subgetopt_r(argc,argv, "hzv:cno:grd:t:p:", &l) ;
             if (opt == -1) break ;
-            if (opt == -2) log_die(LOG_EXIT_USER,"options must be set first") ;
+
             switch (opt)
             {
                 case 'h' :  info_help(); return 0 ;
@@ -909,7 +1565,7 @@ int main(int argc, char const *const *argv, char const *const *envp)
 
     setlocale(LC_ALL, "");
 
-    if(!str_diff(nl_langinfo(CODESET), "UTF-8")) {
+    if(!strcmp(nl_langinfo(CODESET), "UTF-8")) {
         STYLE = &graph_utf8;
     }
     if (!set_ownersysdir(&home,owner)) log_dieusys(LOG_EXIT_SYS, "set owner directory") ;