diff options
-rwxr-xr-x | build | 6 | ||||
-rwxr-xr-x | busybox.pkg/postinst | 17 | ||||
-rwxr-xr-x | busybox.pkg/prerm | 7 | ||||
-rw-r--r-- | changelog | 21 | ||||
-rw-r--r-- | scripts | 13 | ||||
-rwxr-xr-x | src.etc/init.d/hostname | 27 | ||||
-rwxr-xr-x | src.etc/init.d/httpd | 33 | ||||
-rwxr-xr-x | src.etc/init.d/klogd | 32 | ||||
-rwxr-xr-x | src.etc/init.d/mdev | 61 | ||||
-rwxr-xr-x | src.etc/init.d/mountall | 21 | ||||
-rwxr-xr-x | src.etc/init.d/mountdevsubfs | 36 | ||||
-rwxr-xr-x | src.etc/init.d/mountkernfs | 39 | ||||
-rwxr-xr-x | src.etc/init.d/mounttmpfs | 33 | ||||
-rwxr-xr-x | src.etc/init.d/networking | 27 | ||||
-rwxr-xr-x | src.etc/init.d/rc | 39 | ||||
-rwxr-xr-x | src.etc/init.d/rc.local | 10 | ||||
-rwxr-xr-x | src.etc/init.d/syslog | 32 | ||||
-rwxr-xr-x | src.etc/init.d/telnetd | 33 | ||||
-rw-r--r-- | src.etc/rc.common | 128 |
19 files changed, 332 insertions, 283 deletions
@@ -5,6 +5,7 @@ include ../source.mk config_enabled = \ config_enabled() \ { \ + [ "x$${1}" = 'x-' ] && return 0; \ grep "^CONFIG_$${1}=y$$" <src/.config >/dev/null 2>&1; \ } install_init_script = \ @@ -44,16 +45,21 @@ install: build exec 3>&- set -e; $(config_enabled); $(install_init_script); \ if config_enabled INIT; then \ + exec 3>dest/usr/share/busybox/init-scripts; \ install -d -m 0755 dest/etc; \ install -p -m 0644 inittab dest/etc/inittab; \ install -d -m 0755 dest/etc/init.d dest/etc/rc.d; \ install -p -m 0755 ../src.etc/init.d/rc dest/etc/init.d/rc; \ + install -p -m 0755 ../src.etc/rc.common dest/etc/rc.common; \ ln -sf rc dest/etc/init.d/rcS; \ ln -sf rc dest/etc/init.d/rcK; \ while read -r config script links; do \ config_enabled "$${config}" && \ install_init_script "$${script}" $${links}; \ + [ "x$${links:+set}" != 'xset' ] && \ + printf '%s\n' "$${script}" >&3; \ done <../scripts; \ + exec 3>&-; \ fi; \ if config_enabled HTTPD; then \ install -d -m 0755 dest/var/www; \ diff --git a/busybox.pkg/postinst b/busybox.pkg/postinst index d74c331..fa5e152 100755 --- a/busybox.pkg/postinst +++ b/busybox.pkg/postinst @@ -9,10 +9,25 @@ if [ "x${1}" = 'xconfigure' ]; then exec 3>/etc/network/interfaces printf 'auto lo\niface lo inet loopback\n\n' >&3 for iface in /sys/class/net/eth*; do - iface="${iface#*/}" + iface="${iface##*/}" printf 'auto %s\niface %s inet dhcp\n\n' \ "${iface}" "${iface}" >&3 done exec 3>&- fi + if ! [ -f /etc/rc.policy ]; then + if [ "x$(cat /etc/proteanos_plat)" = 'xdev' ]; then + printf 'disabled\n' >/etc/rc.policy + else + printf 'enabled\n' >/etc/rc.policy + fi + fi + if [ -f /usr/share/busybox/init-scripts ]; then + for script in $(cat /usr/share/busybox/init-scripts); do + if [ "x${2:+set}" != 'xset' ]; then + "/etc/init.d/${script}" enable + fi + "/etc/init.d/${script}" start + done + fi fi diff --git a/busybox.pkg/prerm b/busybox.pkg/prerm index 54b5053..160a2d7 100755 --- a/busybox.pkg/prerm +++ b/busybox.pkg/prerm @@ -1,6 +1,11 @@ #!/bin/sh -if [ "x${1}" = 'xremove' ]; then +if [ "x${1}" = 'xupgrade' ]; then + if [ -f /usr/share/busybox/init-scripts ]; then + for script in $(cat /usr/share/busybox/init-scripts); do + "/etc/init.d/${script}" stop + done + fi while read link name prio; do update-alternatives --remove "${name}" "${link}.busybox" done </usr/share/busybox/alternatives @@ -1,3 +1,24 @@ +busybox (1.21.1-5) trunk + + * /etc/rc.common: New framework for service initialization scripts. + - Service scripts can have significantly less boilerplate logic and + be much simpler. + - Services can be enabled and disabled by the user and the system. + - A /etc/rc.policy file can be used to disable all service + initialization and manipulation. + * Convert service scripts to use the new framework. + * Clean up stderr during services initialization. + * Make most of the /etc/rc.d/ links at install time using the new + "enable" action. + * Stop and start services in maintainer scripts. + * Fix interface names in /etc/network/interfaces. + * Make certain service scripts create and use PID files. + * Buffer early service initialization output until syslogd is running. + * Make some service scripts a little more robust. + * /etc/init.d/rc.local: New service initialization script. + + -- "P. J. McDermott" <pj@pehjota.net> Mon, 02 Jun 2014 19:58:21 -0400 + busybox (1.21.1-4) trunk * /etc/init.d/httpd: Add missing space in start message. @@ -1,11 +1,12 @@ HOSTNAME hostname S03 -HTTPD httpd S40 K70 -KLOGD klogd S30 K80 +HTTPD httpd +KLOGD klogd MDEV mdev S02 K98 -FEATURE_MOUNT_FSTAB mountall S10 +FEATURE_MOUNT_FSTAB mountall S30 K70 FEATURE_MOUNT_FLAGS mountdevsubfs S03 K97 FEATURE_MOUNT_FLAGS mountkernfs S01 K99 FEATURE_MOUNT_FLAGS mounttmpfs S03 K97 -IFUPDOWN networking S20 K90 -SYSLOGD syslog S30 K80 -TELNETD telnetd S40 K70 +IFUPDOWN networking S20 K80 +SYSLOGD syslog +TELNETD telnetd +- rc.local diff --git a/src.etc/init.d/hostname b/src.etc/init.d/hostname index f64407d..2a6ffac 100755 --- a/src.etc/init.d/hostname +++ b/src.etc/init.d/hostname @@ -1,24 +1,13 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common start() { - [ -f /etc/hostname ] && HOSTNAME="$(cat /etc/hostname)" - [ -z "${HOSTNAME}" ] && HOSTNAME="$(hostname)" - [ -z "${HOSTNAME}" ] && HOSTNAME='localhost' + local hostname= - printf 'Setting hostname to %s... ' "${HOSTNAME}" - hostname "${HOSTNAME}" - printf 'done.\n' -} + [ -f /etc/hostname ] && hostname="$(cat /etc/hostname)" + [ -z "${hostname}" ] && hostname="$(hostname)" + [ -z "${hostname}" ] && hostname='localhost' -case "${1}" in - start) - start - ;; - stop) - ;; - *) - printf 'Usage: %s {start|stop}\n' "${0}" >&2 - exit 1 - ;; -esac + log 'Setting hostname to %s' "${hostname}" + hostname "${hostname}" +} diff --git a/src.etc/init.d/httpd b/src.etc/init.d/httpd index 1dc0d28..c26e151 100755 --- a/src.etc/init.d/httpd +++ b/src.etc/init.d/httpd @@ -1,32 +1,17 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common + +START='50' +STOP='60' start() { - printf 'Starting httpd... ' - start-stop-daemon -S -q -n httpd -x /usr/sbin/httpd -- -h /var/www - printf 'done.\n' + log 'Starting httpd' + start-stop-daemon -S -q -p /var/run/httpd.pid -m \ + -x /usr/sbin/httpd -b -- -f -h /var/www } stop() { - printf 'Stopping httpd... ' - start-stop-daemon -K -q -n httpd - printf 'done.\n' + log 'Stopping httpd' + start-stop-daemon -K -q -p /var/run/httpd.pid } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - restart) - stop - start - ;; - *) - printf 'Usage: %s {start|stop|restart}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/klogd b/src.etc/init.d/klogd index 5a00ab9..20b7ac3 100755 --- a/src.etc/init.d/klogd +++ b/src.etc/init.d/klogd @@ -1,32 +1,16 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common + +START='40' +STOP='70' start() { - printf 'Starting klogd... ' - start-stop-daemon -S -q -n klogd -x /sbin/klogd - printf 'done.\n' + log 'Starting klogd' + start-stop-daemon -S -q -x /sbin/klogd } stop() { - printf 'Stopping klogd... ' - start-stop-daemon -K -q -n klogd - printf 'done.\n' + log 'Stopping klogd' + start-stop-daemon -K -q -p /var/run/klogd.pid } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - restart) - stop - start - ;; - *) - printf 'Usage: %s {start|stop|restart}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/mdev b/src.etc/init.d/mdev index 8052c3b..81d004a 100755 --- a/src.etc/init.d/mdev +++ b/src.etc/init.d/mdev @@ -1,53 +1,38 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common start() { - printf 'Enabling device hotplugging... ' - - if ! mount | grep -Fq ' /dev '; then - mount -t tmpfs -o noexec,nosuid,mode=0755 tmpfs /dev + log 'Enabling device hotplugging' + if ! [ -e /dev/null ]; then + mount -t tmpfs -o noexec,nosuid,mode=0755 tmpfs /dev || \ + return ${?} + if [ -e /proc/sys/kernel/hotplug ]; then + printf '/sbin/mdev\n' >/proc/sys/kernel/hotplug + fi + mdev -s fi - - printf '/sbin/mdev\n' >/proc/sys/kernel/hotplug - mdev -s - - printf 'done.\n' } stop() { - printf 'Disabling device hotplugging... ' - - printf '\n' >/proc/sys/kernel/hotplug - - if mount | grep -Fq ' /dev '; then - umount /dev + log 'Disabling device hotplugging' + if [ -e /proc/sys/kernel/hotplug ]; then + printf '\n' >/proc/sys/kernel/hotplug + fi + if [ -e /dev/null ]; then + umount /dev || return ${?} fi - - printf 'done.\n' } restart() { - printf 'Recanning devices... ' - + log 'Recanning devices' + if ! [ -e /dev/null ]; then + mount -t tmpfs -o noexec,nosuid,mode=0755 tmpfs /dev || \ + return ${?} + if [ -e /proc/sys/kernel/hotplug ]; then + printf '/sbin/mdev\n' >/proc/sys/kernel/hotplug + fi + fi mdev -s - - printf 'done.\n' } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - *) - printf 'Usage: %s {start|stop|restart}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/mountall b/src.etc/init.d/mountall index 4882427..8515157 100755 --- a/src.etc/init.d/mountall +++ b/src.etc/init.d/mountall @@ -1,20 +1,9 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common start() { - printf 'Mounting file systems... ' - [ -r /etc/fstab ] && mount -a - printf 'done.\n' + log 'Mounting file systems' + if [ -r /etc/fstab ]; then + mount -a + fi } - -case "${1}" in - start) - start - ;; - stop) - ;; - *) - printf 'Usage: %s {start|stop}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/mountdevsubfs b/src.etc/init.d/mountdevsubfs index 5ef7235..03c13e0 100755 --- a/src.etc/init.d/mountdevsubfs +++ b/src.etc/init.d/mountdevsubfs @@ -1,41 +1,21 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common start() { - printf 'Mounting device file systems... ' - + log 'Mounting device file systems' [ -d /dev/pts ] || mkdir -m 0755 /dev/pts - if ! mount | grep -Fq ' /dev/pts '; then - mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts + if ! [ -e /dev/pts/ptmx ]; then + mount -t devpts -o noexec,nosuid,gid=5,mode=0620 \ + devpts /dev/pts || return ${?} fi - ln -sf /run/shm /dev/shm - - printf 'done.\n' } stop() { - printf 'Unmounting device file systems... ' - - if mount | grep -Fq ' /dev/pts '; then - umount /dev/pts + log 'Unmounting device file systems' + if [ -e /dev/pts/ptmx ]; then + umount /dev/pts || return ${?} fi - rm -f /dev/shm - - printf 'done.\n' } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - *) - printf 'Usage: %s {start|stop}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/mountkernfs b/src.etc/init.d/mountkernfs index 8a701a8..83d5179 100755 --- a/src.etc/init.d/mountkernfs +++ b/src.etc/init.d/mountkernfs @@ -1,30 +1,25 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common start() { - printf 'Mounting kernel virtual file systems... ' - [ ! -e /proc/mounts ] && mount -t proc -o nodev,noexec,nosuid proc /proc - [ ! -e /sys/kernel ] && mount -t sysfs -o nodev,noexec,nosuid sysfs /sys - printf 'done.\n' + log 'Mounting kernel virtual file systems' + if ! [ -e /proc/mounts ]; then + mount -t proc -o nodev,noexec,nosuid proc /proc || \ + return ${?} + fi + if ! [ -e /sys/kernel ]; then + mount -t sysfs -o nodev,noexec,nosuid sysfs /sys || \ + return ${?} + fi } stop() { - printf 'Unmounting kernel virtual file systems... ' - [ -e /proc/mounts ] && umount /proc - [ -e /sys/kernel ] && umount /sys - printf 'done.\n' + log 'Unmounting kernel virtual file systems' + if [ -e /proc/mounts ]; then + umount /proc || return ${?} + fi + if [ -e /sys/kernel ]; then + umount /sys || return ${?} + fi } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - *) - printf 'Usage: %s {start|stop}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/mounttmpfs b/src.etc/init.d/mounttmpfs index 96b398e..269ba74 100755 --- a/src.etc/init.d/mounttmpfs +++ b/src.etc/init.d/mounttmpfs @@ -1,47 +1,26 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common start() { - printf 'Mounting temporary file systems... ' - + log 'Mounting temporary file systems' if ! mount | grep -Fq ' /run '; then - mount -t tmpfs -o nodev,noexec,nosuid,mode=0755 tmpfs /run + mount -t tmpfs -o nodev,noexec,nosuid,mode=0755 \ + tmpfs /run fi - [ -d /run/lock ] || mkdir -m 1777 /run/lock [ -d /run/shm ] || mkdir -m 1777 /run/shm - if ! mount | grep -Fq ' /tmp '; then mount -t tmpfs -o nodev,nosuid,mode=1777 tmpfs /tmp fi - - printf 'done.\n' } stop() { - printf 'Unmounting temporary file systems... ' - + log 'Unmounting temporary file systems' if mount | grep -Fq ' /run '; then umount /run fi - if mount | grep -Fq ' /tmp '; then - umount /run + umount /tmp fi - - printf 'done.\n' } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - *) - printf 'Usage: %s {start|stop}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/networking b/src.etc/init.d/networking index 66967f9..f53899f 100755 --- a/src.etc/init.d/networking +++ b/src.etc/init.d/networking @@ -1,40 +1,21 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common start() { - printf 'Configuring network interfaces... ' + log 'Configuring network interfaces' ifdown -a >/dev/null 2>&1 ifup -a - printf 'done.\n' } stop() { - printf 'Deconfiguring network interfaces... ' + log 'Deconfiguring network interfaces' ifdown -a - printf 'done.\n' } restart() { - printf 'Reconfiguring network interfaces... ' + log 'Reconfiguring network interfaces' ifdown -a ifup -a - printf 'done.\n' } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - restart) - restart - ;; - *) - printf 'Usage: %s {start|stop|restart}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/rc b/src.etc/init.d/rc index 0db7c8d..e6985dd 100755 --- a/src.etc/init.d/rc +++ b/src.etc/init.d/rc @@ -3,11 +3,33 @@ # /etc/init.d/rc # Executes init scripts on init and shutdown. # -# Copyright (C) 2012 Patrick "P. J." McDermott +# Copyright (C) 2012, 2014 Patrick "P. J." McDermott +# # This file may be reproduced, distributed, modified, and otherwise dealt in -# under the terms of the Expat/MIT License. +# under the terms of the Expat License. + +LF=' +' + +[ -x /usr/bin/logger ] && logger='logger -p 6 -t sysinit' || logger=cat + +# Buffer log lines until syslogd is running. +log() +{ + local line= + local buf= -[ -x /usr/bin/logger ] && logger='logger -s -p 6 -t sysinit' || logger=cat + while read -r line; do + buf="${buf}${line}${LF}" + if [ -f /var/run/syslogd.pid ]; then + printf '%s' "${buf}" | ${logger} + exec ${logger} + fi + done + if [ -f /var/run/syslogd.pid ]; then + printf '%s' "${buf}" | ${logger} + fi +} level=${0#*/rc} case ${level} in @@ -22,6 +44,11 @@ case ${level} in ;; esac -for i in /etc/rc.d/${level}*; do - [ -x "${i}" ] && "${i}" ${action} 2>&1 -done | ${logger} +{ + for i in /etc/rc.d/${level}[0-1]*; do + [ -x "${i}" ] && "${i}" ${action} 2>&1 + done + for i in /etc/rc.d/${level}[2-9]*; do + [ -x "${i}" ] && "${i}" ${action} 2>&1 + done +} | log diff --git a/src.etc/init.d/rc.local b/src.etc/init.d/rc.local new file mode 100755 index 0000000..167ebdc --- /dev/null +++ b/src.etc/init.d/rc.local @@ -0,0 +1,10 @@ +#!/bin/sh /etc/rc.common + +START='90' + +start() +{ + [ -x /etc/rc.local ] || return 0 + log 'Running local boot scripts' + /etc/rc.local +} diff --git a/src.etc/init.d/syslog b/src.etc/init.d/syslog index 7d274ce..32e4bd6 100755 --- a/src.etc/init.d/syslog +++ b/src.etc/init.d/syslog @@ -1,35 +1,19 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common SYSLOG_ROTATE_SIZE=65536 +START='40' +STOP='70' + start() { - printf 'Starting syslog... ' - start-stop-daemon -S -q -n syslogd -x /sbin/syslogd -- \ + log 'Starting syslog' + start-stop-daemon -S -q -x /sbin/syslogd -- \ -s "${SYSLOG_ROTATE_SIZE}" - printf 'done.\n' } stop() { - printf 'Stopping syslog... ' - start-stop-daemon -K -q -n syslogd - printf 'done.\n' + log 'Stopping syslog' + start-stop-daemon -K -q -p /var/run/syslogd.pid } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - restart) - stop - start - ;; - *) - printf 'Usage: %s {start|stop|restart}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/init.d/telnetd b/src.etc/init.d/telnetd index 0f51046..98f668d 100755 --- a/src.etc/init.d/telnetd +++ b/src.etc/init.d/telnetd @@ -1,32 +1,17 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common + +START='50' +STOP='60' start() { - printf 'Starting telnetd... ' - start-stop-daemon -S -q -n telnetd -x /usr/sbin/telnetd - printf 'done.\n' + log 'Starting telnetd' + start-stop-daemon -S -q -p /var/run/telnetd.pid -m \ + -x /usr/sbin/telnetd -b -- -F } stop() { - printf 'Stopping telnetd... ' - start-stop-daemon -K -q -n telnetd - printf 'done.\n' + log 'Stopping telnetd' + start-stop-daemon -K -q -p /var/run/telnetd.pid } - -case "${1}" in - start) - start - ;; - stop) - stop - ;; - restart) - stop - start - ;; - *) - printf 'Usage: %s {start|stop|restart}\n' "${0}" >&2 - exit 1 - ;; -esac diff --git a/src.etc/rc.common b/src.etc/rc.common new file mode 100644 index 0000000..7ddc27e --- /dev/null +++ b/src.etc/rc.common @@ -0,0 +1,128 @@ +#!/bin/sh +# +# /etc/rc.common +# Framework for service initialization scripts. +# +# Copyright (C) 2014 Patrick "P. J." McDermott +# +# This file may be reproduced, distributed, modified, and otherwise dealt in +# under the terms of the Expat License. + +set -u + +SCRIPT='' +ALL_CMDS='' +LOG_MSG='' +EXTRA_COMMANDS='' +START='' +STOP='' + +main() +{ + local action= + local es= + + SCRIPT="${1}" + + . "${SCRIPT}" + + ALL_CMDS=" start stop restart ${EXTRA_COMMANDS} " + if [ "x${START:+set}" = 'xset' ] || [ "x${STOP:+set}" = 'xset' ]; then + ALL_CMDS="${ALL_CMDS} enable disable " + fi + + if [ ${#} -ne 2 ]; then + usage + return 1 + fi + action="${2:-<unknown>}" + if [ "x${ALL_CMDS#* ${action} }" != "x${ALL_CMDS}" ]; then + if [ -f /etc/rc.policy ]; then + [ "x$(cat /etc/rc.policy)" = 'xdisabled' ] && return 0 + fi + ${action} + es=${?} + log_end ${es} + return ${es} + else + usage + return 1 + fi +} + +tty_printf() +{ + local tty= + + tty="$(tty)" && printf "${@}" >"${tty}" +} + +usage() { + local cmds= + + cmds="$(printf '%s|' ${ALL_CMDS})" + tty_printf 'Usage: %s {%s}\n' "${SCRIPT}" "${cmds%|}" +} + +log() +{ + local fmt="${1}" + shift 1 + + LOG_MSG="$(printf "${fmt}" "${@}")" + tty_printf '[ ] %s...\r' "${LOG_MSG}" +} + +log_end() +{ + local es="${1}" + + [ "x${LOG_MSG:+set}" = 'xset' ] || return 0 + + case ${es} in + 0) + tty_printf '[[32m ok [39m] %s... done.\n' \ + "${LOG_MSG}" + ;; + 255) + tty_printf '[[33mwarn[39m] %s... done.\n' \ + "${LOG_MSG}" + ;; + *) + tty_printf '[[31mfail[39m] %s... failed.\n' \ + "${LOG_MSG}" + ;; + esac +} + +# Default function definitions + +stop() +{ + : +} + +restart() +{ + stop + start +} + +enable() +{ + local name="${SCRIPT##*/}" + name="${name#[SK][0-9][0-9]}" + [ "x${START:+set}" = 'xset' ] && \ + ln -sf "../init.d/${name}" "/etc/rc.d/S${START}${name}" + [ "x${STOP:+set}" = 'xset' ] && \ + ln -sf "../init.d/${name}" "/etc/rc.d/K${STOP}${name}" +} + +disable() +{ + local name="${SCRIPT##*/}" + name="${name#[SK][0-9][0-9]}" + rm -f /etc/rc.d/[SK][0-9][0-9]"${name}" +} + +main "${@}" |