From 0a7b5f1396dc855c89a43633425c67307f85b752 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Thu, 3 Oct 2019 19:40:37 +1100
Subject: [PATCH] split and replace 66-info by 66-intree and 66-inservice

---
 doc/html/66-info.html        | 286 +-----------
 doc/html/66-inservice.html   | 160 +++++++
 doc/html/66-intree.html      | 198 ++++++++
 doc/man/66-info.1.scd        | 269 +----------
 doc/man/66-inservice.1.scd   | 159 +++++++
 doc/man/66-intree.1.scd      | 188 ++++++++
 package/deps.mak             |  17 +-
 package/modes                |   4 +-
 package/targets.mak          |   2 +
 src/66/66-info.c             | 849 +----------------------------------
 src/66/66-inservice.c        | 694 ++++++++++++++++++++++++++++
 src/66/66-intree.c           | 455 +++++++++++++++++++
 src/66/deps-exe/66-inservice |   4 +
 src/66/deps-exe/66-intree    |   4 +
 src/include/66/info.h        |  83 ++++
 src/include/66/resolve.h     |  25 +-
 src/lib66/deps-lib/66        |   1 +
 src/lib66/resolve_graph.c    |  26 +-
 src/lib66/ss_info_utils.c    | 314 +++++++++++++
 19 files changed, 2298 insertions(+), 1440 deletions(-)
 create mode 100644 doc/html/66-inservice.html
 create mode 100644 doc/html/66-intree.html
 create mode 100644 doc/man/66-inservice.1.scd
 create mode 100644 doc/man/66-intree.1.scd
 create mode 100644 src/66/66-inservice.c
 create mode 100644 src/66/66-intree.c
 create mode 100644 src/66/deps-exe/66-inservice
 create mode 100644 src/66/deps-exe/66-intree
 create mode 100644 src/include/66/info.h
 create mode 100644 src/lib66/ss_info_utils.c

diff --git a/doc/html/66-info.html b/doc/html/66-info.html
index f7433f97..2887cbba 100644
--- a/doc/html/66-info.html
+++ b/doc/html/66-info.html
@@ -18,289 +18,9 @@
 <h1>66-info</h1>
 
 	<p>
-      This command displays information about trees and services.
+        <strong>Deprecated</strong>. 
+        See <a href="66-intree.html">66-intree</a> for tree informations.
+        See <a href="66-inservice.html">66-inservice</a> for service informations.
     </p>
-
-<h2>Interface </h2>
-<h3>Main interface</h3>
-	<pre>
-	66-info [ -h help ] [ -T tree ] [ -S service ]
-	</pre>
-<h3>Tree sub interface</h3>
-	<pre>
-	66-info [ -T ] [ -h help ] [ -c | -C ] [ -v <em>verbosity</em> ] [ -l live ] [ -r recurse ] [ -d <em>depth</em> ] <em>tree</em>
-	</pre>
-<h3>Service sub interface</h3>
-	<pre>
-	66-info [ -S ] [ -h help ] [ -c | -C ] [ -v <em>verbosity</em> ] [ -l live ] [ -p n lines ] [ -r recurse ] [ -d <em>depth</em> ] <em>service</em>
-	</pre>
-	<p>
-      66-info displays detailed information about a <em>tree</em> or a specific <em>service</em> depending on the options passed.
-    </p>
-
-<h2>Main Options </h2>
-
-	<ul>
-		<li> 
-			<tt>-h&nbsp;</tt>&nbsp;: prints this help.
-		</li>
-		<li> 
-			<tt>-T&nbsp;</tt>&nbsp;: asks for <em>tree</em> information.
-		</li>
-		<li> 
-			<tt>-S&nbsp;</tt>&nbsp;: asks for <em>service</em> information.
-		</li>
-	</ul>
-<h2>Tree sub options </h2>		 
-	<ul>	
-		<li> 
-			<tt>-h&nbsp;</tt>&nbsp;: prints this help.
-		</li>
-		<li> 
-			<tt>-c&nbsp;</tt>&nbsp;: disable colorization.
-		</li>
-		<li>
-			<tt>-C&nbsp;</tt>&nbsp;: force colorization.
-		</li>
-		<li>
-			<tt>-v&nbsp;<em>verbosity</em>&nbsp;</tt>&nbsp;: increases/decreases 
-			the verbosity of the command. <tt>1(Default)</tt>: Only print 
-			error messages. <tt>2</tt>: Also print warning messages. 
-			<tt>3</tt>: Also print debugging messages.
-		 </li>
-		 <li> 
-			<tt>-l&nbsp;<em>live</em>&nbsp;</tt>&nbsp;: changes the supervision directory of <em>service</em> to <em>live</em>. By default this will be <tt>%%livedir%%</tt>. The default can 
-			also be changed at compile time by passing the <tt>--livedir=<em>live</em></tt>
-			option to <tt>./configure</tt>. An existing absolute path is expected and
-			should be within a writable filesystem - likely a RAM filesystem&mdash;see <tt><a href="66-scandir.html">66-scandir</a></tt>.
-		</li>
-		 <li>
-			<tt>-r&nbsp;</tt>&nbsp;: shows the dependency graph of <em>tree</em> in reverse mode.
-		 </li>
-		 
-		 <li> 
-			<tt>-d&nbsp;<em>depth</em>&nbsp;</tt>&nbsp;: limits the depth of the dependency graph visualisation; defaults to 1.
-		</li>
-		
-		<p>(!) If <em>tree</em> is not specified <tt>66-info</tt> will display information about all available trees for the current owner of the process.</p>
-	</ul>
-	
-<h2>Service sub options </h2>		 
-	<ul>	
-		<li> 
-			<tt>-h&nbsp;</tt>&nbsp;: prints this help.
-		</li>
-		<li> 
-			<tt>-c&nbsp;</tt>&nbsp;: disable colorization.
-		</li>
-		<li>
-			<tt>-C&nbsp;</tt>&nbsp;: force colorization.
-		</li>
-		<li>
-			<tt>-v&nbsp;<em>verbosity</em>&nbsp;</tt>&nbsp;: increases/decreases 
-			the verbosity of the command. <tt>1(Default)</tt>: Only print 
-			error messages. <tt>2</tt>: Also print warning messages. 
-			<tt>3</tt>: Also print debugging messages.
-		 </li>
-		<li> 
-			<tt>-l&nbsp;<em>live</em>&nbsp;</tt>&nbsp;: changes the supervision directory of <em>service</em> to <em>live</em>. By default this will be <tt>%%livedir%%</tt>. The default can 
-			also be changed at compile time by passing the <tt>--livedir=<em>live</em></tt>
-			option to <tt>./configure</tt>. An existing absolute path is expected and
-			should be within a writable filesystem - likely a RAM filesystem&mdash;see <tt><a href="66-scandir.html">66-scandir</a></tt>.
-		</li>
-		<li>
-			<tt>-p&nbsp;<em>n lines</em>&nbsp;</tt>&nbsp;: prints the <em>n</em> last lines from the associated log file of the <em>service</em>.
-		</li>
-		<li>
-			<tt>-r&nbsp;</tt>&nbsp;: shows the dependency graph of <em>service</em> in reverse mode.
-		</li>
-		<li> 
-			<tt>-d&nbsp;<em>depth</em>&nbsp;</tt>&nbsp;: limits the depth of the dependency graph visualisation; defaults to 1.
-		</li>
-	</ul>
-	
-<h2>Tree output display example</h2>
-	
-	<p>The command <tt>66-info -T boot</tt> as root user on the <em>Obarun</em> default system displays the following where <em>boot</em>
-	is the tree used to properly boot the machine:
-	<pre>   
-	               boot           
-	Initialized: yes | Current: no
-	Contains:       | Enabled: no
-	├─(0,Enabled,oneshot) system-hostname
-	├─(0,Enabled,oneshot) mount-run
-	├─(0,Enabled,oneshot) populate-run
-	├─(0,Enabled,oneshot) mount-tmp
-	├─(0,Enabled,oneshot) populate-tmp
-	├─(0,Enabled,oneshot) mount-proc
-	├─(0,Enabled,oneshot) mount-sys
-	├─(0,Enabled,oneshot) populate-sys
-	├─(0,Enabled,oneshot) mount-dev
-	├─(0,Enabled,oneshot) mount-pts
-	├─(0,Enabled,oneshot) mount-shm
-	├─(0,Enabled,oneshot) populate-dev
-	├─(0,Enabled,bundle) 00
-	├─(0,Enabled,oneshot) modules-kernel
-	├─(490,Enabled,longrun) udevd
-	├─(0,Enabled,oneshot) udevadm
-	├─(0,Enabled,oneshot) devices-crypttab
-	├─(0,Enabled,oneshot) system-hwclock
-	├─(0,Enabled,oneshot) system-random
-	├─(0,Enabled,oneshot) modules-system
-	├─(0,Enabled,oneshot) system-sysctl
-	├─(0,Enabled,oneshot) system-fontnkey
-	├─(0,Enabled,oneshot) devices-dmraid
-	├─(0,Enabled,oneshot) devices-btrfs
-	├─(0,Enabled,oneshot) devices-lvm
-	├─(0,Enabled,bundle) system-Devices
-	├─(0,Enabled,oneshot) system-fsck
-	├─(0,Enabled,oneshot) mount-fstab
-	├─(0,Enabled,bundle) all-System
-	├─(0,Enabled,oneshot) mount-rw
-	├─(0,Enabled,oneshot) local-iptables
-	├─(0,Enabled,oneshot) local-ip6tables
-	├─(0,Enabled,oneshot) local-loop
-	├─(0,Enabled,oneshot) local-time
-	├─(0,Enabled,oneshot) local-authfiles
-	├─(0,Enabled,oneshot) local-tmpfiles
-	├─(0,Enabled,oneshot) local-rc
-	├─(0,Enabled,oneshot) local-dmesg
-	├─(0,Enabled,bundle) all-Local
-	├─(0,Enabled,oneshot) mount-cgroups
-	├─(0,Enabled,oneshot) mount-swap
-	├─(0,Enabled,oneshot) mount-zfs
-	├─(0,Enabled,bundle) all-Mount
-	├─(0,Enabled,oneshot) all-Runtime
-	├─(0,Enabled,bundle) All
-	└─(254,Enabled,classic) tty12
-
-	</pre>
-	</p>
-	<p>By default the first service displayed is the first service started, the second one is the second started and so on.</p>
-	<p>The first line give you the name of the <em>tree</em>, <tt><em>Initialized</em></tt> tells if the <tree>tree</tree> was initialized with <tt><a href="66-init.html">66-init</a></tt> tool, 
-		<tt><em>Current</em></tt> tells if the <em>tree</em> is the current one or not&mdash;see <tt><a href="66-tree.html">66-tree -c</a></tt> and
-		<tt><em>Enabled</em></tt> reveals the state of the tree&mdash;see <tt><a href="66-tree.html">66-tree -E</a></tt>.
-		For each service the first number found between '()' bracket is the corresponding pid of the service, the second one is the state of the service, the type of the service is shown next to it. Finally the name of the service is displayed.
-	</p>
-	<p>
-		By default the dependency graph is rendered in order of execution. In this example the <em>'classic' tty12</em> is the last finished
-		service and <em>'oneshot' filesystem</em> is the first one executed. You can reverse the rendered order with the <tt>-r</tt> option.</p>
-	</p>
-	
-<h2>Service output display example</h2>
-
-	<p>The command <tt>sudo 66-info -S -d3 00</tt> displays the following where <em>00</em> 
-	is the name of the service:
-	<pre>
-	<u>                00                     </u>
-	on tree : boot
-	status : Enabled, nothing to display
-	type : bundle
-	description : Set the hostname and mount filesystem
-	source : %%service_system%%/boot/mount/
-	run at : %%livedir%%/tree/0/boot/servicedirs/00
-	<u>             contents                  </u>
-	├─(0,Enabled,oneshot) system-hostname
-	├─(0,Enabled,oneshot) mount-run
-	├─(0,Enabled,oneshot) populate-run
-	│ └─(0,Enabled,oneshot) mount-run
-	├─(0,Enabled,oneshot) mount-tmp
-	├─(0,Enabled,oneshot) populate-tmp
-	│ └─(0,Enabled,oneshot) mount-tmp
-	├─(0,Enabled,oneshot) mount-proc
-	├─(0,Enabled,oneshot) mount-sys
-	│ └─(0,Enabled,oneshot) mount-proc
-	├─(0,Enabled,oneshot) populate-sys
-	│ ├─(0,Enabled,oneshot) mount-proc
-	│ └─(0,Enabled,oneshot) mount-sys
-	├─(0,Enabled,oneshot) mount-dev
-	│ └─(0,Enabled,oneshot) mount-sys
-	├─(0,Enabled,oneshot) mount-pts
-	│ └─(0,Enabled,oneshot) mount-dev
-	├─(0,Enabled,oneshot) mount-shm
-	│ └─(0,Enabled,oneshot) mount-dev
-	└─(0,Enabled,oneshot) populate-dev
-	  └─(0,Enabled,oneshot) mount-dev
-
-
-	</pre>
-	</p>
-	<p>Let's take another example, the command sudo <tt>66-info -S -p5 ntpd</tt> displays the following:
-	<pre>
-	<u>                ntpd                     </u>
-	on tree : root
-	status : Disabled, up (pid 786) 2380 seconds
-	type : classic
-	description : ntpd daemon
-	source : %%service_adm%%
-	run at : %%livedir%%/scandir/0/ntpd
-	<u>            dependencies                 </u>
-	└─(785,Disabled,classic) ntpd-log
-	<u>              scripts                    </u>
-	start script : foreground { mkdir -p  -m 0755 ${dir_run} } 
-	execl-cmdline -s { ntpd ${cmd_args} } 
-	<u>            environment                  </u>
-	dir_run=!/run/openntpd
-	cmd_args=!-d -s
-	<u>              logger                     </u>
-	logger associated : ntpd-log
-	log destination : %%system_log%%/ntpd 
-	<u>             log file                    </u>	
-	2019-03-18 06:50:21.749572500  adjtimex returns frequency of 0.000000ppm
-	2019-03-18 06:50:21.764241500  ntp engine ready
-	2019-03-18 06:50:21.847440500  adjtimex adjusted frequency by 16.428986ppm
-	2019-03-18 06:50:21.847479500  set local clock to Mon Mar 18 06:50:21 +11 2019 (offset 0.000000s)
-
-	</pre>
-	<p> In our case :
-	<ul>
-		<li>
-			<tt>ntpd&nbsp;</tt>&nbsp;: name of the service. Main section where general informations is displayed.
-		</li>
-		<li>
-			<tt>on tree&nbsp;</tt>&nbsp;: service enable on tree root.
-		</li>
-		<li>
-			<tt>status&nbsp;</tt>&nbsp;: status of the service.
-		</li>
-		<li>
-			<tt>type&nbsp;</tt>&nbsp;: type of the service.
-		</li>
-		<li>
-			<tt>description&nbsp;</tt>&nbsp;: short description of the service.
-		</li>
-		<li>
-			<tt>source&nbsp;</tt>&nbsp;: origin of the frontend service file used to enable the service.
-		</li>
-		<li>
-			<tt>run at&nbsp;</tt>&nbsp;: location of the service into the scandir.
-		</li>
-		<li>
-			<tt>dependencies</tt>&nbsp;: dependencies informations section. This section will display a graphical tree on the service dependencies.
-		</li>
-		<li>
-			<tt>scripts</tt>&nbsp;: scripts informations section. This will display the command executed at start and stop process.
-		</li>
-		<li>
-			<tt>start script&nbsp;</tt>&nbsp;: command line executed at start process. If a stop section was set an additionnal field called stop script will be displayed with the corresponding command line executed at stop process.
-		</li>
-		<li>
-			<tt>environment</tt>&nbsp;: environment informations section. Display the environment variables set at <tt>%%service_admconf%%<service_name></tt> or <tt>$HOME/%%service_userconf%%<service_name></tt> depending of the owner of the process.
-		</li>
-		<li>
-			<tt>logger</tt>&nbsp;: logger informations section.
-		</li>
-		<li>
-			<tt>logger associated&nbsp;</tt>&nbsp;: name of the service logger.
-		</li>
-		<li>
-			<tt>log destination&nbsp;</tt>&nbsp;: destination of the logger file.
-		</li>
-		<li>
-			the last part display the last 5 line of the logger file.
-		</li>
-	</ul>
-	</p>
-	<p>Note: <tt>66-info</tt> use color to output the informations, the previous examples do not reflect the veritable output concerning the colors.</p>
 </body>
 </html>
