diff --git a/doc/html/66-info.html b/doc/html/66-info.html index f7433f97005e7367f1b316f3254678334e01c44a..2887cbba2dd5b4cbff73c096474820377d5e4950 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 </tt> : prints this help. - </li> - <li> - <tt>-T </tt> : asks for <em>tree</em> information. - </li> - <li> - <tt>-S </tt> : asks for <em>service</em> information. - </li> - </ul> -<h2>Tree sub options </h2> - <ul> - <li> - <tt>-h </tt> : prints this help. - </li> - <li> - <tt>-c </tt> : disable colorization. - </li> - <li> - <tt>-C </tt> : force colorization. - </li> - <li> - <tt>-v <em>verbosity</em> </tt> : 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 <em>live</em> </tt> : 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—see <tt><a href="66-scandir.html">66-scandir</a></tt>. - </li> - <li> - <tt>-r </tt> : shows the dependency graph of <em>tree</em> in reverse mode. - </li> - - <li> - <tt>-d <em>depth</em> </tt> : 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 </tt> : prints this help. - </li> - <li> - <tt>-c </tt> : disable colorization. - </li> - <li> - <tt>-C </tt> : force colorization. - </li> - <li> - <tt>-v <em>verbosity</em> </tt> : 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 <em>live</em> </tt> : 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—see <tt><a href="66-scandir.html">66-scandir</a></tt>. - </li> - <li> - <tt>-p <em>n lines</em> </tt> : prints the <em>n</em> last lines from the associated log file of the <em>service</em>. - </li> - <li> - <tt>-r </tt> : shows the dependency graph of <em>service</em> in reverse mode. - </li> - <li> - <tt>-d <em>depth</em> </tt> : 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—see <tt><a href="66-tree.html">66-tree -c</a></tt> and - <tt><em>Enabled</em></tt> reveals the state of the tree—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 </tt> : name of the service. Main section where general informations is displayed. - </li> - <li> - <tt>on tree </tt> : service enable on tree root. - </li> - <li> - <tt>status </tt> : status of the service. - </li> - <li> - <tt>type </tt> : type of the service. - </li> - <li> - <tt>description </tt> : short description of the service. - </li> - <li> - <tt>source </tt> : origin of the frontend service file used to enable the service. - </li> - <li> - <tt>run at </tt> : location of the service into the scandir. - </li> - <li> - <tt>dependencies</tt> : dependencies informations section. This section will display a graphical tree on the service dependencies. - </li> - <li> - <tt>scripts</tt> : scripts informations section. This will display the command executed at start and stop process. - </li> - <li> - <tt>start script </tt> : 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> : 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> : logger informations section. - </li> - <li> - <tt>logger associated </tt> : name of the service logger. - </li> - <li> - <tt>log destination </tt> : 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 0000000000000000000000000000000000000000..c243b9f8c192bc86ca00e643506011bedff5ab36 --- /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 </tt> : prints this help. + </li> + <li> + <tt>-v <em>verbosity</em> </tt> : 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 </tt> : enable colorization. + </li> + <li> + <tt>-o </tt> : 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 </tt> : shows the dependency list of <em>service</em> as graph instead of list. + </li> + <li> + <tt>-d <em>depth</em> </tt> : limits the depth of the dependency list visualisation; defaults to 1. This is implies <tt>-g</tt> options. + </li> + <li> + <tt>-r </tt> : shows the dependency list of <em>service</em> in reverse mode. + </li> + <li> + <tt>-t <em>tree</em> </tt> : only search the <em>service</em> at the specified <em>tree</em>. + </li> + + <li> + <tt>-p <em>n lines</em> </tt> : 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> : displays the name of the <em>service</em>. + </li> + <li> + <tt>intree</tt> : displays the <em>service's</em> tree name. + </li> + <li> + <tt>status</tt> : displays the status of the <em>service</em>. + </li> + <li> + <tt>type</tt> : displays the type of the <em>service</em>. + </li> + <li> + <tt>description</tt> : displays the description. + </li> + <li> + <tt>source</tt> : displays the source of the <em>service's</em> frontend file. + </li> + <li> + <tt>live</tt> : displays the <em>service's</em> live directory. + </li> + <li> + <tt>depends</tt> : displays the <em>service's</em> dependencies. + </li> + <li> + <tt>start</tt> : displays the <em>service's</em> start script. + </li> + <li> + <tt>stop</tt> : displays the <em>service's</em> stop script. + </li> + <li> + <tt>envat</tt> : displays the source of the environment file. + </li> + <li> + <tt>envfile</tt> : displays the contains of the environment file. + </li> + <li> + <tt>logname</tt> : displays the logger's name. + </li> + <li> + <tt>logdst</tt> : displays the logger's destination. + </li> + <li> + <tt>logfile</tt> : 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 0000000000000000000000000000000000000000..f054d73364c33ff453f84c62f1c6e426d5fb5023 --- /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 </tt> : prints this help. + </li> + <li> + <tt>-v <em>verbosity</em> </tt> : 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 <em>live</em> </tt> : 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—see <tt><a href="66-scandir.html">66-scandir</a></tt>. + </li> + <li> + <tt>-c </tt> : enable colorization. + </li> + <li> + <tt>-o </tt> : 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 </tt> : shows the dependency list of <em>tree</em> as graph instead of list. + </li> + <li> + <tt>-d <em>depth</em> </tt> : limits the depth of the dependency list visualisation; defaults to 1. This is implies <tt>-g</tt> options. + </li> + <li> + <tt>-r </tt> : 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> : displays the name of the <em>tree</em>. + </li> + <li> + <tt>init</tt> : displays a boolean value of the initialization state. + </li> + <li> + <tt>enabled</tt> : displays a boolean value of the enable state. + </li> + <li> + <tt>current</tt> : displays a boolean value of the current state. + </li> + <li> + <tt>contains</tt> : 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—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—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 d472b625c2df70739e118a443b40e81afc3a0f63..e9063a5ba48c58aa036d9784cd0c69d22074614b 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 0000000000000000000000000000000000000000..36b8a41edad7ec1dc149dc3c46f3b39d5e95274e --- /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 0000000000000000000000000000000000000000..45350218280bc30c5c561f71789f992d31d8ff1a --- /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 75f4c3e6ec85b7cd9f7ea860322714342defe0b5..12b7570fcd79d8dbb7aa67614c4b78e959fa8a79 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 f341068acfdf55323d1364267bbbc4201fdd2fc5..62b9ca06fc49039b0680d4d04ed55fef0ddbed8a 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 8c864254297aa5a6eaf06cef6efafec28d5f23d6..23060bd09f0aa355caa8163da010d018b1134466 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 3de127f33f1c501c25afc1adf5950bdb5f5e3b6f..f2f1736ff45e6b9f48b94b14b5930c0a80c6662c 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 0000000000000000000000000000000000000000..c2f0f3bec1c106cd7078ab2333a528b0df114ace --- /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 0000000000000000000000000000000000000000..065df952330c99a5313048ccc55c5d5afd54a796 --- /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 0000000000000000000000000000000000000000..306db624e775967d5f8dee9157a531ba4d44f70b --- /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 0000000000000000000000000000000000000000..306db624e775967d5f8dee9157a531ba4d44f70b --- /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 0000000000000000000000000000000000000000..26a548a078cf23772b118d0006e69d5ecb8a954d --- /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 40c03e1544e7359573aedf09e7b4ad757e0ca108..087e036377ed54291956257d78f8394f841a33e6 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 f21202a00e5c0d3f685a816bfb5fad8ccab36555..dd73925347939c749fb5b824cf00b569acb82577 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 7c82028345730b72ed6731e2c2b7b0d2daa3dcb9..07902f09c62bbb37de0d71f70bedc582beff77fd 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 0000000000000000000000000000000000000000..fc4592590031d5f322a6d689b1608d2968ca03ad --- /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 ; +}