-#!/bin/sh
+#!/bin/bash
# Copyright (C) 2009 Andy Spencer
# See ../COPYING for terms
-echo
-echo "mkinit -- starting"
+# GLobals
+TEST=false
+RELOAD=false
+FIFO=/lib/mkinit/cmd
+INITCTL=/dev/initctl
+PATH=/lib/mkinit/bin:/bin:/sbin:/usr/bin:/usr/sbin
+export PATH
+
+# Functions
+function usage {
+ echo 'usage: '$0' [options] [command]'
+ echo
+ echo 'Options:'
+ echo ' -h,--help Print usage information'
+ echo ' -r,--relaod Prevent spawning listeners when reloading'
+ echo ' -t,--test Fake all commands'
+ echo
+ echo 'Command:'
+ echo ' boot Execute boot-up procedures'
+ echo ' halt Execute shutdown procedures'
+ echo ' reload Re-execute init process'
+ echo ' mk <rule> Execute mk rule'
+ echo ' start|stop|restart|zap|status <service>'
+ echo ' Start,stop,restart,zap or query status of service'
+ echo ' eval <cmd> Execute command in mkinit process'
+ exit
+}
+# Run mk on the init scripts
function runamk {
+ $TEST &&
+ export P=true
/usr/lib/plan9/bin/mk \
-f /etc/init.mk \
-i -k "$@"
}
-# Handle arguments
-TEST=false
-cmd=boot
-case "$1" in
--t )
- TEST=true
- export P="true"
- ;;
--n )
- cmd=""
- ;;
-esac
-
-
-# Main loop
-echo "mkinit -- entering main loop"
-while true; do
+# Process one command
+function process {
+ cmd=$1
+ shift
+ arg=$*
+ exec 1>/dev/console
case "$cmd" in
boot )
- echo "mkinit -- booting"
- if runamk -a && ! $TEST; then
- # booted successuflly, redirect input
- echo "skipping redirect"
- #pipe=/lib/mkinit/cmd
- #[ -p pipe ] || mkfifo $pipe
- #exec 0< $pipe
- fi
- ;;
- halt )
- echo "mkinit -- halting"
- runamk "halt"
- # exit
+ echo
+ echo mkinit -- booting
+ runamk -a "$arg"
;;
restart )
- if [ "$args" ]; then
- echo "mkinit -- restarting $args"
- runamk "stop-$args"
- runamk "start-$args"
+ if [ "$arg" ]; then
+ echo mkinit -- restarting $arg
+ runamk "$arg"-stop
+ runamk "$arg"-start
fi
;;
start|stop|zap|status )
- if [ "$args" ]; then
- echo "mkinit -- ${cmd}ing $args"
- runamk "${cmd}-$args"
+ if [ "$arg" ]; then
+ echo mkinit -- ${cmd}ing $arg
+ runamk "$arg-$cmd"
fi
;;
- mk )
- if [ "$args" ]; then
- echo "mkinit -- running mk cmd [$args]"
- runamk "$args"
+ mk|runlevel )
+ if [ "$arg" ]; then
+ [ "$cmd" = mk ] &&
+ echo mkinit -- running mk cmd [$arg]
+ [ "$cmd" = runlevel ] &&
+ echo mkinit -- entering runlevel $arg
+ runamk "$arg"
fi
;;
reload )
- exec /sbin/mkinit -n
+ echo mkinit -- ${cmd}ing
+ $TEST &&
+ opt=-t
+ exec $0 -r $opt
;;
eval )
- $args
+ eval $arg
;;
?* )
- echo "unknown command [$cmd $args]"
+ echo mkinit -- unknown command [$cmd] [$arg]
;;
esac
- echo -n "mkinit> "
- read cmd args
+}
+
+# Telinit
+if [ $$ != 1 -a $1 != "-t" ]; then
+ echo "$@" > $FIFO
+ exit
+fi
+
+# Handle arguments
+TMP=`getopt -n "$0" \
+ --options hrt \
+ --longoptions help,reload,test \
+ -- "$@"`
+[ $? != 0 ] &&
+ usage
+eval set -- "$TMP"
+while [ ! "$1" == "--" ]; do
+ $TEST &&
+ echo '$1=' $1
+ case "$1" in
+ -h|--help )
+ usage
+ ;;
+ -r|--reload )
+ RELOAD=true
+ ;;
+ -t|--test )
+ TEST=true
+ FIFO=/tmp/pipe
+ INITCTL=/tmp/initctl
+ trap "pkill -HUP -P $$" EXIT
+ ;;
+ esac
+ shift
+done
+shift; cmd=$1
+shift; arg=$*
+
+# Debugging output
+if $TEST; then
+ echo 'Options'
+ echo ' test:' $TEST
+ echo ' reload:' $RELOAD
+ echo ' cmd:' $cmd
+ echo ' arg:' $arg
+fi
+
+# Create fifos if they don't exist
+test ! -e $FIFO &&
+ mkfifo $FIFO
+test ! -e $INITCTL &&
+ mkfifo $INITCTL
+
+# Initial boot-up
+process $cmd $arg
+
+# Fork listeners
+if ! $RELOAD; then
+ # Fork /dev/initctl listener
+ ( exec 0<&- 1<&- 2<&-
+ initctld $INITCTL |
+ while read line; do
+ echo $line > $FIFO
+ done ) &
+
+ # Fork console listener
+ # Readline uses stdin,stderr
+ ( exec 1<&-;
+ while true; do
+ while read -e -p "mkinit> " line; do
+ echo $line > $FIFO
+ history -s $line
+ done
+ $TEST && break
+ exec 0</dev/console 2>/dev/console
+ echo "Respawning on /dev/console.." >&2
+ sleep 1
+ done) <&0 &
+
+ # Close stdin, stderr
+ exec 0<&- 2<&-
+fi
+
+# Main loop
+while true; do
+ while read line; do
+ process $line
+ done < $FIFO
done