diff --git a/doc/html/66-inservice.html b/doc/html/66-inservice.html
new file mode 100644
index 00000000..c243b9f8
--- /dev/null
+++ b/doc/html/66-inservice.html
@@ -0,0 +1,160 @@
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>The 66 Suite: 66-inservice</title>
+    <meta name="Description" content="Detailed documentation for the 66-inservice command which is part of the 66 software suite" />
+    <meta name="Keywords" content="66 command 66-inservice scandir supervision supervise set service information" />
+    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">66</a><br />
+<a href="//obarun.org/">www.obarun.org</a>
+</p>
+
+<h1>66-inservice</h1>
+
+	<p>
+      This command displays information about services.
+    </p>
+
+<h2>Interface </h2>
+	<pre>
+	66-inservice [ -h ] [ -v verbosity ] [ -c ] [ -o name,intree,status,... ] [ -g ] [ -d depth ] [ -r ] [ -t tree ] [ -p nline ] service
+	</pre>
+
+<h2>Options </h2>
+
+	<ul>
+		<li> 
+			<tt>-h&nbsp;</tt>&nbsp;: prints this help.
+		</li>
+        <li>
+			<tt>-v&nbsp;<em>verbosity</em>&nbsp;</tt>&nbsp;: increases/decreases 
+			the verbosity of the command. <tt>1(Default)</tt>: Only print 
+			error messages. <tt>2</tt>: Also print warning messages. 
+			<tt>3</tt>: Also print debugging messages.
+		</li>
+        <li> 
+			<tt>-c&nbsp;</tt>&nbsp;: enable colorization.
+		</li>
+		<li> 
+			<tt>-o&nbsp;</tt>&nbsp;: comma separated list of field to display. If this option is not past, <tt>66-inservice</tt> will display all field.
+		</li>
+		<li>
+			<tt>-g&nbsp;</tt>&nbsp;: shows the dependency list of <em>service</em> as graph instead of list.
+		</li>
+        <li> 
+			<tt>-d&nbsp;<em>depth</em>&nbsp;</tt>&nbsp;: limits the depth of the dependency list visualisation; defaults to 1. This is implies <tt>-g</tt> options.
+		</li>
+        <li>
+			<tt>-r&nbsp;</tt>&nbsp;: shows the dependency list of <em>service</em> in reverse mode.
+		</li>
+         <li> 
+			<tt>-t&nbsp;<em>tree</em>&nbsp;</tt>&nbsp;: only search the <em>service</em> at the specified <em>tree</em>.
+		</li>
+
+        <li>
+			<tt>-p&nbsp;<em>n lines</em>&nbsp;</tt>&nbsp;: prints the <em>n</em> last lines from the log file of the <em>service</em>. Default to 20.
+		</li>
+
+	</ul>
+<h2>Valid field for <tt>-o</tt> options</h2>
+
+    <ul>
+        <li>
+            <tt>name</tt>&nbsp;: displays the name of the <em>service</em>.
+        </li>
+        <li>
+            <tt>intree</tt>&nbsp;: displays the <em>service's</em> tree name.
+        </li>
+        <li>
+            <tt>status</tt>&nbsp;: displays the status of the <em>service</em>.
+        </li>
+        <li>
+            <tt>type</tt>&nbsp;: displays the type of the <em>service</em>.
+        </li>
+        <li>
+            <tt>description</tt>&nbsp;: displays the description.
+        </li>
+        <li>
+            <tt>source</tt>&nbsp;: displays the source of the <em>service's</em> frontend file.
+        </li>
+        <li>
+            <tt>live</tt>&nbsp;: displays the <em>service's</em> live directory.
+        </li>
+        <li>
+            <tt>depends</tt>&nbsp;: displays the <em>service's</em> dependencies.
+        </li>
+        <li>
+            <tt>start</tt>&nbsp;: displays the <em>service's</em> start script.
+        </li>
+        <li>
+            <tt>stop</tt>&nbsp;: displays the <em>service's</em> stop script.
+        </li>
+        <li>
+            <tt>envat</tt>&nbsp;: displays the source of the environment file.
+        </li>
+        <li>
+            <tt>envfile</tt>&nbsp;: displays the contains of the environment file.
+        </li>
+        <li>
+            <tt>logname</tt>&nbsp;: displays the logger's name.
+        </li>
+        <li>
+            <tt>logdst</tt>&nbsp;: displays the logger's destination.
+        </li>
+        <li>
+            <tt>logfile</tt>&nbsp;: displays the contain of the log file.
+        </li>
+    
+    </ul>
+	
+<h2>Command and output examples</h2>
+	
+	<p>The command <tt>66-inservice 00</tt> as root user on the <em>Obarun</em> default system displays the following where <em>00</em>
+	is a service contained in the tree <em>boot</em>:
+	<pre>   
+    Name               : 00
+    In tree            : boot
+    Status             : enabled, nothing to display
+    Type               : bundle
+    Description        : Set the hostname and mount filesystem
+    Source             : %%service_system%%/boot/mount/00
+    Live               : %%livedir%%/tree/0/boot/servicedirs/00
+    Depends on         : system-hostname  mount-run  populate-run  mount-tmp  populate-tmp  mount-proc  mount-sys
+                         populate-sys  mount-dev  mount-pts  mount-shm  populate-dev  mount-cgroups
+    Start script       : nothing to display
+    Stop script        : nothing to display
+    Environment source : environment was not set
+    Environment file   : environment was not set
+    Log name           : logger doesn't exist
+    Log destination    : logger doesn't exist
+    Log file           : logger doesn't exist
+	</pre>
+	</p>
+	<p>
+		By default the dependency graph is rendered in order of execution. In this example the <em>'oneshot' system-hostname</em> is the first executed
+		service and <em>'oneshot' mount-cgroups</em> is the last finished. You can reverse the rendered order with the <tt>-r</tt> option.</p>
+	</p>
+	
+    <p>You can display the status and depends field and only these fields of a service using the command <tt>66-inservice -o status,depends -g connmand</tt> where the dependency list is diplayed as a graph:
+    <pre>
+    Status             : enabled, up (pid 938) 34652 seconds
+    Depends on         : /
+                         ├─(933,Enabled,longrun) dbus
+                         └─(929,Enabled,longrun) connmand-log
+    </pre>
+    <p>You can display the status,log file and log destination and only these fields of a service using the command <tt>66-inservice -o status,logdst,logfile -g dbus</tt>:
+    <pre>
+    Status             : enabled, up (pid 933) 34852 seconds, ready 34852 seconds
+    Log destination    : %%system_log%%/dbus
+    Log file           :
+    2019-10-03 16:16:05.246991500  dbus-daemon[933]: [system] Rejected send message, 4 matched rules; type="method_call", sender=":1.3" (uid=1000 pid=1226 comm="connman-gtk --tray ") interface="net.connman.Technology" member="Scan" error name="(unset)" requested_reply="0" destination=":1.0" (uid=0 pid=938 comm="connmand -n --nobacktrace --nodnsproxy ")
+    2019-10-03 16:16:35.256146500  dbus-daemon[933]: [system] Rejected send message, 4 matched rules; type="method_call", sender=":1.3" (uid=1000 pid=1226 comm="connman-gtk --tray ") interface="net.connman.Technology" member="Scan" error name="(unset)" requested_reply="0" destination=":1.0" (uid=0 pid=938 comm="connmand -n --nobacktrace --nodnsproxy ")
+    </pre>
+</body>
+</html>
diff --git a/doc/html/66-intree.html b/doc/html/66-intree.html
new file mode 100644
index 00000000..f054d733
--- /dev/null
+++ b/doc/html/66-intree.html
@@ -0,0 +1,198 @@
+<html>
+  <head>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+    <meta http-equiv="Content-Language" content="en" />
+    <title>The 66 Suite: 66-intree</title>
+    <meta name="Description" content="Detailed documentation for the 66-intree command which is part of the 66 software suite" />
+    <meta name="Keywords" content="66 command 66-intree scandir supervision supervise set tree information" />
+    <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
+  </head>
+<body>
+
+<p>
+<a href="index.html">66</a><br />
+<a href="//obarun.org/">www.obarun.org</a>
+</p>
+
+<h1>66-intree</h1>
+
+	<p>
+      This command displays information about trees.
+    </p>
+
+<h2>Interface </h2>
+
+	<pre>
+	66-intree [ -h ] [ -v verbosity ] [ -l live ] [ -c ] [ -o name,init,enabled,... ] [ -g ] [ -d depth ] [ -r ] tree
+	</pre>
+
+<h2>Options </h2>
+
+	<ul>
+		<li> 
+			<tt>-h&nbsp;</tt>&nbsp;: prints this help.
+		</li>
+        <li>
+			<tt>-v&nbsp;<em>verbosity</em>&nbsp;</tt>&nbsp;: increases/decreases 
+			the verbosity of the command. <tt>1(Default)</tt>: Only print 
+			error messages. <tt>2</tt>: Also print warning messages. 
+			<tt>3</tt>: Also print debugging messages.
+		</li>
+		<li> 
+			<tt>-l&nbsp;<em>live</em>&nbsp;</tt>&nbsp;: changes the supervision directory of <em>service</em> to <em>live</em>. By default this will be <tt>%%livedir%%</tt>. The default can 
+			also be changed at compile time by passing the <tt>--livedir=<em>live</em></tt>
+			option to <tt>./configure</tt>. An existing absolute path is expected and
+			should be within a writable filesystem - likely a RAM filesystem&mdash;see <tt><a href="66-scandir.html">66-scandir</a></tt>.
+		</li>
+		<li> 
+			<tt>-c&nbsp;</tt>&nbsp;: enable colorization.
+		</li>
+		<li> 
+			<tt>-o&nbsp;</tt>&nbsp;: comma separated list of field to display. If this option is not past, <tt>66-intree</tt> will display all field.
+		</li>
+        <li>
+			<tt>-g&nbsp;</tt>&nbsp;: shows the dependency list of <em>tree</em> as graph instead of list.
+		</li>
+       	<li> 
+			<tt>-d&nbsp;<em>depth</em>&nbsp;</tt>&nbsp;: limits the depth of the dependency list visualisation; defaults to 1. This is implies <tt>-g</tt> options.
+		</li>
+        <li>
+			<tt>-r&nbsp;</tt>&nbsp;: shows the dependency list of <em>tree</em> in reverse mode.
+		</li> 
+		<p>(!) If <em>tree</em> is not specified <tt>66-intree</tt> will display information about all available trees for the current owner of the process.</p>
+	</ul>
+<h2>Valid field for <tt>-o</tt> options</h2>
+
+    <ul>
+        <li>
+            <tt>name</tt>&nbsp;: displays the name of the <em>tree</em>.
+        </li>
+        <li>
+            <tt>init</tt>&nbsp;: displays a boolean value of the initialization state.
+        </li>
+        <li>
+            <tt>enabled</tt>&nbsp;: displays a boolean value of the enable state.
+        </li>
+        <li>
+            <tt>current</tt>&nbsp;: displays a boolean value of the current state.
+        </li>
+        <li>
+            <tt>contains</tt>&nbsp;: displays the contain of the <em>tree</em>.
+        </li>
+    
+    </ul>
+<h2>Command and output examples</h2>
+	
+	<p>The command <tt>66-intree boot</tt> as root user on the <em>Obarun</em> default system displays the following where <em>boot</em>
+	is the tree used to properly boot the machine:
+	<pre>   
+    Name        : boot
+    Initialized : yes
+    Enabled     : no
+    Current     : no
+    Contains    : tty12  system-hostname  mount-run  populate-run  mount-tmp  populate-tmp  mount-proc  mount-sys
+                  populate-sys  mount-dev  mount-pts  mount-shm  populate-dev  mount-cgroups  00  modules-kernel  udevd
+                  udevadm  devices-crypttab  system-hwclock  system-random  modules-system  system-sysctl
+                  system-fontnkey  devices-dmraid  devices-btrfs  devices-lvm  devices-zfs  system-Devices  mount-swap
+                  all-Mount  system-fsck  mount-fstab  all-System  mount-rw  local-iptables  local-ip6tables  local-loop
+                  local-sethostname  local-time  local-authfiles  local-tmpfiles  local-rc  local-dmesg  all-Local
+                  all-Runtime  All
+
+	</pre>
+	</p>
+	<p> 
+        The field <tt><em>name</em></tt> give you the name of the <em>tree</em>.
+    </p>
+    <p>
+        The field <tt><em>Initialized</em></tt> tells if the <tree>tree</tree> was initialized with <tt><a href="66-init.html">66-init</a></tt> tool.
+    </p>
+    <p>
+        The field <tt><em>Enabled</em></tt> reveals the state of the tree&mdash;see <tt><a href="66-tree.html">66-tree -E</a></tt>.
+    </p>
+    <p>
+        The field <tt><em>Current</em></tt> tells if the <em>tree</em> is the current one or not&mdash;see <tt><a href="66-tree.html">66-tree -c</a></tt>.
+    </p>
+    <p>
+        The field <tt><em>Contains</em></tt> give you a list of all services enabled in the <em>tree</em>.
+    </p>
+    
+    <p>You can display the contain list as a graph and only these fields using the command <tt>66-intree -o contains -g boot</tt>:
+    <pre>
+    Contains    : /
+                  ├─(253,Enabled,classic) tty12
+                  ├─(0,Enabled,oneshot) system-hostname
+                  ├─(0,Enabled,oneshot) mount-run
+                  ├─(0,Enabled,oneshot) populate-run
+                  ├─(0,Enabled,oneshot) mount-tmp
+                  ├─(0,Enabled,oneshot) populate-tmp
+                  ├─(0,Enabled,oneshot) mount-proc
+                  ├─(0,Enabled,oneshot) mount-sys
+                  ├─(0,Enabled,oneshot) populate-sys
+                  ├─(0,Enabled,oneshot) mount-dev
+                  ├─(0,Enabled,oneshot) mount-pts
+                  ├─(0,Enabled,oneshot) mount-shm
+                  ├─(0,Enabled,oneshot) populate-dev
+                  ├─(0,Enabled,oneshot) mount-cgroups
+                  ├─(0,Enabled,bundle) 00
+                  ├─(0,Enabled,oneshot) modules-kernel
+                  ├─(485,Enabled,longrun) udevd
+                  ├─(0,Enabled,oneshot) udevadm
+                  ├─(0,Enabled,oneshot) devices-crypttab
+                  ├─(0,Enabled,oneshot) system-hwclock
+                  ├─(0,Enabled,oneshot) system-random
+                  ├─(0,Enabled,oneshot) modules-system
+                  ├─(0,Enabled,oneshot) system-sysctl
+                  ├─(0,Enabled,oneshot) system-fontnkey
+                  ├─(0,Enabled,oneshot) devices-dmraid
+                  ├─(0,Enabled,oneshot) devices-btrfs
+                  ├─(0,Enabled,oneshot) devices-lvm 
+                  ├─(0,Enabled,oneshot) devices-zfs
+                  ├─(0,Enabled,bundle) system-Devices
+                  ├─(0,Enabled,oneshot) mount-swap 
+                  ├─(0,Enabled,bundle) all-Mount
+                  ├─(0,Enabled,oneshot) system-fsck
+                  ├─(0,Enabled,oneshot) mount-fstab
+                  ├─(0,Enabled,bundle) all-System
+                  ├─(0,Enabled,oneshot) mount-rw
+                  ├─(0,Enabled,oneshot) local-iptables
+                  ├─(0,Enabled,oneshot) local-ip6tables
+                  ├─(0,Enabled,oneshot) local-loop
+                  ├─(0,Enabled,oneshot) local-sethostname
+                  ├─(0,Enabled,oneshot) local-time
+                  ├─(0,Enabled,oneshot) local-authfiles
+                  ├─(0,Enabled,oneshot) local-tmpfiles  
+                  ├─(0,Enabled,oneshot) local-rc
+                  ├─(0,Enabled,oneshot) local-dmesg
+                  ├─(0,Enabled,bundle) all-Local
+                  ├─(0,Enabled,oneshot) all-Runtime
+                  └─(0,Enabled,bundle) All
+    </pre>
+    <p>
+        For each service the first number found between '()' bracket is the corresponding pid of the service, 
+        the second one is the state of the service, the type of the service is shown next to it. Finally the name of the service is displayed.
+	</p>
+	<p>
+		By default the dependency graph is rendered in order of execution. In this example the <em>'classic' tty12</em> is the first executed
+		service and <em>'bundle' All</em> is the last finished. You can reverse the rendered order with the <tt>-r</tt> option.</p>
+	</p>
+	<p>You can display the name and current field and only these fields for each tree using the command <tt>66-intree -o name,current</tt>:
+    <pre>
+    Name        : boot
+    Current     : no
+
+    Name        : docker
+    Current     : no
+
+    Name        : root
+    Current     : no
+
+    Name        : test
+    Current     : yes
+
+    Name        : user
+    Current     : no
+    </pre>
+    </p>
+ </body>
+</html>
diff --git a/doc/man/66-info.1.scd b/doc/man/66-info.1.scd
index d472b625..e9063a5b 100644
--- a/doc/man/66-info.1.scd
+++ b/doc/man/66-info.1.scd
@@ -2,271 +2,4 @@
 
 # NAME
 
-66-info - Display information about trees and services.
-
-# SYNOPSYS
-
-66-info [ *-h* ] [ *-T* _tree_ ] [ *-S* _service_ ]
-
-## TREE
-
-66-info *-T* [ *-h* ] [ *-c* ] [ *-v* _verbosity_ ] [ *-l* _live_ ] [ _-r_ ] [ *-d* _depth_ ] _tree_
-
-## SERVICE
-
-66-info *-S* [ *-h* ] [ *-c* ] [ *-v* _verbosity_ ] [ *-l* _live_ ] [ *-p* _n lines_ ] [ *-r* ] [ *-d* _depth_ ] _service_
-
-# DESCRIPTION
-
-*66-info* displays detailed information about a _tree_ or a specific _service_
-depending on the options passed.
-
-# OPTIONS
-
-*-h*
-	Prints this help.
-
-*-T*
-	Asks for _tree_ information.
-
-*-S*
-	Asks for _service_ information.
-
-## TREE
-
-*-h*
-	Prints this help.
-
-*-c*
-	Disable colorization.
-
-*-C*
-	Force colorization.
-
-*-v* _verbosity_
-	Increases/decreases the verbosity of the command.++
-	*1* : (Default) Only print error messages.++
-	*2* : Also print warning messages.++
-	*3* : Also print debugging messages.
-
-*-l* _live_
-	Changes the supervision directory of _service_ to _live_.
-	By default this will be *%%livedir%%*. The default can also be changed at
-	compile time by passing the --livedir=_live_ option to *./configure*. An
-	existing absolute path is expected and should be within a writable
-	filesystem - likely a RAM filesystem. See *66-scandir*(1).
-
-*-r*
-	Shows the dependency graph of _tree_ in reverse mode.
-
-*-d* _depth_
-	Limits the depth of the dependency graph visualisation; defaults to 1.
-	If _tree_ is not specified *66-info* will display information about all
-	available trees for the current owner of the process.
-
-## SERVICE
-
-*-h*
-	Prints this help.
-
-*-c*
-	Disable colorization.
-
-*-C*
-	Force colorization.
-
-*-v* _verbosity_
-	Increases/decreases the verbosity of the command.++
-	*1* : (Default) Only print error messages.++
-	*2* : Also print warning messages.++
-	*3* : Also print debugging messages.
-
-*-l* _live_
-	Changes the supervision directory of _service_ to _live_.
-	By default this will be *%%livedir%%*. The default can also be changed at
-	compile time by passing the --livedir=_live_ option to *./configure*. An
-	existing absolute path is expected and should be within a writable
-	filesystem - likely a RAM filesystem. See *66-scandir*(1).
-
-*-p* _n lines_
-	Prints the _n last_ lines from the associated log file of the _service_.
-
-*-r*
-	Shows the dependency graph of _service_ in reverse mode.
-
-*-d* _depth_
-	Limits the depth of the dependency graph visualisation; defaults to 1.
-
-# EXAMPLE
-
-## TREE OUTPUT DISPLAY
-
-The command "66-info -T boot" as root user on the _Obarun_ default system
-displays the following where *boot* is the tree used to properly boot the
-machine:
-
-```
-	               boot           
-	Initialized: yes | Current: no
-	Contains:       | Enabled: no
-	├─(0,Enabled,oneshot) system-hostname
-	├─(0,Enabled,oneshot) mount-run
-	├─(0,Enabled,oneshot) populate-run
-	├─(0,Enabled,oneshot) mount-tmp
-	├─(0,Enabled,oneshot) populate-tmp
-	├─(0,Enabled,oneshot) mount-proc
-	├─(0,Enabled,oneshot) mount-sys
-	├─(0,Enabled,oneshot) populate-sys
-	├─(0,Enabled,oneshot) mount-dev
-	├─(0,Enabled,oneshot) mount-pts
-	├─(0,Enabled,oneshot) mount-shm
-	├─(0,Enabled,oneshot) populate-dev
-	├─(0,Enabled,bundle) 00
-	├─(0,Enabled,oneshot) modules-kernel
-	├─(490,Enabled,longrun) udevd
-	├─(0,Enabled,oneshot) udevadm
-	├─(0,Enabled,oneshot) devices-crypttab
-	├─(0,Enabled,oneshot) system-hwclock
-	├─(0,Enabled,oneshot) system-random
-	├─(0,Enabled,oneshot) modules-system
-	├─(0,Enabled,oneshot) system-sysctl
-	├─(0,Enabled,oneshot) system-fontnkey
-	├─(0,Enabled,oneshot) devices-dmraid
-	├─(0,Enabled,oneshot) devices-btrfs
-	├─(0,Enabled,oneshot) devices-lvm
-	├─(0,Enabled,bundle) system-Devices
-	├─(0,Enabled,oneshot) system-fsck
-	├─(0,Enabled,oneshot) mount-fstab
-	├─(0,Enabled,bundle) all-System
-	├─(0,Enabled,oneshot) mount-rw
-	├─(0,Enabled,oneshot) local-iptables
-	├─(0,Enabled,oneshot) local-ip6tables
-	├─(0,Enabled,oneshot) local-loop
-	├─(0,Enabled,oneshot) local-time
-	├─(0,Enabled,oneshot) local-authfiles
-	├─(0,Enabled,oneshot) local-tmpfiles
-	├─(0,Enabled,oneshot) local-rc
-	├─(0,Enabled,oneshot) local-dmesg
-	├─(0,Enabled,bundle) all-Local
-	├─(0,Enabled,oneshot) mount-cgroups
-	├─(0,Enabled,oneshot) mount-swap
-	├─(0,Enabled,oneshot) mount-zfs
-	├─(0,Enabled,bundle) all-Mount
-	├─(0,Enabled,oneshot) all-Runtime
-	├─(0,Enabled,bundle) All
-	└─(254,Enabled,classic) tty12
-```
-
-By default the first service displayed is the first service started, the second
-one is the second started and so on.
-
-The first line give you the name of the _tree_, *Initialized* tells if the
-_tree_ was initialized with *66-init*(1) tool, *Current* tells if the _tree_
-is the current one or not (see *66-tree*(1) *-c* option) and *Enabled* reveals
-the state of the tree(see *66-tree*(1) *-E* option).
-For each service the first number found between *()* bracket is the
-corresponding pid of the service, the second one is the state of the service,
-the type of the service is shown next to it. Finally the name of the service is
-displayed.
-
-By default the dependency graph is rendered in order of execution. In this
-example the *classic* tty12</em> is the last finished service and *oneshot*
-_filesystem_ is the first one executed. You can reverse the rendered order with
-the *-r* option.
-	
-## SERVICE OUTPUT DISPLAY
-
-The command "sudo 66-info -S -d3 00" displays the following where *00* is the
-name of the service:
-
-```
-	                   00
-	on tree : boot
-	status : Enabled, nothing to display
-	type : bundle
-	description : Set the hostname and mount filesystem
-	source : %%service_packager%%/boot/mount/
-	run at : %%livedir%%/tree/0/boot/servicedirs/00
-	             contents                  
-	├─(0,Enabled,oneshot) system-hostname
-	├─(0,Enabled,oneshot) mount-run
-	├─(0,Enabled,oneshot) populate-run
-	│ └─(0,Enabled,oneshot) mount-run
-	├─(0,Enabled,oneshot) mount-tmp
-	├─(0,Enabled,oneshot) populate-tmp
-	│ └─(0,Enabled,oneshot) mount-tmp
-	├─(0,Enabled,oneshot) mount-proc
-	├─(0,Enabled,oneshot) mount-sys
-	│ └─(0,Enabled,oneshot) mount-proc
-	├─(0,Enabled,oneshot) populate-sys
-	│ ├─(0,Enabled,oneshot) mount-proc
-	│ └─(0,Enabled,oneshot) mount-sys
-	├─(0,Enabled,oneshot) mount-dev
-	│ └─(0,Enabled,oneshot) mount-sys
-	├─(0,Enabled,oneshot) mount-pts
-	│ └─(0,Enabled,oneshot) mount-dev
-	├─(0,Enabled,oneshot) mount-shm
-	│ └─(0,Enabled,oneshot) mount-dev
-	└─(0,Enabled,oneshot) populate-dev
-	  └─(0,Enabled,oneshot) mount-dev
-```
-
-Let's take another example, the command "sudo 66-info -S -p5 ntpd" displays
-the following:
-
-```
-	                   ntpd
-	on tree : root
-	status : Disabled, up (pid 786) 2380 seconds
-	type : classic
-	description : ntpd daemon
-	source : %%service_sys%%
-	run at : %%livedir%%/scandir/0/ntpd
-	               dependencies
-	└─(785,Disabled,classic) ntpd-log
-	                 scripts
-	start script : foreground { mkdir -p  -m 0755 ${dir_run} } 
-	execl-cmdline -s { ntpd ${cmd_args} } 
-	               environment
-	dir_run=!/run/openntpd
-	cmd_args=!-d -s
-	                 logger
-	logger associated : ntpd-log
-	log destination : %%system_log%%/ntpd 
-	                log file
-	2019-03-18 06:50:21.749572500  adjtimex returns frequency of 0.000000ppm
-	2019-03-18 06:50:21.764241500  ntp engine ready
-	2019-03-18 06:50:21.847440500  adjtimex adjusted frequency by 16.428986ppm
-	2019-03-18 06:50:21.847479500  set local clock to Mon Mar 18 06:50:21 +11 2019 (offset 0.000000s)
-
-```
-
-In our case :
-
-*ntpd* : name of the service. Main section where general informations is displayed.++
-*on tree* : service enable on tree root.++
-*status* : status of the service.++
-*type* : type of the service.++
-*description* : short description of the service.++
-*source* : origin of the frontend service file used to enable the service.++
-*run at* : location of the service into the scandir.++
-*dependencies* : dependencies informations section. This section will display
-	a graphical tree on the service dependencies.
-*scripts* : scripts informations section. This will display the command
-	executed at start and stop process.
-*start script* : command line executed at start process. If a stop section was
-	set an additionnal field called stop script will be displayed with the
-	corresponding command line executed at stop process.
-*environment* : environment informations section. Display the environment
-	variables set at *%%service_admconf%%<service_name>* or
-	*$HOME/%%service_userconf%%<service_name>* depending of the owner of
-	the process.
-*logger* : logger informations section.++
-*logger associated* : name of the service logger.++
-*log destination* : destination of the logger file.++
-	last part display the last 5 line of the logger file.
-
-# NOTES
-
-*66-info* use color to output the informations, the previous examples do not
-reflect the veritable output concerning the colors.
+66-info is deprecated -- see 66-intree for tree informations and 66-inservice for service informations.
diff --git a/doc/man/66-inservice.1.scd b/doc/man/66-inservice.1.scd
new file mode 100644
index 00000000..36b8a41e
--- /dev/null
+++ b/doc/man/66-inservice.1.scd
@@ -0,0 +1,159 @@
+66-inservice(1)
+
+# NAME
+
+66-inservice - Display information about services.
+
+# SYNOPSYS
+
+66-inservice [ *-h* ] [ *-v* _verbosity_ ] [ *-c* ] [ *-o* _name,intree,enabled,..._ ] [ *-g* ] [ *-d* _depth_ ] [ *-r* ] [ *-t* _tree_ ] [ *-p* _nline_ ] _service_
+
+# DESCRIPTION
+
+*66-inservice* displays detailed information about a specific _service_.
+
+# OPTIONS
+
+*-h*
+	Prints this help.
+
+*-v* _verbosity_
+	Increases/decreases the verbosity of the command.++
+	*1* : (Default) Only print error messages.++
+	*2* : Also print warning messages.++
+	*3* : Also print debugging messages.
+
+*-c*
+	enable colorization.
+
+*-o*
+	comma separated list of field to display. If the option is not past,
+	*66-inservice* will display all field.
+
+*-g*
+	shows the dependency list of _tree_ as graph instead of list.
+
+*-d* _depth_
+	Limits the depth of the dependency list visualisation; defaults to 1.
+	This implies the *-g* option.
+
+*-r*
+	Shows the dependency list of _tree_ in reverse mode.
+
+*-t* _tree_
+	only search the _service_ at the specified _tree_.
+
+*-p* _nline_
+	prints the _nline_ last lines from the log file of the _service_.
+	Default to 20.
+
+## VALID FIELD FOR -g OPTION
+
+*name*
+	Displays the name of the _service_.
+
+*intree*
+	Displays the _service_'s tree name.
+
+*status*
+	Displays the status of the _service_.
+
+*type*
+	Displays the type of the _service_.
+
+*description*
+	Displays the description of the _service_.
+
+*intree*
+	Displays the source of the _service_'s frontend file.
+
+*live*
+	Displays the live _service_'s directory.
+
+*depends*
+	Displays the _service_'s dependencies.
+
+*start*
+	Displays the _service_'s start script.
+
+*stop*
+	Displays the _service_'s stop script.
+
+*envat*
+	Displays the source of the environment file.
+
+*envfile*
+	Displays the contain of the environment file.
+
+*logname*
+	Displays the logger's name.
+
+*logdst*
+	Displays the logger's destination.
+
+*logfile*
+	Displays the contain of the log file.
+
+# COMMAND AND OUTPUT EXAMPLE
+
+The command "66-inservice 00" as root user on the _Obarun_ default system
+displays the following where *00* is service contained in the tree *boot*:
+
+```
+Name               : 00
+In tree            : boot
+Status             : enabled, nothing to display
+Type               : bundle
+Description        : Set the hostname and mount filesystem
+Source             : %%service_packager%%/boot/mount/00
+Live               : %%livedir%%/tree/0/boot/servicedirs/00
+Depends on         : system-hostname  mount-run  populate-run  mount-tmp
+                     populate-tmp  mount-proc  mount-sys  populate-sys
+                     mount-dev  mount-pts  mount-shm  populate-dev
+                     mount-cgroups
+Start script       : nothing to display
+Stop script        : nothing to display
+Environment source : environment was not set
+Environment file   : environment was not set
+Log name           : logger doesn't exist
+Log destination    : logger doesn't exist
+Log file           : logger doesn't exist
+    
+```
+
+By default the dependency graph is rendered in order of execution. In 
+this example the *oneshot system-hostname* is the first executed service and 
+*mount-cgroups* is the last finished. You can reverse the rendered order with
+the *-r* option.
+
+You can display the status and depends field and only these fields of a 
+service using the command "66-inservice -o status,depends -g connmand"
+where the dependency list is diplayed as a graph:
+
+```
+Status             : enabled, up (pid 938) 34652 seconds
+Depends on         : /
+                     ├─(933,Enabled,longrun) dbus
+                     └─(929,Enabled,longrun) connmand-log
+
+```
+You can display the status,log file and log destination and only these fields
+of a service using the command "66-inservice -o status,logdst,logfile -g dbus":
+
+```
+
+Status             : enabled, up (pid 933) 34852 seconds, ready 34852 seconds
+Log destination    : %%system_log%%/dbus
+Log file           :
+2019-10-03 16:16:05.246991500  dbus-daemon[933]: [system] Rejected send 
+message, 4 matched rules; type="method_call", sender=":1.3" (uid=1000 
+pid=1226 comm="connman-gtk --tray ") interface="net.connman.Technology" 
+member="Scan" error name="(unset)" requested_reply="0" destination=":1.0"
+(uid=0 pid=938 comm="connmand -n --nobacktrace --nodnsproxy ")
+2019-10-03 16:16:35.256146500  dbus-daemon[933]: [system] Rejected send 
+message, 4 matched rules; type="method_call", sender=":1.3" (uid=1000 
+pid=1226 comm="connman-gtk --tray ") interface="net.connman.Technology" 
+member="Scan" error name="(unset)" requested_reply="0" destination=":1.0"
+(uid=0 pid=938 comm="connmand -n --nobacktrace --nodnsproxy ")
+
+```
diff --git a/doc/man/66-intree.1.scd b/doc/man/66-intree.1.scd
new file mode 100644
index 00000000..45350218
--- /dev/null
+++ b/doc/man/66-intree.1.scd
@@ -0,0 +1,188 @@
+66-intree(1)
+
+# NAME
+
+66-intree - Display information about trees.
+
+# SYNOPSYS
+
+66-intree [ *-h* ] [ *-v* _verbosity_ ] [ *-l* _live_ ] [ *-c* ] [ *-o* name,init,enabled,... ] [ *-g* ] [ *-d* _depth_ ] [ *-r* ] _tree_
+
+# DESCRIPTION
+
+*66-intree* displays detailed information about a _tree_.
+
+# OPTIONS
+
+*-h*
+	Prints this help.
+
+*-v* _verbosity_
+	Increases/decreases the verbosity of the command.++
+	*1* : (Default) Only print error messages.++
+	*2* : Also print warning messages.++
+	*3* : Also print debugging messages.
+
+*-l* _live_
+	Changes the supervision directory of _service_ to _live_.
+	By default this will be *%%livedir%%*. The default can also be changed at
+	compile time by passing the --livedir=_live_ option to *./configure*. An
+	existing absolute path is expected and should be within a writable
+	filesystem - likely a RAM filesystem. See *66-scandir*(1).
+
+*-c*
+	enable colorization.
+
+*-o*
+	comma separated list of field to display. If the option is not past,
+	*66-intree* will display all field.
+
+*-g*
+	shows the dependency list of _tree_ as graph instead of list.
+
+*-r*
+	Shows the dependency list of _tree_ in reverse mode.
+
+*-d* _depth_
+	Limits the depth of the dependency list visualisation; defaults to 1.
+	This implies the *-g* option.
+
+	If _tree_ is not specified *66-intree* will display information about all
+	available trees for the current owner of the process.
+
+## VALID FIELD FOR -g OPTION
+
+*name*
+	Displays the name of the _tree_.
+
+*init*
+	Display a boolean value of the initialization state.
+
+*enabled*
+	Displays a boolean value of the enable state.
+
+*curren*
+	Displays a boolean value of the current state.
+
+*contains*
+	Displays the contain of _tree_.
+
+# COMMAND AND OUTPUT EXAMPLE
+
+The command "66-intree boot" as root user on the _Obarun_ default system
+displays the following where *boot* is the tree used to properly boot 
+the machine:
+
+```
+Name        : boot
+Initialized : yes
+Enabled     : no
+Current     : no
+Contains    : tty12  system-hostname  mount-run  populate-run  mount-tmp
+              populate-tmp  mount-proc  mount-sys  populate-sys  mount-dev
+              mount-pts  mount-shm  populate-dev  mount-cgroups  00
+              modules-kernel  udevd  udevadm  devices-crypttab
+              system-hwclock  system-random  modules-system  system-sysctl
+              system-fontnkey  devices-dmraid  devices-btrfs  devices-lvm
+              devices-zfs  system-Devices  mount-swap  all-Mount
+              system-fsck  mount-fstab  all-System  mount-rw  local-iptables
+              local-ip6tables  local-loop  local-sethostname  local-time
+              local-authfiles  local-tmpfiles  local-rc  local-dmesg  all-Local
+              all-Runtime  All
+```
+
+The field *name* give you the name of the _tree_.
+
+The field *Initialized* tells if the _tree_ was initialized with "66-init" tool.
+
+The field *Enabled* reveals the state of the tree -- see "66-tree -E".
+
+The field *Current* tells if the _tree_ is the current one or not -- see
+"66-tree -c".
+
+The field *Contains* give you a list of all services enabled in the _tree_.
+
+You can display the contain list as a graph and only these fields using 
+the command "66-intree -o contains -g boot":
+
+```
+Contains    : /
+              ├─(253,Enabled,classic) tty12
+              ├─(0,Enabled,oneshot) system-hostname
+              ├─(0,Enabled,oneshot) mount-run
+              ├─(0,Enabled,oneshot) populate-run
+              ├─(0,Enabled,oneshot) mount-tmp
+              ├─(0,Enabled,oneshot) populate-tmp
+              ├─(0,Enabled,oneshot) mount-proc
+              ├─(0,Enabled,oneshot) mount-sys
+              ├─(0,Enabled,oneshot) populate-sys
+              ├─(0,Enabled,oneshot) mount-dev
+              ├─(0,Enabled,oneshot) mount-pts
+              ├─(0,Enabled,oneshot) mount-shm
+              ├─(0,Enabled,oneshot) populate-dev
+              ├─(0,Enabled,oneshot) mount-cgroups
+              ├─(0,Enabled,bundle) 00
+              ├─(0,Enabled,oneshot) modules-kernel
+              ├─(485,Enabled,longrun) udevd
+              ├─(0,Enabled,oneshot) udevadm
+              ├─(0,Enabled,oneshot) devices-crypttab
+              ├─(0,Enabled,oneshot) system-hwclock
+              ├─(0,Enabled,oneshot) system-random
+              ├─(0,Enabled,oneshot) modules-system
+              ├─(0,Enabled,oneshot) system-sysctl
+              ├─(0,Enabled,oneshot) system-fontnkey
+              ├─(0,Enabled,oneshot) devices-dmraid
+              ├─(0,Enabled,oneshot) devices-btrfs
+              ├─(0,Enabled,oneshot) devices-lvm 
+              ├─(0,Enabled,oneshot) devices-zfs
+              ├─(0,Enabled,bundle) system-Devices
+              ├─(0,Enabled,oneshot) mount-swap 
+              ├─(0,Enabled,bundle) all-Mount
+              ├─(0,Enabled,oneshot) system-fsck
+              ├─(0,Enabled,oneshot) mount-fstab
+              ├─(0,Enabled,bundle) all-System
+              ├─(0,Enabled,oneshot) mount-rw
+              ├─(0,Enabled,oneshot) local-iptables
+              ├─(0,Enabled,oneshot) local-ip6tables
+              ├─(0,Enabled,oneshot) local-loop
+              ├─(0,Enabled,oneshot) local-sethostname
+              ├─(0,Enabled,oneshot) local-time
+              ├─(0,Enabled,oneshot) local-authfiles
+              ├─(0,Enabled,oneshot) local-tmpfiles  
+              ├─(0,Enabled,oneshot) local-rc
+              ├─(0,Enabled,oneshot) local-dmesg
+              ├─(0,Enabled,bundle) all-Local
+              ├─(0,Enabled,oneshot) all-Runtime
+              └─(0,Enabled,bundle) All
+
+```
+For each service the first number found between *()* bracket is the 
+corresponding pid of the service, the second one is the state of the 
+service, the type of the service is shown next to it. Finally the name 
+of the service is displayed.
+
+By default the dependency graph is rendered in order of execution. In 
+this example the *classic tty12* is the first executed service and 
+*bundle All* is the last finished. You can reverse the rendered order with
+the *-r* option.
+
+You can display the name and current field and only these fields for each 
+tree using the command "66-intree -o name,current":
+
+```
+Name        : boot
+Current     : no
+
+Name        : docker
+Current     : no
+
+Name        : root
+Current     : no
+
+Name        : test
+Current     : yes
+
+Name        : user
+Current     : no
+
+```
diff --git a/package/deps.mak b/package/deps.mak
index 75f4c3e6..12b7570f 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -7,6 +7,7 @@ src/include/66/backup.h: src/include/66/ssexec.h
 src/include/66/constants.h: src/include/66/config.h
 src/include/66/db.h: src/include/66/ssexec.h
 src/include/66/hpr.h: src/include/66/constants.h
+src/include/66/info.h: src/include/66/enum.h src/include/66/resolve.h
 src/include/66/parser.h: src/include/66/enum.h src/include/66/ssexec.h
 src/include/66/rc.h: src/include/66/ssexec.h
 src/include/66/resolve.h: src/include/66/parser.h src/include/66/ssexec.h
@@ -20,8 +21,10 @@ src/66/66-disable.o src/66/66-disable.lo: src/66/66-disable.c src/include/66/sse
 src/66/66-enable.o src/66/66-enable.lo: src/66/66-enable.c src/include/66/ssexec.h
 src/66/66-env.o src/66/66-env.lo: src/66/66-env.c src/include/66/ssexec.h
 src/66/66-hpr.o src/66/66-hpr.lo: src/66/66-hpr.c src/include/66/config.h src/include/66/hpr.h
-src/66/66-info.o src/66/66-info.lo: src/66/66-info.c src/include/66/constants.h src/include/66/enum.h src/include/66/environ.h src/include/66/resolve.h src/include/66/tree.h src/include/66/utils.h
+src/66/66-info.o src/66/66-info.lo: src/66/66-info.c
 src/66/66-init.o src/66/66-init.lo: src/66/66-init.c src/include/66/ssexec.h
+src/66/66-inservice.o src/66/66-inservice.lo: src/66/66-inservice.c src/include/66/constants.h src/include/66/enum.h src/include/66/environ.h src/include/66/info.h src/include/66/resolve.h src/include/66/tree.h src/include/66/utils.h
+src/66/66-intree.o src/66/66-intree.lo: src/66/66-intree.c src/include/66/constants.h src/include/66/enum.h src/include/66/info.h src/include/66/resolve.h src/include/66/tree.h src/include/66/utils.h
 src/66/66-parser.o src/66/66-parser.lo: src/66/66-parser.c src/include/66/constants.h src/include/66/parser.h src/include/66/utils.h
 src/66/66-scanctl.o src/66/66-scanctl.lo: src/66/66-scanctl.c src/include/66/utils.h
 src/66/66-scandir.o src/66/66-scandir.lo: src/66/66-scandir.c src/include/66/config.h src/include/66/constants.h src/include/66/environ.h src/include/66/utils.h
@@ -31,7 +34,6 @@ src/66/66-start.o src/66/66-start.lo: src/66/66-start.c src/include/66/ssexec.h
 src/66/66-stop.o src/66/66-stop.lo: src/66/66-stop.c src/include/66/ssexec.h
 src/66/66-svctl.o src/66/66-svctl.lo: src/66/66-svctl.c src/include/66/ssexec.h
 src/66/66-tree.o src/66/66-tree.lo: src/66/66-tree.c src/include/66/config.h src/include/66/constants.h src/include/66/db.h src/include/66/enum.h src/include/66/resolve.h src/include/66/state.h src/include/66/tree.h src/include/66/utils.h
-src/66/66-treeinfo.o src/66/66-treeinfo.lo: src/66/66-treeinfo.c src/include/66/constants.h src/include/66/enum.h src/include/66/environ.h src/include/66/resolve.h src/include/66/tree.h src/include/66/utils.h
 src/extra-tools/66-echo.o src/extra-tools/66-echo.lo: src/extra-tools/66-echo.c
 src/extra-tools/66-umountall.o src/extra-tools/66-umountall.lo: src/extra-tools/66-umountall.c
 src/lib66/backup_cmd_switcher.o src/lib66/backup_cmd_switcher.lo: src/lib66/backup_cmd_switcher.c src/include/66/constants.h src/include/66/enum.h src/include/66/ssexec.h src/include/66/utils.h
@@ -67,6 +69,7 @@ src/lib66/set_livestate.o src/lib66/set_livestate.lo: src/lib66/set_livestate.c
 src/lib66/set_livetree.o src/lib66/set_livetree.lo: src/lib66/set_livetree.c src/include/66/constants.h src/include/66/utils.h
 src/lib66/set_ownerhome.o src/lib66/set_ownerhome.lo: src/lib66/set_ownerhome.c src/include/66/config.h src/include/66/utils.h
 src/lib66/set_ownersysdir.o src/lib66/set_ownersysdir.lo: src/lib66/set_ownersysdir.c src/include/66/config.h src/include/66/utils.h
+src/lib66/ss_info_utils.o src/lib66/ss_info_utils.lo: src/lib66/ss_info_utils.c src/include/66/info.h src/include/66/resolve.h
 src/lib66/ss_utils.o src/lib66/ss_utils.lo: src/lib66/ss_utils.c src/include/66/utils.h
 src/lib66/ssexec_dbctl.o src/lib66/ssexec_dbctl.lo: src/lib66/ssexec_dbctl.c src/include/66/constants.h src/include/66/db.h src/include/66/enum.h src/include/66/resolve.h src/include/66/ssexec.h src/include/66/state.h src/include/66/utils.h
 src/lib66/ssexec_disable.o src/lib66/ssexec_disable.lo: src/lib66/ssexec_disable.c src/include/66/constants.h src/include/66/db.h src/include/66/resolve.h src/include/66/state.h src/include/66/svc.h src/include/66/tree.h src/include/66/utils.h
@@ -113,6 +116,10 @@ src/lib66/tree_switch_current.o src/lib66/tree_switch_current.lo: src/lib66/tree
 66-info: src/66/66-info.o ${LIB66} -ls6 -loblibs -lskarnet
 66-init: EXTRA_LIBS :=
 66-init: src/66/66-init.o ${LIB66} -ls6 -loblibs -lskarnet
+66-inservice: EXTRA_LIBS :=
+66-inservice: src/66/66-inservice.o ${LIB66} -ls6 -loblibs -lskarnet
+66-intree: EXTRA_LIBS :=
+66-intree: src/66/66-intree.o ${LIB66} -ls6 -loblibs -lskarnet
 66-parser: EXTRA_LIBS :=
 66-parser: src/66/66-parser.o ${LIB66} -loblibs -lskarnet
 66-scanctl: EXTRA_LIBS :=
@@ -136,9 +143,9 @@ src/lib66/tree_switch_current.o src/lib66/tree_switch_current.lo: src/lib66/tree
 66-umountall: EXTRA_LIBS :=
 66-umountall: src/extra-tools/66-umountall.o -lskarnet 
 ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
-lib66.a.xyzzy: src/lib66/backup_cmd_switcher.o src/lib66/backup_make_new.o src/lib66/backup_realpath_sym.o src/lib66/db_compile.o src/lib66/db_find_compiled_state.o src/lib66/db_ok.o src/lib66/db_switch_to.o src/lib66/db_update.o src/lib66/environ.o src/lib66/get_enum.o src/lib66/get_uidgid.o src/lib66/get_userhome.o src/lib66/hpr_shutdown.o src/lib66/hpr_wall.o src/lib66/instance.o src/lib66/parser.o src/lib66/parser_enabled.o src/lib66/parser_utils.o src/lib66/parser_write.o src/lib66/rc_init.o src/lib66/rc_manage.o src/lib66/rc_send.o src/lib66/rc_unsupervise.o src/lib66/resolve.o src/lib66/resolve_graph.o src/lib66/scandir_ok.o src/lib66/scandir_send_signal.o src/lib66/set_livedir.o src/lib66/set_livescan.o src/lib66/set_livestate.o src/lib66/set_livetree.o src/lib66/set_ownerhome.o src/lib66/set_ownersysdir.o src/lib66/ss_utils.o src/lib66/ssexec_dbctl.o src/lib66/ssexec_enable.o src/lib66/ssexec_env.o src/lib66/ssexec_disable.o src/lib66/ssexec_free.o src/lib66/ssexec_help.o src/lib66/ssexec_init.o src/lib66/ssexec_main.o src/lib66/ssexec_start.o src/lib66/ssexec_stop.o src/lib66/ssexec_svctl.o src/lib66/state.o src/lib66/sv_alltype_zero.o src/lib66/svc_init.o src/lib66/svc_init_pipe.o src/lib66/svc_send.o src/lib66/svc_switch_to.o src/lib66/svc_unsupervise.o src/lib66/tree_cmd_state.o src/lib66/tree_copy.o src/lib66/tree_copy_tmp.o src/lib66/tree_find_current.o src/lib66/tree_get_permissions.o src/lib66/tree_sethome.o src/lib66/tree_setname.o src/lib66/tree_switch_current.o
+lib66.a.xyzzy: src/lib66/backup_cmd_switcher.o src/lib66/backup_make_new.o src/lib66/backup_realpath_sym.o src/lib66/db_compile.o src/lib66/db_find_compiled_state.o src/lib66/db_ok.o src/lib66/db_switch_to.o src/lib66/db_update.o src/lib66/environ.o src/lib66/get_enum.o src/lib66/get_uidgid.o src/lib66/get_userhome.o src/lib66/hpr_shutdown.o src/lib66/hpr_wall.o src/lib66/instance.o src/lib66/parser.o src/lib66/parser_enabled.o src/lib66/parser_utils.o src/lib66/parser_write.o src/lib66/rc_init.o src/lib66/rc_manage.o src/lib66/rc_send.o src/lib66/rc_unsupervise.o src/lib66/resolve.o src/lib66/resolve_graph.o src/lib66/scandir_ok.o src/lib66/scandir_send_signal.o src/lib66/set_livedir.o src/lib66/set_livescan.o src/lib66/set_livestate.o src/lib66/set_livetree.o src/lib66/set_ownerhome.o src/lib66/set_ownersysdir.o src/lib66/ss_info_utils.o src/lib66/ss_utils.o src/lib66/ssexec_dbctl.o src/lib66/ssexec_enable.o src/lib66/ssexec_env.o src/lib66/ssexec_disable.o src/lib66/ssexec_free.o src/lib66/ssexec_help.o src/lib66/ssexec_init.o src/lib66/ssexec_main.o src/lib66/ssexec_start.o src/lib66/ssexec_stop.o src/lib66/ssexec_svctl.o src/lib66/state.o src/lib66/sv_alltype_zero.o src/lib66/svc_init.o src/lib66/svc_init_pipe.o src/lib66/svc_send.o src/lib66/svc_switch_to.o src/lib66/svc_unsupervise.o src/lib66/tree_cmd_state.o src/lib66/tree_copy.o src/lib66/tree_copy_tmp.o src/lib66/tree_find_current.o src/lib66/tree_get_permissions.o src/lib66/tree_sethome.o src/lib66/tree_setname.o src/lib66/tree_switch_current.o
 else
-lib66.a.xyzzy: src/lib66/backup_cmd_switcher.lo src/lib66/backup_make_new.lo src/lib66/backup_realpath_sym.lo src/lib66/db_compile.lo src/lib66/db_find_compiled_state.lo src/lib66/db_ok.lo src/lib66/db_switch_to.lo src/lib66/db_update.lo src/lib66/environ.lo src/lib66/get_enum.lo src/lib66/get_uidgid.lo src/lib66/get_userhome.lo src/lib66/hpr_shutdown.lo src/lib66/hpr_wall.lo src/lib66/instance.lo src/lib66/parser.lo src/lib66/parser_enabled.lo src/lib66/parser_utils.lo src/lib66/parser_write.lo src/lib66/rc_init.lo src/lib66/rc_manage.lo src/lib66/rc_send.lo src/lib66/rc_unsupervise.lo src/lib66/resolve.lo src/lib66/resolve_graph.lo src/lib66/scandir_ok.lo src/lib66/scandir_send_signal.lo src/lib66/set_livedir.lo src/lib66/set_livescan.lo src/lib66/set_livestate.lo src/lib66/set_livetree.lo src/lib66/set_ownerhome.lo src/lib66/set_ownersysdir.lo src/lib66/ss_utils.lo src/lib66/ssexec_dbctl.lo src/lib66/ssexec_enable.lo src/lib66/ssexec_env.lo src/lib66/ssexec_disable.lo src/lib66/ssexec_free.lo src/lib66/ssexec_help.lo src/lib66/ssexec_init.lo src/lib66/ssexec_main.lo src/lib66/ssexec_start.lo src/lib66/ssexec_stop.lo src/lib66/ssexec_svctl.lo src/lib66/state.lo src/lib66/sv_alltype_zero.lo src/lib66/svc_init.lo src/lib66/svc_init_pipe.lo src/lib66/svc_send.lo src/lib66/svc_switch_to.lo src/lib66/svc_unsupervise.lo src/lib66/tree_cmd_state.lo src/lib66/tree_copy.lo src/lib66/tree_copy_tmp.lo src/lib66/tree_find_current.lo src/lib66/tree_get_permissions.lo src/lib66/tree_sethome.lo src/lib66/tree_setname.lo src/lib66/tree_switch_current.lo
+lib66.a.xyzzy: src/lib66/backup_cmd_switcher.lo src/lib66/backup_make_new.lo src/lib66/backup_realpath_sym.lo src/lib66/db_compile.lo src/lib66/db_find_compiled_state.lo src/lib66/db_ok.lo src/lib66/db_switch_to.lo src/lib66/db_update.lo src/lib66/environ.lo src/lib66/get_enum.lo src/lib66/get_uidgid.lo src/lib66/get_userhome.lo src/lib66/hpr_shutdown.lo src/lib66/hpr_wall.lo src/lib66/instance.lo src/lib66/parser.lo src/lib66/parser_enabled.lo src/lib66/parser_utils.lo src/lib66/parser_write.lo src/lib66/rc_init.lo src/lib66/rc_manage.lo src/lib66/rc_send.lo src/lib66/rc_unsupervise.lo src/lib66/resolve.lo src/lib66/resolve_graph.lo src/lib66/scandir_ok.lo src/lib66/scandir_send_signal.lo src/lib66/set_livedir.lo src/lib66/set_livescan.lo src/lib66/set_livestate.lo src/lib66/set_livetree.lo src/lib66/set_ownerhome.lo src/lib66/set_ownersysdir.lo src/lib66/ss_info_utils.lo src/lib66/ss_utils.lo src/lib66/ssexec_dbctl.lo src/lib66/ssexec_enable.lo src/lib66/ssexec_env.lo src/lib66/ssexec_disable.lo src/lib66/ssexec_free.lo src/lib66/ssexec_help.lo src/lib66/ssexec_init.lo src/lib66/ssexec_main.lo src/lib66/ssexec_start.lo src/lib66/ssexec_stop.lo src/lib66/ssexec_svctl.lo src/lib66/state.lo src/lib66/sv_alltype_zero.lo src/lib66/svc_init.lo src/lib66/svc_init_pipe.lo src/lib66/svc_send.lo src/lib66/svc_switch_to.lo src/lib66/svc_unsupervise.lo src/lib66/tree_cmd_state.lo src/lib66/tree_copy.lo src/lib66/tree_copy_tmp.lo src/lib66/tree_find_current.lo src/lib66/tree_get_permissions.lo src/lib66/tree_sethome.lo src/lib66/tree_setname.lo src/lib66/tree_switch_current.lo
 endif
 lib66.so.xyzzy: EXTRA_LIBS := -ls6rc -ls6 -loblibs -lexecline -lskarnet
-lib66.so.xyzzy: src/lib66/backup_cmd_switcher.lo src/lib66/backup_make_new.lo src/lib66/backup_realpath_sym.lo src/lib66/db_compile.lo src/lib66/db_find_compiled_state.lo src/lib66/db_ok.lo src/lib66/db_switch_to.lo src/lib66/db_update.lo src/lib66/environ.lo src/lib66/get_enum.lo src/lib66/get_uidgid.lo src/lib66/get_userhome.lo src/lib66/hpr_shutdown.lo src/lib66/hpr_wall.lo src/lib66/instance.lo src/lib66/parser.lo src/lib66/parser_enabled.lo src/lib66/parser_utils.lo src/lib66/parser_write.lo src/lib66/rc_init.lo src/lib66/rc_manage.lo src/lib66/rc_send.lo src/lib66/rc_unsupervise.lo src/lib66/resolve.lo src/lib66/resolve_graph.lo src/lib66/scandir_ok.lo src/lib66/scandir_send_signal.lo src/lib66/set_livedir.lo src/lib66/set_livescan.lo src/lib66/set_livestate.lo src/lib66/set_livetree.lo src/lib66/set_ownerhome.lo src/lib66/set_ownersysdir.lo src/lib66/ss_utils.lo src/lib66/ssexec_dbctl.lo src/lib66/ssexec_enable.lo src/lib66/ssexec_env.lo src/lib66/ssexec_disable.lo src/lib66/ssexec_free.lo src/lib66/ssexec_help.lo src/lib66/ssexec_init.lo src/lib66/ssexec_main.lo src/lib66/ssexec_start.lo src/lib66/ssexec_stop.lo src/lib66/ssexec_svctl.lo src/lib66/state.lo src/lib66/sv_alltype_zero.lo src/lib66/svc_init.lo src/lib66/svc_init_pipe.lo src/lib66/svc_send.lo src/lib66/svc_switch_to.lo src/lib66/svc_unsupervise.lo src/lib66/tree_cmd_state.lo src/lib66/tree_copy.lo src/lib66/tree_copy_tmp.lo src/lib66/tree_find_current.lo src/lib66/tree_get_permissions.lo src/lib66/tree_sethome.lo src/lib66/tree_setname.lo src/lib66/tree_switch_current.lo
+lib66.so.xyzzy: src/lib66/backup_cmd_switcher.lo src/lib66/backup_make_new.lo src/lib66/backup_realpath_sym.lo src/lib66/db_compile.lo src/lib66/db_find_compiled_state.lo src/lib66/db_ok.lo src/lib66/db_switch_to.lo src/lib66/db_update.lo src/lib66/environ.lo src/lib66/get_enum.lo src/lib66/get_uidgid.lo src/lib66/get_userhome.lo src/lib66/hpr_shutdown.lo src/lib66/hpr_wall.lo src/lib66/instance.lo src/lib66/parser.lo src/lib66/parser_enabled.lo src/lib66/parser_utils.lo src/lib66/parser_write.lo src/lib66/rc_init.lo src/lib66/rc_manage.lo src/lib66/rc_send.lo src/lib66/rc_unsupervise.lo src/lib66/resolve.lo src/lib66/resolve_graph.lo src/lib66/scandir_ok.lo src/lib66/scandir_send_signal.lo src/lib66/set_livedir.lo src/lib66/set_livescan.lo src/lib66/set_livestate.lo src/lib66/set_livetree.lo src/lib66/set_ownerhome.lo src/lib66/set_ownersysdir.lo src/lib66/ss_info_utils.lo src/lib66/ss_utils.lo src/lib66/ssexec_dbctl.lo src/lib66/ssexec_enable.lo src/lib66/ssexec_env.lo src/lib66/ssexec_disable.lo src/lib66/ssexec_free.lo src/lib66/ssexec_help.lo src/lib66/ssexec_init.lo src/lib66/ssexec_main.lo src/lib66/ssexec_start.lo src/lib66/ssexec_stop.lo src/lib66/ssexec_svctl.lo src/lib66/state.lo src/lib66/sv_alltype_zero.lo src/lib66/svc_init.lo src/lib66/svc_init_pipe.lo src/lib66/svc_send.lo src/lib66/svc_switch_to.lo src/lib66/svc_unsupervise.lo src/lib66/tree_cmd_state.lo src/lib66/tree_copy.lo src/lib66/tree_copy_tmp.lo src/lib66/tree_find_current.lo src/lib66/tree_get_permissions.lo src/lib66/tree_sethome.lo src/lib66/tree_setname.lo src/lib66/tree_switch_current.lo
diff --git a/package/modes b/package/modes
index f341068a..62b9ca06 100644
--- a/package/modes
+++ b/package/modes
@@ -10,7 +10,9 @@
 66-stop			    0755
 66-svctl		    0755
 66-all			    0755
-66-info			    0755
+66-info             0755
+66-intree           0755
+66-inservice        0755
 66-env			    0755
 66-boot			    0755
 66-shutdown		    0755
diff --git a/package/targets.mak b/package/targets.mak
index 8c864254..23060bd0 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -12,6 +12,8 @@ BIN_TARGETS := \
 66-svctl \
 66-all \
 66-info \
+66-intree \
+66-inservice \
 66-env \
 66-boot \
 66-shutdown \
diff --git a/src/66/66-info.c b/src/66/66-info.c
index 3de127f3..f2f1736f 100644
--- a/src/66/66-info.c
+++ b/src/66/66-info.c
@@ -12,844 +12,28 @@
  * except according to the terms contained in the LICENSE file./
  */
 
-#include <string.h>
-#include <sys/stat.h>
-#include <locale.h>
-#include <langinfo.h>
-#include <stdio.h>
-
 #include <oblibs/obgetopt.h>
 #include <oblibs/error2.h>
-#include <oblibs/string.h>
-#include <oblibs/files.h>
-#include <oblibs/directory.h>
-#include <oblibs/types.h>
-#include <oblibs/sastr.h>
 
 #include <skalibs/buffer.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/unix-transactional.h>
-#include <skalibs/direntry.h>
-#include <skalibs/types.h>
-#include <skalibs/bytestr.h>
-#include <skalibs/lolstdio.h>
-#include <skalibs/djbunix.h>
-
-#include <66/utils.h>
-#include <66/tree.h>
-#include <66/constants.h>
-#include <66/enum.h>
-#include <66/resolve.h>
-#include <66/environ.h>
-
-#include <s6/s6-supervise.h>//s6_svc_ok
-
-
-
-unsigned int VERBOSITY = 1 ;
-static stralloc base = STRALLOC_ZERO ;
-static stralloc live = STRALLOC_ZERO ;
-static uid_t OWNER ;
-static char OWNERSTR[UID_FMT] ;
-static int force_color = 0 ;
-
-#define MAXSIZE 4096
-#define DBG_INFO(...) bprintf(buffer_1, __VA_ARGS__) ;\
-				buffer_putflush(buffer_1,"\n",1) ;
-
-
-#define USAGE "66-info [ -h ] [ -T ] [ -S ] sub-options (use -h as sub-options for futher informations)"
-
-#define TREE_USAGE "66-info -T [ -c | -C ] [ -h ] [ -v verbosity ] [ -r ] [ -d depth ] tree "
-#define exit_tree_usage() exitusage(TREE_USAGE)
-#define SV_USAGE "66-info -S [ -c | -C ] [ -h ] [ -v verbosity ] [-t tree ] [ -l live ] [ -p n lines ] [ -r ] [ -d depth ] service"
-#define exit_sv_usage() exitusage(SV_USAGE)
-
-unsigned int REVERSE = 0 ;
-
-ss_resolve_graph_style *STYLE = &graph_default ;
-unsigned int MAXDEPTH = 1 ;
-
-typedef struct depth_s depth_t ;
-struct depth_s
-{
-	depth_t *prev ;
-	depth_t *next ;
-	int level ;
-} ;
-
-struct set_color {
-	const char *bold_white ;
-	const char *back_blue ;
-	const char *white_underline ; 
-	const char *yellow ;
-	const char *blue ;
-	const char *blink_blue ;
-	const char *red ;
-	const char *off ;
-} ;
 
-static struct set_color use_color = {
-	"\033[1;37m", // bold_white
-	"\033[44m", // background blue 
-	"\033[3;4;1;117m", // white underline 
-	"\033[1;38;5;226m", // yellow 
-	"\033[1;38;5;117m", // blue 
-	"\033[1;5;38;5;117m", // blink blue
-	"\033[1;31m", // red
-	"\033[0m" //off
-} ;
-
-static struct set_color no_color = {
-	"",
-	"",
-	"",
-	"",
-	"",
-	"",
-	"",
-	""
-} ;
-
-static struct set_color *color = &no_color;
+#define USAGE "66-info is deprecated -- use 66-intree for tree informations or 66-inservice for service informations"
 
 static inline void info_help (void)
 {
   static char const *help =
-"66-info <options> sub-options \n"
-"\n"
-"options :\n"
-"	-h: print this help\n"
-"	-v: increase/decrease verbosity\n"
-"	-T: get informations about tree(s)\n"
-"	-S: get informations about service(s)\n"
-;
-
- if (buffer_putsflush(buffer_1, help) < 0)
-    strerr_diefu1sys(111, "write to stdout") ;
-}
-
-static inline void tree_help (void)
-{
-  static char const *help =
-"66-info -T <options> tree\n"
-"\n"
-"options :\n"
-"	-h: print this help\n"
-"	-c: disable colorization\n" 
-"	-C: force colorization\n"
-"	-v: increase/decrease verbosity\n"
-"	-r: reserve the dependencies graph\n" 
-"	-d: limit the depth of the graph recursion\n" 
-;
-
- if (buffer_putsflush(buffer_1, help) < 0)
-    strerr_diefu1sys(111, "write to stdout") ;
-}
-
-static inline void sv_help (void)
-{
-  static char const *help =
-"66-info -S <options> service\n"
-"\n"
-"options :\n"
-"	-h: print this help\n"
-"	-c: disable colorization\n" 
-"	-C: force colorization\n"
-"	-t: tree to use\n"
-"	-l: live directory\n"
-"	-p: print n last lines of the associated log file\n"
-"	-r: reserve the dependencies graph\n" 
-"	-d: limit the depth of the graph recursion\n"
+"66-info is deprecated -- use 66-intree for tree informations or 66-inservice for service informations\n"
 ;
 
  if (buffer_putsflush(buffer_1, help) < 0)
     strerr_diefu1sys(111, "write to stdout") ;
 }
 
-char *print_nlog(char *str, int n) 
-{ 
-	int r = 0 ;
-	int DELIM ='\n' ;
-	size_t slen = strlen(str) ;
-	
-	if (n <= 0) return NULL; 
-
-	size_t ndelim = 0;  
-	char *target_pos = NULL;   
-	
-	r = get_rlen_until(str,DELIM,slen) ;
-	
-	target_pos = str + r ; 
-
-	if (target_pos == NULL) return NULL; 
-
-	while (ndelim < n) 
-	{ 
-		while (str < target_pos && *target_pos != DELIM) 
-			--target_pos; 
-
-		if (*target_pos ==  DELIM) 
-			--target_pos, ++ndelim; 
-		else break; 
-	} 
-
-	if (str < target_pos) 
-		target_pos += 2; 
-
-	return target_pos ;
-} 
-
-int info_print_title(char const *name)
-{	
-	size_t half = 17 ;
-	size_t tlen = strlen(name) ;
-	size_t htlen = tlen/2 ;
-	size_t paddingl ;
-	size_t paddingr ;
-	if (tlen > half) paddingr = 0 ;
-	paddingl = half + htlen ;
-	paddingr = paddingl - htlen < half ? half : (half-htlen) ;
-	
-	if (!bprintf(buffer_1,"%s%*s%*s",color->white_underline,paddingl,name,paddingr,color->off)) return 0 ;
-	if (buffer_putsflush(buffer_1,"\n") < 0) return 0 ; 
-	return 1 ;
-}
-
-int info_print_tree(char const *treename,int init,int current,int enabled)
-{
-	int indent = init ? 0 : 1 ;
-	if (!info_print_title(treename)) return 0 ;
-	if (!bprintf(buffer_1,"%s%s%s%*s%s%s","Initialized: ",init ? color->blue : color->yellow, init ? "yes":"no",indent,"",color->off,"| ")) return 0 ;
-	if (!bprintf(buffer_1,"%s%s%s%s","Current: ",current ? color->blink_blue : color->yellow ,current ? "yes":"no",color->off)) return 0 ;
-	if (buffer_putsflush(buffer_1,"\n") < 0) return 0 ; 
-	if (!bprintf(buffer_1,"%s%9s%s%s%s%s","Contains:"," | ","Enabled: ",enabled == 1 ? color->blue : color->yellow ,enabled ? "yes":"no",color->off)) return 0 ;
-	if (buffer_putsflush(buffer_1,"\n") < 0) return  0 ;
-	return 1 ;
-} 
-
-int info_print_status(ss_resolve_t *res,char const *treename, char const *const *envp)
-{
-	int r ;
-	int wstat ;
-	pid_t pid ;
-	
-		
-	if (res->type == CLASSIC || res->type == LONGRUN)
-	{
-		r = s6_svc_ok(res->sa.s + res->runat) ;
-		if (r != 1)
-		{
-			if (buffer_putsflush(buffer_1,"not running\n") < 0) return 0 ;
-			return 1 ;
-		}
-		char const *newargv[3] ;
-		unsigned int m = 0 ;
-		
-		newargv[m++] = SS_BINPREFIX "s6-svstat" ;
-		newargv[m++] = res->sa.s + res->runat ;
-		newargv[m++] = 0 ;
-					
-		pid = child_spawn0(newargv[0],newargv,envp) ;
-		if (waitpid_nointr(pid,&wstat, 0) < 0)
-			strerr_diefu2sys(111,"wait for ",newargv[0]) ;
-		
-		if (wstat)
-			strerr_diefu2x(111,"status for service: ",res->sa.s + res->name) ;
-	}
-	else if (buffer_putsflush(buffer_1,"nothing to display\n") < 0) return 0 ;
-			
-	return 1 ;
-}
-
-static void info_print_graph(ss_resolve_t *res, depth_t *depth, int last)
-{
-	s6_svstatus_t status = S6_SVSTATUS_ZERO ;
-	char *name = res->sa.s + res->name ;
-	if (res->type == CLASSIC || res->type == LONGRUN)
-	{
-		s6_svstatus_read(res->sa.s + res->runat ,&status) ;
-	}
-	else status.pid = 0 ;	
-	
-	const char *tip = "" ;
-	int level = 1 ;
-		
-	if(depth->level > 0)
-	{
-		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), "", STYLE->indent, STYLE->limb)) return ;
-			level = depth->level + 1;
-			depth = depth->next;
-		} 
-	}
-
-	if(depth->level > 0)
-	{
-		if (!bprintf(buffer_1,"%*s%s(%s%i%s,%s%s%s,%s) %s", STYLE->indent * (depth->level - level), "", tip, status.pid ? color->blue : color->off,status.pid ? status.pid : 0,color->off, res->disen ? color->off : color->red, res->disen ? "Enabled" : "Disabled",color->off,get_keybyid(res->type), name)) return ;
-	}
-	else if (!bprintf(buffer_1,"%s(%i,%s) %s",tip, status.pid ? status.pid : 0, get_keybyid(res->type),name)) return ;
-
-	if (buffer_putsflush(buffer_1,"\n") < 0) return ; 
-}
-
-int info_cmpnsort(stralloc *sa)
-{
-	size_t pos = 0 ;
-	if (!sa->len) return 0 ;
-	size_t salen = sa->len ;
-	size_t nel = sastr_len(sa), idx = 0, a = 0, b = 0 ;
-	char names[nel][4096] ;
-	char tmp[4096] ;
-	
-	for (; pos < salen && idx < nel ; pos += strlen(sa->s + pos) + 1,idx++)
-	{
-		memcpy(names[idx],sa->s + pos,strlen(sa->s + pos)) ;
-		names[idx][strlen(sa->s+pos)] = 0 ;
-	}
-	for (; a < nel - 1 ; a++)
-	{
-		for (b = a + 1 ; b < idx ; b++)
-		{
-			if (strcmp(names[a],names[b]) > 0)
-			{
-				strcpy(tmp,names[a]) ;
-				strcpy(names[a],names[b]);
-				strcpy(names[b],tmp);
-			}
-		}
-	}
-	sa->len = 0 ;
-	for (a = 0 ; a < nel ; a++)
-	{
-		if (!sastr_add_string(sa,names[a])) return 0 ;
-	}	
-	return 1 ;
-}
-
-int info_walk(ss_resolve_t *res,char const *src,int reverse, depth_t *depth)
-{
-	size_t pos = 0, idx = 0 ;
-	stralloc sadeps = STRALLOC_ZERO ;
-	ss_resolve_t dres = RESOLVE_ZERO ;
-	
-	if((!res->ndeps) || (depth->level > MAXDEPTH))
-		goto freed ;
-	
-	if (!sastr_clean_string(&sadeps,res->sa.s + res->deps)) goto err ;
-	if (reverse) stralloc_reverse(&sadeps) ;
-	for(; pos < sadeps.len ; pos += strlen(sadeps.s + pos) + 1,idx++ )
-	{	
-		int last =  idx + 1 < res->ndeps  ? 0 : 1 ;		
-		char *name = sadeps.s + pos ;
-		
-		if (!ss_resolve_check(src,name)) goto err ;	
-		if (!ss_resolve_read(&dres,src,name)) goto err ;
-		
-		info_print_graph(&dres, depth, last) ;
-						
-		if (dres.ndeps)
-		{
-			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 (!info_walk(&dres,src,reverse,&d)) goto err;
-			depth->next = NULL;
-		}
-	}
-	freed:
-	ss_resolve_free(&dres) ;
-	stralloc_free(&sadeps) ;
-	return 1 ;
-	err: 
-		ss_resolve_free(&dres) ;
-		stralloc_free(&sadeps) ;
-		return 0 ;
-}
-
-/** what = 0 -> complete tree
- * what = 1 -> only name */
-int graph_display(char const *tree,char const *name,unsigned int what)
-{
-	int e ;
-	size_t pos = 0, i = 0 ;
-	ss_resolve_t res = RESOLVE_ZERO ;
-	stralloc tokeep = STRALLOC_ZERO ;
-	ss_resolve_graph_t graph = RESOLVE_GRAPH_ZERO ;
-	stralloc inres = STRALLOC_ZERO ;
-	e = 0 ;
-	
-	size_t treelen = strlen(tree) ;
-	char src[treelen + SS_SVDIRS_LEN + 1] ;
-	memcpy(src,tree,treelen) ;
-	memcpy(src + treelen,SS_SVDIRS,SS_SVDIRS_LEN) ;
-	src[treelen + SS_SVDIRS_LEN] = 0 ;
-	char srcres[treelen + SS_SVDIRS_LEN + SS_RESOLVE_LEN + 1] ;
-	memcpy(srcres,tree,treelen) ;
-	memcpy(srcres + treelen,SS_SVDIRS,SS_SVDIRS_LEN) ;
-	memcpy(srcres + treelen + SS_SVDIRS_LEN,SS_RESOLVE,SS_RESOLVE_LEN) ;
-	srcres[treelen + SS_SVDIRS_LEN + SS_RESOLVE_LEN] = 0 ;
-	
-	depth_t d = {
-		NULL,
-		NULL,
-		1
-	} ;	
-
-	if (!what)
-	{
-		if (!sastr_dir_get(&tokeep,srcres,SS_MASTER+1,S_IFREG)) goto err ;
-		if (tokeep.len)
-		{
-			for(; pos < tokeep.len ; pos += strlen(tokeep.s + pos) +1 )
-			{
-				char *name = tokeep.s + pos ;
-				if (!ss_resolve_check(src,name)) goto err ;
-				if (!ss_resolve_read(&res,src,name)) goto err ;
-				if (!ss_resolve_graph_build(&graph,&res,src,REVERSE)) goto err ;
-			}
-			if (!ss_resolve_graph_publish(&graph,REVERSE)) goto err ;
-			for (; i < genalloc_len(ss_resolve_t,&graph.sorted) ; i++)
-			{
-				char *string = genalloc_s(ss_resolve_t,&graph.sorted)[i].sa.s ;
-				char *name = string + genalloc_s(ss_resolve_t,&graph.sorted)[i].name ;
-				
-				if (!stralloc_cats(&inres,name)) goto err ;
-				if (!stralloc_cats(&inres," ")) goto err ;
-			}
-			inres.len-- ;
-			if (!stralloc_0(&inres)) goto err ;
-			ss_resolve_init(&res) ;
-			res.ndeps = genalloc_len(ss_resolve_t,&graph.sorted) ;
-			res.deps = ss_resolve_add_string(&res,inres.s) ;
-			if(!info_walk(&res,src,0,&d)) goto err ;
-		}
-		else
-		{
-			goto empty ;
-		}
-	}
-	else
-	{
-		if (!ss_resolve_check(src,name)) goto err ;
-		if (!ss_resolve_read(&res,src,name)) goto err ;
-		/*if (res.disen)*/ if(!info_walk(&res,src,REVERSE,&d)) goto err ;
-		
-	}
-	
-	ss_resolve_free(&res) ;
-	stralloc_free(&tokeep) ;
-	ss_resolve_graph_free(&graph) ;
-	stralloc_free(&inres) ;
-	return 1 ;
-	
-	empty:
-		e = -1 ;
-	err:
-		ss_resolve_free(&res) ;
-		stralloc_free(&tokeep) ;
-		ss_resolve_graph_free(&graph) ;
-		stralloc_free(&inres) ;
-		return e ;
-}
-
-int tree_args(int argc, char const *const *argv)
-{
-	int r ;
-	size_t newlen, pos = 0 ;
-	stralloc satree = STRALLOC_ZERO ;//all tree
-	stralloc tree = STRALLOC_ZERO ;
-	stralloc sacurrent = STRALLOC_ZERO ;
-	stralloc currname = STRALLOC_ZERO ;
-	stralloc src = STRALLOC_ZERO ;
-
-	int todisplay = 0 ;
-	
-	{
-		subgetopt_t l = SUBGETOPT_ZERO ;
-			
-		for (;;)
-		{
-			int opt = getopt_args(argc,argv, ">hcCv:rd:l:", &l) ;
-			if (opt == -1) break ;
-			if (opt == -2) strerr_dief1x(110,"options must be set first") ;
-			
-			switch (opt)
-			{
-				case 'h' : 	tree_help(); return 1 ;
-				case 'c' :	color = &no_color ; break ;
-				case 'C' :	force_color = 1 ; break ;
-				case 'v' :  if (!uint0_scan(l.arg, &VERBOSITY)) exit_tree_usage() ; break ;
-				case 'r' : 	REVERSE = 1 ; break ;
-				case 'd' : 	if (!uint0_scan(l.arg, &MAXDEPTH)) exit_tree_usage(); break ;
-				case 'l' : 	if (!stralloc_cats(&live,l.arg)) retstralloc(0,"sv_args") ;
-							if (!stralloc_0(&live)) retstralloc(0,"sv_args") ;
-							break ;
-				default : exit_tree_usage() ; 
-			}
-		}
-		argc -= l.ind ; argv += l.ind ;
-	}
-	if (argc > 1) exit_tree_usage();
-	
-	if (argv[0]) todisplay = 1 ;
-
-	// -c and -C cannot be added togheter
-	if (color == &no_color && force_color) exit_tree_usage() ;
-
-	if (!isatty(1) && !force_color)
-		color = &no_color ;
-	
-	r = set_livedir(&live) ;
-	if (!r) retstralloc(0,"sv_args") ;
-	if (r < 0 ) strerr_dief3x(111,"live: ",live.s," must be an absolute path") ;
-	
-	if (!stralloc_cats(&live,SS_STATE + 1)) goto err ;
-	if (!stralloc_cats(&live,"/")) goto err ;
-	if (!stralloc_cats(&live,OWNERSTR)) goto err ;
-	if (!stralloc_cats(&live,"/")) goto err ;
-	newlen = live.len ;
-	
-	r = tree_find_current(&sacurrent,base.s,OWNER) ;
-	if (r)
-	{
-		if (!tree_setname(&currname,sacurrent.s)) strerr_diefu1x(111,"set the tree name") ;
-	}
-	
-	if (!stralloc_copy(&src,&base)) goto err ;
-	if (!stralloc_cats(&src,"/" SS_SYSTEM)) goto err ;
-	if (!stralloc_0(&src)) goto err ;
-	if (!scan_mode(src.s,S_IFDIR)) goto empty ;
-	if (todisplay)
-		if (!dir_search(src.s,argv[0],S_IFDIR)) strerr_dief2x(110,"unknown tree: ",argv[0]) ;
-	
-	if (!sastr_dir_get(&satree, src.s,SS_BACKUP + 1, S_IFDIR)) goto err ;
-	if (satree.len)
-	{
-		if (!info_cmpnsort(&satree)) strerr_diefu1x(111,"sort list of tree") ;
-		for(; pos < satree.len ; pos += strlen(satree.s + pos) +1 )
-		{
-			tree.len = 0 ;
-				
-			char *treename = satree.s + pos ;
-			if (todisplay)
-				if (!obstr_equal(treename,argv[0])) continue ;
-			
-			int current = 0 ;
-			int init = 0 ;
-			live.len = newlen ;
-			if (!stralloc_cats(&live,treename)) goto err ;
-			if (!stralloc_cats(&live,"/init")) goto err ;
-			if (!stralloc_0(&live)) goto err ;
-			if (!access(live.s, F_OK)) init = 1 ;
-		
-			int enabled = tree_cmd_state(VERBOSITY,"-s",treename) ; 
-			if (currname.len)
-				current = obstr_equal(treename,currname.s) ;
-			
-			if (!info_print_tree(treename,init,current,enabled)) goto err ;
-					
-			if(!stralloc_cats(&tree,treename)) retstralloc(0,"tree_args") ;
-			if(!stralloc_0(&tree)) retstralloc(0,"tree_args") ;
-	
-			r = tree_sethome(&tree,base.s,OWNER) ;
-			if (!r) strerr_diefu2sys(111,"find tree: ", tree.s) ;
-			
-			r = graph_display(tree.s,"",0) ;
-			if (r < 0)
-			{
-				if (!bprintf(buffer_1,"%s","nothing to display")) goto err ;
-				if (buffer_putflush(buffer_1,"\n",1) < 0) goto err ;
-			}else if (!r) goto err ;
-			if (buffer_putflush(buffer_1,"\n",1) < 0) goto err ;		
-		}
-	}
-	else 
-	{
-		empty:
-		strerr_warni1x("no tree exist yet") ;
-	}
-	
-	stralloc_free(&live) ;
-	stralloc_free(&tree) ;
-	stralloc_free(&src) ;
-	stralloc_free(&sacurrent) ;
-	stralloc_free(&currname) ;
-	stralloc_free(&satree) ;
-	
-	return 1 ;
-	
-	err:
-		stralloc_free(&live) ;
-		stralloc_free(&tree) ;
-		stralloc_free(&src) ;
-		stralloc_free(&sacurrent) ;
-		stralloc_free(&currname) ;
-		stralloc_free(&satree) ;
-		return 0 ;
-}
-
-int sv_args(int argc, char const *const *argv,char const *const *envp)
-{
-	int r, found ; 
-	unsigned int nlog = 0 ;
-	size_t pos = 0 ;
-	stralloc treename = STRALLOC_ZERO ;
-	stralloc tree = STRALLOC_ZERO ;
-	stralloc satree = STRALLOC_ZERO ;
-	stralloc src = STRALLOC_ZERO ;
-	stralloc conf = STRALLOC_ZERO ;
-	stralloc env = STRALLOC_ZERO ;
-	
-	ss_resolve_t res = RESOLVE_ZERO ;
-	
-	char const *svname = 0 ;
-	char const *tname = 0 ;
-	
-	r = found = 0 ;
-	
-	{
-		subgetopt_t l = SUBGETOPT_ZERO ;
-		
-		for (;;)
-		{
-			int opt = getopt_args(argc,argv, ">hcCv:l:p:rd:t:", &l) ;
-			if (opt == -1) break ;
-			if (opt == -2) strerr_dief1x(110,"options must be set first") ;
-			switch (opt)
-			{
-				case 'h' : 	sv_help(); return 1 ;
-				case 'c' :	color = &no_color ; break ;
-				case 'C' :	force_color = 1 ; break ;
-				case 'v' :  if (!uint0_scan(l.arg, &VERBOSITY)) exit_sv_usage() ; break ;
-				case 'l' : 	if (!stralloc_cats(&live,l.arg)) retstralloc(0,"sv_args") ;
-							if (!stralloc_0(&live)) retstralloc(0,"sv_args") ;
-							break ;
-				case 'p' :	if (!uint0_scan(l.arg, &nlog)) exit_sv_usage() ; break ;
-				case 'r' : 	REVERSE = 1 ; break ;
-				case 'd' : 	if (!uint0_scan(l.arg, &MAXDEPTH)) exit_sv_usage(); break ;
-				case 't' :	tname = l.arg ; break ;
-				default : exit_sv_usage() ; 
-			}
-		}
-		argc -= l.ind ; argv += l.ind ;
-	}
-	if (argc > 1 || !argc) exit_sv_usage() ;
-
-	// -c and -C cannot be added togheter
-	if (color == &no_color && force_color) exit_sv_usage() ;
-
-	if (!isatty(1) && !force_color)
-		color = &no_color ;
-
-	svname = *argv ;
-	
-	r = set_livedir(&live) ;
-	if (!r) retstralloc(0,"sv_args") ;
-	if (r < 0 ) strerr_dief3x(111,"live: ",live.s," must be an absolute path") ;
-	
-	size_t newlen ;
-	
-	if (!stralloc_copy(&src,&base)) goto err ;
-	if (!stralloc_cats(&src,SS_SYSTEM)) goto err ;
-	if (!stralloc_cats(&src,"/")) goto err ;
-	newlen = src.len ;
-
-	if (!tname)
-	{	
-		
-		if (!stralloc_0(&src)) goto err ;
-		
-		if (!sastr_dir_get(&satree, src.s,SS_BACKUP+1, S_IFDIR)) 
-			strerr_diefu2x(111,"get tree from directory: ",src.s) ;
-		
-		if (satree.len)
-		{
-			for(; pos < satree.len ; pos += strlen(satree.s + pos) +1 )
-			{
-				src.len = newlen ;
-				char *name = satree.s + pos ;
-				
-				if (!stralloc_cats(&src,name)) goto err ;
-				if (!stralloc_cats(&src,SS_SVDIRS)) goto err ;
-				if (!stralloc_0(&src)) goto err ;
-				if (ss_resolve_check(src.s,svname))
-				{
-					if(!stralloc_cats(&treename,name)) retstralloc(0,"sv_args") ;
-					if(!stralloc_0(&treename)) retstralloc(0,"sv_args") ;
-					found++ ;
-				}
-			}
-		}
-		else 
-		{
-			if (!bprintf(buffer_1," %s ","nothing to display")) goto err ;
-			if (buffer_putflush(buffer_1,"\n",1) < 0) goto err ;
-			goto end ;
-		}
-	}
-	else
-	{
-		if (!stralloc_cats(&treename,tname)) retstralloc(0,"sv_args") ;
-		if (!stralloc_0(&treename)) retstralloc(0,"sv_args") ;
-		if (!stralloc_cats(&src,treename.s)) goto err ;
-		if (!stralloc_cats(&src,SS_SVDIRS)) goto err ;
-		if (!stralloc_0(&src)) goto err ;
-		if (ss_resolve_check(src.s,svname)) found++;
-	}
-
-	if (!found)
-	{
-		strerr_warnw2x("unknown service: ",svname) ;
-		goto err ;
-	}
-	else if (found > 1)
-	{
-		strerr_warnw2x(svname," is set on divers tree -- please use -t options") ;
-		goto err ;
-	}
-	if (!stralloc_cats(&tree,treename.s)) goto err ;
-	r = tree_sethome(&tree,base.s,OWNER) ;
-	if (r<=0) strerr_diefu2sys(111,"find tree: ", tree.s) ;
-	
-	if (!info_print_title(svname)) goto err ;
-	if (!bprintf(buffer_1,"%s%s\n","on tree : ",treename.s)) goto err ;
-	
-	src.len = newlen ;
-	if (!stralloc_cats(&src,treename.s)) goto err ;
-	if (!stralloc_cats(&src,SS_SVDIRS)) goto err ;
-	if (!stralloc_0(&src)) goto err ;
-	if (!ss_resolve_read(&res,src.s,svname)) strerr_diefu2sys(111,"read resolve file of: ",svname) ;
-	
-	/** status */
-	if (!bprintf(buffer_1,"%s%s%s%s%s","status : ",res.disen ? color->off : color->red,res.disen ? "Enabled" : "Disabled",color->off,", ")) goto err ;
-	if (buffer_putsflush(buffer_1,"") < 0) goto err ;
-	if (!info_print_status(&res,treename.s,envp)) goto err ;
-
-	/** print the type */	
-	if (!bprintf(buffer_1,"%s %s\n","type :",get_keybyid(res.type))) goto err ;
-	
-	if (!bprintf(buffer_1,"%s %s\n","description :",res.sa.s + res.description)) goto err ;
-	if (!bprintf(buffer_1,"%s%s\n","source : ",res.sa.s + res.src)) goto err ;
-	if (!bprintf(buffer_1,"%s%s\n","run at : ",res.sa.s + res.runat)) goto err ;
-	/** dependencies */
-	if (res.ndeps) 
-	{	
-		if (res.type == BUNDLE){ if (!info_print_title("contents")) goto err ; }
-		else if (!info_print_title("dependencies")) goto err ;
-	
-		if (!graph_display(tree.s,svname,1)) strerr_diefu2x(111,"display dependencies of: ", svname) ;
-		
-	}
-	/** scripts*/
-	if (res.exec_run||res.exec_finish)
-	{
-		if (!info_print_title("scripts")) goto err ;
-		if (res.exec_run)
-		{
-			if (!bprintf(buffer_1,"%s%s\n","start script :",res.sa.s + res.exec_run)) goto err ;
-		}
-		if (res.exec_finish)
-		{
-			if (!bprintf(buffer_1,"%s%s\n","stop script :",res.sa.s + res.exec_finish)) goto err ;
-		}
-	}
-	/** environment */
-	if (res.srconf)
-	{
-		if (!env_resolve_conf(&env,MYUID)) goto err ;
-		if (!file_readputsa(&conf,env.s,svname)) goto err ;
-		if (!info_print_title("environment")) goto err ;
-		if (!bprintf(buffer_1,"%s%s\n","source : ",env.s)) goto err ;
-		if (!bprintf(buffer_1,"%s",conf.s)) goto err ;
-	}
-	
-	/** logger */
-	if (res.type == CLASSIC || res.type == LONGRUN) 
-	{
-		if (res.logger)
-		{
-			if (!info_print_title("logger")) goto err ;
-			if (!bprintf(buffer_1,"%s%s\n","logger associated : ",res.sa.s + res.logger)) goto err ;
-			if (!bprintf(buffer_1,"%s ","log destination :")) goto err ;
-			if (!bprintf(buffer_1,"%s \n",res.sa.s + res.dstlog)) goto err ;
-			if (nlog)
-			{
-				if (!info_print_title("log file")) goto err ;
-				stralloc log = STRALLOC_ZERO ;
-				/** the file current may not exist if the service was never started*/
-				if (!dir_search(res.sa.s + res.dstlog,"current",S_IFREG)){	if (!bprintf(buffer_1,"%s%s%s \n",color->red,"unable to find the log file",color->off)) goto err ; }
-				else
-				{
-					if (!file_readputsa(&log,res.sa.s + res.dstlog,"current")) retstralloc(0,"sv_args") ;
-					if (log.len < 10) 
-					{
-						if (!bprintf(buffer_1,"\n")) goto err ;
-						if (!bprintf(buffer_1,"%s%s%s",color->yellow,"log file is empty \n",color->off)) goto err ;
-					}
-					else
-					{
-						if (!bprintf(buffer_1,"\n")) goto err ;
-						if (!bprintf(buffer_1,"%s \n",print_nlog(log.s,nlog))) goto err ;
-					}
-				}
-				stralloc_free(&log) ;
-			}
-		}
-	}
-	if (buffer_putsflush(buffer_1,"") < 0) goto err ;
-	
-	end:
-	stralloc_free(&tree) ;
-	stralloc_free(&treename) ;
-	stralloc_free(&satree) ;
-	ss_resolve_free(&res) ;
-	stralloc_free(&src) ;
-	stralloc_free(&conf) ;
-	stralloc_free(&env) ;
-	return 1 ;
-	
-	err:
-		stralloc_free(&tree) ;
-		stralloc_free(&treename) ;
-		stralloc_free(&satree) ;
-		ss_resolve_free(&res) ;
-		stralloc_free(&src) ;
-		stralloc_free(&conf) ;
-		stralloc_free(&env) ;
-		return 0 ;
-}
-
 int main(int argc, char const *const *argv, char const *const *envp)
 {
 	int what ;
 	
 	what = -1 ;
-	color = &use_color ;
 	
 	PROG = "66-info" ;
 	{
@@ -869,31 +53,14 @@ int main(int argc, char const *const *argv, char const *const *envp)
 			}
 		}
 	}
-	if (what<0) exitusage(USAGE) ;
-	
-	argc-- ; argv++ ;
-		
-	OWNER = MYUID ;
-	size_t ownerlen = uid_fmt(OWNERSTR,OWNER) ;
-	OWNERSTR[ownerlen] = 0 ;
+	if (what == -1) exitusage(USAGE) ;
 	
-		
-	setlocale(LC_ALL, "");
-	
-	if(!str_diff(nl_langinfo(CODESET), "UTF-8")) {
-		STYLE = &graph_utf8;
+	if (!what) {
+		strerr_warnw1x("66-info is deprecated -- use 66-intree instead") ;
+	}
+	else if (what) {
+		strerr_warnw1x("66-info is deprecated -- use 66-inservice instead") ;
 	}
-		
-	if (!set_ownersysdir(&base,OWNER)) strerr_diefu1sys(111, "set owner directory") ;
-	
-	if (!what)
-		if (!tree_args(argc,argv)) strerr_diefu1x(111,"display trees informations") ;
-	
-	if (what)
-		if (!sv_args(argc,argv,envp)) strerr_diefu1x(111,"display services informations") ;
-	
-	stralloc_free(&base) ;
-	stralloc_free(&live) ;
 		
 	return 0 ;
 }
diff --git a/src/66/66-inservice.c b/src/66/66-inservice.c
new file mode 100644
index 00000000..c2f0f3be
--- /dev/null
+++ b/src/66/66-inservice.c
@@ -0,0 +1,694 @@
+/* 
+ * 66-intree.c
+ * 
+ * Copyright (c) 2018-2019 Eric Vidal <eric@obarun.org>
+ * 
+ * All rights reserved.
+ * 
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <sys/types.h>
+#include <wchar.h>
+#include <unistd.h>//access
+#include <stdio.h>//access
+
+#include <oblibs/sastr.h>
+#include <oblibs/error2.h>
+#include <oblibs/obgetopt.h>
+#include <oblibs/types.h>
+#include <oblibs/string.h>
+#include <oblibs/files.h>
+#include <oblibs/directory.h>
+
+#include <skalibs/strerr2.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+#include <skalibs/lolstdio.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/buffer.h>
+#include <skalibs/djbunix.h>
+
+#include <66/info.h>
+#include <66/utils.h>
+#include <66/constants.h>
+#include <66/tree.h>
+#include <66/enum.h>
+#include <66/resolve.h>
+#include <66/environ.h>
+
+#include <s6/s6-supervise.h>
+
+unsigned int VERBOSITY = 1 ;
+static unsigned int REVERSE = 0 ;
+unsigned int MAXDEPTH = 1 ;
+static unsigned int GRAPH = 0 ;
+static uid_t OWNER ;
+static char OWNERSTR[UID_FMT] ;
+static char const *const *ENVP ;
+static unsigned int nlog = 20 ;
+static stralloc src = STRALLOC_ZERO ;
+
+static wchar_t const field_suffix[] = L" :" ;
+static char fields[ENDOFKEY][INFO_FIELD_MAXLEN] = {{ 0 }} ;
+static void info_display_string(char const *str) ;
+static void info_display_name(char const *field, ss_resolve_t *res) ;
+static void info_display_intree(char const *field, ss_resolve_t *res) ;
+static void info_display_status(char const *field, ss_resolve_t *res) ;
+static void info_display_type(char const *field, ss_resolve_t *res) ;
+static void info_display_description(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_start(char const *field, ss_resolve_t *res) ;
+static void info_display_stop(char const *field, ss_resolve_t *res) ;
+static void info_display_envat(char const *field, ss_resolve_t *res) ;
+static void info_display_envfile(char const *field, ss_resolve_t *res) ;
+static void info_display_logname(char const *field, ss_resolve_t *res) ;
+static void info_display_logdst(char const *field, ss_resolve_t *res) ;
+static void info_display_logfile(char const *field, ss_resolve_t *res) ;
+
+ss_resolve_graph_style *STYLE = &graph_default ;
+
+info_opts_map_t const opts_sv_table[] =
+{
+	{ .str = "name", .svfunc = &info_display_name, .id = 0 },
+	{ .str = "intree", .svfunc = &info_display_intree, .id = 1 },
+	{ .str = "status", .svfunc = &info_display_status, .id = 2 },
+	{ .str = "type", .svfunc = &info_display_type, .id = 3 },
+	{ .str = "description", .svfunc = &info_display_description, .id = 4 },
+	{ .str = "source", .svfunc = &info_display_source, .id = 5 },
+	{ .str = "live", .svfunc = &info_display_live, .id = 6 },
+	{ .str = "depends", .svfunc = &info_display_deps, .id = 7 },
+	{ .str = "start", .svfunc = &info_display_start, .id = 8 },
+	{ .str = "stop", .svfunc = &info_display_stop, .id = 9 },
+	{ .str = "envat", .svfunc = &info_display_envat, .id = 10 },
+	{ .str = "envfile", .svfunc = &info_display_envfile, .id = 11 },
+	{ .str = "logname", .svfunc = &info_display_logname, .id = 12 },
+	{ .str = "logdst", .svfunc = &info_display_logdst, .id = 13 },
+	{ .str = "logfile", .svfunc = &info_display_logfile, .id = 14 },
+	{ .str = 0, .svfunc = 0, .id = -1 }
+} ;
+
+#define MAXOPTS 16
+#define checkopts(n) if (n >= MAXOPTS) strerr_dief1x(100, "too many options")
+#define DELIM ','
+
+#define USAGE "66-inservice [ -h ] [ -v verbosity ] [ -c ] [ -o name,instree,status,... ] [ -g ] [ -d depth ] [ -r ] [ -t tree ] [ -p nline ] service"
+
+static inline void info_help (void)
+{
+  static char const *help =
+"66-inservice <options> service \n"
+"\n"
+"options :\n"
+"	-h: print this help\n"
+"	-v: increase/decrease verbosity\n"
+"	-c: use color\n"
+"	-o: comma separated list of field to display\n"
+"	-g: displays the contains field as graph\n"
+"	-d: limit the depth of the contains field recursion\n"
+"	-r: reserve the contains field\n"
+"	-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"
+"\n"
+"	name: displays the name\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"
+"	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 contains of the environment file\n"
+"	logname: displays the logger's name\n"
+"	logdst: displays the logger's destination\n"
+"	logfile: displays the contains of the log file\n"
+"\n"
+;
+
+ if (buffer_putsflush(buffer_1, help) < 0)
+    strerr_diefu1sys(111, "write to stdout") ;
+}
+
+char *print_nlog(char *str, int n) 
+{ 
+	int r = 0 ;
+	int delim ='\n' ;
+	size_t slen = strlen(str) ;
+	
+	if (n <= 0) return NULL; 
+
+	size_t ndelim = 0;  
+	char *target_pos = NULL;   
+	
+	r = get_rlen_until(str,delim,slen) ;
+	
+	target_pos = str + r ; 
+
+	if (target_pos == NULL) return NULL; 
+
+	while (ndelim < n) 
+	{ 
+		while (str < target_pos && *target_pos != delim) 
+			--target_pos; 
+
+		if (*target_pos ==  delim) 
+			--target_pos, ++ndelim; 
+		else break; 
+	} 
+
+	if (str < target_pos) 
+		target_pos += 2; 
+
+	return target_pos ;
+} 
+
+static void info_display_string(char const *str)
+{
+	if (!bprintf(buffer_1," %s",str))
+		strerr_diefu1sys(111,"write to stdout") ;
+	
+	if (buffer_putsflush(buffer_1,"\n") == -1) 
+		strerr_diefu1sys(111,"write to stdout") ;
+}
+
+static void info_display_name(char const *field, ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	info_display_string(res->sa.s + res->name) ;
+}
+
+static void info_display_intree(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	info_display_string(res->sa.s + res->treename) ;
+}
+
+static void info_get_status(ss_resolve_t *res)
+{
+	int r ;
+	int wstat ;
+	pid_t pid ;
+	
+		
+	if (res->type == CLASSIC || res->type == LONGRUN)
+	{
+		r = s6_svc_ok(res->sa.s + res->runat) ;
+		if (r != 1)
+		{
+			if (!bprintf(buffer_1,"%s%s%s",info_color->warning,"not running\n",info_color->off))
+				strerr_diefu1sys(111,"write to stdout") ;
+			return ;
+		}
+		char const *newargv[3] ;
+		unsigned int m = 0 ;
+		
+		newargv[m++] = SS_BINPREFIX "s6-svstat" ;
+		newargv[m++] = res->sa.s + res->runat ;
+		newargv[m++] = 0 ;
+					
+		pid = child_spawn0(newargv[0],newargv,ENVP) ;
+		if (waitpid_nointr(pid,&wstat, 0) < 0)
+			strerr_diefu2sys(111,"wait for ",newargv[0]) ;
+		
+		if (wstat)
+			strerr_diefu2x(111,"status for service: ",res->sa.s + res->name) ;
+	}
+	else
+	{
+		if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning,"nothing to display",info_color->off))
+				strerr_diefu1sys(111,"write to stdout") ;
+	}
+}
+
+static void info_display_status(char const *field,ss_resolve_t *res)
+{
+	
+	info_display_field_name(field) ;
+		
+	if (!bprintf(buffer_1," %s%s%s%s",res->disen ? info_color->valid : info_color->error,res->disen ? "enabled" : "disabled",info_color->off,", "))
+		strerr_diefu1sys(111,"write to stdout") ;
+	
+	if (buffer_putsflush(buffer_1,"") == -1) 
+		strerr_diefu1sys(111,"write to stdout") ;
+	
+	info_get_status(res) ;
+
+}
+
+static void info_display_type(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	info_display_string(get_keybyid(res->type)) ;
+}
+
+static void info_display_description(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	info_display_string(res->sa.s + res->description) ;
+}
+
+static void info_display_source(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	info_display_string(res->sa.s + res->src) ;
+}
+
+static void info_display_live(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	info_display_string(res->sa.s + res->runat) ;
+}
+
+static void info_display_deps(char const *field, ss_resolve_t *res)
+{
+	size_t padding = 1 ;
+	
+	stralloc salist = STRALLOC_ZERO ;
+	
+	padding = info_display_field_name(field) ;
+	
+	if (!res->ndeps) goto empty ;
+	
+	if (GRAPH)
+	{
+		if (!bprintf(buffer_1," %s\n","/")) 
+			strerr_diefu1sys(111,"write to stdout") ;
+	
+		if (!info_graph_init(res,src.s,REVERSE, padding, STYLE))
+			strerr_dief2x(111,"display graph of: ",res->sa.s + res->name) ;
+		goto freed ;
+	}
+	else
+	{
+		if (!bprintf(buffer_1,"%s"," ")) 
+			strerr_diefu1sys(111,"write to stdout") ;
+		if (!sastr_clean_string(&salist,res->sa.s + res->deps)) 
+			strerr_diefu1x(111,"build dependencies list") ;
+		if (REVERSE)
+			if (!sastr_reverse(&salist))
+				strerr_diefu1x(111,"reverse dependencies list") ;
+		info_display_list(field,&salist) ;
+		goto freed ;
+	}
+	empty:
+		if (GRAPH)
+		{
+			if (!bprintf(buffer_1," %s\n","/")) 
+				strerr_diefu1sys(111,"write to stdout") ;
+			if (!bprintf(buffer_1,"%*s%s%s%s%s\n",padding, "", STYLE->last, info_color->warning," no dependencies",info_color->off))
+				strerr_diefu1sys(111,"write to stdout") ;
+		}
+		else
+		{
+			if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," no dependencies",info_color->off))
+				strerr_diefu1sys(111,"write to stdout") ;
+		}
+		
+	freed:
+		stralloc_free(&salist) ;
+}
+
+static void info_display_start(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	if (res->exec_run)
+	{
+		info_display_nline(field,res->sa.s + res->exec_run) ;
+	}
+	else
+	{
+		if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," nothing to display",info_color->off))
+			strerr_diefu1sys(111,"write to stdout") ;
+	}
+}
+
+static void info_display_stop(char const *field,ss_resolve_t *res)
+{	
+	info_display_field_name(field) ;
+	if (res->exec_finish)
+	{
+		info_display_nline(field,res->sa.s + res->exec_finish) ;
+	}
+	else
+	{
+		if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," nothing to display",info_color->off))
+			strerr_diefu1sys(111,"write to stdout") ;
+	}
+	
+}
+
+static void info_display_envat(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	char *name = res->sa.s + res->name ;
+	if (!res->srconf) goto empty ;
+	{
+		char *src = res->sa.s + res->srconf ;
+		size_t srclen = strlen(src) ;
+		size_t namelen = strlen(name) ;
+		char tmp[namelen + srclen + 1] ;
+		memcpy(tmp,src,srclen) ;
+		tmp[srclen] = '/' ;
+		memcpy(tmp + srclen,name,namelen) ;
+		tmp[srclen + namelen] = 0 ;
+		info_display_string(tmp) ;
+		return ;
+	}
+	empty:
+	
+	if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," environment was not set",info_color->off))
+		strerr_diefu1sys(111,"write to stdout") ;
+}
+
+static void info_display_envfile(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	if (!res->srconf) goto empty ;
+	{
+		stralloc sa = STRALLOC_ZERO ;
+		char *name = res->sa.s + res->name ;
+		char *src = res->sa.s + res->srconf ;
+		if (!file_readputsa(&sa,src,name)) strerr_diefu1sys(111,"read environment file") ;
+		info_display_nline(field,sa.s) ;
+		return ;
+	}
+	empty:
+	if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," environment was not set",info_color->off))
+		strerr_diefu1sys(111,"write to stdout") ;
+}
+
+static void info_display_logname(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	if (res->type == CLASSIC || res->type == LONGRUN) 
+	{
+		if (res->logger)
+		{
+			info_display_string(res->sa.s + res->logger) ;
+		}
+		else goto empty ;
+	}
+	else goto empty ;
+	
+	return ;
+	empty:
+		if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," logger doesn't exist",info_color->off))
+			strerr_diefu1sys(111,"write to stdout") ;
+}
+
+static void info_display_logdst(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	if (res->type == CLASSIC || res->type == LONGRUN) 
+	{
+		if (res->logger)
+		{
+			info_display_string(res->sa.s + res->dstlog) ;
+		}
+		else goto empty ;
+	}
+	else goto empty ;
+	
+	return ;
+	empty:
+		if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," logger doesn't exist",info_color->off))
+			strerr_diefu1sys(111,"write to stdout") ;
+}
+
+static void info_display_logfile(char const *field,ss_resolve_t *res)
+{
+	info_display_field_name(field) ;
+	if (res->type == CLASSIC || res->type == LONGRUN) 
+	{
+		if (res->logger)
+		{
+			if (nlog)
+			{
+				stralloc log = STRALLOC_ZERO ;
+				/** the file current may not exist if the service was never started*/
+				size_t dstlen = strlen(res->sa.s + res->dstlog) ;
+				char scan[dstlen + 9] ;
+				memcpy(scan,res->sa.s + res->dstlog,dstlen) ;
+				memcpy(scan + dstlen,"/current",8) ;
+				scan[dstlen + 8] = 0 ;
+				
+				int r = scan_mode(scan,S_IFREG) ;
+				if (r < 0) { errno = EEXIST ; strerr_dief2sys(111,"conflicting format of: ",scan) ; }
+				if (!r)
+				{ 
+					if (!bprintf(buffer_1,"%s%s%s\n",info_color->error," unable to find the log file",info_color->off)) 
+					goto err ; 
+				}
+				else
+				{
+					if (!file_readputsa(&log,res->sa.s + res->dstlog,"current")) strerr_diefu2sys(111,"read log file of: ",res->sa.s + res->name) ;
+					if (log.len < 10) 
+					{
+						if (!bprintf(buffer_1,"%s%s%s",info_color->warning," log file is empty \n",info_color->off)) goto err ;
+					}
+					else
+					{
+						if (!bprintf(buffer_1,"\n")) goto err ;
+						if (!bprintf(buffer_1,"%s\n",print_nlog(log.s,nlog))) goto err ;
+					}
+				}
+				stralloc_free(&log) ;
+			}
+		}
+	}
+	else goto empty ;
+	
+	return ;
+	empty:
+		if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," logger doesn't exist",info_color->off))
+			strerr_diefu1sys(111,"write to stdout") ;
+		return ;
+	err:
+		strerr_diefu1sys(111,"write to stdout") ;
+}
+
+static void info_display_all(ss_resolve_t *res,int *what)
+{
+	
+	unsigned int i = 0 ;
+	for (; what[i] >= 0 ; i++)
+	{
+		unsigned int idx = what[i] ;
+		(*opts_sv_table[idx].svfunc)(fields[opts_sv_table[idx].id],res) ;
+	}
+	
+}
+
+static void info_parse_options(char const *str,int *what)
+{
+	size_t pos = 0 ;
+	stralloc sa = STRALLOC_ZERO ;
+	
+	if (!sastr_clean_string_wdelim(&sa,str,DELIM)) strerr_diefu1x(111,"parse options") ;
+	unsigned int n = sastr_len(&sa), nopts = 0 , old ;
+	checkopts(n) ;
+	info_opts_map_t const *t ;
+	
+	for (;pos < sa.len; pos += strlen(sa.s + pos) + 1)
+	{
+		char *o = sa.s + pos ;
+		t = opts_sv_table ;
+		old = nopts ;
+		for (; t->str; t++)
+		{			
+			if (obstr_equal(o,t->str))
+				what[nopts++] = t->id ;
+		}
+		if (old == nopts) strerr_dief2x(111,"invalid option: ",o) ;
+	}
+	
+	stralloc_free(&sa) ;
+}
+
+int main(int argc, char const *const *argv, char const *const *envp)
+{
+	unsigned int legacy = 1 ;
+	int found = 0 ;
+	size_t pos, newlen ;
+	int what[MAXOPTS] = { 0 } ;
+	
+	ss_resolve_t res = RESOLVE_ZERO ;
+	stralloc satree = STRALLOC_ZERO ;
+	
+	info_color = &no_color ;
+	
+	char const *svname = 0 ;
+	char const *tname = 0 ;
+	
+	ENVP = envp ;
+	
+	for (int i = 0 ; i < MAXOPTS ; i++)
+		what[i] = -1 ;
+		
+	
+	char buf[MAXOPTS][INFO_FIELD_MAXLEN] = {
+		"Name",
+		"In tree",
+		"Status",
+		"Type",
+		"Description",
+		"Source",
+		"Live",
+		"Depends on",
+		"Start script",
+		"Stop script",
+		"Environment source",
+		"Environment file",
+		"Log name",
+		"Log destination",
+		"Log file" } ;
+	
+	PROG = "66-inservice" ;
+	{
+		subgetopt_t l = SUBGETOPT_ZERO ;
+
+		for (;;)
+		{
+			int opt = getopt_args(argc,argv, ">hv:co:grd:t:p:", &l) ;
+			if (opt == -1) break ;
+			if (opt == -2) strerr_dief1x(110,"options must be set first") ;
+			switch (opt)
+			{
+				case 'h' : 	info_help(); return 0 ;
+				case 'v' :  if (!uint0_scan(l.arg, &VERBOSITY)) exitusage(USAGE) ; break ;
+				case 'c' :	info_color = !isatty(1) ? &no_color : &use_color ; 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)) exitusage(USAGE) ; break ;
+				case 't' : 	tname = l.arg ; break ;
+				case 'p' : 	if (!uint0_scan(l.arg, &nlog)) exitusage(USAGE) ; break ;
+				default : exitusage(USAGE) ; 
+			}
+		}
+		argc -= l.ind ; argv += l.ind ;
+	}
+	
+	if (!argc) exitusage(USAGE) ;
+	svname = *argv ;
+	
+	if (legacy)
+	{
+		unsigned int i = 0 ;
+		for (; i < MAXOPTS - 1 ; i++)
+			what[i] = i ;
+			
+		what[i] = -1 ;
+	}
+	
+	OWNER = getuid() ;
+	size_t ownerlen = uid_fmt(OWNERSTR,OWNER) ;
+	OWNERSTR[ownerlen] = 0 ;
+	
+	info_field_align(buf,fields,field_suffix,MAXOPTS) ;
+		
+	setlocale(LC_ALL, "");
+	
+	if(!str_diff(nl_langinfo(CODESET), "UTF-8")) {
+		STYLE = &graph_utf8;
+	}
+	
+	if (!set_ownersysdir(&src,OWNER)) strerr_diefu1sys(111, "set owner directory") ;
+	if (!stralloc_cats(&src,SS_SYSTEM) ||
+	!stralloc_0(&src))  exitstralloc("main") ;
+	src.len-- ;
+	
+	if (!scan_mode(src.s,S_IFDIR))
+	{
+		strerr_warni1x("no tree exist yet") ;
+		goto freed ;
+	}
+	
+	if (!stralloc_cats(&src,"/")) exitstralloc("main") ;
+	newlen = src.len ;
+	
+	if (!tname)
+	{	
+		stralloc tmp = STRALLOC_ZERO ;
+		if (!stralloc_0(&src) ||
+		!stralloc_copy(&tmp,&src)) exitstralloc("main") ;
+		
+		if (!sastr_dir_get(&satree, src.s,SS_BACKUP+1, S_IFDIR)) 
+			strerr_diefu2x(111,"get tree from directory: ",src.s) ;
+		
+		if (satree.len)
+		{
+			for(pos = 0 ; pos < satree.len ; pos += strlen(satree.s + pos) + 1)
+			{
+				tmp.len = newlen ;
+				char *name = satree.s + pos ;
+				
+				if (!stralloc_cats(&tmp,name) ||
+				!stralloc_cats(&tmp,SS_SVDIRS) ||
+				!stralloc_0(&tmp)) exitstralloc("main");
+				if (ss_resolve_check(tmp.s,svname))
+				{
+					if (!found)
+						if (!stralloc_copy(&src,&tmp)) exitstralloc("main") ;
+					found++ ;
+				}
+			}
+		}
+		else 
+		{
+			if (!bprintf(buffer_1,"%s%s%s\n",info_color->warning," nothing to display",info_color->off))
+				strerr_diefu1sys(111,"write to stdout") ;
+			if (buffer_putsflush(buffer_1,"\n") < 0)
+				strerr_diefu1sys(111,"write to stdout") ;
+		}
+		stralloc_free(&tmp) ;
+	}
+	else
+	{
+		if (!stralloc_cats(&src,tname) ||
+		!stralloc_cats(&src,SS_SVDIRS) ||
+		!stralloc_0(&src)) exitstralloc("main") ;
+		if (ss_resolve_check(src.s,svname)) found++;
+	}
+
+	if (!found)
+	{
+		strerr_dief2x(111,"unknown service: ",svname) ;
+	
+	}
+	else if (found > 1)
+	{
+		strerr_dief2x(111,svname," is set on different tree -- please use -t options") ;
+	}
+	
+	if (!ss_resolve_read(&res,src.s,svname)) 
+		strerr_diefu2sys(111,"read resolve file of: ",svname) ;
+	
+	info_display_all(&res,what) ;
+	
+	if (buffer_putsflush(buffer_1,"\n") == -1) 
+		strerr_diefu1sys(111, "write to stdout") ;
+	
+		
+	freed:
+	ss_resolve_free(&res) ;
+	stralloc_free(&src) ;
+	stralloc_free(&satree) ;
+		
+	return 0 ;
+
+}
diff --git a/src/66/66-intree.c b/src/66/66-intree.c
new file mode 100644
index 00000000..065df952
--- /dev/null
+++ b/src/66/66-intree.c
@@ -0,0 +1,455 @@
+/* 
+ * 66-intree.c
+ * 
+ * Copyright (c) 2018-2019 Eric Vidal <eric@obarun.org>
+ * 
+ * All rights reserved.
+ * 
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <sys/types.h>
+#include <wchar.h>
+#include <unistd.h>//access
+
+#include <oblibs/sastr.h>
+#include <oblibs/error2.h>
+#include <oblibs/obgetopt.h>
+#include <oblibs/types.h>
+#include <oblibs/string.h>
+
+#include <skalibs/strerr2.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+#include <skalibs/lolstdio.h>
+#include <skalibs/bytestr.h>
+#include <skalibs/buffer.h>
+
+#include <66/info.h>
+#include <66/utils.h>
+#include <66/constants.h>
+#include <66/tree.h>
+#include <66/enum.h>
+#include <66/resolve.h>
+
+unsigned int VERBOSITY = 1 ;
+static unsigned int REVERSE = 0 ;
+unsigned int MAXDEPTH = 1 ;
+static unsigned int GRAPH = 0 ;
+static uid_t OWNER ;
+static char OWNERSTR[UID_FMT] ;
+
+static stralloc base = STRALLOC_ZERO ;
+static stralloc live = STRALLOC_ZERO ;
+static stralloc src = STRALLOC_ZERO ;
+
+static wchar_t const field_suffix[] = L" :" ;
+static char fields[ENDOFKEY][INFO_FIELD_MAXLEN] = {{ 0 }} ;
+static void info_display_name(char const *field,char const *treename) ;
+static void info_display_init(char const *field,char const *treename) ;
+static void info_display_enabled(char const *field,char const *treename) ;
+static void info_display_current(char const *field,char const *treename) ;
+static void info_display_contains(char const *field,char const *treename) ;
+ss_resolve_graph_style *STYLE = &graph_default ;
+
+info_opts_map_t const opts_tree_table[] =
+{
+	{ .str = "name", .func = &info_display_name, .id = 0 },
+	{ .str = "init", .func = &info_display_init, .id = 1 },
+	{ .str = "enabled", .func = &info_display_enabled, .id = 2 },
+	{ .str = "current", .func = &info_display_current, .id = 3 },
+	{ .str = "contains", .func = &info_display_contains, .id = 4 },
+	{ .str = 0, .func = 0, .id = -1 }
+} ;
+
+#define MAXOPTS 6
+#define checkopts(n) if (n >= MAXOPTS) strerr_dief1x(100, "too many options")
+#define DELIM ','
+
+#define USAGE "66-intree [ -h ] [ -v verbosity ] [ -l live ] [ -c ] [ -o name,init,enabled,... ] [ -g ] [ -d depth ] [ -r ] tree"
+
+static inline void info_help (void)
+{
+  static char const *help =
+"66-intree <options> tree \n"
+"\n"
+"options :\n"
+"	-h: print this help\n"
+"	-v: increase/decrease verbosity\n"
+"	-l: live directory\n"
+"	-c: use color\n"
+"	-o: comma separated list of field to display\n"
+"	-g: displays the contains field as graph\n"
+"	-d: limit the depth of the contains field recursion\n"
+"	-r: reserve the contains field\n" 
+"\n"
+"valid field for -o options are:\n"
+"\n"
+"	name: displays the name of the tree\n"
+"	init: displays a boolean value of the initialization state\n"
+"	enabled: displays a boolean value of the enable state\n"
+"	current: displays a boolean value of the current state\n"
+"	contains: displays the contain of the tree\n"
+"\n"
+;
+
+ if (buffer_putsflush(buffer_1, help) < 0)
+    strerr_diefu1sys(111, "write to stdout") ;
+}
+
+static int info_cmpnsort(stralloc *sa)
+{
+	size_t pos = 0 ;
+	if (!sa->len) return 0 ;
+	size_t salen = sa->len ;
+	size_t nel = sastr_len(sa), idx = 0, a = 0, b = 0 ;
+	char names[nel][4096] ;
+	char tmp[4096] ;
+	
+	for (; pos < salen && idx < nel ; pos += strlen(sa->s + pos) + 1,idx++)
+	{
+		memcpy(names[idx],sa->s + pos,strlen(sa->s + pos)) ;
+		names[idx][strlen(sa->s+pos)] = 0 ;
+	}
+	for (; a < nel - 1 ; a++)
+	{
+		for (b = a + 1 ; b < idx ; b++)
+		{
+			if (strcmp(names[a],names[b]) > 0)
+			{
+				strcpy(tmp,names[a]) ;
+				strcpy(names[a],names[b]);
+				strcpy(names[b],tmp);
+			}
+		}
+	}
+	sa->len = 0 ;
+	for (a = 0 ; a < nel ; a++)
+	{
+		if (!sastr_add_string(sa,names[a])) return 0 ;
+	}	
+	return 1 ;
+}
+
+static void info_display_name(char const *field, char const *treename)
+{
+	info_display_field_name(field) ;
+	if (!bprintf(buffer_1," %s",treename)) 
+		strerr_diefu1sys(111,"write to stdout") ;
+	if (buffer_putsflush(buffer_1,"\n") == -1) 
+		strerr_diefu1sys(111,"write to stdout") ;
+}
+
+static void info_display_init(char const *field,char const *treename)
+{
+	unsigned int init = 0 ;
+	int r = set_livedir(&live) ;
+	if (!r) exitstralloc("display_init") ;
+	if (r == -1) strerr_dief3x(111,"live: ",live.s," must be an absolute path") ;
+	
+	if (!stralloc_cats(&live,SS_STATE + 1) ||
+	!stralloc_cats(&live,"/") ||
+	!stralloc_cats(&live,OWNERSTR) ||
+	!stralloc_cats(&live,"/") ||
+	!stralloc_cats(&live,treename) ||
+	!stralloc_cats(&live,"/init") ||
+	!stralloc_0(&live)) exitstralloc("display_init") ;
+	if (!access(live.s, F_OK)) init = 1 ;
+	
+	info_display_field_name(field) ;
+	if (!bprintf(buffer_1," %s%s%s",init ? info_color->valid : info_color->warning, init ? "yes":"no",info_color->off)) 
+		strerr_diefu1sys(111,"write to stdout") ;
+	
+	if (buffer_putsflush(buffer_1,"\n") == -1) 
+		strerr_diefu1sys(111,"write to stdout") ;
+
+}
+
+static void info_display_current(char const *field,char const *treename)
+{
+	stralloc sacurr = STRALLOC_ZERO ;
+	int current = 0 ;
+	
+	if (tree_find_current(&sacurr,base.s,OWNER))
+	{
+		char name[sacurr.len] ;
+		if (!basename(name,sacurr.s)) strerr_diefu2x(111,"basename of: ",sacurr.s) ;
+		current = obstr_equal(treename,name) ;
+	}
+	info_display_field_name(field) ;
+	if (!bprintf(buffer_1," %s%s%s", current ? info_color->blink : info_color->warning, current ? "yes":"no",info_color->off))
+		strerr_diefu1sys(111,"write to stdout") ;
+	
+	if (buffer_putsflush(buffer_1,"\n") == -1) 
+		strerr_diefu1sys(111,"write to stdout") ;	
+	
+	stralloc_free(&sacurr) ;
+}
+
+static void info_display_enabled(char const *field,char const *treename)
+{
+	int enabled = tree_cmd_state(VERBOSITY,"-s",treename) ;
+	info_display_field_name(field) ;
+	if (!bprintf(buffer_1," %s%s%s",enabled == 1 ? info_color->valid : info_color->warning, enabled == 1 ? "yes":"no",info_color->off)) 
+		strerr_diefu1sys(111,"write to stdout") ;
+	
+	if (buffer_putsflush(buffer_1,"\n") == -1) 
+		strerr_diefu1sys(111,"write to stdout") ;
+}
+
+static void info_display_contains(char const *field, char const *treename)
+{
+	int r ;
+	size_t padding = 1 ;
+	ss_resolve_t res = RESOLVE_ZERO ;
+	ss_resolve_graph_t graph = RESOLVE_GRAPH_ZERO ;
+	stralloc salist = STRALLOC_ZERO ;
+
+	if (!stralloc_cats(&src,treename) ||
+	!stralloc_cats(&src,SS_SVDIRS) ||
+	!stralloc_0(&src)) exitstralloc("display_contains") ;
+	
+	r = ss_resolve_graph_src(&graph,src.s,0,2) ;
+	if (!r) strerr_diefu2x(111,"resolve source of graph for tree: ",treename) ;
+	
+	padding = info_display_field_name(field) ;
+	
+	if (!genalloc_len(ss_resolve_t,&graph.name)) goto empty ;
+	
+	r = ss_resolve_graph_publish(&graph,0) ;
+	if (r < 0) strerr_dief2x(110,"cyclic graph detected at tree: ", treename) ;
+	else if (!r) strerr_diefu2sys(111,"publish service graph of tree: ",treename) ;
+	
+	for (size_t i = 0 ; i < genalloc_len(ss_resolve_t,&graph.sorted) ; i++)
+	{
+		char *string = genalloc_s(ss_resolve_t,&graph.sorted)[i].sa.s ;
+		char *name = string + genalloc_s(ss_resolve_t,&graph.sorted)[i].name ;
+		if (!stralloc_catb(&salist,name,strlen(name)+1)) exitstralloc("display_contains") ;
+	}
+		
+	if (GRAPH)
+	{
+		if (!bprintf(buffer_1," %s\n","/")) 
+			strerr_diefu1sys(111,"write to stdout") ;
+		size_t el = sastr_len(&salist) ;
+		if (!sastr_rebuild_in_oneline(&salist)) strerr_diefu1x(111,"rebuild dependencies list") ;
+		ss_resolve_init(&res) ;
+		res.ndeps = el ;
+		res.deps = ss_resolve_add_string(&res,salist.s) ;
+		if (!info_graph_init(&res,src.s,REVERSE, padding, STYLE))
+			strerr_dief2x(111,"display graph of: ",treename) ;
+		goto freed ;
+	}
+	else
+	{
+		if (!bprintf(buffer_1,"%s"," ")) 
+			strerr_diefu1sys(111,"write to stdout") ;
+		if (REVERSE) 
+			if (!sastr_reverse(&salist))
+				strerr_diefu1x(111,"reverse dependencies list") ;
+		info_display_list(field,&salist) ;
+		goto freed ;
+	}
+	empty:
+		if (GRAPH)
+		{
+			if (!bprintf(buffer_1," %s\n","/")) 
+				strerr_diefu1sys(111,"write to stdout") ;
+			if (!bprintf(buffer_1,"%*s%s%s",padding,"",STYLE->last," empty tree")) 
+				strerr_diefu1sys(111,"write to stdout") ;
+		}
+		else
+		{
+			if (!bprintf(buffer_1,"%s"," empty tree")) 
+				strerr_diefu1sys(111,"write to stdout") ;
+		}
+		if (buffer_putsflush(buffer_1,"\n") == -1)
+			strerr_diefu1sys(111,"write to stdout") ;
+	freed:
+		ss_resolve_free(&res) ;
+		ss_resolve_graph_free(&graph) ;
+		stralloc_free(&salist) ;
+}
+
+static void info_display_all(char const *treename,int *what)
+{
+	
+	unsigned int i = 0 ;
+	for (; what[i] >= 0 ; i++)
+	{
+		unsigned int idx = what[i] ;
+		(*opts_tree_table[idx].func)(fields[opts_tree_table[idx].id],treename) ;
+	}
+	
+}
+
+static void info_parse_options(char const *str,int *what)
+{
+	size_t pos = 0 ;
+	stralloc sa = STRALLOC_ZERO ;
+	
+	if (!sastr_clean_string_wdelim(&sa,str,DELIM)) strerr_diefu1x(111,"parse options") ;
+	unsigned int n = sastr_len(&sa), nopts = 0 , old ;
+	checkopts(n) ;
+	info_opts_map_t const *t ;
+	
+	for (;pos < sa.len; pos += strlen(sa.s + pos) + 1)
+	{
+		char *o = sa.s + pos ;
+		t = opts_tree_table ;
+		old = nopts ;
+		for (; t->str; t++)
+		{			
+			if (obstr_equal(o,t->str))
+			{
+				/*if (!t->id){ what[0] = t->id ; old++ ; }
+				else*/ what[nopts++] = t->id ;
+			}
+		}
+		if (old == nopts) strerr_dief2x(111,"invalid option: ",o) ;
+	}
+	
+	stralloc_free(&sa) ;
+}
+
+int main(int argc, char const *const *argv, char const *const *envp)
+{
+	unsigned int legacy = 1 ;
+	
+	size_t pos, newlen ;
+	int what[MAXOPTS] = { 0 } ;
+	
+	info_color = &no_color ;
+	
+	char const *treename = 0 ;
+	
+	for (int i = 0 ; i < MAXOPTS ; i++)
+		what[i] = -1 ;
+		
+	
+	char buf[MAXOPTS][INFO_FIELD_MAXLEN] = {
+		"Name",
+		"Initialized",
+		"Enabled",
+		"Current",
+		"Contains" } ;
+	
+	
+	stralloc satree = STRALLOC_ZERO ;
+	
+	PROG = "66-intree" ;
+	{
+		subgetopt_t l = SUBGETOPT_ZERO ;
+
+		for (;;)
+		{
+			int opt = getopt_args(argc,argv, ">hv:co:grd:l:", &l) ;
+			if (opt == -1) break ;
+			if (opt == -2) strerr_dief1x(110,"options must be set first") ;
+			switch (opt)
+			{
+				case 'h' : 	info_help(); return 0 ;
+				case 'v' :  if (!uint0_scan(l.arg, &VERBOSITY)) exitusage(USAGE) ; break ;
+				case 'c' :	info_color = !isatty(1) ? &no_color : &use_color ; 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)) exitusage(USAGE) ; break ;
+				case 'l' : 	if (!stralloc_cats(&live,l.arg)) exitusage(USAGE) ;
+							if (!stralloc_0(&live)) exitusage(USAGE) ;
+							break ;
+				default : exitusage(USAGE) ; 
+			}
+		}
+		argc -= l.ind ; argv += l.ind ;
+	}
+	
+	if (argv[0]) treename = argv[0] ;
+	
+	if (legacy)
+	{
+		unsigned int i = 0 ;
+		for (; i < MAXOPTS - 1 ; i++)
+			what[i] = i ;
+			
+		what[i] = -1 ;
+	}
+	
+	OWNER = getuid() ;
+	size_t ownerlen = uid_fmt(OWNERSTR,OWNER) ;
+	OWNERSTR[ownerlen] = 0 ;
+	
+	info_field_align(buf,fields,field_suffix,MAXOPTS) ;
+		
+	setlocale(LC_ALL, "");
+	
+	if(!str_diff(nl_langinfo(CODESET), "UTF-8")) {
+		STYLE = &graph_utf8;
+	}
+	
+	if (!set_ownersysdir(&base,OWNER)) strerr_diefu1sys(111, "set owner directory") ;
+	if (!stralloc_copy(&src,&base) ||
+	!stralloc_cats(&src,SS_SYSTEM) ||
+	!stralloc_0(&src))  exitstralloc("main") ;
+	src.len-- ;
+	
+	if (!scan_mode(src.s,S_IFDIR))
+	{
+		strerr_warni1x("no tree exist yet") ;
+		goto freed ;
+	}
+	
+	if (!stralloc_cats(&src,"/")) exitstralloc("main") ;
+	newlen = src.len ;
+	
+	if (treename)
+	{
+		
+		if (!stralloc_cats(&src,treename) ||
+		!stralloc_0(&src)) exitstralloc("main") ;
+		if (!scan_mode(src.s,S_IFDIR)) strerr_diefu2sys(111,"find tree: ", src.s) ;
+		src.len = newlen ;
+		info_display_all(treename,what) ;		
+	}
+	else
+	{
+		
+	    if (!sastr_dir_get(&satree, src.s,SS_BACKUP + 1, S_IFDIR)) strerr_diefu2sys(111,"get list of tree at: ",src.s) ;
+		if (satree.len)
+		{
+			if (!info_cmpnsort(&satree)) strerr_diefu1x(111,"sort list of tree") ;
+			for(pos = 0 ; pos < satree.len ; pos += strlen(satree.s + pos) +1 )
+			{
+				src.len = newlen ;
+				char *name = satree.s + pos ;
+				info_display_all(name,what) ;
+				if (buffer_puts(buffer_1,"\n") == -1) 
+					strerr_diefu1sys(111,"write to stdout") ;	
+			}
+		}
+		else 
+		{
+			strerr_warni1x("no tree exist yet") ;
+			goto freed ;
+		}
+	}
+
+	if (buffer_putsflush(buffer_1,"\n") == -1) 
+		strerr_diefu1sys(111, "write to stdout") ;
+	
+		
+	freed:
+	stralloc_free(&base) ;
+	stralloc_free(&live) ;
+	stralloc_free(&src) ;
+	stralloc_free(&satree) ;
+		
+	return 0 ;
+}
diff --git a/src/66/deps-exe/66-inservice b/src/66/deps-exe/66-inservice
new file mode 100644
index 00000000..306db624
--- /dev/null
+++ b/src/66/deps-exe/66-inservice
@@ -0,0 +1,4 @@
+${LIB66}
+-ls6
+-loblibs
+-lskarnet
diff --git a/src/66/deps-exe/66-intree b/src/66/deps-exe/66-intree
new file mode 100644
index 00000000..306db624
--- /dev/null
+++ b/src/66/deps-exe/66-intree
@@ -0,0 +1,4 @@
+${LIB66}
+-ls6
+-loblibs
+-lskarnet
diff --git a/src/include/66/info.h b/src/include/66/info.h
new file mode 100644
index 00000000..26a548a0
--- /dev/null
+++ b/src/include/66/info.h
@@ -0,0 +1,83 @@
+/* 
+ * info.h
+ * 
+ * Copyright (c) 2018-2019 Eric Vidal <eric@obarun.org>
+ * 
+ * All rights reserved.
+ * 
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <wchar.h>
+
+#include <oblibs/string.h>
+#include <oblibs/display.h>
+
+#include <66/enum.h>
+#include <66/resolve.h>
+
+ 
+#ifndef SS_INFO_H
+#define SS_INFO_H
+
+#define INFO_FIELD_MAXLEN 30
+
+set_color_t *info_color ;
+extern set_color_t use_color ;
+extern set_color_t no_color ;
+
+typedef struct depth_s depth_t ;
+struct depth_s
+{
+	depth_t *prev ;
+	depth_t *next ;
+	int level ;
+} ;
+
+typedef void info_opts_func_t (char const *field,char const *treename) ;
+typedef info_opts_func_t *info_opts_func_t_ref ;
+typedef void info_opts_svfunc_t (char const *field,ss_resolve_t *res) ;
+typedef info_opts_svfunc_t *info_opts_svfunc_t_ref ;
+
+typedef struct info_opts_map_s info_opts_map_t ;
+struct info_opts_map_s
+{
+	char const *str ;
+	info_opts_func_t *func ;
+	info_opts_svfunc_t *svfunc ;
+	unsigned int id ;
+} ;
+
+#define UTF_V   "\342\224\202"  /* U+2502, Vertical line drawing char */
+#define UTF_VR  "\342\224\234"  /* U+251C, Vertical and right */
+#define UTF_H   "\342\224\200"  /* U+2500, Horizontal */
+#define UTF_UR  "\342\224\224"  /* U+2514, Up and right */
+
+typedef struct ss_resolve_graph_style_s ss_resolve_graph_style ;
+struct ss_resolve_graph_style_s
+{
+	const char *tip;
+	const char *last;
+	const char *limb;
+	int indent;
+} ;
+
+extern unsigned int MAXDEPTH ;
+extern ss_resolve_graph_style *STYLE ; 
+extern ss_resolve_graph_style graph_utf8 ;
+extern ss_resolve_graph_style graph_default ;
+
+extern void info_field_align (char buf[][INFO_FIELD_MAXLEN],char fields[][INFO_FIELD_MAXLEN],wchar_t const field_suffix[],size_t buflen) ;
+extern int info_getcols_fd(int fd) ;
+extern size_t info_length_from_wchar(char const *str) ;
+extern void info_graph_display(ss_resolve_t *res, depth_t *depth, int last,int padding, ss_resolve_graph_style *style) ;
+extern int info_graph_init (ss_resolve_t *res,char const *src,unsigned int reverse, int padding, ss_resolve_graph_style *style) ;
+extern int info_walk(ss_resolve_t *res,char const *src,int reverse, depth_t *depth, int padding, ss_resolve_graph_style *style) ;
+extern size_t info_display_field_name(char const *field) ;
+extern void info_display_list(char const *field, stralloc *list) ;
+extern void info_display_nline(char const *field,char const *str) ;
+#endif
diff --git a/src/include/66/resolve.h b/src/include/66/resolve.h
index 40c03e15..087e0363 100644
--- a/src/include/66/resolve.h
+++ b/src/include/66/resolve.h
@@ -85,30 +85,11 @@ struct ss_resolve_graph_s
 typedef enum visit_e visit ;
 enum visit_e
 {
-	WHITE = 0, 
-	GRAY, 
-	BLACK
+	SS_WHITE = 0, 
+	SS_GRAY, 
+	SS_BLACK
 } ; 
 
-#define UTF_V   "\342\224\202"  /* U+2502, Vertical line drawing char */
-#define UTF_VR  "\342\224\234"  /* U+251C, Vertical and right */
-#define UTF_H   "\342\224\200"  /* U+2500, Horizontal */
-#define UTF_UR  "\342\224\224"  /* U+2514, Up and right */
-
-typedef struct ss_resolve_graph_style_s ss_resolve_graph_style ;
-struct ss_resolve_graph_style_s
-{
-	const char *tip;
-	const char *last;
-	const char *limb;
-	int indent;
-} ;
-
-extern unsigned int MAXDEPTH ;
-extern ss_resolve_graph_style *STYLE ; 
-extern ss_resolve_graph_style graph_utf8 ;
-extern ss_resolve_graph_style graph_default ;
-
 extern ss_resolve_t const ss_resolve_zero ;
 extern void ss_resolve_init(ss_resolve_t *res) ;
 extern void ss_resolve_free(ss_resolve_t *res) ;
diff --git a/src/lib66/deps-lib/66 b/src/lib66/deps-lib/66
index f21202a0..dd739253 100644
--- a/src/lib66/deps-lib/66
+++ b/src/lib66/deps-lib/66
@@ -31,6 +31,7 @@ set_livestate.o
 set_livetree.o
 set_ownerhome.o
 set_ownersysdir.o
+ss_info_utils.o
 ss_utils.o
 ssexec_dbctl.o
 ssexec_enable.o
diff --git a/src/lib66/resolve_graph.c b/src/lib66/resolve_graph.c
index 7c820283..07902f09 100644
--- a/src/lib66/resolve_graph.c
+++ b/src/lib66/resolve_graph.c
@@ -28,20 +28,6 @@
 #include <66/constants.h>
 #include <66/utils.h>
 
-ss_resolve_graph_style graph_utf8 = {
-	UTF_VR UTF_H,
-	UTF_UR UTF_H,
-	UTF_V " ",
-	2
-} ;
-
-ss_resolve_graph_style graph_default = {
-	"|-",
-	"`-",
-	"|",
-	2
-} ;
-
 void ss_resolve_graph_ndeps_free(ss_resolve_graph_ndeps_t *graph)
 {
 	genalloc_free(uint32_t,&graph->ndeps) ;
@@ -59,10 +45,10 @@ int ss_resolve_dfs(ss_resolve_graph_t *graph, unsigned int idx, visit *c,unsigne
 	int cycle = 0 ;
 	unsigned int i, data ;
 	unsigned int len = genalloc_len(uint32_t,&genalloc_s(ss_resolve_graph_ndeps_t,&graph->cp)[idx].ndeps) ;
-	if (c[idx] == GRAY) return 1 ;
-	if (c[idx] == WHITE)
+	if (c[idx] == SS_GRAY) return 1 ;
+	if (c[idx] == SS_WHITE)
 	{
-		c[idx] = GRAY ;
+		c[idx] = SS_GRAY ;
 		for (i = 0 ; i < len ; i++)
 		{
 			data = genalloc_s(uint32_t,&genalloc_s(ss_resolve_graph_ndeps_t,&graph->cp)[idx].ndeps)[i] ;
@@ -77,7 +63,7 @@ int ss_resolve_dfs(ss_resolve_graph_t *graph, unsigned int idx, visit *c,unsigne
 				goto end ; 
 			} 
 		}
-		c[idx] = BLACK ;
+		c[idx] = SS_BLACK ;
 		genalloc_insertb(ss_resolve_t, &graph->sorted, 0, &genalloc_s(ss_resolve_t,&graph->name)[idx],1) ; 
 	}
 	end:
@@ -89,12 +75,12 @@ int ss_resolve_graph_sort(ss_resolve_graph_t *graph)
 	unsigned int len = genalloc_len(ss_resolve_graph_ndeps_t,&graph->cp) ;
 	visit c[len] ;
 	unsigned int i, ename = 0, edeps = 0 ;
-	for (i = 0 ; i < len; i++) c[i] = WHITE ;
+	for (i = 0 ; i < len; i++) c[i] = SS_WHITE ;
 	if (!len) return 0 ;
 
 	for (i = 0 ; i < len ; i++)
 	{
-		if (c[i] == WHITE && ss_resolve_dfs(graph,genalloc_s(ss_resolve_graph_ndeps_t,&graph->cp)[i].idx,c,&ename,&edeps))
+		if (c[i] == SS_WHITE && ss_resolve_dfs(graph,genalloc_s(ss_resolve_graph_ndeps_t,&graph->cp)[i].idx,c,&ename,&edeps))
 		{
 			int data = genalloc_s(uint32_t,&genalloc_s(ss_resolve_graph_ndeps_t,&graph->cp)[ename].ndeps)[edeps] ;
 			char *name = genalloc_s(ss_resolve_t,&graph->name)[ename].sa.s + genalloc_s(ss_resolve_t,&graph->name)[ename].name ;
diff --git a/src/lib66/ss_info_utils.c b/src/lib66/ss_info_utils.c
new file mode 100644
index 00000000..fc459259
--- /dev/null
+++ b/src/lib66/ss_info_utils.c
@@ -0,0 +1,314 @@
+/* 
+ * ss_info_utils.c
+ * 
+ * Copyright (c) 2018-2019 Eric Vidal <eric@obarun.org>
+ * 
+ * All rights reserved.
+ * 
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ * */
+ 
+#include <66/info.h>
+
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <wchar.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h> //ssize_t
+
+#include <oblibs/display.h>
+#include <oblibs/sastr.h>
+#include <oblibs/error2.h>
+
+#include <skalibs/buffer.h>
+#include <skalibs/lolstdio.h>
+
+#include <s6/s6-supervise.h>
+
+#include <66/resolve.h>
+
+ss_resolve_graph_style graph_utf8 = {
+	UTF_VR UTF_H,
+	UTF_UR UTF_H,
+	UTF_V " ",
+	2
+} ;
+
+ss_resolve_graph_style graph_default = {
+	"|-",
+	"`-",
+	"|",
+	2
+} ;
+
+set_color_t use_color = {
+	BWHITE, //info
+	BGREEN, // valid
+	BYELLOW,  //warning
+	BL_BBLUE, // blink
+	BRED, //error
+	NOCOLOR //reset
+} ;
+
+set_color_t no_color = {
+	"",
+	"",
+	"",
+	"",
+	"",
+	""
+} ;
+
+int info_getcols_fd(int fd)
+{
+	int width = -1;
+
+	if(!isatty(fd))	return 0;
+
+#if defined(TIOCGSIZE)
+	struct ttysize win;
+	if(ioctl(fd, TIOCGSIZE, &win) == 0)
+		width = win.ts_cols;
+#elif defined(TIOCGWINSZ)
+	struct winsize win;
+	if(ioctl(fd, TIOCGWINSZ, &win) == 0)
+		width = win.ws_col;
+#endif
+	
+	// return abitrary value
+	if(width <= 0) return 100 ;
+	
+	return width;
+}
+
+void info_field_align (char buf[][INFO_FIELD_MAXLEN],char fields[][INFO_FIELD_MAXLEN],wchar_t const field_suffix[],size_t buflen)
+{
+	unsigned int i ;
+	
+	size_t maxlen = 0 ;
+	
+	int maxcol = 0 ;
+	
+	static wchar_t wbuf[][INFO_FIELD_MAXLEN+nb_el(field_suffix)] = {{ 0 }} ;
+	
+	size_t wlen[buflen] ;
+	
+	int wcol[buflen] ;
+
+	for(i = 0; i < buflen; i++)
+	{
+		wlen[i] = mbstowcs(wbuf[i], buf[i], strlen(buf[i]) + 1) ;
+		wcol[i] = wcswidth(wbuf[i], wlen[i]) ;
+		if(wcol[i] > maxcol) {
+			maxcol = wcol[i] ;
+		}
+		if(wlen[i] > maxlen) {
+			maxlen = wlen[i] ;
+		}
+	}
+
+	for(i = 0; i < buflen; i++)
+	{
+		size_t padlen = maxcol - wcol[i] ;
+		wmemset(wbuf[i] + wlen[i], L' ', padlen) ;
+		wmemcpy(wbuf[i] + wlen[i] + padlen, field_suffix, nb_el(field_suffix)) ;
+		wcstombs(fields[i], wbuf[i], sizeof(wbuf[i])) ;
+	}
+}
+
+size_t info_length_from_wchar(char const *str)
+{
+	ssize_t len ;
+	wchar_t *wcstr ;
+	if(!str || !str[0]) return 0 ;
+	
+	len = strlen(str) + 1 ;
+	wcstr = calloc(len, sizeof(wchar_t)) ;
+	len = mbstowcs(wcstr, str, len) ;
+	len = wcswidth(wcstr, len) ;
+	free(wcstr) ;
+
+	return len == -1 ? 0 : (size_t)len  ;
+}
+
+size_t info_display_field_name(char const *field)
+{
+	size_t len = 0 ;
+	if(field)
+	{
+		len = info_length_from_wchar(field) + 1 ;
+		if (!bprintf(buffer_1,"%s%s%s", info_color->info, field, info_color->off)) strerr_diefu1sys(111,"write to stdout") ;
+	}
+	return len ;
+}
+
+void info_display_list(char const *field, stralloc *list)
+{
+	size_t a = 0 , b, cols, padding = 0, slen = 0 ;
+	
+	unsigned short maxcols = info_getcols_fd(1) ;
+	
+	padding = info_length_from_wchar(field) + 1 ;
+	
+	cols = padding ;
+	
+	for (; a < list->len ; a += strlen(list->s + a) + 1)
+	{
+		char const *str = list->s + a ;
+		slen = info_length_from_wchar(str) ;
+		if((maxcols > padding) && (cols + slen + 2 >= maxcols))
+		{
+			cols = padding ;
+			if (buffer_puts(buffer_1,"\n") == -1) goto err ;
+			for(b = 1 ; b <= padding ; b++)
+				if (buffer_puts(buffer_1," ") == -1) goto err ;
+		} 
+		else if (cols != padding)
+		{
+			if (buffer_puts(buffer_1,"  ") == -1) goto err ;
+			cols += 2 ;
+		}
+		if (!bprintf(buffer_1,"%s",str)) goto err ;
+		cols += slen ;
+	}
+	if (buffer_puts(buffer_1,"\n") == -1) goto err ;
+	
+	return ;
+	err:
+		strerr_diefu1sys(111,"write to stdout") ;
+}
+
+void info_display_nline(char const *field,char const *str)
+{
+	size_t pos = 0, padding = info_length_from_wchar(field) + 1 ;
+	stralloc tmp = STRALLOC_ZERO ;
+	stralloc cp = STRALLOC_ZERO ;
+	if (!stralloc_cats(&tmp,str) ||
+	!stralloc_0(&tmp)) exitstralloc("info_display_nline") ;
+	if (!sastr_split_string_in_nline(&tmp)) strerr_diefu1x(111,"split string in nline") ;
+	for (;pos < tmp.len ; pos += strlen(tmp.s + pos) + 1)
+	{
+		cp.len = 0 ;
+		if (!stralloc_cats(&cp,tmp.s + pos) ||
+		!stralloc_0(&cp)) exitstralloc("info_display_nline") ;
+		if (!pos)
+		{
+			if (!bprintf(buffer_1,"%s"," "))
+				strerr_diefu1sys(111,"write to stdout") ;
+		}
+		else
+		{
+			if (!bprintf(buffer_1,"%*s",padding,""))
+				strerr_diefu1sys(111,"write to stdout") ;
+		}
+		info_display_list(field,&cp) ;
+	}
+	stralloc_free(&tmp) ;
+	stralloc_free(&cp) ;
+}
+
+void info_graph_display(ss_resolve_t *res, depth_t *depth, int last, int padding, ss_resolve_graph_style *style)
+{
+	s6_svstatus_t status = S6_SVSTATUS_ZERO ;
+	char *name = res->sa.s + res->name ;
+	if (res->type == CLASSIC || res->type == LONGRUN)
+	{
+		s6_svstatus_read(res->sa.s + res->runat ,&status) ;
+	}
+	else status.pid = 0 ;	
+	
+	const char *tip = "" ;
+	int level = 1 ;
+	
+	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 ;
+		level = depth->level + 1 ;
+		depth = depth->next ;
+	} 
+	
+	if (!bprintf(buffer_1,"%*s%*s%s(%s%i%s,%s%s%s,%s) %s",level == 1 ? padding : 0,"", style->indent * (depth->level - level), "", tip, status.pid ? info_color->valid : info_color->off,status.pid ? status.pid : 0,info_color->off, res->disen ? info_color->off : info_color->error, res->disen ? "Enabled" : "Disabled",info_color->off,get_keybyid(res->type), name)) return ;
+
+	if (buffer_putsflush(buffer_1,"\n") < 0) return ; 
+}
+
+int info_walk(ss_resolve_t *res,char const *src,int reverse, depth_t *depth, int padding, ss_resolve_graph_style *style)
+{
+	size_t pos = 0, idx = 0 ;
+	stralloc sadeps = STRALLOC_ZERO ;
+	ss_resolve_t dres = RESOLVE_ZERO ;
+	
+	if((!res->ndeps) || (depth->level > MAXDEPTH))
+		goto freed ;
+	
+	if (!sastr_clean_string(&sadeps,res->sa.s + res->deps)) goto err ;
+	if (reverse) sastr_reverse(&sadeps) ;
+
+	for(; pos < sadeps.len ; pos += strlen(sadeps.s + pos) + 1,idx++ )
+	{	
+		int last =  idx + 1 < res->ndeps  ? 0 : 1 ;		
+		char *name = sadeps.s + pos ;
+		
+		if (!ss_resolve_check(src,name)) goto err ;	
+		if (!ss_resolve_read(&dres,src,name)) goto err ;
+		
+		info_graph_display(&dres, depth, last,padding,style) ;
+						
+		if (dres.ndeps)
+		{
+			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 (!info_walk(&dres, src, reverse, &d, padding, style)) goto err;
+			depth->next = NULL;
+		}
+	}
+	freed:
+	ss_resolve_free(&dres) ;
+	stralloc_free(&sadeps) ;
+	return 1 ;
+	err: 
+		ss_resolve_free(&dres) ;
+		stralloc_free(&sadeps) ;
+		return 0 ;
+}
+
+int info_graph_init (ss_resolve_t *res,char const *src,unsigned int reverse, int padding, ss_resolve_graph_style *style)
+{
+	depth_t d = {
+		NULL,
+		NULL,
+		1
+	} ;	
+
+	if(!info_walk(res,src,reverse,&d,padding,style)) return 0 ;
+	
+	return 1 ;
+}
-- 
GitLab