summary refs log tree commit diff
path: root/runit-2.1.2
diff options
context:
space:
mode:
Diffstat (limited to 'runit-2.1.2')
-rw-r--r--runit-2.1.2/doc/benefits.html187
-rw-r--r--runit-2.1.2/doc/chpst.8.html152
l---------runit-2.1.2/doc/debian1
-rw-r--r--runit-2.1.2/doc/dependencies.html36
-rw-r--r--runit-2.1.2/doc/faq.html438
-rw-r--r--runit-2.1.2/doc/index.html261
-rw-r--r--runit-2.1.2/doc/install.html61
-rw-r--r--runit-2.1.2/doc/replaceinit.html254
-rw-r--r--runit-2.1.2/doc/runit-init.8.html60
-rw-r--r--runit-2.1.2/doc/runit.8.html74
-rw-r--r--runit-2.1.2/doc/runlevels.html98
-rw-r--r--runit-2.1.2/doc/runscripts.html1058
-rw-r--r--runit-2.1.2/doc/runsv.8.html157
-rw-r--r--runit-2.1.2/doc/runsvchdir.8.html52
-rw-r--r--runit-2.1.2/doc/runsvdir.8.html73
-rw-r--r--runit-2.1.2/doc/sv.8.html218
-rw-r--r--runit-2.1.2/doc/svlogd.8.html264
-rw-r--r--runit-2.1.2/doc/upgrade.html105
-rw-r--r--runit-2.1.2/doc/usedietlibc.html35
-rw-r--r--runit-2.1.2/doc/useinit.html102
-rw-r--r--runit-2.1.2/doc/utmpset.8.html63
-rwxr-xr-xrunit-2.1.2/etc/26
-rwxr-xr-xrunit-2.1.2/etc/debian/110
l---------runit-2.1.2/etc/debian/21
-rwxr-xr-xrunit-2.1.2/etc/debian/314
-rwxr-xr-xrunit-2.1.2/etc/debian/ctrlaltdel9
-rwxr-xr-xrunit-2.1.2/etc/debian/getty-tty5/finish2
-rwxr-xr-xrunit-2.1.2/etc/debian/getty-tty5/run2
-rwxr-xr-xrunit-2.1.2/etc/freebsd/117
l---------runit-2.1.2/etc/freebsd/21
-rwxr-xr-xrunit-2.1.2/etc/freebsd/315
-rwxr-xr-xrunit-2.1.2/etc/freebsd/ctrlaltdel9
-rwxr-xr-xrunit-2.1.2/etc/freebsd/getty-ttyv4/finish2
-rwxr-xr-xrunit-2.1.2/etc/freebsd/getty-ttyv4/run2
l---------runit-2.1.2/etc/macosx/21
-rw-r--r--runit-2.1.2/etc/macosx/StartupItems/StartupParameters.plist11
-rwxr-xr-xrunit-2.1.2/etc/macosx/StartupItems/runit22
-rw-r--r--runit-2.1.2/etc/macosx/org.smarden.runit.plist20
-rwxr-xr-xrunit-2.1.2/etc/openbsd/117
l---------runit-2.1.2/etc/openbsd/21
-rwxr-xr-xrunit-2.1.2/etc/openbsd/315
-rwxr-xr-xrunit-2.1.2/etc/openbsd/ctrlaltdel9
-rwxr-xr-xrunit-2.1.2/etc/openbsd/getty-ttyC4/finish2
-rwxr-xr-xrunit-2.1.2/etc/openbsd/getty-ttyC4/run2
-rw-r--r--runit-2.1.2/man/chpst.8265
-rw-r--r--runit-2.1.2/man/runit-init.863
-rw-r--r--runit-2.1.2/man/runit.888
-rw-r--r--runit-2.1.2/man/runsv.8225
-rw-r--r--runit-2.1.2/man/runsvchdir.855
-rw-r--r--runit-2.1.2/man/runsvdir.8102
-rw-r--r--runit-2.1.2/man/sv.8285
-rw-r--r--runit-2.1.2/man/svlogd.8464
-rw-r--r--runit-2.1.2/man/utmpset.863
-rw-r--r--runit-2.1.2/package/CHANGES688
-rw-r--r--runit-2.1.2/package/COPYING24
-rw-r--r--runit-2.1.2/package/README3
-rw-r--r--runit-2.1.2/package/THANKS2
-rw-r--r--runit-2.1.2/package/TODO8
-rwxr-xr-xrunit-2.1.2/package/check9
-rw-r--r--runit-2.1.2/package/commands9
-rwxr-xr-xrunit-2.1.2/package/compile27
-rwxr-xr-xrunit-2.1.2/package/install6
-rwxr-xr-xrunit-2.1.2/package/install-man26
-rw-r--r--runit-2.1.2/package/sharing3
-rwxr-xr-xrunit-2.1.2/package/upgrade29
-rw-r--r--runit-2.1.2/package/versions54
-rw-r--r--runit-2.1.2/src/Makefile468
-rw-r--r--runit-2.1.2/src/TARGETS143
-rw-r--r--runit-2.1.2/src/alloc.c33
-rw-r--r--runit-2.1.2/src/alloc.h10
-rw-r--r--runit-2.1.2/src/alloc_re.c19
-rw-r--r--runit-2.1.2/src/buffer.c12
-rw-r--r--runit-2.1.2/src/buffer.h61
-rw-r--r--runit-2.1.2/src/buffer_0.c13
-rw-r--r--runit-2.1.2/src/buffer_1.c7
-rw-r--r--runit-2.1.2/src/buffer_2.c7
-rw-r--r--runit-2.1.2/src/buffer_get.c69
-rw-r--r--runit-2.1.2/src/buffer_put.c90
-rw-r--r--runit-2.1.2/src/buffer_read.c9
-rw-r--r--runit-2.1.2/src/buffer_write.c9
-rw-r--r--runit-2.1.2/src/byte.h15
-rw-r--r--runit-2.1.2/src/byte_chr.c22
-rw-r--r--runit-2.1.2/src/byte_copy.c16
-rw-r--r--runit-2.1.2/src/byte_cr.c18
-rw-r--r--runit-2.1.2/src/byte_diff.c18
-rw-r--r--runit-2.1.2/src/byte_rchr.c25
-rwxr-xr-xrunit-2.1.2/src/check-diff5
-rwxr-xr-xrunit-2.1.2/src/check-dist8
-rwxr-xr-xrunit-2.1.2/src/check-local9
-rw-r--r--runit-2.1.2/src/chkshsgr.c12
-rw-r--r--runit-2.1.2/src/choose.sh18
-rw-r--r--runit-2.1.2/src/chpst.c475
-rwxr-xr-xrunit-2.1.2/src/chpst.check36
-rw-r--r--runit-2.1.2/src/chpst.dist13
-rw-r--r--runit-2.1.2/src/coe.c9
-rw-r--r--runit-2.1.2/src/coe.h8
-rw-r--r--runit-2.1.2/src/conf-cc5
-rw-r--r--runit-2.1.2/src/conf-ld3
-rw-r--r--runit-2.1.2/src/direntry.h112
-rw-r--r--runit-2.1.2/src/direntry.h212
-rw-r--r--runit-2.1.2/src/env.c17
-rw-r--r--runit-2.1.2/src/env.h10
-rw-r--r--runit-2.1.2/src/error.c132
-rw-r--r--runit-2.1.2/src/error.h33
-rw-r--r--runit-2.1.2/src/error_str.c267
-rw-r--r--runit-2.1.2/src/fd.h9
-rw-r--r--runit-2.1.2/src/fd_copy.c14
-rw-r--r--runit-2.1.2/src/fd_move.c12
-rw-r--r--runit-2.1.2/src/fifo.c12
-rw-r--r--runit-2.1.2/src/fifo.h8
-rw-r--r--runit-2.1.2/src/find-systype.sh143
-rw-r--r--runit-2.1.2/src/fmt.h27
-rw-r--r--runit-2.1.2/src/fmt_ptime.c42
-rw-r--r--runit-2.1.2/src/fmt_ptime.h14
-rw-r--r--runit-2.1.2/src/fmt_uint.c8
-rw-r--r--runit-2.1.2/src/fmt_uint0.c12
-rw-r--r--runit-2.1.2/src/fmt_ulong.c15
-rw-r--r--runit-2.1.2/src/gen_alloc.h9
-rw-r--r--runit-2.1.2/src/gen_allocdefs.h36
-rw-r--r--runit-2.1.2/src/hasflock.h13
-rw-r--r--runit-2.1.2/src/hasflock.h24
-rw-r--r--runit-2.1.2/src/hasmkffo.h13
-rw-r--r--runit-2.1.2/src/hasmkffo.h24
-rw-r--r--runit-2.1.2/src/hassgact.h13
-rw-r--r--runit-2.1.2/src/hassgact.h24
-rw-r--r--runit-2.1.2/src/hassgprm.h13
-rw-r--r--runit-2.1.2/src/hassgprm.h24
-rw-r--r--runit-2.1.2/src/hasshsgr.h13
-rw-r--r--runit-2.1.2/src/hasshsgr.h24
-rw-r--r--runit-2.1.2/src/haswaitp.h13
-rw-r--r--runit-2.1.2/src/haswaitp.h24
-rw-r--r--runit-2.1.2/src/iopause.c78
-rw-r--r--runit-2.1.2/src/iopause.h121
-rw-r--r--runit-2.1.2/src/iopause.h220
-rw-r--r--runit-2.1.2/src/lock.h10
-rw-r--r--runit-2.1.2/src/lock_ex.c13
-rw-r--r--runit-2.1.2/src/lock_exnb.c13
-rw-r--r--runit-2.1.2/src/ndelay.h9
-rw-r--r--runit-2.1.2/src/ndelay_off.c14
-rw-r--r--runit-2.1.2/src/ndelay_on.c14
-rw-r--r--runit-2.1.2/src/open.h12
-rw-r--r--runit-2.1.2/src/open_append.c8
-rw-r--r--runit-2.1.2/src/open_read.c8
-rw-r--r--runit-2.1.2/src/open_trunc.c8
-rw-r--r--runit-2.1.2/src/open_write.c8
-rw-r--r--runit-2.1.2/src/openreadclose.c18
-rw-r--r--runit-2.1.2/src/openreadclose.h10
-rw-r--r--runit-2.1.2/src/pathexec.h11
-rw-r--r--runit-2.1.2/src/pathexec_env.c74
-rw-r--r--runit-2.1.2/src/pathexec_run.c48
-rw-r--r--runit-2.1.2/src/pmatch.c40
-rw-r--r--runit-2.1.2/src/pmatch.h6
-rw-r--r--runit-2.1.2/src/print-ar.sh14
-rw-r--r--runit-2.1.2/src/print-cc.sh5
-rw-r--r--runit-2.1.2/src/print-ld.sh6
-rw-r--r--runit-2.1.2/src/prot.c21
-rw-r--r--runit-2.1.2/src/prot.h9
-rw-r--r--runit-2.1.2/src/readclose.c23
-rw-r--r--runit-2.1.2/src/readclose.h11
-rw-r--r--runit-2.1.2/src/reboot_system.h18
-rw-r--r--runit-2.1.2/src/reboot_system.h28
-rw-r--r--runit-2.1.2/src/runit-init.c76
-rwxr-xr-xrunit-2.1.2/src/runit-init.check3
-rw-r--r--runit-2.1.2/src/runit-init.dist3
-rw-r--r--runit-2.1.2/src/runit.c346
-rwxr-xr-xrunit-2.1.2/src/runit.check3
-rw-r--r--runit-2.1.2/src/runit.dist2
-rw-r--r--runit-2.1.2/src/runit.h4
-rw-r--r--runit-2.1.2/src/runsv.c607
-rwxr-xr-xrunit-2.1.2/src/runsv.check59
-rw-r--r--runit-2.1.2/src/runsv.dist16
-rw-r--r--runit-2.1.2/src/runsvchdir.c76
-rwxr-xr-xrunit-2.1.2/src/runsvchdir.check3
-rw-r--r--runit-2.1.2/src/runsvchdir.dist3
-rw-r--r--runit-2.1.2/src/runsvctrl.c82
-rwxr-xr-xrunit-2.1.2/src/runsvctrl.check23
-rw-r--r--runit-2.1.2/src/runsvctrl.dist8
-rw-r--r--runit-2.1.2/src/runsvdir.c286
-rwxr-xr-xrunit-2.1.2/src/runsvdir.check3
-rw-r--r--runit-2.1.2/src/runsvdir.dist3
-rw-r--r--runit-2.1.2/src/runsvstat.c167
-rwxr-xr-xrunit-2.1.2/src/runsvstat.check26
-rw-r--r--runit-2.1.2/src/runsvstat.dist12
-rw-r--r--runit-2.1.2/src/scan.h30
-rw-r--r--runit-2.1.2/src/scan_ulong.c16
-rw-r--r--runit-2.1.2/src/seek.h17
-rw-r--r--runit-2.1.2/src/seek_set.c9
-rw-r--r--runit-2.1.2/src/select.h112
-rw-r--r--runit-2.1.2/src/select.h213
-rw-r--r--runit-2.1.2/src/sgetopt.c53
-rw-r--r--runit-2.1.2/src/sgetopt.h23
-rw-r--r--runit-2.1.2/src/sig.c15
-rw-r--r--runit-2.1.2/src/sig.h28
-rw-r--r--runit-2.1.2/src/sig_block.c40
-rw-r--r--runit-2.1.2/src/sig_catch.c18
-rw-r--r--runit-2.1.2/src/sig_pause.c16
-rw-r--r--runit-2.1.2/src/str.h16
-rw-r--r--runit-2.1.2/src/str_chr.c19
-rw-r--r--runit-2.1.2/src/str_diff.c17
-rw-r--r--runit-2.1.2/src/str_len.c16
-rw-r--r--runit-2.1.2/src/str_start.c15
-rw-r--r--runit-2.1.2/src/stralloc.h31
-rw-r--r--runit-2.1.2/src/stralloc_cat.c9
-rw-r--r--runit-2.1.2/src/stralloc_catb.c14
-rw-r--r--runit-2.1.2/src/stralloc_cats.c10
-rw-r--r--runit-2.1.2/src/stralloc_eady.c8
-rw-r--r--runit-2.1.2/src/stralloc_opyb.c13
-rw-r--r--runit-2.1.2/src/stralloc_opys.c10
-rw-r--r--runit-2.1.2/src/stralloc_pend.c7
-rw-r--r--runit-2.1.2/src/strerr.h80
-rw-r--r--runit-2.1.2/src/strerr_die.c33
-rw-r--r--runit-2.1.2/src/strerr_sys.c14
-rw-r--r--runit-2.1.2/src/subgetopt.c67
-rw-r--r--runit-2.1.2/src/subgetopt.h26
-rw-r--r--runit-2.1.2/src/sv.c394
-rwxr-xr-xrunit-2.1.2/src/sv.check27
-rw-r--r--runit-2.1.2/src/sv.dist12
-rw-r--r--runit-2.1.2/src/svlogd.c848
-rwxr-xr-xrunit-2.1.2/src/svlogd.check27
-rw-r--r--runit-2.1.2/src/svlogd.dist21
-rw-r--r--runit-2.1.2/src/svwaitdown.c177
-rwxr-xr-xrunit-2.1.2/src/svwaitdown.check24
-rw-r--r--runit-2.1.2/src/svwaitdown.dist12
-rw-r--r--runit-2.1.2/src/svwaitup.c126
-rwxr-xr-xrunit-2.1.2/src/svwaitup.check28
-rw-r--r--runit-2.1.2/src/svwaitup.dist14
-rw-r--r--runit-2.1.2/src/tai.h28
-rw-r--r--runit-2.1.2/src/tai_now.c9
-rw-r--r--runit-2.1.2/src/tai_pack.c18
-rw-r--r--runit-2.1.2/src/tai_sub.c8
-rw-r--r--runit-2.1.2/src/tai_unpack.c18
-rw-r--r--runit-2.1.2/src/taia.h36
-rw-r--r--runit-2.1.2/src/taia_add.c20
-rw-r--r--runit-2.1.2/src/taia_approx.c8
-rw-r--r--runit-2.1.2/src/taia_frac.c8
-rw-r--r--runit-2.1.2/src/taia_less.c14
-rw-r--r--runit-2.1.2/src/taia_now.c15
-rw-r--r--runit-2.1.2/src/taia_pack.c22
-rw-r--r--runit-2.1.2/src/taia_sub.c23
-rw-r--r--runit-2.1.2/src/taia_uint.c12
-rw-r--r--runit-2.1.2/src/trycpp.c9
-rw-r--r--runit-2.1.2/src/trydrent.c10
-rw-r--r--runit-2.1.2/src/tryflock.c10
-rw-r--r--runit-2.1.2/src/trymkffo.c9
-rw-r--r--runit-2.1.2/src/trypoll.c20
-rw-r--r--runit-2.1.2/src/tryreboot.c6
-rw-r--r--runit-2.1.2/src/trysgact.c12
-rw-r--r--runit-2.1.2/src/trysgprm.c12
-rw-r--r--runit-2.1.2/src/tryshsgr.c16
-rw-r--r--runit-2.1.2/src/trysocketlib.c12
-rw-r--r--runit-2.1.2/src/trysysel.c11
-rw-r--r--runit-2.1.2/src/tryulong64.c13
-rw-r--r--runit-2.1.2/src/tryuwtmp.c9
-rw-r--r--runit-2.1.2/src/tryuwtmpx.c9
-rw-r--r--runit-2.1.2/src/trywaitp.c9
-rw-r--r--runit-2.1.2/src/uidgid.c74
-rw-r--r--runit-2.1.2/src/uidgid.h18
-rw-r--r--runit-2.1.2/src/uint64.h110
-rw-r--r--runit-2.1.2/src/uint64.h210
-rw-r--r--runit-2.1.2/src/utmpset.c112
-rwxr-xr-xrunit-2.1.2/src/utmpset.check5
-rw-r--r--runit-2.1.2/src/utmpset.dist7
-rw-r--r--runit-2.1.2/src/uw_tmp.h119
-rw-r--r--runit-2.1.2/src/uw_tmp.h213
-rw-r--r--runit-2.1.2/src/wait.h16
-rw-r--r--runit-2.1.2/src/wait_nohang.c14
-rw-r--r--runit-2.1.2/src/wait_pid.c41
-rw-r--r--runit-2.1.2/src/warn-auto.sh2
-rw-r--r--runit-2.1.2/src/warn-shsgr3
-rw-r--r--runit-2.1.2/src/x86cpuid.c40
270 files changed, 14542 insertions, 0 deletions
diff --git a/runit-2.1.2/doc/benefits.html b/runit-2.1.2/doc/benefits.html
new file mode 100644
index 0000000..b1687d9
--- /dev/null
+++ b/runit-2.1.2/doc/benefits.html
@@ -0,0 +1,187 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - benefits</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - benefits</h1>
+<hr>
+<a href="#supervision">Service supervision</a><br>
+<a href="#state">Clean process state</a><br>
+<a href="#log">Reliable logging facility</a><br>
+<a href="#fast">Fast system boot up and shutdown</a><br>
+<a href="#portability">Portability</a><br>
+<a href="#packaging">Packaging friendly</a><br>
+<a href="#smallcode">Small code size</a>
+<hr>
+<a name="supervision"><h3>Service supervision</h3></a>
+Each service is associated with a <i>service directory</i>, and each
+service daemon runs as a child process of a supervising
+<a href="runsv.8.html">runsv</a> process running in this directory.
+The <a href="runsv.8.html">runsv</a> program provides a reliable interface
+for signalling the service daemon and controlling the service and
+supervisor.
+Normally the <a href="sv.8.html">sv</a> program is used to send commands
+through this interface, and to query status informations about the service.
+<p>
+The <a href="runsv.8.html">runsv</a> program supervises the corresponding
+service daemon.
+By default a service is defined to be up, that means, if the service daemon
+dies, it will be restarted.
+Of course you can <a href="sv.8.html">tell runsv</a> otherwise.
+<p>
+This reliable interface to control daemons and supervisors obsoletes
+pid-guessing programs, such as <tt>pidof</tt>, <tt>killall</tt>,
+<tt>start-stop-daemon</tt>, which, due to guessing, are prone to failures
+by design.
+It also obsoletes so called <tt>pid-files</tt>, no need for each and every
+service daemon to include code to daemonize, to write the new process id
+into a file, and to take care that the file is removed properly on shutdown,
+which might be very difficult in case of a crash.
+<hr>
+<a name="state"><h3>Clean process state</h3></a>
+<i>runit</i> guarantees each service a clean process state, no matter if the
+service is activated for the first time or automatically at boot time,
+reactivated, or simply restarted.
+This means that the service always is started with the same environment,
+resource limits, open file descriptors, and controlling terminals.
+<p>
+You don't necessarily have that with <i>sysv init</i> scripts for example.
+It requires a carefully written init script that reliably cleans up and sets
+the process state before starting the service daemon.
+This adds even more complexity to the init script in comparison with a run
+script used by <i>runit</i>.
+Many of today's init scripts don't provide a clean process state, here is
+an example on what could happen:
+<pre>
+ # /etc/init.d/foo-daemon start
+ Starting foo daemon: food.
+ #
+</pre>
+Fine.
+Everything works, nothing to worry about.
+After rebooting the system this shows up on the screen:
+<pre>
+ ...
+ Starting foo daemon: food: command not found
+ failed.
+ ...
+</pre>
+The <tt>food</tt> program is installed in <tt>/opt/foo/bin/</tt>.
+When starting the service for the first time using the init script, the
+<tt>PATH</tt> environment variable contained <tt>/opt/foo/bin</tt>.
+After reboot <tt>init</tt> started the service using the init script, but
+with a different value for the <tt>PATH</tt> variable, not containing
+<tt>/opt/foo/bin</tt>.
+Of course the init script should have set <tt>PATH</tt> before starting the
+daemon; the problem is that it worked in the first place, and that the error
+didn't show up until system reboot.
+<p>
+With bad init scripts miraculous things could also happen when just doing
+<pre>
+ # /etc/init.d/foo-daemon restart
+</pre>
+at the command line.
+<p>
+The clean process state includes open file descriptors, obsoleting the
+widely used hack in many service daemons to force-close all file descriptors
+that might be open, up to the limit of available file descriptors for the
+daemon process (often results in 1024 unnecessary close() system calls in a
+great number of service daemon implementations).
+<hr>
+<a name="log"><h3>Reliable logging facility</h3></a>
+The <a href="runsv.8.html">runsv</a> program provides a reliable logging
+facility for the service daemon.
+If configured, <a href="runsv.8.html">runsv</a> creates a pipe, starts and
+supervises an additional log service, redirects the log daemon's standard
+input to read from the pipe, and redirects the service daemon's standard
+output to write to the pipe.
+Restarting the service does not require restarting the log service, and vice
+versa.
+A good choice for a log daemon is <i>runit</i>'s service logging daemon
+<a href="svlogd.8.html">svlogd</a>.
+<p>
+The service daemon and the log daemon can run with different process states,
+and under different user id's.
+<i>runit</i> supports easy and reliable logging for service daemons running
+chroot'ed.
+<p>
+If <a href="runsv.8.html">runsv</a> is told to shutdown a service, e.g. at
+system shutdown, it ensures that the log service stays up as long as the
+corresponding service daemon is running and possibly writing to the log.
+<hr>
+<a name="fast"><h3>Fast system boot up and shutdown</h3></a>
+After the system's one time tasks (stage 1) are done, the system services
+are started up in parallel.
+The operating system's process scheduler takes care of having the services
+available as soon as possible.
+<p>
+On system shutdown, stage 3 uses <a href="runsv.8.html">runsv</a>'s control
+interface to wait until each service daemon is terminated and all logs are
+written.
+Again, services are taken down in parallel.
+As soon as all services are down, system halt or system reboot is initiated.
+<hr>
+<a name="portability"><h3>Portability</h3></a>
+<i>runit</i> comes ready-to-run for Debian GNU/Linux and BSD systems, and
+can easily be configured to run on other UNIX systems.
+The UNIX system's one time initialization tasks and tasks to shutdown the
+system must be identified and <i>runit</i>'s stages 1 and 3 configured
+accordingly.
+<p>
+Stages 1 and 3 handle one time tasks.
+They only run for short and exit soon.
+Stage 2 handles the system's uptime tasks (via the
+<a href="runsvdir.8.html">runsvdir</a> program) and is running the whole
+system's uptime.
+<p>
+<i>runit</i>'s stage 2 is portable across UNIX systems.
+<i>runit</i> is well suited for server systems and embedded systems, and
+also does its job well on desktop systems.
+<hr>
+<a name="packaging"><h3>Packaging friendly</h3></a>
+<i>runit</i>'s stages 1 and 3 are distribution specific.
+They normally are shell scripts, and an operating system distribution with
+software package management should adapt these scripts if they need support
+for their package management.
+The
+<a href="http://packages.debian.org/unstable/admin/runit-run.html">
+runit-run</a>
+Debian package is an attempt to integrate <i>runit</i> into
+<a href="http://www.debian.org/">Debian GNU/Linux</a> as an alternative to
+the default
+<a href="http://packages.debian.org/unstable/base/sysvinit.html">
+sysvinit</a>.
+<p>
+Stage 2 is packaging friendly:
+all a software package that provides a service needs to do is to include
+a <i>service directory</i> in the package, and to provide a symbolic link
+to this directory in <tt>/service/</tt>.
+The service will be started within five seconds, and automatically at boot
+time.
+The package's install and update scripts can use the reliable control
+interface to stop, start, restart, or send signals to the service.
+On package removal, the symbolic link simply is removed.
+The service will be taken down automatically.
+<hr>
+<a name="smallcode"><h3>Small code size</h3></a>
+One of the <i>runit</i> project's principles is to keep the code size
+small.
+As of version 1.0.0 of <i>runit</i>, the <tt>runit.c</tt> source contains
+330 lines of code; the <tt>runsvdir.c</tt> source is  274 lines of code, the
+<tt>runsv.c</tt> source 509.
+This minimizes the possibility of bugs introduced by programmer's fault,
+and makes it more easy for security related people to proofread the source
+code.
+<p>
+The <i>runit</i> core programs have a very small memory footprint and do not
+allocate memory dynamically.
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/chpst.8.html b/runit-2.1.2/doc/chpst.8.html
new file mode 100644
index 0000000..97d90f2
--- /dev/null
+++ b/runit-2.1.2/doc/chpst.8.html
@@ -0,0 +1,152 @@
+
+
+
+<html>
+<head>
+<title>chpst(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+chpst - runs a program with a changed process state 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>chpst</b> [-vP012]
+[-u <i>user</i>] [-U <i>user</i>] [-b <i>argv0</i>] [-e <i>dir</i>] [-/ <i>root</i>] [-n <i>inc</i>] [-l|-L <i>lock</i>] [-m <i>bytes</i>] [-d <i>bytes</i>]
+[-o <i>n</i>] [-p <i>n</i>] [-f <i>bytes</i>] [-c <i>bytes</i>] <i>prog</i> 
+<h2><a name='sect2'>Description</a></h2>
+<i>prog</i> consists of one or
+more arguments. <p>
+<b>chpst</b> changes the process state according to the given options,
+and runs <i>prog</i>. 
+<h2><a name='sect3'>Options</a></h2>
+
+<dl>
+
+<dt><b>-u <i>[:]user[:group]</b> </i></dt>
+<dd>setuidgid. Set uid and gid to the
+<i>user</i>&rsquo;s uid and gid, as found in <i>/etc/passwd</i>. If <i>user</i> is followed by a colon
+and a <i>group</i>, set the gid to <i>group</i>&rsquo;s gid, as found in <i>/etc/group</i>, instead
+of <i>user</i>&rsquo;s gid. If <i>group</i> consists of a colon-separated list of group names,
+<b>chpst</b> sets the group ids of all listed groups. If <i>user</i> is prefixed with
+a colon, the <i>user</i> and all <i>group</i> arguments are interpreted as uid and gids
+respectivly, and not looked up in the password or group file. All initial
+supplementary groups are removed. </dd>
+
+<dt><b>-U <i>[:]user[:group]</b> </i></dt>
+<dd>envuidgid. Set the environment
+variables $UID and $GID to the <i>user</i>&rsquo;s uid and gid, as found in <i>/etc/passwd</i>.
+If <i>user</i> is followed by a colon and a <i>group</i>, set $GID to the <i>group</i>&rsquo;s gid,
+as found in <i>/etc/group</i>, instead of <i>user</i>&rsquo;s gid. If <i>user</i> is prefixed with a
+colon, the <i>user</i> and <i>group</i> arguments are interpreted as uid and gid respectivly,
+and not looked up in the password or group file. </dd>
+
+<dt><b>-b <i>argv0</b> </i></dt>
+<dd>argv0. Run <i>prog</i>
+with <i>argv0</i> as the 0th argument. </dd>
+
+<dt><b>-e <i>dir</b> </i></dt>
+<dd>envdir. Set various
+environment variables as specified by files in the directory <i>dir</i>: If <i>dir</i>
+contains a file named <i>k</i> whose first line is <i>v</i>, <b>chpst</b> removes the environment
+variable <i>k</i> if it exists, and then adds the environment variable <i>k</i> with
+the value <i>v</i>. The name <i>k</i> must not contain =. Spaces and tabs at the end of
+<i>v</i> are removed, and nulls in <i>v</i> are changed to newlines. If the file <i>k</i> is
+empty (0 bytes long), <b>chpst</b> removes the environment variable <i>k</i> if it exists,
+without adding a new variable. </dd>
+
+<dt><b>-/ <i>root</b> </i></dt>
+<dd>chroot. Change the root directory to
+<i>root</i> before starting <i>prog</i>. </dd>
+
+<dt><b>-n <i>inc</b> </i></dt>
+<dd>nice. Add <i>inc</i> to the <i><b>nice</b>(2)</i> value before
+starting <i>prog</i>. <i>inc</i> must be an integer, and may start with a minus or plus.
+</dd>
+
+<dt><b>-l <i>lock</b> </i></dt>
+<dd>lock. Open the file <i>lock</i> for writing, and obtain an exclusive lock
+on it. <i>lock</i> will be created if it does not exist. If <i>lock</i> is locked by another
+process, wait until a new lock can be obtained. </dd>
+
+<dt><b>-L <i>lock</b> </i></dt>
+<dd>The same as -l, but
+fail immediately if <i>lock</i> is locked by another process. </dd>
+
+<dt><b>-m <i>bytes</b> </i></dt>
+<dd>limit memory.
+Limit the data segment, stack segment, locked physical pages, and total
+of all segment per process to <i>bytes</i> bytes each. </dd>
+
+<dt><b>-d <i>bytes</b> </i></dt>
+<dd>limit data segment.
+Limit the data segment per process to <i>bytes</i> bytes. </dd>
+
+<dt><b>-o <i>n</b> </i></dt>
+<dd>limit open files.
+Limit the number of open file descriptors per process to <i>n</i>. </dd>
+
+<dt><b>-p <i>n</b> </i></dt>
+<dd>limit processes.
+Limit the number of processes per uid to <i>n</i>. </dd>
+
+<dt><b>-f <i>bytes</b> </i></dt>
+<dd>limit output size. Limit
+the output file size to <i>bytes</i> bytes. </dd>
+
+<dt><b>-c <i>bytes</b> </i></dt>
+<dd>limit core size. Limit the core
+file size to <i>bytes</i> bytes. </dd>
+
+<dt><b>-v</b> </dt>
+<dd>verbose. Print verbose messages to standard error.
+This includes warnings about limits unsupported by the system. </dd>
+
+<dt><b>-P</b> </dt>
+<dd>pgrphack.
+Run <i>prog</i> in a new process group. </dd>
+
+<dt><b>-0</b> </dt>
+<dd>Close standard input before starting
+<i>prog</i>. </dd>
+
+<dt><b>-1</b> </dt>
+<dd>Close standard output before starting <i>prog</i>. </dd>
+
+<dt><b>-2</b> </dt>
+<dd>Close standard error
+before starting <i>prog</i>. </dd>
+</dl>
+
+<h2><a name='sect4'>Exit Codes</a></h2>
+<b>chpst</b> exits 100 when called with wrong options.
+It prints an error message and exits 111 if it has trouble changing the
+process state. Otherwise its exit code is the same as that of <i>prog</i>. 
+<h2><a name='sect5'>Emulation</a></h2>
+If
+<b>chpst</b> is called as <b>envdir</b>, <b>envuidgid</b>, <b>pgrphack</b>, <b>setlock</b>, <b>setuidgid</b>, or
+<b>softlimit</b>, it emulates the functionality of these programs from the daemontools
+package respectively. 
+<h2><a name='sect6'>See Also</a></h2>
+<i>sv(8)</i>, <i>runsv(8)</i>, <i>setsid(2)</i>, <i>runit(8)</i>, <i>runit-init(8)</i>,
+<i>runsvdir(8)</i>, <i>runsvchdir(8)</i> <p>
+ <i>http://smarden.org/runit/</i><br>
+  <i>http://cr.yp.to/daemontools.html</i><br>
+ 
+<h2><a name='sect7'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt; <p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Options</a></li>
+<li><a name='toc4' href='#sect4'>Exit Codes</a></li>
+<li><a name='toc5' href='#sect5'>Emulation</a></li>
+<li><a name='toc6' href='#sect6'>See Also</a></li>
+<li><a name='toc7' href='#sect7'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/debian b/runit-2.1.2/doc/debian
new file mode 120000
index 0000000..8784129
--- /dev/null
+++ b/runit-2.1.2/doc/debian
@@ -0,0 +1 @@
+../etc/debian
\ No newline at end of file
diff --git a/runit-2.1.2/doc/dependencies.html b/runit-2.1.2/doc/dependencies.html
new file mode 100644
index 0000000..452b56c
--- /dev/null
+++ b/runit-2.1.2/doc/dependencies.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit -service dependencies</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - service dependencies</h1>
+<hr>
+<i>runit</i>'s service supervision resolves dependencies for service daemons
+designed to be run by a supervisor process automatically.
+The service daemon (or the corresponding <tt>run</tt> scripts) should behave
+as follows:
+<ul>
+  <li>before providing the service, check if all services it depends on are
+  available.
+  If not, exit with an error, the supervisor will then try again.
+  <li>write all logs through <i>runit</i>'s logging facility.
+  The <a href="runsv.8.html">runsv</a> program takes care that all logs for
+  the service are written safely to disk.
+  Therefore there's no need to depend on a system logging service.
+  <li>optionally when the service is told to become down, take down other
+  services that depend on this one after disabling the service.
+</ul>
+If you want to run service daemons that do not support service supervision
+as described above, please refer to
+<a href="http://smarden.org/pape/djb/daemontools/noinit.html">this page</a>
+about service dependencies I wrote some time ago.
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/faq.html b/runit-2.1.2/doc/faq.html
new file mode 100644
index 0000000..a2eae27
--- /dev/null
+++ b/runit-2.1.2/doc/faq.html
@@ -0,0 +1,438 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - Frequently asked questions</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - Frequently asked questions</h1>
+<hr>
+<a href="#what">
+What's runit, why is it that different
+</a><br>
+<a href="#help">
+I need some help with runit, what should I do
+</a><br>
+<!--
+<a href="#service">
+What is a service, what a service daemon
+</a><br>
+-->
+<a href="#license">
+What's the license, is runit free software
+</a><br>
+<p>
+<a href="#run">
+How do I run a service under runit service supervision
+</a><br>
+<a href="#create">
+How do I create a new service directory
+</a><br>
+<!--
+<a href="#log">
+What is a log service
+</a><br>
+-->
+<a href="#createlog">
+How do I create a new service directory with an appendant log service
+</a><br>
+<a href="#tell">
+How do I tell runit about a new service
+</a><br>
+<a href="#control">
+How do I start, stop, or restart a service
+</a><br>
+<a href="#signal">
+How can I send signals to a service daemon
+</a><br>
+<a href="#status"> 
+How can I query the status of a service
+</a><br>
+<a href="#remove">
+How do I remove a service
+</a><br>
+<p>
+<a href="#depends">
+How do I make a service depend on another service
+</a><br>
+<!--
+<a href="#strongdepends">
+How can I make a service affect a dependant service
+</a><br>
+-->
+<p>
+<a href="#runlevels">
+What about runlevels
+</a><br>
+<a href="#lsb">
+What about LSB init scripts compliance
+</a><br>
+<p>
+<a href="#user">
+Is it possible to allow a user other than root to control a service
+</a><br>
+<a href="#userservices">
+Does runit support user-specific services?
+</a><br>
+<a href="#readonlyfs">
+Does runit work on a read-only filesystem
+</a><br>
+
+<hr>
+<a name="what"><h3>
+What's runit, why is it that different
+</h3></a>
+What is this runit init scheme about? 
+Why is it that different from sysvinit and other init schemes?
+<p>
+Answer:
+Please see the <a href="index.html">introduction</a>, and web page about
+runit's <a href="benefits.html">benefits</a>.
+
+<hr>
+<a name="help"><h3>
+I need some help with runit, what should I do
+</h3></a>
+I have a question, runit is doing something wrong, or I'm doing something
+wrong, what should I do?
+<p>
+Answer:
+First see the documentation, especially this list of
+<a href="faq.html">frequently asked questions</a>, and the man pages
+if you have a question about a specific runit program.
+If that still doesn't answer your question, try to search the
+<a href="http://news.gmane.org/gmane.comp.sysutils.supervision.general">
+supervision mailing list archive</a>.
+Finally, if this fails, feel free to post your question to the
+<a href="http://skarnet.org/lists/">supervision mailing list</a>.
+
+<!--
+<hr>
+<a name="service"><h3>
+What is a service, what a service daemon
+</h3></a>
+The runit documentation talks about services and service daemons.
+What actually is a service, and what a service daemon?
+<p>
+Answer:
+-->
+
+<hr>
+<a name="license"><h3>
+What's the license, is runit free software
+</h3></a>
+I would like to distribute runit, in source and binary form.
+Am I allowed to do so?
+<p>
+Answer:
+runit is free software, it's licensed under a three-clause BSD alike
+license.
+See the file <tt>package/COPYING</tt> in the runit tarball.
+
+<hr>
+<a name="run"><h3>
+How do I run a service under runit service supervision
+</h3></a>
+I want a service to be run under runit service supervision, so that it's
+automatically started on system boot, and supervised while system uptime.
+How does that work?
+<p>
+Answer:
+runit doesn't use the usual <tt>/etc/init.d/</tt> init script interface,
+but uses a directory per service.
+To integrate a service into the runit init scheme,
+<a href="#create">create a service directory</a> for the service, and
+<a href="#tell">tell runit</a> about it.
+
+<hr>
+<a name="create"><h3>
+How do I create a new service directory
+</h3></a>
+How do I create a service directory for the use with runit?
+<p>
+Answer:
+Service directories usually are placed into the <tt>/etc/sv/</tt>
+directory.
+Create a new directory for your service in <tt>/etc/sv/</tt>, put a
+<tt>./run</tt> script into it, and make the script executable.
+Note that for the use with runit,
+<a href="#service">service daemons</a> must not put themself into the
+background, but must run in the foreground.
+Here's a simple example for a <tt>getty</tt> service:
+<pre>
+ $ cat /etc/sv/getty-2/run
+ #!/bin/sh
+ exec getty 38400 tty2 linux
+ $ 
+</pre>
+Note the <tt>exec</tt> in the last line, it tells the shell that
+interprets the script to replace itself with the service daemon
+<tt>getty</tt>; this is necessary to make
+<a href="#control">controlling the service</a> work properly.
+
+<!--
+<hr>
+<a name="log"><h3>
+What is a log service
+</h3></a>
+Additionally to supervising a service runit can supervise an appendant
+log service.
+What does that mean?
+<p>
+Answer:
+-->
+
+<hr>
+<a name="createlog"><h3>
+How do I create a new service directory with an appendant log service
+</h3></a>
+How do I create a service directory with an appendant log service for the
+use with runit?
+<p>
+Answer:
+First <a href="#create">create the service directory</a> for the service.
+Then create a subdirectory <tt>./log</tt> in the service directory, again
+put a <tt>./run</tt> script into it, and make the script executable.
+The <tt>./run</tt> script must run a service logging daemon, normally
+this is the <a href="svlogd.8.html">svlogd</a> program.
+See the <a href="runsv.8.html">runsv</a> man page for details.
+Here's an example of a <tt>./log/run</tt> script:
+<pre>
+ $ cat /etc/sv/socklog-klog/log/run
+ #!/bin/sh
+ exec chpst -ulog svlogd -tt ./main
+ $ 
+</pre>
+
+<hr>
+<a name="tell"><h3>
+How do I tell runit about a new service
+</h3></a>
+I created a service directory for a service that should run under runit
+service supervision.
+How do I tell runit about the new service directory, so that it picks
+up and runs the service by default?
+<p>
+Answer:
+Create a symbolic link in <tt>/service/</tt> pointing to the service
+directory, runit will pick up the service within the next five seconds,
+and automatically start it on system boot.
+E.g.:
+<pre>
+ # ln -s /etc/sv/getty-2 /service/
+</pre>
+
+<hr>
+<a name="control"><h3>
+How do I start, stop, or restart a service
+</h3></a>
+I want to stop a service temporarily, and probably restart is later, or
+I want to have it restarted immediately.
+How can I control a service running under runit service supervision?
+<p>
+Answer:
+Use the <a href="sv.8.html">sv</a> program.
+E.g., to restart the <tt>socklog-unix</tt> service, do:
+<pre>
+ # sv restart socklog-unix
+</pre>
+
+<hr>
+<a name="signal"><h3>
+How can I send signals to a service daemon
+</h3></a>
+I want to send a service daemon the HUP signal, to have it re-read its
+configuration, or I want to send it the INT signal.
+How can a send signals to a service daemon?
+<p>
+Answer:
+Use the <a href="sv.8.html">sv</a> program.
+E.g., to send the <tt>dhcp</tt> service the HUP signal, do:
+<pre>
+ # sv hup dhcp
+</pre>
+
+<hr>
+<a name="status"><h3>
+How can I query the status of a service
+</a></h3>
+I want to now the status of a service, whether it is up and available,
+or down as requested, or so.
+How can I find out this information?
+<p>
+Answer:
+User the <a href="sv.8.html">sv</a> program.
+E.g., to query or check the status of the <tt>socklog-unix</tt> service,
+do:
+<pre>
+ # sv status socklog-unix
+</pre>
+or
+<pre>
+ # sv check socklog-unix
+</pre>
+
+<hr>
+<a name="remove"><h3>
+How do I remove a service
+</h3></a>
+I want to remove a service that currently runs under runit service
+supervision.
+How do I tell runit?
+<p>
+Answer:
+Remove the symbolic link in <tt>/service/</tt> pointing to the service
+directory, runit recognizes the removed service within the next five
+seconds, then stops the service, the optional log service, and finally the
+supervisor process.
+E.g.:
+<pre>
+ # rm /service/getty-2
+</pre>
+
+<hr>
+<a name="depends"><h3>
+How do I make a service depend on another service
+</a></h3>
+I have a service that needs another service to be available before it can
+start.
+How can I tell runit about this dependency?
+<p>
+Answer:
+Make sure in the <tt>./run</tt> script of the dependant service that the
+service it depends on is available before the service daemon starts.
+The <a href="sv.8.html">sv</a> program can be used for that.
+E.g. the <tt>cron</tt> service wants the <tt>socklog-unix</tt> system
+logging service to be available before starting the <tt>cron</tt> service
+daemon, so no logs get lost:
+<pre>
+ $ cat /etc/sv/cron/run
+ #!/bin/sh
+ sv start socklog-unix || exit 1
+ exec cron -f
+ $ 
+</pre>
+See also the <a href="dependencies.html">documentation</a>.
+
+<!--
+<hr>
+<a name="strongdepends"><h3>
+How can I make a service affect a dependant service
+</a></h3>
+<a href="#depends">This dependency</a> is not enough.
+I have a service that needs to be stopped or restarted, whenever a service
+it depends on stops or restarts.
+How can I tell runit about that a service affects a dependant service in
+such a way?
+<p>
+Answer:
+First think about whether you really need this, it almost never should be
+necessary.
+If you really need this,
+-->
+
+<hr>
+<a name="runlevels"><h3>
+What about runlevels
+</a></h3>
+Other init schemes support runlevels, what about runit?
+<p>
+Answer:
+runit supports runlevels, even more flexible than traditional init schemes.
+See <a href="runlevels.html">the documentation</a>.
+
+<hr>
+<a name="lsb"><h3>
+What about LSB init scripts compliance
+</a></h3>
+I know about the <a href="sv.8.html">sv</a> program to control a service,
+but have applications that rely on the <tt>/etc/init.d/</tt> scripts
+interface as defined through LSB.
+Do I need to change the application to work with runit?
+<p>
+Answer:
+You don't need to change the application.
+The <a href="sv.8.html">sv</a> program supports the <tt>/etc/init.d/</tt>
+script interface
+<a href="http://refspecs.freestandards.org/LSB_2.1.0/LSB-generic/LSB-generic/iniscrptact.html">
+as defined through LSB</a>.
+To make this script interface work for a service, create a symbolic link
+in <tt>/etc/init.d/</tt>, named as the service daemon, pointing to the
+<a href="sv.8.html">sv</a> program, e.g. for the <tt>cron</tt> service:
+<pre>
+ # ln -s /bin/sv /etc/init.d/cron
+ # /etc/init.d/cron restart
+ ok: run: cron: (pid 5869) 0s
+ # 
+</pre>
+
+<hr>
+<a name="user"><h3>
+Is it possible to allow a user other than root to control a service
+</a></h3>
+Using the <a href="sv.8.html">sv</a> program to control a service, or query
+its status informations, only works as root.
+Is it possible to allow non-root users to control a service too?
+<p>
+Answer:
+Yes, you simply need to adjust file system permissions for the
+<tt>./supervise/</tt> subdirectory in the service directory.
+E.g.: to allow the user <tt>burdon</tt> to control the service
+<tt>dhcp</tt>, change to the <tt>dhcp</tt> service directory, and do
+<pre>
+ # chmod 755 ./supervise
+ # chown burdon ./supervise/ok ./supervise/control ./supervise/status
+</pre>
+This works similarly with groups, of course.
+
+<hr>
+<a name="userservices"><h3>
+Does runit support user-specific services?
+</a></h3>
+It's very nice to simply
+<a href="#tell">create symbolic links</a> to add system-wide services.
+Does this work for user-specific services too?
+<p>
+Answer:
+Yes.
+E.g.: to provide the user <tt>floyd</tt> with facility to manage services
+through <tt>~/service/</tt>, <a href="#createlog">create a service</a>
+<tt>runsvdir-floyd</tt> with the following run script and a usual log/run
+script, and <a href="#tell">tell runit</a> about the service
+<pre>
+ #!/bin/sh
+ exec 2>&1
+ exec chpst -ufloyd runsvdir /home/floyd/service
+</pre>
+Now <tt>floyd</tt> can create services on his own, and manage them through
+symbolic links in <tt>~/service/</tt> to have them run under his user id.
+
+<hr>
+<a name="readonlyfs"><h3>
+Does runit work on a read-only filesystem
+</a></h3>
+On my system <tt>/etc/</tt> is mounted read-only by default.
+runit uses many files in <tt>/etc/</tt> it needs to write to, like
+<tt>/etc/runit/stopit</tt>, and the <tt>./supervise/</tt>
+subdirectories in the service directories.
+How can I make runit work on my system?
+<p>
+Answer:
+Use symbolic links, runit deals with them well, even with dangling
+symlinks.
+E.g., make a ramdisk available at a moint point, say <tt>/var/run/</tt>,
+and create symbolic links for the files and directories that runit needs
+to write access to pointing into <tt>/var/run/</tt>:
+<pre>
+ # ln -s /var/run/runit.stopit /etc/runit/stopit
+ # ln -s /var/run/sv.getty-2 /etc/sv/getty-2/supervise
+</pre>
+
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/index.html b/runit-2.1.2/doc/index.html
new file mode 100644
index 0000000..85bb01b
--- /dev/null
+++ b/runit-2.1.2/doc/index.html
@@ -0,0 +1,261 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - a UNIX init scheme with service supervision</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a>
+<hr>
+<h1>runit - a UNIX init scheme with service supervision</h1>
+<hr>
+<a href="install.html">How to install runit</a><br>
+<a href="upgrade.html">Upgrading from previous versions of runit</a>
+<p>
+<a href="benefits.html">Benefits</a><br>
+<a href="replaceinit.html">How to replace init</a><br>
+<a href="useinit.html">How to use runit with current init</a><br>
+<a href="usedietlibc.html">How to use dietlibc</a><br>
+<a href="faq.html">Frequently asked questions</a><br>
+<p>
+<a href="runlevels.html">Runlevels</a><br>
+<a href="dependencies.html">Service dependencies</a><br>
+<a href="runscripts.html">A collection of run scripts</a><br>
+<p>
+<a href="runit.8.html">The <tt>runit</tt> program</a><br>
+<a href="runit-init.8.html">The <tt>runit-init</tt> program</a><br>
+<br>
+<a href="sv.8.html">The <tt>sv</tt> program</a><br>
+<br>
+<a href="runsvdir.8.html">The <tt>runsvdir</tt> program</a><br>
+<a href="runsvchdir.8.html">The <tt>runsvchdir</tt> program</a><br>
+<a href="runsv.8.html">The <tt>runsv</tt> program</a><br>
+<br>
+<a href="svlogd.8.html">The <tt>svlogd</tt> program</a><br>
+<br>
+<a href="chpst.8.html">The <tt>chpst</tt> program</a><br>
+<a href="utmpset.8.html">The <tt>utmpset</tt> program</a><br>
+<hr>
+<i>runit</i> is a
+cross-platform Unix init scheme with service supervision, a replacement for
+<a href="ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/">sysvinit</a>,
+and other init schemes.
+It runs on <b>GNU/Linux</b>, <b>*BSD</b>, <b>MacOSX</b>, <b>Solaris</b>,
+and can easily be adapted to other Unix operating systems.
+If <i>runit</i> runs for you on any other operating system, please
+<a href="mailto:supervision@list.skarnet.org">let me know</a>.
+<hr>
+<i>runit</i> is discussed on the
+<a href="http://skarnet.org/lists/#supervision">
+&lt;supervision@list.skarnet.org&gt;</a>
+mailing list.
+Please contact this list and not me privately.
+<p>
+To subscribe send an empty email to
+<a href="mailto:supervision-subscribe@list.skarnet.org">
+&lt;supervision-subscribe@list.skarnet.org&gt;</a>.
+<p>
+Mailing list archives are available at
+<a href="http://skarnet.org/lists/archive.cgi?2">skarnet.org</a>, and
+<a href="http://news.gmane.org/gmane.comp.sysutils.supervision.general">
+gmane.org</a>.
+<hr>
+The program <a href="runit.8.html">runit</a> is intended to run as Unix
+process no 1, it is automatically started by the
+<a href="runit-init.8.html">runit-init</a> <tt>/sbin/init</tt>-replacement
+if this is started by the kernel.
+<p>
+<a href="runit.8.html">runit</a> performs the system's <i>booting</i>,
+<i>running</i> and <i>shutting down</i> in <b>three stages</b>:
+<ul>
+  <li><b>Stage 1:</b><br>
+  <i>runit</i> starts <tt>/etc/runit/1</tt> and waits for it to
+  terminate.
+  The system's one time initialization tasks are done here.
+  <tt>/etc/runit/1</tt> has full control over <tt>/dev/console</tt> to be
+  able to start an emergency shell in case the one time initialization
+  tasks fail.
+  <li><b>Stage 2:</b><br>
+  <i>runit</i> starts <tt>/etc/runit/2</tt> which should not return
+  until the system is going to halt or reboot; if it crashes, it will be
+  restarted.
+  Normally, <tt>/etc/runit/2</tt> runs
+  <a href="runsvdir.8.html">runsvdir</a>.
+  In Stage 2 <i>runit</i> optionally handles the INT signal (ctrl-alt-del
+  keyboard request on Linux/i386).
+  <li><b>Stage 3:</b><br>
+  If <i>runit</i> is told to halt or reboot the system, or Stage 2 returns
+  without errors, it terminates Stage 2 if it is running, and runs
+  <tt>/etc/runit/3</tt>.
+  The systems tasks to shutdown and halt or reboot are done here.
+</ul>
+These are working examples for Debian sarge:
+<a href="debian/1">/etc/runit/1</a>,
+<a href="debian/2">/etc/runit/2</a>,
+<a href="debian/3">/etc/runit/3</a>.
+<p>
+The program <a href="runit-init.8.html">runit-init</a> is intended to
+replace <tt>/sbin/init</tt>.
+The command <b><tt>init 0</tt></b> tells <i>runit</i> to halt the system,
+and <b><tt>init 6</tt></b> to reboot.
+<a href="runlevels.html">Runlevels</a> are handled through the
+<a href="runsvdir.8.html">runsvdir</a> and
+<a href="runsvchdir.8.html">runsvchdir</a> programs.
+Service <a href="dependencies.html">dependencies</a> are resolved
+automatically.
+<p>
+<i>runit</i> is optimized for reliability and small size.
+The amount of code in process no 1 should be minimal.
+<hr>
+See <a href="install.html">How to install runit</a> for installing
+<i>runit</i>, and <a href="replaceinit.html">How to replace init</a> for
+configuring <i>runit</i> to run as process no 1.
+See <a href="useinit.html">How to use with current init</a> if you want to
+use <i>runit</i> without replacing the current init scheme.
+Please read the list of
+<a href="faq.html">Frequently asked questions with answers</a>.
+<hr>
+If <i>runit</i> on Linux is compiled and linked with the
+<a href="http://www.fefe.de/dietlibc/">dietlibc</a>, it yields in a
+statically linked <tt>runit</tt> binary of 8.5k size and this
+<tt>ps axuw</tt> output on my system:
+<pre>
+ USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
+ root         1  0.0  0.0    20   16 ?        S     2002   0:02 runit
+</pre>
+I recommend doing this; for instructions, see
+<a href="usedietlibc.html">How to use dietlibc</a>.
+<hr>
+The following distributions are known to include or package <i>runit</i>:
+<ul>
+<li><a href="http://packages.qa.debian.org/runit">
+Debian GNU/Linux</a> (as alternative init scheme)
+<li><a href="http://www.freshports.org/sysutils/runit/">
+FreeBSD</a>
+<li><a href="http://www.openbsd.org/cgi-bin/cvsweb/ports/sysutils/runit/">
+OpenBSD</a>
+<li><a href="http://pkgsrc.se/wip/runit/">
+NetBSD</a>
+<li><a href="http://packages.ubuntu.com/runit">
+Ubuntu</a> (as alternative init scheme)
+<li><a href="http://packages.gentoo.org/package/sys-process/runit">
+Gentoo</a>
+<li><a href="https://code.google.com/p/runit-for-lfs/">
+Linux from Scratch</a>
+<li><a href="http://www.finnix.org/">
+Finnix</a>
+<li><a href="http://www.smeserver.org/">
+SME server</a>
+<li><a href="http://linux-vserver.org/Running_runit-supervised_services_inside_a_vserver">
+Linux-VServer</a>
+<li><a href="http://www.t2-project.org/">
+T2</a>
+<li><a href="http://www.gobolinux.org/">
+GoboLinux</a>
+<li><a href="http://www.dragora.org/">
+Dragora GNU/Linux</a> (as default init scheme)
+<li><a href="https://wiki.archlinux.org/index.php/Runit">
+ArchLinux</a>
+<li><a href="http://www.opensde.org/">
+OpenSDE</a>
+<li><a href="http://zinux.cynicbytrade.com/">
+Zinux Linux</a> (as default init scheme)
+<li><a href="http://deepofix.org/">
+deepOfix Mail Server</a> (as default init scheme)
+</ul>
+If you know of more distributions, please
+<a href="mailto:supervision@list.skarnet.org">let me know</a>.
+<hr>
+<b><i>runit</i> in use</b>:
+I replaced <i>sysvinit</i> successfully with <i>runit</i> on several server
+systems and a laptop running Debian/GNU Linux sarge, woody, and potato.
+Here is an example:
+<pre>
+ # strings /proc/1/exe |grep Id
+ &#36;Id: runit.c,v 1.7 2002/02/13 09:59:52 pape Exp &#36;
+ # uptime
+  11:59:13 up 365 days, 23:22,  3 users,  load average: 0.01, 0.02, 0.00
+ # ps axuw |head -n20
+ USER       PID %CPU %MEM   VSZ  RSS TTY      STAT START   TIME COMMAND
+ root         1  0.0  0.0    20   16 ?        S     2002   0:07 runit
+ root         2  0.0  0.0     0    0 ?        SW    2002   0:00 [keventd]
+ root         3  0.0  0.0     0    0 ?        SWN   2002   0:51 [ksoftirqd_CPU0]
+ root         4  0.0  0.0     0    0 ?        SW    2002 144:38 [kswapd]
+ root         5  0.0  0.0     0    0 ?        SW    2002   0:08 [bdflush]
+ root         6  0.0  0.0     0    0 ?        SW    2002   7:24 [kupdated]
+ root       168  0.0  0.0  1652  168 ?        S     2002   0:27 /usr/sbin/cron
+ root       174  0.0  0.0    36   24 ?        S     2002   1:06 runsvdir /var/service log: ...............................................................................................
+ root       176  0.0  0.0    20   20 ?        S     2002   0:00 runsv qmail-send
+ root       177  0.0  0.0    20   20 ?        S     2002   0:00 runsv getty-5
+ root       178  0.0  0.0    20   20 ?        S     2002   0:00 runsv getty-4
+ root       179  0.0  0.0    20   20 ?        S     2002   0:00 runsv getty-3
+ root       180  0.0  0.0    20   20 ?        S     2002   0:00 runsv getty-2
+ root       182  0.0  0.0    20   20 ?        S     2002   0:00 runsv socklog-unix
+ root       183  0.0  0.0  1256    4 tty5     S     2002   0:00 /sbin/getty 38400 tty5 linux
+ root       184  0.0  0.0  1256    4 tty3     S     2002   0:00 getty 38400 tty3 linux
+ root       185  0.0  0.0    20   20 ?        S     2002   0:00 runsv socklog-klog
+ root       186  0.0  0.0    20   20 ?        S     2002   0:00 runsv ssh
+ root       187  0.0  0.0  1256    4 tty4     S     2002   0:00 getty 38400 tty4 linux
+ # pstree
+ runit-+-bdflush
+       |-cron
+       |-gcache
+       |-keventd
+       |-ksoftirqd_CPU0
+       |-kswapd
+       |-kupdated
+       `-runsvdir-+-runsv-+-multilog
+                  |       `-qmail-send-+-qmail-clean
+                  |                    |-qmail-lspawn
+                  |                    `-qmail-rspawn---qmail-remote
+                  |-4*[runsv---getty]
+                  |-2*[runsv-+-multilog]
+                  |          `-socklog]
+                  |-runsv-+-multilog
+                  |       `-sshd-+-sshd---sshd---bash---bash---pstree
+                  |              `-sshd---sshd---rsync
+                  |-runsv---clockspeed
+                  |-runsv-+-dnscache
+                  |       `-multilog
+                  |-runsv---apache-ssl-+-9*[apache-ssl]
+                  |                    |-gcache
+                  |                    `-4*[multilog]
+                  |-7*[runsv-+-multilog]
+                  |          `-tcpserver]
+                  |-4*[runsv-+-multilog]
+                  |          `-tinydns]
+                  |-runsv---uncat
+                  |-2*[runsv-+-multilog]
+                  |          `-tcpsvd]
+                  |-runsv-+-svlogd
+                  |       `-tcpsvd-+-smtpfront-qmail
+                  |                `-smtpfront-qmail---qmail-queue
+                  `-runsv-+-svlogd
+                          `-tcpsvd---bincimap-up---bincimapd
+</pre>
+<hr>
+See <a href="http://smarden.org/runit/">http://smarden.org/runit/</a>
+for recent informations.
+<hr>
+Related links:
+<ul>
+<li><a href="http://www.fefe.de/minit/">
+minit</a> - a small yet feature-complete init
+<li><a href="http://multivac.cwru.edu/svscan-1/">
+svscan as process 1</a> - by Paul Jarc
+<li><a href="ftp://ftp.cistron.nl/pub/people/miquels/sysvinit/">
+sysvinit</a> - source code
+<li><a href="http://www.freebsd.org/cgi/cvsweb.cgi/src/sbin/init/">
+FreeBSD's init</a> - CVS repository
+<li><a href="http://cvsweb.netbsd.org/bsdweb.cgi/src/sbin/init/">
+NetBSD's init</a> - CVS repository
+<li><a href="http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/init/">
+OpenBSD's init</a> - CVS repository
+<li><a href="http://www.atnf.csiro.au/~rgooch/linux/boot-scripts/">
+Linux Boot Scripts</a> - by Richard Gooch
+</ul>
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/install.html b/runit-2.1.2/doc/install.html
new file mode 100644
index 0000000..fb3b2c4
--- /dev/null
+++ b/runit-2.1.2/doc/install.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - installation</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - installation</h1>
+<hr>
+<i>runit</i> installs into
+<a href="http://cr.yp.to/slashpackage.html">/package</a>.
+If you don't have a <tt>/package</tt> directory, create it now:
+<pre>
+ # mkdir -p /package
+ # chmod 1755 /package
+</pre>
+Download
+<a href="runit-2.1.2.tar.gz">runit-2.1.2.tar.gz</a> into <tt>/package</tt>
+and unpack the archive
+<pre>
+ # cd /package
+ # gunzip runit-2.1.2.tar
+ # tar -xpf runit-2.1.2.tar
+ # rm runit-2.1.2.tar
+ # cd admin/runit-2.1.2
+</pre>
+On MacOSX, do
+<pre>
+ # echo 'cc -Xlinker -x' &gt;src/conf-ld
+ # cp src/Makefile src/Makefile.old
+ # sed -e 's/ -static//' &lt;src/Makefile.old &gt;src/Makefile
+</pre>
+Now compile and install the <i>runit</i> programs
+<pre>
+ # package/install
+</pre>
+If you want to make the man pages available in the <tt>/usr/local/man/</tt>
+hierarchy, do:
+<pre>
+ # package/install-man
+</pre>
+To report success:
+<pre>
+ # mail pape-runit-2.1.2@smarden.org &lt;compile/sysdeps
+</pre>
+If you use <i>runit</i> regularly, please
+<a href="http://smarden.org/pape/#contribution">contribute</a> to the project.
+<p>
+Refer to <a href="replaceinit.html">replacing init</a> for
+replacing <i>init</i> with <i>runit</i>, or to
+<a href="useinit.html">use with traditional init</a> for running
+<i>runit</i>'s service supervision with your system's current <i>init</i>
+scheme.
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/replaceinit.html b/runit-2.1.2/doc/replaceinit.html
new file mode 100644
index 0000000..70f6f7d
--- /dev/null
+++ b/runit-2.1.2/doc/replaceinit.html
@@ -0,0 +1,254 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - replacing init</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a>
+<hr>
+<h1>runit - replacing init</h1>
+<hr>
+<a href="#sysv">How to replace sysvinit on GNU/Linux</a><br>
+<a href="#bsd">How to replace init on *BSD</a><br>
+<a href="#macosx">How to replace init on MacOSX</a><br>
+<a href="#solaris">How to replace init on Solaris</a>
+<hr>
+<a name="sysv"><h2>Replacing sysvinit (GNU/Linux)</h2></a>
+Follow these steps to migrate from <i>sysvinit</i> to <i>runit</i> on
+<a href="http://www.debian.org/releases/woody/">Debian GNU/Linux (woody)</a>.
+The <tt>/sbin/init</tt> binary is not replaced until step 6, <i>runit</i> is
+the default Unix process no 1 after step 7.
+<p>
+If you have installed the precompiled Debian package, start at step 3.
+<h3>Step 1: The three stages</h3>
+<i>runit</i> looks for the three stages implementing the system's
+<i>booting</i>, <i>running</i> and <i>shutdown</i> in <tt>/etc/runit/1</tt>,
+<tt>/etc/runit/2</tt> and <tt>/etc/runit/3</tt>, create the files now:
+<pre>
+ # mkdir -p /etc/runit
+ # cp -p /package/admin/runit/etc/debian/[123] /etc/runit/
+</pre>
+Create also a getty service directory:
+<pre>
+ # mkdir -p /etc/sv/getty-5
+ # cp -p /package/admin/runit/etc/debian/getty-tty5/run /etc/sv/getty-5/
+ # cp -p /package/admin/runit/etc/debian/getty-tty5/finish /etc/sv/getty-5/
+</pre>
+If you want <i>runit</i> to handle the ctrl-alt-del keyboard request, do:
+<pre>
+ # cp -p /package/admin/runit/etc/debian/ctrlaltdel /etc/runit/
+</pre>
+<h3>Step 2: The runit programs</h3>
+The <i>runit</i> programs must reside on the root partition, copy them to
+<tt>/sbin</tt>:
+<pre>
+ # cp -p /package/admin/runit/command/runit* /sbin/
+</pre>
+<h3>Step 3: The getties</h3>
+At least one getty must run in stage 2 so that you are able to login.
+Choose a free <tt>tty</tt>, say <tt>tty5</tt>, where <i>sysvinit</i> is not
+running any getty (edit <tt>/etc/inittab</tt> and <tt>kill -HUP 1</tt> if
+needed), and tell <a href="runsvdir.8.html">runsvdir</a> about the getty-5
+<i>service</i>:
+<pre>
+ # mkdir -p /service
+ # ln -s /etc/sv/getty-5 /service/
+</pre>
+Start <i>runit</i>'s stage 2 for testing:
+<pre>
+ # /etc/runit/2 &
+</pre>
+And check that the getty is running.
+<h3>Step 4: Reboot into runit for testing</h3>
+Boot your system with <i>runit</i> for the first time.
+This does not change the default boot behavior of your system, <i>lilo</i>
+will be told to use <i>runit</i> just once:
+<ul>
+<li>reboot the system
+<li>enter the following on the lilo prompt:<br>
+<tt>init=/sbin/runit-init</tt>
+<li>watch the console output while <i>runit</i> boots up the system
+<li>switch to <tt>tty5</tt> when stage 2 is reached, a <tt>getty</tt>
+should run there, you are able to login.
+</ul>
+If you are not using <i>lilo</i> as boot loader, refer to the documentation
+of your boot loader on how to pass <tt>init=/sbin/runit-init</tt> to the
+kernel.
+<h3>Step 5: Service migration</h3>
+The goal is to migrate all services from <i>sysvinit</i> scheme to the
+<i>runit</i> service supervision design; take a look at these
+<a href="runscripts.html">run scripts</a> for popular services.
+The migration can be done smoothly.
+For those services that are not migrated to use <tt>run</tt> scripts yet,
+add the corresponding <tt>init</tt>-script startup to <tt>/etc/runit/1</tt>,
+e.g.:
+<pre>
+ #!/bin/sh
+ # one time tasks
+
+ /etc/init.d/kerneld start
+ /etc/init.d/rmnologin
+
+ touch /etc/runit/stopit
+ chmod 0 /etc/runit/stopit
+</pre>
+It is possible to just add <tt>/etc/init.d/rc 2</tt> for having all services
+from the former runlevel 2 started as one time tasks, but keep the goal above
+in mind, supervising services has great advantages.
+<p>
+To migrate a service,
+<a href="faq.html#create">create a service directory</a>, disable the service
+if it is running, disable the service in <tt>/etc/rc.conf</tt> or remove the
+service startup from the <tt>/etc/rc.*</tt> scripts and
+<a href="faq.html#tell">tell runsvdir</a> about the new service.
+<p>
+Repeat step 4 and 5, using <tt><b>/sbin/runit-init 6</b></tt> to reboot the
+system, until you are satisfied with your services startup.
+If anything goes wrong, reboot the system into the default <i>sysvinit</i>
+<tt>/sbin/init</tt> and repair the <i>runit</i> stages, then start again at
+step 4.
+<h3>Step 6: Replace /sbin/init</h3>
+Now it is time to replace the <i>sysvinit</i> <tt>/sbin/init</tt> binary:
+<pre>
+ # mv /sbin/init /sbin/init.sysv
+ # ln -s runit-init /sbin/init
+</pre>
+<h3>Step 7: Final reboot</h3>
+The last step is to do the final reboot to boot the system with the new
+default Unix process no 1 <i>runit</i>.
+<pre>
+ # init 6
+</pre>
+To report success:
+<pre>
+ # ( uname -a ; cat /etc/runit/[123] ) |mail pape-runit-2.1.2@smarden.org
+</pre>
+<hr>
+
+<a name="bsd"><h2>Replacing init (*BSD)</h2></a>
+Follow these steps to migrate from <i>init</i> to <i>runit</i> on
+<a href="http://www.openbsd.org/">OpenBSD 2.9</a> or
+<a href="http://www.freebsd.org/">FreeBSD 4.4</a>.
+The <tt>/sbin/init</tt> binary is not replaced until step 4.
+<h3>Step 1: The three stages</h3>
+<i>runit</i> looks for the three stages implementing the system's
+<i>booting</i>, <i>running</i> and <i>shutdown</i> in <tt>/etc/runit/1</tt>,
+<tt>/etc/runit/2</tt> and <tt>/etc/runit/3</tt> respectively.
+Create the scripts now:
+<pre>
+ # mkdir -p /etc/runit
+
+OpenBSD 2.9:
+ # cp -p /package/admin/runit/etc/openbsd/[123] /etc/runit/
+
+FreeBSD 4.4:
+ # cp -p /package/admin/runit/etc/freebsd/[123] /etc/runit/
+</pre>
+Remove the <tt>svscanboot</tt> startup from <tt>/etc/rc.local</tt> by
+deleting the line <tt>csh -cf '/command/svscanboot &'</tt> (this normally
+is the last one); <i>runit</i> will start
+<a href="runsvdir.8.html">runsvdir</a> in stage 2 after running
+<tt>rc.local</tt> in stage 1.
+<pre>
+ # vi /etc/rc.local
+</pre>
+<h3>Step 2: The runit programs</h3>
+The <i>runit</i> programs must reside on the root partition, install them
+into <tt>/sbin</tt>:
+<pre>
+ # install -m0500 /package/admin/runit/command/runit* /sbin/
+</pre>
+<h3>Step 3: The getties</h3>
+At least one getty must run in stage 2 so that you are able to login.
+To have it run on the virtual console no 5, create the getty-5 service
+directory:
+<pre>
+ # mkdir -p /etc/sv/getty-5
+
+OpenBSD 2.9:
+ # cp -p /package/admin/runit/etc/openbsd/getty-ttyC4/run /etc/sv/getty-5/
+ # cp -p /package/admin/runit/etc/openbsd/getty-ttyC4/finish /etc/sv/getty-5/
+
+FreeBSD 4.4:
+ # cp -p /package/admin/runit/etc/freebsd/getty-ttyv4/run /etc/sv/getty-5/
+ # cp -p /package/admin/runit/etc/freebsd/getty-ttyv4/finish /etc/sv/getty-5/
+</pre>
+and tell <a href="runsvdir.8.html">runsvdir</a> about the <tt>getty-5</tt>
+<i>service</i>:
+<pre>
+ # mkdir -p /service
+ # ln -s /etc/sv/getty-5 /service/
+</pre>
+Start <i>runit</i>'s stage 2 for testing:
+<pre>
+ # /etc/runit/2 &
+</pre>
+And check that the getty is running.
+<h3>Step 4: Replace the <tt>/sbin/init</tt> binary</h3>
+Before replacing the <tt>init</tt> binary, make sure that you are able
+to boot your system alternatively, e.g. with a boot floppy, to restore the
+former <tt>/sbin/init</tt> if anything goes wrong.
+<p>
+Make a backup copy of the current <tt>/sbin/init</tt> program and replace
+it with <tt>/sbin/runit-init</tt>:
+<pre>
+ # cp -p /sbin/init /sbin/init.bsd
+ # install /sbin/runit-init /sbin/init
+</pre>
+Boot your system with <i>runit</i> for the first time:
+<pre>
+ # reboot
+</pre>
+Watch the console output while <i>runit</i> boots up the system.
+Switch to the virtual console 5 (CTRL-ALT-F5) when stage 2 is reached, a
+getty should run there, you are able to login.
+<p>
+Use <b>init 6</b> to reboot and <b>init 0</b> to halt a system that runs
+<i>runit</i>.
+This will cause <i>runit</i> to enter stage 3 which runs
+<tt>/sbin/reboot</tt> or <tt>/sbin/halt</tt> as last command.
+<p>
+To report success:
+<pre>
+ # ( uname -a ; cat /etc/runit/[123] ) |mail pape-runit-2.1.2@smarden.org
+</pre>
+<h3>Step 5: Service migration</h3>
+The goal is to migrate all services from <i>/etc/rc.*</i> scheme to the
+<i>runit</i> service supervision design; take a look at these
+<a href="runscripts.html">run scripts</a> for popular services.
+The migration can be done smoothly.
+By default <i>runit</i> runs the <tt>/etc/rc</tt> scripts in stage 1 as a
+one time task, so the services are started automatically:
+<pre>
+ #!/bin/sh
+ # system one time tasks
+
+ /bin/sh /etc/rc autoboot
+
+ touch /etc/runit/stopit
+ chmod 0 /etc/runit/stopit
+</pre>
+To migrate a service,
+<a href="faq.html#create">create a service directory</a>, disable the service
+if it is running, disable the service in <tt>/etc/rc.conf</tt> or remove the
+service startup from the <tt>/etc/rc.*</tt> scripts and 
+<a href="faq.html#tell">tell runsvdir</a> about the new service.
+<hr>
+
+<a name="macosx"><h2>Replacing init on MacOSX</h2></a>
+Replacing init on MacOSX is not yet supported.
+Please refer to the <a href="useinit.html">instructions</a> on how to use
+<i>runit</i> service supervision with the MacOSX init scheme.
+<hr>
+
+<a name="solaris"><h2>Replacing init on Solaris</h2></a>
+Replacing init on Solaris is not yet supported.
+Please refer to the <a href="useinit.html">instructions</a> on how to use
+<i>runit</i> service supervision with the Solaris sysvinit scheme.
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/runit-init.8.html b/runit-2.1.2/doc/runit-init.8.html
new file mode 100644
index 0000000..014d2f1
--- /dev/null
+++ b/runit-2.1.2/doc/runit-init.8.html
@@ -0,0 +1,60 @@
+
+
+
+<html>
+<head>
+<title>runit-init(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+init - a UNIX process no 1 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>init</b> [ 0 | 6 ] 
+<h2><a name='sect2'>Description</a></h2>
+<b>runit-init</b>
+is the first process the kernel starts. If <b>runit-init</b> is started as process
+no 1, it runs and replaces itself with <i><b>runit</b>(8)</i>. <p>
+If <b>runit-init</b> is started
+while the system is up, it must be either called as <b>init 0</b> or <b>init 6:</b> 
+<dl>
+
+<dt><b>init
+0</b> </dt>
+<dd>tells the Unix process no 1 to shutdown and halt the system. To signal
+<i><b>runit</b>(8)</i> the system halt request, <b>runit-init</b> removes all permissions of
+the file <i>/etc/runit/reboot</i> (chmod 0), and sets the execute by owner permission
+of the file <i>/etc/runit/stopit</i> (chmod 100). Then a CONT signal is sent to
+<i><b>runit</b>(8)</i>. </dd>
+
+<dt><b>init 6</b> </dt>
+<dd>tells the Unix process no 1 to shutdown and reboot the
+system. To signal <i><b>runit</b>(8)</i> the system reboot request, <b>runit-init</b> sets the
+execute by owner permission of the files <i>/etc/runit/reboot</i> and <i>/etc/runit/stopit</i>
+(chmod 100). Then a CONT signal is sent to <i><b>runit</b>(8)</i>. </dd>
+</dl>
+
+<h2><a name='sect3'>Exit Codes</a></h2>
+<b>runit-init</b>
+returns 111 on error, 0 in all other cases. 
+<h2><a name='sect4'>See Also</a></h2>
+<i>runit(8)</i>, <i>runsvdir(8)</i>,
+<i>runsvchdir(8)</i>, <i>sv(8)</i>, <i>runsv(8)</i>, <i>chpst(8)</i>, <i>utmpset(8)</i>, <i>svlogd(8)</i> <p>
+<i>http://smarden.org/runit/</i>
+
+<h2><a name='sect5'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt; <p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Exit Codes</a></li>
+<li><a name='toc4' href='#sect4'>See Also</a></li>
+<li><a name='toc5' href='#sect5'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/runit.8.html b/runit-2.1.2/doc/runit.8.html
new file mode 100644
index 0000000..6c46b39
--- /dev/null
+++ b/runit-2.1.2/doc/runit.8.html
@@ -0,0 +1,74 @@
+
+
+
+<html>
+<head>
+<title>runit(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+runit - a UNIX process no 1 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>runit</b> 
+<h2><a name='sect2'>Description</a></h2>
+<b>runit</b> must be run
+as Unix process no 1. It performs the system&rsquo;s booting, running, and shutdown
+in three stages: 
+<h2><a name='sect3'>Stage 1</a></h2>
+<b>runit</b> runs <i>/etc/runit/1</i> and waits for it to terminate.
+The system&rsquo;s one time tasks are done here. <i>/etc/runit/1</i> has full control
+of <i>/dev/console</i> to be able to start an emergency shell if the one time
+initialization tasks fail. If <i>/etc/runit/1</i> crashes, or exits 100, <b>runit</b>
+will skip stage 2 and enter stage 3. 
+<h2><a name='sect4'>Stage 2</a></h2>
+<b>runit</b> runs <i>/etc/runit/2</i>, which
+should not return until system shutdown; if it crashes, or exits 111, it
+will be restarted. Normally <i>/etc/runit/2</i> starts <i><b>runsvdir</b>(8)</i>. <b>runit</b> is able
+to handle the ctrl-alt-del keyboard request in stage 2, see below. 
+<h2><a name='sect5'>Stage 3</a></h2>
+If
+<b>runit</b> is told to shutdown the system, or stage 2 returns, it terminates
+stage 2 if it is running, and runs <i>/etc/runit/3</i>. The systems tasks to shutdown
+and possibly halt or reboot the system are done here. If stage 3 returns,
+<b>runit</b> checks if the file <i>/etc/runit/reboot</i> exists and has the execute by
+owner permission set. If so, the system is rebooted, it&rsquo;s halted otherwise.
+
+<h2><a name='sect6'>Ctrl-alt-del</a></h2>
+If <b>runit</b> receives the ctrl-alt-del keyboard request and the file
+<i>/etc/runit/ctrlaltdel</i> exists and has the execute by owner permission set,
+<b>runit</b> runs <i>/etc/runit/ctrlaltdel</i>, waits for it to terminate, and then sends
+itself a CONT signal. 
+<h2><a name='sect7'>Signals</a></h2>
+<b>runit</b> only accepts signals in stage 2. <p>
+If <b>runit</b>
+receives a CONT signal and the file <i>/etc/runit/stopit</i> exists and has the
+execute by owner permission set, <b>runit</b> is told to shutdown the system. <p>
+if
+<b>runit</b> receives an INT signal, a ctrl-alt-del keyboard request is triggered.
+
+<h2><a name='sect8'>See Also</a></h2>
+<i>runit-init(8)</i>, <i>runsvdir(8)</i>, <i>runsvchdir(8)</i>, <i>sv(8)</i>, <i>runsv(8)</i>, <i>chpst(8)</i>,
+<i>utmpset(8)</i>, <i>svlogd(8)</i> <p>
+<i>http://smarden.org/runit/</i> 
+<h2><a name='sect9'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt;
+<p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Stage 1</a></li>
+<li><a name='toc4' href='#sect4'>Stage 2</a></li>
+<li><a name='toc5' href='#sect5'>Stage 3</a></li>
+<li><a name='toc6' href='#sect6'>Ctrl-alt-del</a></li>
+<li><a name='toc7' href='#sect7'>Signals</a></li>
+<li><a name='toc8' href='#sect8'>See Also</a></li>
+<li><a name='toc9' href='#sect9'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/runlevels.html b/runit-2.1.2/doc/runlevels.html
new file mode 100644
index 0000000..c0e49c3
--- /dev/null
+++ b/runit-2.1.2/doc/runlevels.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - runlevels</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - runlevels</h1>
+<hr>
+<a href="#prepare">Prepare runit for using runlevels</a><br>
+<a href="#switch">Switching runlevels</a><br>
+<a href="#create">Creating runlevels</a>
+<hr>
+<a name="prepare"><h3>Prepare runit</h3></a>
+If not yet done, configure your system to use
+<a href="runit.8.html">runit</a> as process no 1 by following the
+<a href="replaceinit.html">instructions</a>.
+<p>
+Create the following directories and symbolic links:
+<pre>
+ # mkdir -p /etc/runit/runsvdir/default
+ # mkdir -p /etc/runit/runsvdir/single
+ # ln -s /etc/sv/getty-5 /etc/runit/runsvdir/single/
+ # ln -s default /etc/runit/runsvdir/current
+</pre>
+Copy the contents of <tt>/service/</tt> to
+<tt>/etc/runit/runsvdir/current/</tt> and replace <tt>/service/</tt>
+with a symbolic link:
+<pre>
+ # cp -pR /service/* /etc/runit/runsvdir/current/
+ # mv -f /service /service.old && \
+     ln -s /etc/runit/runsvdir/current /service
+</pre>
+You have now created two runlevels: <tt>default</tt> and <tt>single</tt>.
+The <tt>current</tt> runlevel is <tt>default</tt>.
+It is safe to remove <tt>/service.old/</tt> if you don't need it anymore.
+<p>
+Finally edit <tt>/etc/runit/2</tt> to set the <tt>default</tt> runlevel when
+stage 2 starts:
+<pre>
+ $ cat /etc/runit/2 
+ #!/bin/sh
+ PATH=/command:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin
+ 
+ <b>runsvchdir default &gt;/dev/null</b>
+ 
+ exec env - PATH=$PATH \
+ runsvdir /service 'log: ...........................................................................................................................................................................................................................................................................................................................................................................................................'
+</pre>
+<hr>
+<a name="switch"><h3>Switching runlevels</h3></a>
+Switching runlevels with <i>runit</i> is done by switching the directory the
+<a href="runsvdir.8.html">runsvdir</a> program is running in.
+This is done by the <a href="runsvchdir.8.html">runsvchdir</a> program, e.g.
+to switch to the <tt>single</tt> user runlevel, do:
+<pre>
+ # runsvchdir single
+</pre>
+To switch back to the <tt>default</tt> runlevel, do:
+<pre>
+ # runsvchdir default
+</pre>
+See <a href="runsvdir.8.html">the runsvdir program</a> for a description of
+what happens when <i>runsvdir</i> sees the directory changed.
+Note that there is no guarantee that all services from the <tt>previous</tt>
+runlevel will stop, the <a href="runsv.8.html">runsv</a> processes have sent
+the service daemons a SIGTERM and wait for them to terminate.
+You can check the status of the <tt>previous</tt> runlevel through
+<tt>/etc/runit/runsvdir/previous/</tt>.
+<hr>
+<a name="create"><h3>Creating new runlevels</h3></a>
+To create a new runlevel, simply create a new directory in
+<tt>/etc/runit/runsvdir/</tt>.
+The name of the directory is the name of the new runlevel.
+The name must not start with a dot and must not be <tt>current</tt>,
+<tt>current.new</tt>, or <tt>previous</tt>, e.g.:
+<pre>
+ # mkdir /etc/runit/runsvdir/maintenance
+</pre>
+Add the services you want to run in the runlevel <tt>maintenance</tt> to the
+newly created directory, e.g.:
+<pre>
+ # ln -s /etc/sv/getty-5 /etc/runit/runsvdir/maintenance/
+ # ln -s /etc/sv/ssh /etc/runit/runsvdir/maintenance/
+ # ln -s /etc/sv/dnscache /etc/runit/runsvdir/maintenance/
+</pre>
+If you want to switch to the runlevel <tt>maintenance</tt>, do:
+<pre>
+ # runsvchdir maintenance
+</pre>
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/runscripts.html b/runit-2.1.2/doc/runscripts.html
new file mode 100644
index 0000000..f832b63
--- /dev/null
+++ b/runit-2.1.2/doc/runscripts.html
@@ -0,0 +1,1058 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - collection of run scripts</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<a href="replaceinit.html">How to replace init</a>
+<hr>
+<h1>runit - collection of run scripts</h1>
+<hr>
+This is a collection of <tt>run</tt> scripts for popular services to have
+them monitored by the
+<a href="http://cr.yp.to/daemontools.html">daemontools</a> or
+<a href="http://smarden.org/runit/">runit</a> package.
+If you have additional run scripts or one of these run scripts works for you on
+an operating system not stated here, please
+<a href="mailto:supervision@list.skarnet.org">let me know</a>. 
+<p>
+Thanks go to the following people for contributing run scripts:
+<small>
+Alessandro Bono, Robin S. Socha, Claus Alboege, Paul Jarc, clemens fischer,
+Jesse Cablek, Lukas Beeler, Thomas Baden, Ralf Hildebrandt, Antonio Dias,
+Erich Schubert, Lang Martin, Tomasz Nidecki, Marek Bartnikowski,
+Thomas Schwinge, Gael Canal, Woon Wai Keen, Richard A Downing, Phil Genera,
+Stefan Karrmann, Kevin Berry, Karl Chen, Sascha Huedepohl, Jason Smith,
+Kevin, marlowe, ed neville, xavier dutoit.
+</small>
+<p>
+See also
+<a href="http://thedjbway.org/services.html">here</a> for some more run
+scripts.
+<hr>
+<a href="#atftpd">atftpd</a><br>
+<a href="#apache">apache</a><br>
+<a href="#apache2">apache2</a><br>
+<a href="#atd">atd</a><br>
+<a href="#bind9">bind9</a><br>
+<a href="#boa">boa</a><br>
+<a href="#cfengine">cfengine</a><br>
+<a href="#cfsd">cfsd</a><br>
+<a href="#chrony">chrony</a><br>
+<a href="#clamav">clamav</a><br>
+<a href="#clamsmtpd">clamsmtpd</a><br>
+<a href="#courier-imap">courier-imap</a><br>
+<a href="#cron">cron</a><br>
+<a href="#cups">cups</a><br>
+<a href="#dhclient">dhclient</a><br>
+<a href="#dhcpcd">dhcpcd</a><br>
+<a href="#dhcpd">dhcpd</a><br>
+<a href="#dictd">dictd</a><br>
+<a href="#dropbear">dropbear</a><br>
+<a href="#exim">exim</a><br>
+<a href="#expireproctitle">expireproctitle</a><br>
+<a href="#fam">fam</a><br>
+<a href="#fcron">fcron</a><br>
+<a href="#fetchmail">fetchmail</a><br>
+<a href="#gdm">gdm</a><br>
+<a href="#getty">getty</a><br>
+<a href="#gpm">gpm</a><br>
+<a href="#hotwayd">hotwayd</a><br>
+<a href="#identd">identd</a><br>
+<a href="#inn">inn</a><br>
+<a href="#jabberd">jabberd</a><br>
+<a href="#junkbuster">junkbuster</a><br>
+<a href="#kdm">kdm</a><br>
+<a href="#keepalived">keepalived</a><br>
+<a href="#klogd">klogd</a><br>
+<a href="#leafnode">leafnode</a><br>
+<a href="#loglinuxkernel">logging Linux kernel messages</a><br>
+<a href="http://multivac.cwru.edu./fdtools/grabconsole/">
+logging console messages</a><br>
+<a href="#mdadm">mdadm</a><br>
+<a href="#minidentd">minidentd</a><br>
+<a href="#mpd">mpd</a><br>
+<a href="#nscd">nscd</a><br>
+<a href="#ntpd">ntpd</a><br>
+<a href="#nullidentd">nullidentd</a><br>
+<a href="#polipo">polipo</a><br>
+<a href="#pop3-ssl">pop3-ssl</a><br>
+<a href="#pop3vscan">pop3vscan</a><br>
+<a href="#portmap">portmap</a><br>
+<a href="#postfix">postfix</a><br>
+<a href="#postgresql">postgresql</a><br>
+<a href="#powernowd">powernowd</a><br>
+<a href="#ppp">ppp</a><br>
+<a href="#privoxy">privoxy</a><br>
+<a href="#proftpd">proftpd</a><br>
+<a href="#pure-ftpd">pure-ftpd</a><br>
+<a href="#radiusd">radiusd</a><br>
+<a href="#rmrtg">rmrtg</a><br>
+<a href="#rsyncd">rsyncd</a><br>
+<a href="#samba">samba (smbd, nmbd)</a><br>
+<a href="#shoutcast">shoutcast</a><br>
+<a href="#spamd">spamd</a><br>
+<a href="#squid">squid</a><br>
+<a href="#sshd">sshd</a><br>
+<a href="#sshdtcpserver">sshd under tcpserver</a><br>
+<a href="#statd">statd</a>, <a href="#mountd">mountd</a><br>
+<a href="#stunnel">stunnel</a><br>
+<a href="#subversion">subversion</a><br>
+<a href="#swat">swat</a><br>
+<a href="#syslogd">syslogd</a><br>
+<a href="#taiclockd">taiclockd</a><br>
+<a href="#tmda-ofmipd">tmda-ofmipd</a><br>
+<a href="#tomcat">tomcat</a><br>
+<a href="#tor">tor</a><br>
+<a href="#vsftpd">vsftpd</a><br>
+<a href="#wvdial">wvdial</a><br>
+<a href="#xdm">xdm</a><br>
+<a href="#xfs">xfs</a><br>
+<hr>
+
+<h3><a name="atftpd">An <tt>atftpd</tt> run script</a></h3>
+(<i>Debian</i>)
+<pre>
+ #!/bin/sh
+ exec in.tftpd --daemon --no-fork --tftpd-timeout 30 \
+   --retry-timeout 5 --no-tsize --no-blksize --no-multicast \
+   --maxthread 1000 --verbose=7 /var/atfpd 2&gt;&amp;1
+</pre>
+<hr>
+<h3><a name="apache">An <tt>apache</tt> run script</a></h3>
+(<i>SunOS</i>, Apache 1.*, patched to run under supervise)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec env -i \
+ /pack/apache/1.3.27-1/sbin/httpd -F 2&gt;&amp;1
+</pre>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec 1&gt;&amp;2
+ exec apache-ssl -F
+</pre>
+<hr>
+<h3><a name="apache2">An <tt>apache2</tt> run script</a></h3>
+(<i>SunOS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec env -i /command/pgrphack \
+ /pack/apache/2.0.43-1/sbin/httpd -DFOREGROUND 2&gt;&amp;1
+</pre>
+(<i>HP-UX/GNU</i>, <i>Linux</i>)
+<pre>
+ #!/bin/sh
+ TZ=MET-1METDST
+ export TZ
+ exec /usr/local/apache2/bin/httpd -DNO_DETACH
+</pre>
+<hr>
+<h3><a name="atd">An <tt>atd</aa> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec atd -d
+</pre>
+<hr>
+<h3><a name="bind9">A <tt>bind9</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ MEM="`head -1 ./env/MEM`"
+ CHROOT="`head -1 ./env/CHROOT`"
+ exec softlimit -m "${MEM}" \
+   named -u bind -t "${CHROOT}" -g 2&gt;&amp;1
+</pre>
+(<i>HP-UX/GNU</i>, <i>Linux</i>)
+<pre>
+ #!/bin/sh
+ exec named -f -t /var/spool/named/ -u named
+</pre>
+<hr>
+<h3><a name="boa">A <tt>boa</tt> run script</a></h3>
+(<i>SunOS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ ulimit -n 1024
+ exec /pack/boa/current/boa -c /pack/boa/current -d 2&gt;&amp;1
+</pre>
+<hr>
+<h3><a name="cfengine">A <tt>cfengine</tt> run script</a></h3>
+(<i>SunOS</i>)
+<pre>
+ #!/bin/sh
+ /pack/cfengine/sbin/cfagent --file /pack/cfengine/etc/cfagent.conf \
+   -L -v -q exec sleep 3600
+</pre>
+<hr>
+<h3><a name="cfsd">A <tt>cfsd</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ 
+ set -e
+ 
+ PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+ DAEMON=cfsd
+ CONFIG_FILE=/etc/cfs.conf
+ 
+ # source config file
+ test ! -r "$CONFIG_FILE" || . "$CONFIG_FILE"
+ 
+ test -n "$CRYPT_ROOT" || exit 0
+ test -n "$NULL_EXPORT" || exit 0
+ test -n "$CFS_MOUNT" || exit 0
+ test -n "$CFS_UMOUNT" || exit 0
+ 
+ sv start portmap || exit 1
+ 
+ exec env \
+    NODAEMON=1 CFS_MOUNT="$CFS_MOUNT" CFS_UMOUNT="$CFS_UMOUNT" $DAEMON
+</pre>
+<hr>
+<h3><a name="chrony">A <tt>chrony</tt> run script</a></h3>
+(<i>LFS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec chronyd -d -r -s
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="clamav">A <tt>clamd</tt> run script</a></h3>
+(<i>RedHat 7</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec setuidgid clamav softlimit -a 40000000 clamd
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="clamsmtpd">A <tt>clamsmtpd</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec chpst -uclamav clamsmtpd -d 3
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="courier-imap">A <tt>courier-imap</tt> run script</a></h3>
+(<i>SunOS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ PREFIX="/usr/lib/courier-imap"
+ exec envdir ./env \
+   tcpserver -v -R 0 143 \
+   $PREFIX/sbin/imaplogin \
+   $PREFIX/libexec/authlib/authshadow \
+   $PREFIX/libexec/authlib/authvchkpw \
+   $PREFIX/bin/imapd Maildir
+</pre>
+See also <a href="http://jonaspasche.de/courier-imap-daemontools.txt">
+this page</a>.
+<hr>
+<h3><a name="cron">A <tt>cron</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec cron -f -l
+</pre>
+<hr>
+<h3><a name="cups">A <tt>cups</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec cupsd -f
+</pre>
+<hr>
+<h3><a name="dhclient">A <tt>dhclient</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec dhclient -e -d -cf ./config -lf ./leases -pf ./pid eth1
+</pre>
+<hr>
+<h3><a name="dhcpcd">A <tt>dhcpcd</tt> run script</a></h3>
+(<i>Linux</i>, DHCP Client Daemon v.scriptconfig-0.1)
+<pre>
+ #!/bin/sh
+ exec dhcpcd -a -d -D -H eth0
+</pre>
+<hr>
+<h3><a name="dhcpd">A <tt>dhcpd</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec dhcpd-2.2.x -f -d -cf ./config eth0
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<p>
+(<i>Solaris 8</i>, uses additional dsvclockd service, would get fired off
+automatically, but then it's not supervised)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec envdir ./env /usr/lib/inet/dsvclockd -f
+</pre>
+<pre>
+ #!/bin/sh
+ if svok /service/dsvclockd; then
+   sleep 2 # wait to make sure dsvclockd is initialized
+   exec 2&gt;&amp;1
+   exec envdir ./env /usr/lib/inet/in.dhcpd -b manual -d # -v
+ fi
+ echo dsvclockd is not running - aborting
+ exec /usr/bin/sleep 5
+</pre>
+The in.dhcpd service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="dictd">A <tt>dictd</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec dictd -d nodetach
+</pre>
+<hr>
+<h3><a name="dropbear">A <tt>dropbear</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec dropbear -F -E -p 22
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<p>
+(<i>Linux</i>, running under
+<a href="http://smarden.org/ipsvd/tcpsvd.8.html">tcpsvd</a>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec tcpsvd -v -i./peers 0 22 dropbear -i -E
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="exim">An <tt>exim</tt> run script</a></h3>
+(<i>Linux</i>, <i>FreeBSD</i>)
+<pre>
+ #!/bin/sh
+ exec /usr/local/sbin/exim -bdf -q30m
+</pre>
+<hr>
+<h3><a name="expireproctitle">
+<tt>expireproctitle</tt> run script examples</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ echo -n .
+ exec sleep 300
+</pre>
+<hr>
+<h3><a name="fam">A <tt>fam</tt> run script</a></h3>
+(<i>Slackware Linux 9.0</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec fam -L -f -v
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<p>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ sv start /service/portmap || exit 1
+ exec famd -T 0 -f
+</pre>
+<hr>
+<h3><a name="postfix">A postfix <tt>master</tt> run script</a></h3>
+(<i>Debian etch</i>)
+<pre>
+ #!/bin/sh
+ exec 1>&2
+ 
+ daemon_directory=/usr/lib/postfix \
+ command_directory=/usr/sbin \
+ config_directory=/etc/postfix \
+ queue_directory=/var/spool/postfix \
+ mail_owner=postfix \
+ setgid_group=postdrop \
+   /etc/postfix/postfix-script check || exit 1
+ 
+ exec /usr/lib/postfix/master
+</pre>
+<hr>
+<h3><a name="fcron">A <tt>fcron</tt> run script</a></h3>
+(<i>LFS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec fcron -f -y
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="fetchmail">A <tt>fetchmail</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ INTERVAL=551
+ exec 2>&1
+ echo "*** Starting fetchmail service..."
+ exec env FETCHMAILHOME="./pid" \
+   chpst -u fetchmail fetchmail -v \
+     -f ./fetchmail.conf \
+     --nodetach \
+     --daemon ${INTERVAL}
+</pre>
+<hr>
+<h3><a name="gdm">A <tt>gdm</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec gdm -nodaemon
+</pre>
+<hr>
+<h3><a name="getty">A <tt>mingetty</tt> run script</a></h3>
+(<i>Debian</i>)
+<pre>
+ #!/bin/sh
+ exec mingetty tty5
+</pre>
+The <a href="index.html">runit</a> package does not care about utmp records
+for getties. You should choose a getty that handles its own utmp and wtmp
+records.
+Debian's <tt>mingetty</tt> creates its own utmp record.
+<h3>An <tt>agetty</tt> run script</h3>
+(<i>Slackware Linux 9.0</i>)
+<pre>
+ #!/bin/sh
+ exec agetty 38400 tty1 linux
+</pre>
+<h3>A <tt>fgetty</tt> run script</h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ exec chpst -P fgetty tty4
+</pre>
+The <a href="runsv.8.html">runsv</a> program does not automatically create
+a new session and separate process group for run scripts, which can
+cause some <i>getties</i> to fail due to limited permissions.
+The <a href="chpst.8.html">chpst</a> program can be used to alter the
+process state for those <i>getties</i>.
+<hr>
+<h3><a name="gpm">A <tt>gpm</tt> run script</a></h3>
+(<i>LFS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ . /etc/sysconfig/mouse
+ exec gpm -D -m $MDEVICE -t $PROTOCOL
+</pre>
+<hr>
+<h3><a name="hotwayd">A <tt>hotwayd</tt> run script</a></h3>
+(<i>LFS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec tcpsvd -l0 -u nobody 127.0.0.1 110 hotwayd
+</pre>
+<hr>
+<h3><a name="identd">An <tt>oidentd</tt> run script</a></h3>
+(<i>Linux</i>, oidentd version 2.0.6)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec oidentd -i -S -t 10 -u daemon -g daemon
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<p>
+(<i>Debian</i>)
+<pre>
+ #!/bin/sh
+ exec /usr/local/sbin/oidentd --nosyslog -i -u ident -g ident -l 15 -m \
+   -C /etc/oidentd/oidentd.conf 2&gt;&amp;1
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="inn">An <tt>innd</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ MEM="`head -1 ./env/MEM`"
+ exec softlimit -m "${MEM}" \
+   setuidgid news \
+   /usr/sw/bin/news/inndstart -f -r
+</pre>
+<hr>
+<h3><a name="jabberd"><tt>jabberd</tt> run scripts</a></h3>
+(<i>RedHat 7</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ if [ -f /usr/local/jabber/jabber.pid ]; then
+   rm /usr/local/jabber/jabber.pid
+ fi
+ exec setuidgid jabberd \
+   /usr/local/jabber/jabberd/jabberd -D -c /etc/jabber.xml
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ sleep 5 # so that jit starts after jabberd is up
+ exec setuidgid jabberd \
+   /usr/local/jabber/jit/jabberd/jabberd -c /etc/jit.xml
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="junkbuster">A <tt>junkbuster</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ DAEMON=junkbuster
+ exec "$DAEMON" /etc/junkbuster/config
+</pre>
+<hr>
+<h3><a name="kdm">A <tt>kdm</tt> run script</a></h3>
+(<i>Debian sid</i>, <i>FreeBSD 5.3-REL</i>)
+<pre>
+ #!/bin/sh
+ sv start /service/getty-* || exit 1
+ exec kdm -nodaemon
+</pre>
+<hr>
+<h3><a name="keepalived">A <tt>keepalived</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec keepalived -n
+</pre>
+<hr>
+<h3><a name="klogd">A <tt>klogd</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec klogd -n
+</pre>
+<hr>
+<h3><a name="leafnode">A <tt>leafnode</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec envuidgid news \
+   tcpserver -v -x rules.cdb -c 10 -U 0 119 \
+   leafnode
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="loglinuxkernel">
+A run script for <tt>logging Linux kernel messages with multilog</tt></a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh -e
+ exec &lt; /proc/kmsg \
+ setuidgid loguser \
+ multilog t n64 ./main
+</pre>
+<hr>
+<h3><a name="mdadm">A <tt>mdadm</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ DEBIANCONFIG=/etc/default/mdadm
+ MAIL_TO=root
+ test -f $DEBIANCONFIG && . $DEBIANCONFIG
+ exec mdadm --monitor --scan --mail $MAIL_TO
+</pre>
+<hr>
+<h3><a name="minidentd">A <tt>minidentd</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec envuidgid nobody \
+   tcpserver -vUR 0 113 \
+   timeoutafter 60 \
+   minidentd -v
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="mpd">A <tt>mpd</tt> run script</a></h3>
+(<i>Debian sid</i>, <i>FreeBSD 5.3-REL</i>)
+<pre>
+ #!/bin/sh
+ MPDCONF=/etc/mpd.conf
+ exec mpd --stdout --no-daemon $MPDCONF
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="nscd">A <tt>nscd</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ secure=""
+ for table in passwd group
+   do
+     if egrep '^'$table':.*nisplus' /etc/nsswitch.conf >/dev/null
+       then
+         nscd_nischeck $table || secure="$secure -S $table,yes"
+     fi
+ done
+ exec nscd -d -- $secure
+</pre>
+<hr>
+<h3><a name="ntpd">A <tt>ntpd</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ MEM=`head -1 ./env/MEM`
+ exec softlimit -m "${MEM}" \
+   ntpd -n
+</pre>
+(<i>OpenNTPD on OpenBSD/Linux</i>)
+<pre>
+ #!/bin/sh
+ exec /usr/sbin/ntpd -s -d 2>&1
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="nullidentd">A <tt>nullidentd</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec tcpsvd -u nobody -x nullidentd-cdb -t 60 0 113 nullidentd
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="polipo">A <tt>polipo</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec setuidgid polipo \
+   polipo -c config forbiddenFile="`pwd`"/forbidden diskCacheRoot="`pwd`"/cache
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="pop3-ssl">A <tt>pop3-ssl</tt> run script</a></h3>
+(<i>BSD</i>)
+<pre>
+ #!/bin/sh
+ exec tcpserver -R -v -c 50 0 995 /usr/local/sbin/stunnel
+ -f  -p /etc/ssl/stunnel.pem \
+ -l /var/qmail/bin/qmail-popup -- /var/qmail/bin/qmail-popup
+ "`cat /var/qmail/control/me`" vchkpw /var/qmail/bin/qmail-pop3d Maildir 2&gt;&amp;1
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="pop3vscan">A <tt>pop3vscan</tt> run script</a></h3>
+(<i>RedHat 7</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec setuidgid pop3vscan pop3vscan -d
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="portmap">A <tt>portmap</tt> run script</a></h3>
+(<i>LFS</i>, <i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec portmap -d
+</pre>
+<hr>
+<h3><a name="postgresql">A <tt>postgresql</tt> run script</a></h3>
+(<i>Debian</i>, <i>SunOS</i>)
+<pre>
+ #!/bin/sh
+ exec setuidgid postgres /usr/lib/postgresql/bin/postmaster \
+   -D /var/lib/postgres/data 2&gt;&amp;1
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="powernowd">A <tt>powernowd</tt> run script</a></h3>
+(<i>Debian</i>)
+<pre>
+ #!/bin/sh
+ set -e  # barf if modprobe fails
+ modprobe cpufreq-userspace
+ test ! -f /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ||
+   exec /usr/sbin/powernowd -d
+ 
+ echo "required sysfs objects not found!"
+ echo "Read /usr/share/doc/powernowd/README.Debian for more information."
+ sv down "$(pwd)"
+</pre>
+<hr>
+<h3><a name="ppp">A <tt>ppp</tt> run script</a></h3>
+(<i>FreeBSD</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ echo "ppp -ddial dsl "
+ exec ppp -unit0 -foreground dsl
+</pre>
+<h3>A <tt>pppd</tt> run script</h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec chpst -P pppd call isp nodetach
+</pre>
+<hr>
+<h3><a name="privoxy">A <tt>privoxy</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec chpst -u privoxy:nogroup privoxy --no-daemon /etc/privoxy/config
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="proftpd">A <tt>proftpd</tt> run script</a></h3>
+(<i>Linux</i>, ProFTPD Version 1.2.8rc1,
+configure it to use 'ErrorLog "/dev/stdout"')
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec proftpd -n -d 1
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="pure-ftpd">A <tt>pure-ftpd</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec pure-ftpd -a 50 -E -l pam -u 100
+</pre>
+<hr>
+<h3><a name="radiusd">A <tt>radiusd</tt> run script</a></h3>
+(<i>Slackware Linux 9.0</i>, cistron radius 1.6.1)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec radiusd -f -y -z -lstdout
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="rmrtg">A <tt>rmrtg</tt> run script</a></h3>
+()
+<pre>
+ #!/bin/sh
+ MRTGUID=`id -u mrtg`
+ MRTGGID=`id -g mrtg`
+ exec 2&gt;&amp;1
+ exec tcpserver -l 0 -R -H -q \
+   -u"${MRTGUID}" -g"${MRTGGID}" 0 5660 /home/mrtg/ext/rmrtg
+</pre>
+<hr>
+<h3><a name="rsyncd">A <tt>rsyncd</tt> run script</a></h3>
+(<i>SunOS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec softlimit -d 100000000 tcpserver \
+   -x /pack/rsync/rsync.service/tcp.rsync.cdb -v -c 100 -U -H -l 0 -R \
+   1.2.3.4 873 nice -2 /pack/rsync/bin/rsync --daemon --no-detach \
+   --config /pack/rsync/etc/rsyncd.conf
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="samba">A <tt>smbd</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ PATH="/usr/local/samba/bin"
+ exec 2&gt;&amp;1
+ exec smbd -F -S -d3
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<h3>A <tt>nmbd</tt> run script</h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ PATH="/usr/local/samba/bin"
+ exec 2&gt;&amp;1
+ exec nmbd -F -S -d1
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="shoutcast">A <tt>shoutcast</tt> run script</a></h3>
+(<i>RedHat 7</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec setuidgid sc_serv \
+   /usr/local/sc_serv/bin/sc_serv /etc/sc_serv.conf
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="spamd">A <tt>spamd</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec spamd -m 20 -a -H -s stderr 2&gt;&amp;1
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="squid">A <tt>squid</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec squid -f ./config -sN
+</pre>
+<hr>
+<h3><a name="sshd">A <tt>sshd</tt> run script</a></h3>
+(<i>Debian</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec /usr/sbin/sshd -D -e
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="sshdtcpserver">
+A <tt>sshd (under tcpserver)</tt> run script</a></h3>
+(<i>Linux</i>, sshd version OpenSSH_3.4p1)
+<pre>
+ #!/bin/sh -e
+ exec 2&gt;&amp;1
+ exec \
+ tcpserver -1vpdl0 -Xxtcp.cdb 0 ssh \
+ sshd -ief config
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="statd">A <tt>statd</tt> run script</a></h3>
+(<i>Debian woody</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ NEED_LOCKD=yes
+ if test -f /proc/ksyms; then
+   # We need to be conservative and run lockd,
+   # unless we can prove that it isn't required.
+   grep -q lockdctl /proc/ksyms || NEED_LOCKD=no
+ fi
+ if [ "$NEED_LOCKD" = yes ]; then
+   rpc.lockd
+ fi
+ exec rpc.statd -F -d
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<h3><a name="mountd">A <tt>mountd</tt> run script</a></h3>
+(<i>Debian</i>)
+<pre>
+ #!/bin/sh
+ sv start portmap statd || exit 1
+ RPCNFSDCOUNT=8  # Number of servers to be started up by default
+ RPCMOUNTDOPTS=
+ 
+ trap '/usr/bin/killall -2 nfsd' 0
+ trap 'exit 2' 1 2 3 15
+ 
+ exportfs -r
+ rpc.nfsd -- $RPCNFSDCOUNT
+ rpcinfo -u localhost nfs 3 &gt;/dev/null 2&gt;&amp;1 ||
+   RPCMOUNTDOPTS="$RPCMOUNTDOPTS --no-nfs-version 3"
+ exec rpc.mountd -F $RPCMOUNTDOPTS
+</pre>
+<hr>
+<h3><a name="stunnel">A <tt>stunnel</tt> run script</a></h3>
+(<i>BSD</i>)
+<pre>
+ #!/bin/sh
+ exec /usr/local/sbin/stunnel -f -d 1234 -r 25 -v3 -a /etc/ssl/mailcerts 2&gt;&amp;1
+</pre>
+<hr>
+<h3><a name="subversion">A <tt>svnserve</tt> run script</a></h3>
+(<i>Debian</i>)
+<pre>
+ #!/bin/sh
+ exec 2>&1
+ exec /usr/bin/svnserve -d --foreground
+</pre>
+<hr>
+<h3><a name="swat">A <tt>swat</tt> run script</a></h3>
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec tcpsvd -l0 127.0.0.1 901 swat
+</pre>
+<hr>
+<h3><a name="syslogd">A <tt>syslogd</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec syslogd -n
+</pre>
+<hr>
+<h3><a name="taiclockd">A <tt>taiclockd</tt> run script</a></h3>
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec setuidgid taiclock /usr/local/clockspeed/bin/taiclockd
+</pre>
+<hr>
+<h3><a name="tmda-ofmipd">A <tt>tmda-ofmipd</tt> run script</a></h3>
+(<i>RedHat 7</i>)
+<pre>
+ #!/bin/sh
+ exec /usr/local/tmda/bin/tmda-ofmipd -f -d -R pop3 -p my.host.name:8025 2&gt;&amp;1
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="tomcat">A <tt>tomcat</tt> run script</a></h3>
+(<i>SunOS</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec \
+ setuidgid apache \
+ /pack/tomcat/current/bin/catalina.sh run
+</pre>
+<hr>
+<h3><a name="tor">A <tt>tor</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec chpst -P -u debian-tor:debian-tor tor
+</pre>
+<hr>
+<h3><a name="vsftpd">A <tt>vsftpd</tt> run script</a></h3>
+(<i>RedHat 7</i>)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec tcpserver -c30 -Xv -llocalhost \
+   -x/etc/tcp.ftp.cdb -uvsftpd -gvsftpd 0 ftp \
+     softlimit -d300000 /var/vsftpd/bin/vsftpd
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="wvdial">A <tt>wvdial</tt> run script</a></h3>
+(<i>Slackware Linux 9.0</i>, the service should have a <tt>down</tt>
+file, use <tt>svc -o /service/wvdial</tt> to bring up a ppp connection)
+<pre>
+ #!/bin/sh
+ exec 2&gt;&amp;1
+ exec wvdial ISP
+</pre>
+This service needs a
+<a href="faq.html#createlog">log service</a>
+to be set up.
+<hr>
+<h3><a name="xdm">A <tt>xdm</tt> run script</a></h3>
+(<i>Linux</i>)
+<pre>
+ #!/bin/sh
+ sv start /service/vc-* || exit 1
+ exec xdm -nodaemon
+</pre>
+<hr>
+<h3><a name="xfs">A <tt>xfs</tt> run script</a></h3>
+(<i>Debian sarge</i>)
+<pre>
+ #!/bin/sh
+ SOCKET_DIR=/tmp/.font-unix
+ mkdir -p $SOCKET_DIR
+ chown 0:0 $SOCKET_DIR
+ chmod 1777 $SOCKET_DIR
+ exec /usr/bin/X11/xfs -nodaemon
+</pre>
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/runsv.8.html b/runit-2.1.2/doc/runsv.8.html
new file mode 100644
index 0000000..d27deeb
--- /dev/null
+++ b/runit-2.1.2/doc/runsv.8.html
@@ -0,0 +1,157 @@
+
+
+
+<html>
+<head>
+<title>runsv(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+runsv - starts and monitors a service and optionally an appendant log
+service 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>runsv</b> <i>service</i> 
+<h2><a name='sect2'>Description</a></h2>
+<i>service</i> must be a directory. <p>
+<b>runsv</b>
+switches to the directory <i>service</i> and starts ./run. If ./run exits and ./finish
+exists, <b>runsv</b> starts ./finish. If ./finish doesn&rsquo;t exist or ./finish exits,
+<b>runsv</b> restarts ./run. <p>
+If ./run or ./finish exit immediately, <b>runsv</b> waits a
+second before starting ./finish or restarting ./run. <p>
+Two arguments are given
+to ./finish. The first one is ./run&rsquo;s exit code, or -1 if ./run didn&rsquo;t exit normally.
+The second one is the least significant byte of the exit status as determined
+by <i><b>waitpid</b>(2)</i>; for instance it is 0 if ./run exited normally, and the signal
+number if ./run was terminated by a signal. If <b>runsv</b> cannot start ./run for
+some reason, the exit code is 111 and the status is 0. <p>
+If the file <i>service</i>/down
+exists, <b>runsv</b> does not start ./run immediately. The control interface (see
+below) can be used to start the service and to give other commands to <b>runsv</b>.
+<p>
+If the directory <i>service</i>/log exists, <b>runsv</b> creates a pipe, redirects <i>service</i>/run&rsquo;s
+and <i>service</i>/finish&rsquo;s standard output to the pipe, switches to the directory
+<i>service</i>/log and starts ./run (and ./finish) exactly as described above for
+the <i>service</i> directory. The standard input of the log service is redirected
+to read from the pipe. <p>
+<b>runsv</b> maintains status information in a binary format
+(compatible to the daemontools&rsquo; <b>supervise</b> program) in <i>service</i>/supervise/status
+and <i>service</i>/log/supervise/status, and in a human-readable format in <i>service</i>/supervise/stat,
+<i>service</i>/log/supervise/stat, <i>service</i>/supervise/pid, <i>service</i>/log/supervise/pid.
+
+<h2><a name='sect3'>Control</a></h2>
+The named pipes <i>service</i>/supervise/control, and (optionally) <i>service</i>/log/supervise/control
+are provided to give commands to <b>runsv</b>. You can use <i><b>sv</b>(8)</i> to control the
+service or just write one of the following characters to the named pipe:
+
+<dl>
+
+<dt><b>u</b> </dt>
+<dd>Up. If the service is not running, start it. If the service stops, restart
+it. </dd>
+
+<dt><b>d</b> </dt>
+<dd>Down. If the service is running, send it a TERM signal, and then a
+CONT signal. If ./run exits, start ./finish if it exists. After it stops, do
+not restart service. </dd>
+
+<dt><b>o</b> </dt>
+<dd>Once. If the service is not running, start it. Do not
+restart it if it stops. </dd>
+
+<dt><b>p</b> </dt>
+<dd>Pause. If the service is running, send it a STOP
+signal. </dd>
+
+<dt><b>c</b> </dt>
+<dd>Continue. If the service is running, send it a CONT signal. </dd>
+
+<dt><b>h</b> </dt>
+<dd>Hangup.
+If the service is running, send it a HUP signal. </dd>
+
+<dt><b>a</b> </dt>
+<dd>Alarm. If the service
+is running, send it a ALRM signal. </dd>
+
+<dt><b>i</b> </dt>
+<dd>Interrupt. If the service is running,
+send it a INT signal. </dd>
+
+<dt><b>q</b> </dt>
+<dd>Quit. If the service is running, send it a QUIT signal. </dd>
+
+<dt><b>1</b> </dt>
+<dd>User-defined 1. If the service is running, send it a USR1 signal. </dd>
+
+<dt><b>2</b> </dt>
+<dd>User-defined 2. If the service is running, send it a USR2 signal. </dd>
+
+<dt><b>t</b> </dt>
+<dd>Terminate. If the service
+is running, send it a TERM signal. </dd>
+
+<dt><b>k</b> </dt>
+<dd>Kill. If the service is running, send
+it a KILL signal. </dd>
+
+<dt><b>x</b> </dt>
+<dd>Exit. If the service is running, send it a TERM signal,
+and then a CONT signal. Do not restart the service. If the service is down,
+and no log service exists, <b>runsv</b> exits. If the service is down and a log
+service exists, <b>runsv</b> closes the standard input of the log service, and
+waits for it to terminate. If the log service is down, <b>runsv</b> exits. This
+command is ignored if it is given to <i>service</i>/log/supervise/control. </dd>
+</dl>
+<p>
+Example:
+to send a TERM signal to the socklog-unix service, either do   # sv term
+/service/socklog-unix<br>
+  or<br>
+   # printf t &gt;/service/socklog-unix/supervise/control<br>
+ <p>
+<i><b>printf</b>(1)</i> usually blocks if no <b>runsv</b> process is running in the service
+directory. 
+<h2><a name='sect4'>Customize Control</a></h2>
+For each control character <i>c</i> sent to the control
+pipe, <b>runsv</b> first checks if <i>service</i>/control/<i>c</i> exists and is executable.
+If so, it starts <i>service</i>/control/<i>c</i> and waits for it to terminate, before
+interpreting the command. If the program exits with return code 0, <b>runsv</b>
+refrains from sending the service the corresponding signal. The command
+<i>o</i> is always considered as command <i>u</i>. On command <i>d</i> first <i>service</i>/control/<i>t</i>
+is checked, and then <i>service</i>/control/<i>d</i>. On command <i>x</i> first <i>service</i>/control/<i>t</i>
+is checked, and then <i>service</i>/control/<i>x</i>. The control of the optional log
+service cannot be customized. 
+<h2><a name='sect5'>Signals</a></h2>
+If <b>runsv</b> receives a TERM signal, it
+acts as if the character x was written to the control pipe. 
+<h2><a name='sect6'>Exit Codes</a></h2>
+<b>runsv</b>
+exits 111 on an error on startup or if another <b>runsv</b> is running in <i>service</i>.
+<p>
+<b>runsv</b> exits 0 if it was told to exit. 
+<h2><a name='sect7'>See Also</a></h2>
+<i>sv(8)</i>, <i>chpst(8)</i>, <i>svlogd(8)</i>,
+<i>runit(8)</i>, <i>runit-init(8)</i>, <i>runsvdir(8)</i>, <i>runsvchdir(8)</i>, <i>utmpset(8)</i> <p>
+<i>http://smarden.org/runit/</i>
+
+<h2><a name='sect8'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt; <p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Control</a></li>
+<li><a name='toc4' href='#sect4'>Customize Control</a></li>
+<li><a name='toc5' href='#sect5'>Signals</a></li>
+<li><a name='toc6' href='#sect6'>Exit Codes</a></li>
+<li><a name='toc7' href='#sect7'>See Also</a></li>
+<li><a name='toc8' href='#sect8'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/runsvchdir.8.html b/runit-2.1.2/doc/runsvchdir.8.html
new file mode 100644
index 0000000..54e66a5
--- /dev/null
+++ b/runit-2.1.2/doc/runsvchdir.8.html
@@ -0,0 +1,52 @@
+
+
+
+<html>
+<head>
+<title>runsvchdir(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+runsvchdir - change services directory of <i>runsvdir(8)</i> 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>runsvchdir</b>
+<i>dir</i> 
+<h2><a name='sect2'>Description</a></h2>
+<i>dir</i> is a services directory for the use with <i><b>runsvdir</b>(8)</i>.
+If <i>dir</i> does not start with a slash, it is searched in /etc/runit/runsvdir/.
+<i>dir</i> must not start with a dot. <p>
+<b>runsvchdir</b> switches to the directory <i>/etc/runit/runsvdir/</i>,
+copies <i>current</i> to <i>previous</i>, and replaces <i>current</i> with a symlink pointing
+to <i>dir</i>. <p>
+Normally  <i>/service</i> is a symlink to <i>current</i>, and <i><b>runsvdir</b>(8)</i> is running
+<i>/service/</i>. 
+<h2><a name='sect3'>Exit Codes</a></h2>
+<b>runsvchdir</b> prints an error message and exits 111 on
+error. <b>runsvchdir</b> exits 0 on success. 
+<h2><a name='sect4'>Files</a></h2>
+ /etc/runit/runsvdir/previous<br>
+  /etc/runit/runsvdir/current<br>
+  /etc/runit/runsvdir/current.new<br>
+ 
+<h2><a name='sect5'>See Also</a></h2>
+<i>runsvdir(8)</i>, <i>runit(8)</i>, <i>runit-init(8)</i>, <i>sv(8)</i>, <i>runsv(8)</i> <p>
+<i>http://smarden.org/runit/</i>
+
+<h2><a name='sect6'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt; <p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Exit Codes</a></li>
+<li><a name='toc4' href='#sect4'>Files</a></li>
+<li><a name='toc5' href='#sect5'>See Also</a></li>
+<li><a name='toc6' href='#sect6'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/runsvdir.8.html b/runit-2.1.2/doc/runsvdir.8.html
new file mode 100644
index 0000000..f4053db
--- /dev/null
+++ b/runit-2.1.2/doc/runsvdir.8.html
@@ -0,0 +1,73 @@
+
+
+
+<html>
+<head>
+<title>runsvdir(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+runsvdir - starts and monitors a collection of <i>runsv(8)</i> processes 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>runsvdir</b>
+[-P] <i>dir</i> [ <i>log</i> ] 
+<h2><a name='sect2'>Description</a></h2>
+<i>dir</i> must be a directory. <i>log</i> is a space holder
+for a readproctitle log, and must be at least seven characters long or
+absent. <p>
+<b>runsvdir</b> starts a <i><b>runsv</b>(8)</i> process for each subdirectory, or symlink
+to a directory, in the services directory <i>dir</i>, up to a limit of 1000 subdirectories,
+and restarts a <i><b>runsv</b>(8)</i> process if it terminates. <b>runsvdir</b> skips subdirectory
+names starting with dots. <i><b>runsv</b>(8)</i> must be in <b>runsvdir</b>&rsquo;s PATH. <p>
+At least every
+five seconds <b>runsvdir</b> checks whether the time of last modification, the
+inode, or the device, of the services directory <i>dir</i> has changed. If so,
+it re-scans the service directory, and if it sees a new subdirectory, or
+new symlink to a directory, in <i>dir</i>, it starts a new <i><b>runsv</b>(8)</i> process; if
+<b>runsvdir</b> sees a subdirectory being removed that was previously there, it
+sends the corresponding <i><b>runsv</b>(8)</i> process a TERM signal, stops monitoring
+this process, and so does not restart the <i><b>runsv</b>(8)</i> process if it exits.
+<p>
+If the <i>log</i> argument is given to <b>runsvdir</b>, all output to standard error
+is redirected to this <i>log</i>, which is similar to the daemontools&rsquo; <b>readproctitle</b>
+log. To see the most recent error messages, use a process-listing tool such
+as <i><b>ps</b>(1)</i>. <b>runsvdir</b> writes a dot to the readproctitle log every 15 minutes
+so that old error messages expire. 
+<h2><a name='sect3'>Options</a></h2>
+
+<dl>
+
+<dt><b>-P</b> </dt>
+<dd>use <i><b>setsid</b>(2)</i> to run each <i><b>runsv</b>(8)</i>
+process in a new session and separate process group. </dd>
+</dl>
+
+<h2><a name='sect4'>Signals</a></h2>
+If <b>runsvdir</b>
+receives a TERM signal, it exits with 0 immediately. <p>
+If <b>runsvdir</b> receives
+a HUP signal, it sends a TERM signal to each <i><b>runsv</b>(8)</i> process it is monitoring
+and then exits with 111. 
+<h2><a name='sect5'>See Also</a></h2>
+<i>sv(8)</i>, <i>runsv(8)</i>, <i>runsvchdir(8)</i>, <i>runit(8)</i>,
+<i>runit-init(8)</i>, <i>chpst(8)</i>, <i>svlogd(8)</i>, <i>utmpset(8)</i>, <i>setsid(2)</i> <p>
+<i>http://smarden.org/runit/</i>
+
+<h2><a name='sect6'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt; <p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Options</a></li>
+<li><a name='toc4' href='#sect4'>Signals</a></li>
+<li><a name='toc5' href='#sect5'>See Also</a></li>
+<li><a name='toc6' href='#sect6'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/sv.8.html b/runit-2.1.2/doc/sv.8.html
new file mode 100644
index 0000000..504b30b
--- /dev/null
+++ b/runit-2.1.2/doc/sv.8.html
@@ -0,0 +1,218 @@
+
+
+
+<html>
+<head>
+<title>sv(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+sv - control and manage services monitored by <i><b>runsv</b>(8)</i> 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>sv</b> [-v]
+[-w <i>sec]</i> <i>command</i> <i>services</i> <p>
+<b>/etc/init.d/</b><i>service</i> [-w <i>sec]</i> <i>command</i> 
+<h2><a name='sect2'>Description</a></h2>
+The
+<b>sv</b> program reports the current status and controls the state of services
+monitored by the <i><b>runsv</b>(8)</i> supervisor. <p>
+<i>services</i> consists of one or more arguments,
+each argument naming a directory <i>service</i> used by <i><b>runsv</b>(8)</i>. If <i>service</i> doesn&rsquo;t
+start with a dot or slash and doesn&rsquo;t end with a slash, it is searched in
+the default services directory <i>/service/</i>, otherwise relative to the current
+directory. <p>
+<i>command</i> is one of up, down, status, once, pause, cont, hup, alarm,
+interrupt, 1, 2, term, kill, or exit, or start, stop, restart, shutdown,
+force-stop, force-reload, force-restart, force-shutdown. <p>
+The <b>sv</b> program can
+be sym-linked to <i>/etc/init.d/</i> to provide an LSB init script interface. The
+<i>service</i> to be controlled then is specified by the base name of the &lsquo;&lsquo;init
+script&rsquo;&rsquo;. 
+<h2><a name='sect3'>Commands</a></h2>
+
+<dl>
+
+<dt><b>status</b> </dt>
+<dd>Report the current status of the service, and the
+appendant log service if available, to standard output. </dd>
+
+<dt><b>up</b> </dt>
+<dd>If the service
+is not running, start it. If the service stops, restart it. </dd>
+
+<dt><b>down</b> </dt>
+<dd>If the service
+is running, send it the TERM signal, and the CONT signal. If ./run exits,
+start ./finish if it exists. After it stops, do not restart service. </dd>
+
+<dt><b>once</b>
+</dt>
+<dd>If the service is not running, start it. Do not restart it if it stops. </dd>
+
+<dt><b>pause
+cont hup alarm interrupt quit 1 2 term kill</b> </dt>
+<dd>If the service is running,
+send it the STOP, CONT, HUP, ALRM, INT, QUIT, USR1, USR2, TERM, or KILL
+signal respectively. </dd>
+
+<dt><b>exit</b> </dt>
+<dd>If the service is running, send it the TERM signal,
+and the CONT signal. Do not restart the service. If the service is down,
+and no log service exists, <i><b>runsv</b>(8)</i> exits. If the service is down and a
+log service exists, <i><b>runsv</b>(8)</i> closes the standard input of the log service
+and waits for it to terminate. If the log service is down, <i><b>runsv</b>(8)</i> exits.
+This command is ignored if it is given to an appendant log service. </dd>
+</dl>
+<p>
+<b>sv</b> actually
+looks only at the first character of these <i>command</i>s. 
+<h3><a name='sect4'>Commands compatible
+to LSB init script actions</a></h3>
+
+<dl>
+
+<dt><b>status</b> </dt>
+<dd>Same as <i>status</i>. </dd>
+
+<dt><b>start</b> </dt>
+<dd>Same as <i>up</i>, but wait
+up to 7 seconds for the command to take effect. Then report the status or
+timeout. If the script <i>./check</i> exists in the service directory, <b>sv</b> runs this
+script to check whether the service is up and available; it&rsquo;s considered
+to be available if <i>./check</i> exits with 0. </dd>
+
+<dt><b>stop</b> </dt>
+<dd>Same as <i>down</i>, but wait up to
+7 seconds for the service to become down. Then report the status or timeout.
+</dd>
+
+<dt><b>reload</b> </dt>
+<dd>Same as <i>hup</i>, and additionally report the status afterwards. </dd>
+
+<dt><b>restart</b>
+</dt>
+<dd>Send the commands <i>term</i>, <i>cont</i>, and <i>up</i> to the service, and wait up to 7 seconds
+for the service to restart. Then report the status or timeout. If the script
+<i>./check</i> exists in the service directory, <b>sv</b> runs this script to check whether
+the service is up and available again; it&rsquo;s considered to be available if
+<i>./check</i> exits with 0. </dd>
+
+<dt><b>shutdown</b> </dt>
+<dd>Same as <i>exit</i>, but wait up to 7 seconds for
+the <i><b>runsv</b>(8)</i> process to terminate. Then report the status or timeout. </dd>
+
+<dt><b>force-stop</b>
+</dt>
+<dd>Same as <i>down</i>, but wait up to 7 seconds for the service to become down. Then
+report the status, and on timeout send the service the <i>kill</i> command. </dd>
+
+<dt><b>force-reload</b>
+</dt>
+<dd>Send the service the <i>term</i> and <i>cont</i> commands, and wait up to 7 seconds for
+the service to restart. Then report the status, and on timeout send the
+service the <i>kill</i> command. </dd>
+
+<dt><b>force-restart</b> </dt>
+<dd>Send the service the <i>term</i>, <i>cont</i> and
+<i>up</i> commands, and wait up to 7 seconds for the service to restart. Then report
+the status, and on timeout send the service the <i>kill</i> command. If the script
+<i>./check</i> exists in the service directory, <b>sv</b> runs this script to check whether
+the service is up and available again; it&rsquo;s considered to be available if
+<i>./check</i> exits with 0. </dd>
+
+<dt><b>force-shutdown</b> </dt>
+<dd>Same as <i>exit</i>, but wait up to 7 seconds
+for the <i><b>runsv</b>(8)</i> process to terminate. Then report the status, and on timeout
+send the service the <i>kill</i> command. </dd>
+
+<dt><b>try-restart</b> </dt>
+<dd>if the service is running,
+send it the <i>term</i> and <i>cont</i> commands, and wait up to 7 seconds for the service
+to restart. Then report the status or timeout. 
+<p> </dd>
+</dl>
+
+<h3><a name='sect5'>Additional Commands</a></h3>
+
+<dl>
+
+<dt><b>check</b>
+</dt>
+<dd>Check for the service to be in the state that&rsquo;s been requested. Wait up to
+7 seconds for the service to reach the requested state, then report the
+status or timeout. If the requested state of the service is <i>up</i>, and the
+script <i>./check</i> exists in the service directory, <b>sv</b> runs this script to check
+whether the service is up and running; it&rsquo;s considered to be up if <i>./check</i>
+exits with 0. </dd>
+</dl>
+
+<h2><a name='sect6'>Options</a></h2>
+
+<dl>
+
+<dt><b>-v</b> </dt>
+<dd>If the <i>command</i> is up, down, term, once, cont, or
+exit, then wait up to 7 seconds for the command to take effect. Then report
+the status or timeout. </dd>
+
+<dt><b>-w <i>sec</b> </i></dt>
+<dd>Override the default timeout of 7 seconds with
+<i>sec</i> seconds. This option implies <i>-v</i>. </dd>
+</dl>
+
+<h2><a name='sect7'>Environment</a></h2>
+
+<dl>
+
+<dt><b>SVDIR</b> </dt>
+<dd>The environment variable
+$SVDIR overrides the default services directory <i>/service/</i>. </dd>
+
+<dt><b>SVWAIT</b> </dt>
+<dd>The environment
+variable $SVWAIT overrides the default 7 seconds to wait for a command
+to take effect. It is overridden by the -w option. </dd>
+</dl>
+
+<h2><a name='sect8'>Exit Codes</a></h2>
+<b>sv</b> exits 0, if
+the <i>command</i> was successfully sent to all <i>services</i>, and, if it was told
+to wait, the <i>command</i> has taken effect to all services. <p>
+For each <i>service</i>
+that caused an error (e.g. the directory is not controlled by a <i><b>runsv</b>(8)</i>
+process, or <b>sv</b> timed out while waiting), <b>sv</b> increases the exit code by
+one and exits non zero. The maximum is 99. <b>sv</b> exits 100 on error. <p>
+If <b>sv</b> is
+called with a base name other than <b>sv</b>: it exits 1 on timeout or trouble
+sending the command; if the <i>command</i> is <b>status</b>, it exits 3 if the service
+is down, and 4 if the status is unknown; it exits 2 on wrong usage, and
+151 on error. 
+<h2><a name='sect9'>See Also</a></h2>
+<i>runsv(8)</i>, <i>chpst(8)</i>, <i>svlogd(8)</i>, <i>runsvdir(8)</i>, <i>runsvchdir(8)</i>,
+<i>runit(8)</i>, <i>runit-init(8)</i> <p>
+<i>http://smarden.org/runit/</i> 
+<h2><a name='sect10'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt;
+<p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Commands</a></li>
+<ul>
+<li><a name='toc4' href='#sect4'>Commands compatible to LSB init script actions</a></li>
+<li><a name='toc5' href='#sect5'>Additional Commands</a></li>
+</ul>
+<li><a name='toc6' href='#sect6'>Options</a></li>
+<li><a name='toc7' href='#sect7'>Environment</a></li>
+<li><a name='toc8' href='#sect8'>Exit Codes</a></li>
+<li><a name='toc9' href='#sect9'>See Also</a></li>
+<li><a name='toc10' href='#sect10'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/svlogd.8.html b/runit-2.1.2/doc/svlogd.8.html
new file mode 100644
index 0000000..9d300ae
--- /dev/null
+++ b/runit-2.1.2/doc/svlogd.8.html
@@ -0,0 +1,264 @@
+
+
+
+<html>
+<head>
+<title>svlogd(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+svlogd - runit&rsquo;s service logging daemon 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>svlogd</b> [-tttv] [-r <i>c]</i> [-R
+<i>xyz]</i> [-l <i>len]</i> [-b <i>buflen]</i> <i>logs</i> 
+<h2><a name='sect2'>Description</a></h2>
+<i>logs</i> consists of one or more arguments,
+each specifying a directory. <p>
+<b>svlogd</b> continuously reads log data from its
+standard input, optionally filters log messages, and writes the data to
+one or more automatically rotated <i>logs</i>. <p>
+Recent log files can automatically
+be processed by an arbitrary processor program when they are rotated, and
+<b>svlogd</b> can be told to alert selected log messages to standard error, and
+through udp. <p>
+<b>svlogd</b> runs until it sees end-of-file on standard input or is
+sent a TERM signal, see below. 
+<h3><a name='sect3'>Log Directory</a></h3>
+A log directory <i>log</i> contains
+some number of old log files, and the current log file <i>current</i>. Old log
+files have a file name starting with <i>@</i> followed by a precise timestamp
+(see the daemontools&rsquo; <b>tai64n</b> program), indicating when <i>current</i> was rotated
+and renamed to this file. <p>
+A log directory additionally contains the lock
+file <i>lock</i>, maybe <i>state</i> and <i>newstate</i>, and optionally the file <i>config</i>. <b>svlogd</b>
+creates necessary files if they don&rsquo;t exist. <p>
+If <b>svlogd</b> has trouble opening
+a log directory, it prints a warning, and ignores this log directory. If
+<b>svlogd</b> is unable to open all log directories given at the command line,
+it exits with an error. This can happen on start-up or after receiving a
+HUP signal. 
+<h3><a name='sect4'>Log File Rotation</a></h3>
+<b>svlogd</b> appends selected log messages to the
+<i>current</i> log file. If <i>current</i> has <i>size</i> bytes or more (or there is a new-line
+within the last <i>len</i> of <i>size</i> bytes), or is older than a specified amount
+of <i>time</i>, <i>current</i> is rotated: <p>
+<b>svlogd</b> closes <i>current</i>, changes permission
+of <i>current</i> to 0755, renames <i>current</i> to @<i>timestamp.s,</i> and starts with a new
+empty <i>current</i>. If <b>svlogd</b> sees <i>num</i> or more old log files in the log directory,
+it removes the oldest one. Note that this doesn&rsquo;t decrease the number of
+log files if there are already more than <i>num</i> log files, this must be done
+manually, e.g. for keeping 10 log files: <p>
+ ls -1 \@* |sort |sed -ne &rsquo;10,$p&rsquo; |xargs
+rm<br>
+ 
+<h3><a name='sect5'>Processor</a></h3>
+If <b>svlogd</b> is told to process recent log files, it saves <i>current</i>
+to @<i>timestamp.u,</i> feeds @<i>timestamp.u</i> through &lsquo;&lsquo;sh -c "<i>processor</i>"&rsquo;&rsquo; and writes the
+output to @<i>timestamp.t.</i> If the <i>processor</i> finishes successfully, @<i>timestamp.t</i>
+is renamed to @<i>timestamp.s,</i> and @<i>timestamp.u</i> is deleted; otherwise @<i>timestamp.t</i>
+is deleted and the <i>processor</i> is started again. <b>svlogd</b> also saves any output
+that the <i>processor</i> writes to file descriptor 5, and makes that output available
+on file descriptor 4 when running <i>processor</i> on the next log file rotation.
+<p>
+A <i>processor</i> is run in the background. If <b>svlogd</b> sees a previously started
+<i>processor</i> still running when trying to start a new one for the same <i>log</i>,
+it blocks until the currently running <i>processor</i> has finished successfully.
+Only the HUP signal works in that situation. Note that this may block any
+program feeding its log data to <b>svlogd.</b> 
+<p> 
+<h3><a name='sect6'>Config</a></h3>
+On startup, and after receiving
+a HUP signal, <b>svlogd</b> checks for each log directory <i>log</i> if the configuration
+file <i>log/config</i> exists, and if so, reads the file line by line and adjusts
+configuration for <i>log</i> as follows: <p>
+If the line is empty, or starts with
+a &lsquo;&lsquo;#&rsquo;&rsquo;, it is ignored. A line of the form 
+<dl>
+
+<dt>s<i>size</i> </dt>
+<dd>sets the maximum file size
+of <i>current</i> when <b>svlogd</b> should rotate the current log file to <i>size</i> bytes.
+Default is 1000000. If <i>size</i> is zero, <b>svlogd</b> doesn&rsquo;t rotate log files. You
+should set <i>size</i> to at least (2 * <i>len</i>). </dd>
+
+<dt>n<i>num</i> </dt>
+<dd>sets the number of old log files
+<b>svlogd</b> should maintain to <i>num</i>. If <b>svlogd</b> sees more that <i>num</i> old log files
+in <i>log</i> after log file rotation, it deletes the oldest one. Default is 10.
+If <i>num</i> is zero, <b>svlogd</b> doesn&rsquo;t remove old log files. </dd>
+
+<dt>N<i>min</i> </dt>
+<dd>sets the minimum
+number of old log files <b>svlogd</b> should maintain to <i>min</i>. <i>min</i> must be less
+than <i>num</i>. If <i>min</i> is set, and <b>svlogd</b> cannot write to <i>current</i> because the
+filesystem is full, and it sees more than <i>min</i> old log files, it deletes
+the oldest one. </dd>
+
+<dt>t<i>timeout</i> </dt>
+<dd>sets the maximum age of the <i>current</i> log file when
+<b>svlogd</b> should rotate the current log file to <i>timeout</i> seconds. If <i>current</i>
+is <i>timeout</i> seconds old, and is not empty, <b>svlogd</b> forces log file rotation.
+</dd>
+
+<dt>!<i>processor</i> </dt>
+<dd>tells <b>svlogd</b> to feed each recent log file through <i>processor</i>
+(see above) on log file rotation. By default log files are not processed.
+</dd>
+
+<dt>u<i>a.b.c.d[:port]</i> </dt>
+<dd>tells <b>svlogd</b> to transmit the first <i>len</i> characters of selected
+log messages to the IP address <i>a.b.c.d</i>, port number <i>port</i>. If <i>port</i> isn&rsquo;t set,
+the default port for syslog is used (514). <i>len</i> can be set through the -l
+option, see below. If <b>svlogd</b> has trouble sending udp packets, it writes
+error messages to the log directory. Attention: logging through udp is unreliable,
+and should be used in private networks only. </dd>
+
+<dt>U<i>a.b.c.d[:port]</i> </dt>
+<dd>is the same as
+the <i>u</i> line above, but the log messages are no longer written to the log
+directory, but transmitted through udp only. Error messages from <b>svlogd</b>
+concerning sending udp packages still go to the log directory. </dd>
+
+<dt>p<i>prefix</i> </dt>
+<dd>tells
+<b>svlogd</b> to prefix each line to be written to the log directory, to standard
+error, or through UDP, with <i>prefix</i>. </dd>
+</dl>
+<p>
+If a line starts with a <i>-</i>, <i>+</i>, <i>e</i>, or <i>E</i>,
+<b>svlogd</b> matches the first <i>len</i> characters of each log message against <i>pattern</i>
+and acts accordingly: 
+<dl>
+
+<dt>-<i>pattern</i> </dt>
+<dd>the log message is deselected. </dd>
+
+<dt>+<i>pattern</i> </dt>
+<dd>the
+log message is selected. </dd>
+
+<dt>e<i>pattern</i> </dt>
+<dd>the log message is selected to be printed
+to standard error. </dd>
+
+<dt>E<i>pattern</i> </dt>
+<dd>the log message is deselected to be printed
+to standard error. </dd>
+</dl>
+<p>
+Initially each line is selected to be written to <i>log/current</i>.
+Deselected log messages are discarded from <i>log</i>. Initially each line is deselected
+to be written to standard err. Log messages selected for standard error
+are written to standard error. 
+<h2><a name='sect7'>Pattern Matching</a></h2>
+<b>svlogd</b> matches a log message
+against the string <i>pattern</i> as follows: <p>
+<i>pattern</i> is applied to the log message
+one character by one, starting with the first. A character not a star (&lsquo;&lsquo;*&rsquo;&rsquo;)
+and not a plus (&lsquo;&lsquo;+&rsquo;&rsquo;) matches itself. A plus matches the next character in
+<i>pattern</i> in the log message one or more times. A star before the end of <i>pattern</i>
+matches any string in the log message that does not include the next character
+in <i>pattern</i>. A star at the end of <i>pattern</i> matches any string. <p>
+Timestamps optionally
+added by <b>svlogd</b> are not considered part of the log message. <p>
+An <b>svlogd</b> pattern
+is not a regular expression. For example consider a log message like this
+<p>
+ 2005-12-18_09:13:50.97618 tcpsvd: info: pid 1977 from 10.4.1.14<br>
+ <p>
+The following pattern doesn&rsquo;t match <p>
+ -*pid*<br>
+ <p>
+because the first star matches up to the first p in tcpsvd, and then the
+match fails because i is not s. To match this log message, you can use a
+pattern like this instead <p>
+ -*: *: pid *<br>
+ 
+<h2><a name='sect8'>Options</a></h2>
+
+<dl>
+
+<dt><b>-t</b> </dt>
+<dd>timestamp. Prefix each selected line with a precise timestamp
+(see the daemontools&rsquo; <b>tai64n</b> program) when writing to <i>log</i> or to standard
+error. </dd>
+
+<dt><b>-tt</b> </dt>
+<dd>timestamp. Prefix each selected line with a human readable, sortable
+UTC timestamp of the form YYYY-MM-DD_HH:MM:SS.xxxxx when writing to <i>log</i> or
+to standard error. </dd>
+
+<dt><b>-ttt</b> </dt>
+<dd>timestamp. Prefix each selected line with a human
+readable, sortable UTC timestamp of the form YYYY-MM-DDTHH:MM:SS.xxxxx when
+writing to <i>log</i> or to standard error. </dd>
+
+<dt><b>-r <i>c</b> </i></dt>
+<dd>replace. <i>c</i> must be a single character.
+Replace non-printable characters in log messages with <i>c</i>. Characters are replaced
+before pattern matching is applied. </dd>
+
+<dt><b>-R <i>xyz</b> </i></dt>
+<dd>replace charset. Additionally to
+non-printable characters, replace all characters found in <i>xyz</i> with <i>c</i> (default
+&lsquo;&lsquo;_&rsquo;&rsquo;). </dd>
+
+<dt><b>-l <i>len</b> </i></dt>
+<dd>line length. Pattern matching applies to the first <i>len</i> characters
+of a log message only. Default is 1000. </dd>
+
+<dt><b>-b <i>buflen</b> </i></dt>
+<dd>buffer size. Set the size
+of the buffer <b>svlogd</b> uses when reading from standard input and writing
+to <i>logs</i> to <i>buflen</i>. Default is 1024. <i>buflen</i> must be greater than <i>len</i>. For <b>svlogd</b>
+instances that process a lot of data in short time, the buffer size should
+be increased to improve performance. </dd>
+
+<dt><b>-v</b> </dt>
+<dd>verbose. Print verbose messages to
+standard error. </dd>
+</dl>
+
+<h2><a name='sect9'>Signals</a></h2>
+If <b>svlogd</b> is sent a HUP signal, it closes and reopens
+all <i>logs</i>, and updates their configuration according to <i>log/config</i>. If <b>svlogd</b>
+has trouble opening a log directory, it prints a warning, and discards
+this log directory. If <b>svlogd</b> is unable to open all log directories given
+at the command line, it exits with an error. <p>
+If <b>svlogd</b> is sent a TERM signal,
+or if it sees end-of-file on standard input, it stops reading standard input,
+processes the data in the buffer, waits for all <i>processor</i> subprocesses
+to finish if any, and exits 0 as soon as possible. <p>
+If <b>svlogd</b> is sent an
+ALRM signal, it forces log file rotation for all <i>logs</i> with a non empty
+<i>current</i> log file. 
+<h2><a name='sect10'>See Also</a></h2>
+<i>sv(8)</i>, <i>runsv(8)</i>, <i>chpst(8)</i>, <i>runit(8)</i>, <i>runit-init(8)</i>,
+<i>runsvdir(8)</i>, <i>runsvchdir(8)</i> <p>
+<i>http://smarden.org/runit/</i> 
+<h2><a name='sect11'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt;
+<p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<ul>
+<li><a name='toc3' href='#sect3'>Log Directory</a></li>
+<li><a name='toc4' href='#sect4'>Log File Rotation</a></li>
+<li><a name='toc5' href='#sect5'>Processor</a></li>
+<li><a name='toc6' href='#sect6'>Config</a></li>
+</ul>
+<li><a name='toc7' href='#sect7'>Pattern Matching</a></li>
+<li><a name='toc8' href='#sect8'>Options</a></li>
+<li><a name='toc9' href='#sect9'>Signals</a></li>
+<li><a name='toc10' href='#sect10'>See Also</a></li>
+<li><a name='toc11' href='#sect11'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/upgrade.html b/runit-2.1.2/doc/upgrade.html
new file mode 100644
index 0000000..83d12e1
--- /dev/null
+++ b/runit-2.1.2/doc/upgrade.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - upgrading from previous versions</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - upgrading from previous versions</h1>
+<hr>
+<h3>2.0.0 to 2.1.2</h3>
+The <a href="chpst.8.html">chpst</a> program learned a new option -b to run
+a program with a different name as the 0th argument.
+<h3>1.9.0 to 2.0.0</h3>
+No further action from you is required.
+<h3>1.8.0 to 1.9.0</h3>
+The default directory for services is now <tt>/service/</tt>, and no longer
+<tt>/var/service/</tt>.
+To be consistent with the new default location, create a symlink when
+upgrading
+<pre>
+ # ln -s /var/service /
+</pre>
+When installing runit on a system that should comply with the Filesystem
+Hierarchy Standard (FHS), neither <tt>/service/</tt> nor
+<tt>/var/service/</tt> should be chosen, but <tt>/etc/service/</tt>.
+It is recommended to create a compatibility symlink <tt>/service</tt>
+pointing to <tt>/etc/service</tt> in this case.
+<h3>1.7.x to 1.8.0</h3>
+The <a href="runit.8.html">runit</a> program, the process no 1, has been
+fixed to reap dead processes that re-parented to process no 1 (zombies)
+more thoroughly.
+Instructions on how to run <tt>runit</tt> with upstart as init scheme have
+been added, <a href="svlogd.8.html">svlogd</a> has been changed to use a
+new source port for each log message sent through udp, and this release
+includes a build fix for AIX.
+<h3>1.6.0 to 1.7.x</h3>
+With this version the <a href="runsv.8.html">runsv</a> program starts to
+run the ./finish script with two arguments, the exit code and the exit
+status of the just finished ./run script.
+The timestamp <a href="svlogd.8.html">svlogd</a> optionally prepends to log
+messages can be specified to be in iso 8601 alike format.
+See the man pages for details.
+<h3>1.5.x to 1.6.0</h3>
+<a href="svlogd.8.html">svlogd</a> has been changed to prepend the optional
+timestamp also to log messages sent to the network through UDP, just as it
+does for log messages written to a log directory or standard error.
+<h3>1.4.0 or 1.4.1 to 1.5.x</h3>
+The <a href="svlogd.8.html">svlogd</a> program supports a new configuration
+option p to optionally prefix each line written to logs, standard error, or
+through UDP with a string, and no longer strips empty lines from the logs.
+<h3>1.3.x to 1.4.0 or 1.4.1</h3>
+With this version the <tt>runsvctrl</tt>, <tt>runsvstat</tt>,
+<tt>svwaitdown</tt>, and <tt>svwaitup</tt> programs no longer are being
+installed, the functionality of these programs has been incorporated into
+the <a href="sv.8.html">sv</a> program.
+The documentation now suggest to put service directories by default into
+the <tt>/etc/sv/</tt> directory, and a list of frequently asked questions
+with answers has been added.
+The <a href="chpst.8.html">chpst</a> program understands a new option -d
+to limit memory of the data segment per process.
+<h3>1.2.x to 1.3.x</h3>
+This release introduces a first test version of the <a href="sv.8.html">sv</a>
+program, which can be used to control the state and query the status of
+services monitored by <a href="runsv.8.html">runsv</a>.
+Optionally it can be sym-linked into <tt>/etc/init.d/</tt> to provide an
+interface to LSB init script actions for services controlled by runit.
+See the <a href="sv.8.html">man page</a> for details.
+Thanks to Lars Uffmann, instructions on how to run runit under launchd on
+MacOSX 10.4 have been added.
+<h3>1.1.0 to 1.2.x</h3>
+With this version the <a href="runsv.8.html">runsv</a> program makes
+controlling the service through commands normally sent by
+<a href="runsvctrl.8.html">runsvctrl</a> configurable;
+arbitrary actions through external programs can optionally be specified, and
+signalling of the service disabled if desired.
+See the <a href="runsv.8.html">man page</a> for details.
+<p>
+<a href="runsv.8.html">runsv</a> now reports the seconds since <tt>./run</tt>
+has been started when running the <tt>./finish</tt> script, instead of the
+seconds since <tt>./finish</tt> has been started.
+It no longer reports immediately failing <tt>./run</tt> scripts as ``running''
+for up to one second, but as ``down, normally up, want up''.
+<h3>1.0.x to 1.1.0</h3>
+The <a href="svlogd.8.html">svlogd</a> program now interprets the ``e'' and
+``E'' configuration options so that they can be combined to select or
+deselect log messages to be written to standard error, similar to the ``+''
+and ``-'' options for the rotated log.
+It also provides the new ``t'' and ``N'' configuration options, see the
+<a href="svlogd.8.html">man page</a> for details.
+The <a href="chpst.8.html">chpst</a> program supports adjusting the nice
+level through the new -n command line option.
+<p>
+Starting with this version, <tt>/etc/runit/2</tt> by default runs the
+<a href="runsvdir.8.html">runsvdir</a> program with the -P option.
+To adapt edit <tt>/etc/runit/2</tt> and change the invocation of
+<a href="runsvdir.8.html">runsvdir</a> accordingly, see
+<a href="../etc/2"">here</a>.
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/usedietlibc.html b/runit-2.1.2/doc/usedietlibc.html
new file mode 100644
index 0000000..70c5b2f
--- /dev/null
+++ b/runit-2.1.2/doc/usedietlibc.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - use dietlibc</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - use dietlibc</h1>
+<hr>
+To recompile the <i>runit</i> programs with the
+<a href="http://www.fefe.de/dietlibc/">diet libc</a>, check that you have
+the recent version of
+<a href="http://www.fefe.de/dietlibc/">dietlibc</a> installed.
+<p>
+Change to the package directory of <i>runit</i>
+<pre>
+ # cd /package/admin/runit/
+</pre>
+Change the <tt>conf-cc</tt> and <tt>conf-ld</tt> to use <tt>diet</tt>
+<pre>
+ # echo 'diet -Os gcc -O2 -Wall' &gt;src/conf-cc
+ # echo 'diet -Os gcc -s -Os -pipe' &gt;src/conf-ld
+</pre>
+Rebuild and install the <i>runit</i> programs
+<pre>
+ # package/install
+</pre>
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/useinit.html b/runit-2.1.2/doc/useinit.html
new file mode 100644
index 0000000..a5c2853
--- /dev/null
+++ b/runit-2.1.2/doc/useinit.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<title>runit - use with traditional init</title>
+</head>
+<body>
+<a href="http://smarden.org/pape/">G. Pape</a><br>
+<a href="index.html">runit</a><br>
+<hr>
+<h1>runit - use with traditional init</h1>
+<hr>
+It's possible to use <i>runit</i>'s service supervision without replacing
+the <i>init</i> scheme of the system.
+Simply run the <i>stage 2</i> of <i>runit</i> as a service with your
+current <i>init</i>.
+<p>
+Normally this is done by either adding an entry for
+<tt>/sbin/runsvdir-start</tt> to <tt>/etc/inittab</tt>, or by adding
+<tt>/sbin/runsvdir-start</tt> as command to </tt>/etc/rc.local</tt>, or by
+adding <tt>/sbin/runsvdir-start</tt> to the system's <tt>StartupItems</tt>.
+<p>
+In any case, you first need to copy the <i>stage 2</i> script to
+<tt>/sbin/runsvdir-start</tt>, and create the services directory
+<tt>/service/</tt>:
+<pre>
+ # install -m0750 /package/admin/runit/etc/2 /sbin/runsvdir-start
+ # mkdir -p /service
+</pre>
+<hr>
+<a href="#sysv">How to use with sysvinit and inittab</a><br>
+<a href="#upstart">How to use with sysvinit and upstart</a><br>
+<a href="#bsd">How to use with *BSD init</a><br>
+<a href="#macosx">How to use with MacOSX init</a>
+<hr>
+<a name="sysv"><h2>Using with sysvinit and inittab</h2></a>
+If your system uses a sysvinit alike init scheme with a <tt>/etc/inittab</tt>
+file, do:
+<pre>
+ # cat &gt;&gt;/etc/inittab &lt;&lt;EOT
+ SV:123456:respawn:/sbin/runsvdir-start
+ EOT
+</pre>
+and tell <i>init</i> to re-read its configuration, e.g.:
+<pre>
+ # init q
+</pre>
+<hr>
+<a name="upstart"><h2>Using with sysvinit and upstart</h2></a>
+If your system uses a sysvinit alike init scheme that utilizes upstart
+instead of inittab, and which has start and stop scripts located in
+<tt>/etc/init/</tt>, do:
+<pre>
+ # cat >/etc/init/runsvdir.conf <<\EOT
+ # for runit - manage /usr/sbin/runsvdir-start
+ start on runlevel 2
+ start on runlevel 3
+ start on runlevel 4
+ start on runlevel 5
+ stop on shutdown
+ respawn
+ exec /usr/sbin/runsvdir-start
+ EOT
+</pre>
+and tell init to start the new service, e.g.:
+<pre>
+ # start runsvdir
+</pre>
+<hr>
+<a name="bsd"><h2>Using with *BSD init</h2></a>
+If your system uses a BSD alike init scheme with a <tt>/etc/rc.local</tt>
+script, do:
+<pre>
+ # cat &gt;&gt;/etc/rc.local &lt;&lt;EOT
+ csh -cf '/sbin/runsvdir-start &amp;'
+ EOT
+</pre>
+and reboot your system.
+<hr>
+<a name="macosx"><h2>Using with MacOSX init</h2></a>
+On MacOSX 10.2 create an entry for <i>runit</i> in
+<tt>/System/Library/StartupItems/</tt>:
+<pre>
+ # cd /System/Library/StartupItems
+ # mkdir -p runit
+ # cp -p /package/admin/runit/etc/macosx/StartupItems/* runit/
+</pre>
+and reboot your system.
+<p>
+On MacOSX 10.4 create an entry for <i>runit</i> in
+<tt>/Library/LaunchDaemons/</tt>, and tell <i>launchd</i> to start the new 
+service:
+<pre>
+ # cp /package/admin/runit/etc/macosx/org.smarden.runit.plist \
+     /Library/LaunchDaemons/
+ # launchctl load /Library/LaunchDaemons/org.smarden.runit.plist
+</pre>
+<hr>
+<address><a href="mailto:pape@smarden.org">
+Gerrit Pape &lt;pape@smarden.org&gt;
+</a></address>
+</body>
+</html>
diff --git a/runit-2.1.2/doc/utmpset.8.html b/runit-2.1.2/doc/utmpset.8.html
new file mode 100644
index 0000000..3b96cb6
--- /dev/null
+++ b/runit-2.1.2/doc/utmpset.8.html
@@ -0,0 +1,63 @@
+
+
+
+<html>
+<head>
+<title>utmpset(8) manual page</title>
+</head>
+<body bgcolor='white'>
+<a href='http://smarden.org/pape/'>G. Pape</a><br><a href='index.html'>runit</A><hr><p>
+
+<h2><a name='sect0'>Name</a></h2>
+utmpset - logout a line from utmp and wtmp file 
+<h2><a name='sect1'>Synopsis</a></h2>
+<b>utmpset</b> [ <b>-w</b>
+] <i>line</i> 
+<h2><a name='sect2'>Description</a></h2>
+The <b>utmpset</b> program modifies the user accounting database
+<i><b>utmp</b>(5)</i> and optionally <i><b>wtmp</b>(5)</i> to indicate that the user on the terminal
+<i>line</i> has logged out. <p>
+Ordinary <i><b>init</b>(8)</i> processes handle utmp file records
+for local login accounting. The <i><b>runit</b>(8)</i> program doesn&rsquo;t include code to
+update the utmp file, the <i><b>getty</b>(8)</i> processes are handled the same as all
+other services. <p>
+To enable local login accounting, add <b>utmpset</b> to the <i><b>getty</b>(8)</i>
+<i>finish</i> scripts, e.g.: <p>
+ $ cat /service/getty-5/finish<br>
+  #!/bin/sh<br>
+  exec utmpset -w tty5<br>
+  $<br>
+ 
+<h2><a name='sect3'>Options</a></h2>
+
+<dl>
+
+<dt><b>-w</b> </dt>
+<dd>wtmp. Additionally to the utmp file, write an empty record for
+<i>line</i> to the wtmp file. </dd>
+</dl>
+
+<h2><a name='sect4'>Exit Codes</a></h2>
+<b>utmpset</b> returns 111 on error, 1 on wrong
+usage, 0 in all other cases. 
+<h2><a name='sect5'>See Also</a></h2>
+<i>sv(8)</i>, <i>runsv(8)</i>, <i>runit(8)</i>, <i>runit-init(8)</i>
+<i>runsvdir(8)</i>, <i>runsvchdir(8)</i>, <i>chpst(8)</i>, <i>svlogd(8)</i>, <i>getty(8)</i> <p>
+<i>http://smarden.org/runit/</i>
+
+<h2><a name='sect6'>Author</a></h2>
+Gerrit Pape &lt;pape@smarden.org&gt; <p>
+
+<hr><p>
+<a name='toc'><b>Table of Contents</b></a><p>
+<ul>
+<li><a name='toc0' href='#sect0'>Name</a></li>
+<li><a name='toc1' href='#sect1'>Synopsis</a></li>
+<li><a name='toc2' href='#sect2'>Description</a></li>
+<li><a name='toc3' href='#sect3'>Options</a></li>
+<li><a name='toc4' href='#sect4'>Exit Codes</a></li>
+<li><a name='toc5' href='#sect5'>See Also</a></li>
+<li><a name='toc6' href='#sect6'>Author</a></li>
+</ul>
+</body>
+</html>
diff --git a/runit-2.1.2/etc/2 b/runit-2.1.2/etc/2
new file mode 100755
index 0000000..3bb822d
--- /dev/null
+++ b/runit-2.1.2/etc/2
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+PATH=/command:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin
+
+exec env - PATH=$PATH \
+runsvdir -P /service 'log: ...........................................................................................................................................................................................................................................................................................................................................................................................................'
diff --git a/runit-2.1.2/etc/debian/1 b/runit-2.1.2/etc/debian/1
new file mode 100755
index 0000000..4cd10cb
--- /dev/null
+++ b/runit-2.1.2/etc/debian/1
@@ -0,0 +1,10 @@
+#!/bin/sh
+# system one time tasks
+
+PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
+
+/etc/init.d/rcS
+/etc/init.d/rmnologin
+
+touch /etc/runit/stopit
+chmod 0 /etc/runit/stopit
diff --git a/runit-2.1.2/etc/debian/2 b/runit-2.1.2/etc/debian/2
new file mode 120000
index 0000000..5fae01f
--- /dev/null
+++ b/runit-2.1.2/etc/debian/2
@@ -0,0 +1 @@
+../2
\ No newline at end of file
diff --git a/runit-2.1.2/etc/debian/3 b/runit-2.1.2/etc/debian/3
new file mode 100755
index 0000000..10354d7
--- /dev/null
+++ b/runit-2.1.2/etc/debian/3
@@ -0,0 +1,14 @@
+#!/bin/sh
+exec 2>&1
+
+PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
+
+LAST=0
+test -x /etc/runit/reboot && LAST=6
+
+echo 'Waiting for services to stop...'
+sv -w196 force-stop /service/*
+sv exit /service/*
+
+echo 'Shutdown...'
+/etc/init.d/rc $LAST
diff --git a/runit-2.1.2/etc/debian/ctrlaltdel b/runit-2.1.2/etc/debian/ctrlaltdel
new file mode 100755
index 0000000..6684457
--- /dev/null
+++ b/runit-2.1.2/etc/debian/ctrlaltdel
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+PATH=/bin:/usr/bin
+MSG="System is going down in 14 seconds..."
+
+# echo 'disabled.' ; exit
+touch /etc/runit/stopit
+chmod 100 /etc/runit/stopit && echo "$MSG" | wall
+/bin/sleep 14
diff --git a/runit-2.1.2/etc/debian/getty-tty5/finish b/runit-2.1.2/etc/debian/getty-tty5/finish
new file mode 100755
index 0000000..72d719b
--- /dev/null
+++ b/runit-2.1.2/etc/debian/getty-tty5/finish
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec utmpset -w tty5
diff --git a/runit-2.1.2/etc/debian/getty-tty5/run b/runit-2.1.2/etc/debian/getty-tty5/run
new file mode 100755
index 0000000..6767eae
--- /dev/null
+++ b/runit-2.1.2/etc/debian/getty-tty5/run
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /sbin/getty 38400 tty5 linux
diff --git a/runit-2.1.2/etc/freebsd/1 b/runit-2.1.2/etc/freebsd/1
new file mode 100755
index 0000000..2a4492d
--- /dev/null
+++ b/runit-2.1.2/etc/freebsd/1
@@ -0,0 +1,17 @@
+#!/bin/sh
+# system one time tasks
+
+PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
+trap : 2
+trap : 3
+
+sh /etc/rc autoboot
+if test $? -ne 0; then
+  # /etc/rc crashed, start emergency shell.
+  echo '/etc/rc failed. Press <enter> for emergency shell...'
+  read input
+  sh -p
+  exec reboot
+fi
+touch /etc/runit/stopit
+chmod 0 /etc/runit/stopit
diff --git a/runit-2.1.2/etc/freebsd/2 b/runit-2.1.2/etc/freebsd/2
new file mode 120000
index 0000000..5fae01f
--- /dev/null
+++ b/runit-2.1.2/etc/freebsd/2
@@ -0,0 +1 @@
+../2
\ No newline at end of file
diff --git a/runit-2.1.2/etc/freebsd/3 b/runit-2.1.2/etc/freebsd/3
new file mode 100755
index 0000000..f7f9327
--- /dev/null
+++ b/runit-2.1.2/etc/freebsd/3
@@ -0,0 +1,15 @@
+#!/bin/sh
+exec 2>&1
+
+PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
+
+echo 'Waiting for services to stop...'
+sv -w196 force-stop /service/*
+sv exit /service/*
+
+echo 'Shutdown...'
+if test -x /etc/runit/reboot; then
+  exec reboot
+else
+  exec halt
+fi
diff --git a/runit-2.1.2/etc/freebsd/ctrlaltdel b/runit-2.1.2/etc/freebsd/ctrlaltdel
new file mode 100755
index 0000000..6684457
--- /dev/null
+++ b/runit-2.1.2/etc/freebsd/ctrlaltdel
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+PATH=/bin:/usr/bin
+MSG="System is going down in 14 seconds..."
+
+# echo 'disabled.' ; exit
+touch /etc/runit/stopit
+chmod 100 /etc/runit/stopit && echo "$MSG" | wall
+/bin/sleep 14
diff --git a/runit-2.1.2/etc/freebsd/getty-ttyv4/finish b/runit-2.1.2/etc/freebsd/getty-ttyv4/finish
new file mode 100755
index 0000000..b53d0af
--- /dev/null
+++ b/runit-2.1.2/etc/freebsd/getty-ttyv4/finish
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec utmpset -w ttyv4
diff --git a/runit-2.1.2/etc/freebsd/getty-ttyv4/run b/runit-2.1.2/etc/freebsd/getty-ttyv4/run
new file mode 100755
index 0000000..2d5e3dc
--- /dev/null
+++ b/runit-2.1.2/etc/freebsd/getty-ttyv4/run
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/libexec/getty Pc ttyv4
diff --git a/runit-2.1.2/etc/macosx/2 b/runit-2.1.2/etc/macosx/2
new file mode 120000
index 0000000..5fae01f
--- /dev/null
+++ b/runit-2.1.2/etc/macosx/2
@@ -0,0 +1 @@
+../2
\ No newline at end of file
diff --git a/runit-2.1.2/etc/macosx/StartupItems/StartupParameters.plist b/runit-2.1.2/etc/macosx/StartupItems/StartupParameters.plist
new file mode 100644
index 0000000..14b5116
--- /dev/null
+++ b/runit-2.1.2/etc/macosx/StartupItems/StartupParameters.plist
@@ -0,0 +1,11 @@
+{
+  Description     = "runit service supervision";
+  Provides        = ("runit");
+  Requires        = ("Disks");
+  OrderPreference = "None";
+  Messages =
+  {
+    start = "Starting runit service supervision";
+    stop  = "Stopping runit service supervision";
+  };
+}
diff --git a/runit-2.1.2/etc/macosx/StartupItems/runit b/runit-2.1.2/etc/macosx/StartupItems/runit
new file mode 100755
index 0000000..9f0eaf3
--- /dev/null
+++ b/runit-2.1.2/etc/macosx/StartupItems/runit
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+##
+# runit
+##
+
+. /etc/rc.common
+
+StartService() {
+  ConsoleMessage "Starting runit service supervision"
+  /bin/csh -cf '/sbin/runsvdir-start &'
+}
+StopService() {
+  ConsoleMessage "Stopping runit service supervision"
+  sv -w196 force-stop /service/*
+  sv exit /service/*
+}
+RestartService() {
+  return 0
+}
+
+RunService "$1"
diff --git a/runit-2.1.2/etc/macosx/org.smarden.runit.plist b/runit-2.1.2/etc/macosx/org.smarden.runit.plist
new file mode 100644
index 0000000..1331f8a
--- /dev/null
+++ b/runit-2.1.2/etc/macosx/org.smarden.runit.plist
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>Label</key>
+	<string>org.smarden.runit</string>
+	<key>ServiceDescription</key>
+	<string>runsvdir - starts and monitors a collection of runsv(8) processes</string>
+	<key>QueueDirectories</key>
+	<array>
+		<string>/service</string>
+	</array>
+	<key>OnDemand</key>
+	<false/>
+	<key>ProgramArguments</key>
+	<array>
+		<string>/sbin/runsvdir-start</string>
+	</array>
+</dict>
+</plist>
diff --git a/runit-2.1.2/etc/openbsd/1 b/runit-2.1.2/etc/openbsd/1
new file mode 100755
index 0000000..eaa3d39
--- /dev/null
+++ b/runit-2.1.2/etc/openbsd/1
@@ -0,0 +1,17 @@
+#!/bin/sh
+# system one time tasks
+
+PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
+trap : 2
+trap : 3
+
+sh /etc/rc autoboot
+if test $? -ne 0; then
+  # /etc/rc crashed, start emergency shell.
+  echo '/etc/rc failed. Press <enter> for emergency shell...'
+  read input
+  sh -l
+  exec reboot
+fi
+touch /etc/runit/stopit
+chmod 0 /etc/runit/stopit
diff --git a/runit-2.1.2/etc/openbsd/2 b/runit-2.1.2/etc/openbsd/2
new file mode 120000
index 0000000..5fae01f
--- /dev/null
+++ b/runit-2.1.2/etc/openbsd/2
@@ -0,0 +1 @@
+../2
\ No newline at end of file
diff --git a/runit-2.1.2/etc/openbsd/3 b/runit-2.1.2/etc/openbsd/3
new file mode 100755
index 0000000..f7f9327
--- /dev/null
+++ b/runit-2.1.2/etc/openbsd/3
@@ -0,0 +1,15 @@
+#!/bin/sh
+exec 2>&1
+
+PATH=/command:/sbin:/bin:/usr/sbin:/usr/bin
+
+echo 'Waiting for services to stop...'
+sv -w196 force-stop /service/*
+sv exit /service/*
+
+echo 'Shutdown...'
+if test -x /etc/runit/reboot; then
+  exec reboot
+else
+  exec halt
+fi
diff --git a/runit-2.1.2/etc/openbsd/ctrlaltdel b/runit-2.1.2/etc/openbsd/ctrlaltdel
new file mode 100755
index 0000000..6684457
--- /dev/null
+++ b/runit-2.1.2/etc/openbsd/ctrlaltdel
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+PATH=/bin:/usr/bin
+MSG="System is going down in 14 seconds..."
+
+# echo 'disabled.' ; exit
+touch /etc/runit/stopit
+chmod 100 /etc/runit/stopit && echo "$MSG" | wall
+/bin/sleep 14
diff --git a/runit-2.1.2/etc/openbsd/getty-ttyC4/finish b/runit-2.1.2/etc/openbsd/getty-ttyC4/finish
new file mode 100755
index 0000000..b3c7aa7
--- /dev/null
+++ b/runit-2.1.2/etc/openbsd/getty-ttyC4/finish
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec utmpset -w ttyC4
diff --git a/runit-2.1.2/etc/openbsd/getty-ttyC4/run b/runit-2.1.2/etc/openbsd/getty-ttyC4/run
new file mode 100755
index 0000000..c1d9cb9
--- /dev/null
+++ b/runit-2.1.2/etc/openbsd/getty-ttyC4/run
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/libexec/getty Pc ttyC4
diff --git a/runit-2.1.2/man/chpst.8 b/runit-2.1.2/man/chpst.8
new file mode 100644
index 0000000..43c0b8d
--- /dev/null
+++ b/runit-2.1.2/man/chpst.8
@@ -0,0 +1,265 @@
+.TH chpst 8
+.SH NAME
+chpst \- runs a program with a changed process state
+.SH SYNOPSIS
+.B chpst
+[\-vP012]
+[\-u
+.IR user ]
+[\-U
+.IR user ]
+[\-b
+.IR argv0 ]
+[-e
+.IR dir ]
+[\-/
+.IR root ]
+[\-n
+.IR inc ]
+[-l|-L
+.IR lock ]
+[-m
+.IR bytes ]
+[-d
+.IR bytes ]
+[-o
+.IR n ]
+[-p
+.IR n ]
+[-f
+.IR bytes ]
+[-c
+.IR bytes ]
+.I prog
+.SH DESCRIPTION
+.I prog
+consists of one or more arguments.
+.P
+.B chpst
+changes the process state according to the given options, and runs
+.IR prog .
+.SH OPTIONS
+.TP
+.B \-u \fI[:]user[:group]
+setuidgid.
+Set uid and gid to the
+.IR user 's
+uid and gid, as found in
+.IR /etc/passwd .
+If
+.I user
+is followed by a colon and a
+.IR group ,
+set the gid to
+.IR group 's
+gid, as found in
+.IR /etc/group ,
+instead of
+.IR user 's
+gid.
+If
+.I group
+consists of a colon-separated list of group names,
+.B chpst
+sets the group ids of all listed groups.
+If
+.I user
+is prefixed with a colon, the
+.I user
+and all
+.I group
+arguments are interpreted as uid and gids respectivly, and not looked up in
+the password or group file.
+All initial supplementary groups are removed.
+.TP
+.B \-U \fI[:]user[:group]
+envuidgid.
+Set the environment variables $UID and $GID to the
+.IR user 's
+uid and gid, as found in
+.IR /etc/passwd .
+If
+.I user
+is followed by a colon and a
+.IR group ,
+set $GID to the
+.IR group 's
+gid, as found in
+.IR /etc/group ,
+instead of
+.IR user 's
+gid.
+If
+.I user
+is prefixed with a colon, the
+.I user
+and
+.I group
+arguments are interpreted as uid and gid respectivly, and not looked up in
+the password or group file.
+.TP
+.B \-b \fIargv0
+argv0.
+Run
+.I prog
+with
+.I argv0
+as the 0th argument.
+.TP
+.B \-e \fIdir
+envdir.
+Set various environment variables as specified by files in the directory
+.IR dir :
+If
+.I dir
+contains a file named
+.I k
+whose first line is
+.IR v ,
+.B chpst
+removes the environment variable
+.I k
+if it exists, and then adds the environment variable
+.I k
+with the value
+.IR v .
+The name
+.I k
+must not contain =.
+Spaces and tabs at the end of
+.I v
+are removed, and nulls in
+.I v
+are changed to newlines.
+If the file
+.I k
+is empty (0 bytes long),
+.B chpst
+removes the environment variable
+.I k
+if it exists, without adding a new variable.
+.TP
+.B \-/ \fIroot
+chroot.
+Change the root directory to
+.I root
+before starting
+.IR prog .
+.TP
+.B \-n \fIinc
+nice.
+Add
+.I inc
+to the
+.BR nice (2)
+value before starting
+.IR prog .
+.I inc
+must be an integer, and may start with a minus or plus.
+.TP
+.B \-l \fIlock
+lock.
+Open the file
+.I lock
+for writing, and obtain an exclusive lock on it.
+.I lock
+will be created if it does not exist.
+If
+.I lock
+is locked by another process, wait until a new lock can be obtained.
+.TP
+.B \-L \fIlock
+The same as \-l, but fail immediately if
+.I lock
+is locked by another process.
+.TP
+.B \-m \fIbytes
+limit memory.
+Limit the data segment, stack segment, locked physical pages, and total of
+all segment per process to
+.I bytes
+bytes each.
+.TP
+.B \-d \fIbytes
+limit data segment.
+Limit the data segment per process to
+.I bytes
+bytes.
+.TP
+.B \-o \fIn
+limit open files.
+Limit the number of open file descriptors per process to
+.IR n .
+.TP
+.B \-p \fIn
+limit processes.
+Limit the number of processes per uid to
+.IR n .
+.TP
+.B \-f \fIbytes
+limit output size.
+Limit the output file size to
+.I bytes
+bytes.
+.TP
+.B \-c \fIbytes
+limit core size.
+Limit the core file size to
+.I bytes
+bytes.
+.TP
+.B \-v
+verbose.
+Print verbose messages to standard error.
+This includes warnings about limits unsupported by the system.
+.TP
+.B \-P
+pgrphack.
+Run
+.I prog
+in a new process group.
+.TP
+.B \-0
+Close standard input before starting
+.IR prog .
+.TP
+.B \-1
+Close standard output before starting
+.IR prog .
+.TP
+.B \-2
+Close standard error before starting
+.IR prog .
+.SH EXIT CODES
+.B chpst
+exits 100 when called with wrong options.
+It prints an error message and exits 111 if it has trouble changing the
+process state.
+Otherwise its exit code is the same as that of
+.IR prog .
+.SH EMULATION
+If
+.B chpst
+is called as
+.BR envdir ,
+.BR envuidgid ,
+.BR pgrphack ,
+.BR setlock ,
+.BR setuidgid ,
+or
+.BR softlimit ,
+it emulates the functionality of these programs from the daemontools package
+respectively.
+.SH SEE ALSO
+sv(8),
+runsv(8),
+setsid(2),
+runit(8),
+runit-init(8),
+runsvdir(8),
+runsvchdir(8)
+.P
+ http://smarden.org/runit/
+ http://cr.yp.to/daemontools.html
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/man/runit-init.8 b/runit-2.1.2/man/runit-init.8
new file mode 100644
index 0000000..4ea33c2
--- /dev/null
+++ b/runit-2.1.2/man/runit-init.8
@@ -0,0 +1,63 @@
+.TH runit-init 8
+.SH NAME
+init \- a UNIX process no 1
+.SH SYNOPSIS
+.B init
+[ 0 | 6 ]
+.SH DESCRIPTION
+.B runit-init
+is the first process the kernel starts.
+If
+.B runit-init
+is started as process no 1, it runs and replaces itself with
+.BR runit (8).
+.P
+If
+.B runit-init
+is started while the system is up, it must be either called as
+.B init 0
+or
+.B init 6\fR:
+.TP
+.B init 0
+tells the Unix process no 1 to shutdown and halt the system.
+To signal
+.BR runit (8)
+the system halt request,
+.B runit-init
+removes all permissions of the file
+.I /etc/runit/reboot
+(chmod 0), and sets the execute by owner permission of the file
+.I /etc/runit/stopit
+(chmod 100).
+Then a CONT signal is sent to
+.BR runit (8).
+.TP
+.B init 6
+tells the Unix process no 1 to shutdown and reboot the system.
+To signal
+.BR runit (8)
+the system reboot request,
+.B runit-init
+sets the execute by owner permission of the files
+.I /etc/runit/reboot
+and
+.I /etc/runit/stopit
+(chmod 100). Then a CONT signal is sent to
+.BR runit (8).
+.SH EXIT CODES
+.B runit-init
+returns 111 on error, 0 in all other cases.
+.SH SEE ALSO
+runit(8),
+runsvdir(8),
+runsvchdir(8),
+sv(8),
+runsv(8),
+chpst(8),
+utmpset(8),
+svlogd(8)
+.P
+http://smarden.org/runit/
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/man/runit.8 b/runit-2.1.2/man/runit.8
new file mode 100644
index 0000000..a53cf6e
--- /dev/null
+++ b/runit-2.1.2/man/runit.8
@@ -0,0 +1,88 @@
+.TH runit 8
+.SH NAME
+runit \- a UNIX process no 1
+.SH SYNOPSIS
+.B runit
+.SH DESCRIPTION
+.B runit
+must be run as Unix process no 1.
+It performs the system's booting, running, and shutdown in three stages:
+.SH STAGE 1
+.B runit
+runs
+.I /etc/runit/1
+and waits for it to terminate.
+The system's one time tasks are done here.
+.I /etc/runit/1
+has full control of
+.I /dev/console
+to be able to start an emergency shell if the one time initialization tasks
+fail. If
+.I /etc/runit/1
+crashes, or exits 100,
+.B runit
+will skip stage 2 and enter stage 3.
+.SH STAGE 2
+.B runit
+runs
+.IR /etc/runit/2 ,
+which should not return until system shutdown; if it crashes, or exits 111,
+it will be restarted.
+Normally
+.I /etc/runit/2
+starts
+.BR runsvdir (8).
+.B runit
+is able to handle the ctrl-alt-del keyboard request in stage 2, see below.
+.SH STAGE 3
+If
+.B runit
+is told to shutdown the system, or stage 2 returns, it terminates stage 2 if
+it is running, and runs
+.IR /etc/runit/3 .
+The systems tasks to shutdown and possibly halt or reboot the system are
+done here.
+If stage 3 returns,
+.B runit
+checks if the file
+.I /etc/runit/reboot
+exists and has the execute by owner permission set.
+If so, the system is rebooted, it's halted otherwise.
+.SH CTRL-ALT-DEL
+If
+.B runit
+receives the ctrl-alt-del keyboard request and the file
+.I /etc/runit/ctrlaltdel
+exists and has the execute by owner permission set,
+.B runit
+runs
+.IR /etc/runit/ctrlaltdel ,
+waits for it to terminate, and then sends itself a CONT signal.
+.SH SIGNALS
+.B runit
+only accepts signals in stage 2.
+.P
+If
+.B runit
+receives a CONT signal and the file
+.I /etc/runit/stopit
+exists and has the execute by owner permission set,
+.B runit
+is told to shutdown the system.
+.P
+if
+.B runit
+receives an INT signal, a ctrl-alt-del keyboard request is triggered.
+.SH SEE ALSO
+runit-init(8),
+runsvdir(8),
+runsvchdir(8),
+sv(8),
+runsv(8),
+chpst(8),
+utmpset(8),
+svlogd(8)
+.P
+http://smarden.org/runit/
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/man/runsv.8 b/runit-2.1.2/man/runsv.8
new file mode 100644
index 0000000..7c5abfc
--- /dev/null
+++ b/runit-2.1.2/man/runsv.8
@@ -0,0 +1,225 @@
+.TH runsv 8
+.SH NAME
+runsv \- starts and monitors a service and optionally an appendant log
+service
+.SH SYNOPSIS
+.B runsv
+.I service
+.SH DESCRIPTION
+.I service
+must be a directory.
+.P
+.B runsv
+switches to the directory
+.I service
+and starts ./run.
+If ./run exits and ./finish exists,
+.B runsv
+starts ./finish.
+If ./finish doesn't exist or ./finish exits,
+.B runsv
+restarts ./run.
+.P
+If ./run or ./finish exit immediately,
+.B runsv
+waits a second before starting ./finish or restarting ./run.
+.P
+Two arguments are given to ./finish.
+The first one is ./run's exit code, or -1 if ./run didn't exit normally.
+The second one is the least significant byte of the exit status as
+determined by
+.BR waitpid (2);
+for instance it is 0 if ./run exited normally, and the signal number
+if ./run was terminated by a signal.
+If
+.B runsv
+cannot start ./run for some reason, the exit code is 111 and the status is 0.
+.P
+If the file
+.IR service /down
+exists,
+.B runsv
+does not start ./run immediately.
+The control interface (see below) can be used to start the service and to
+give other commands to
+.BR runsv .
+.P
+If the directory
+.IR service /log
+exists,
+.B runsv
+creates a pipe, redirects
+.IR service /run's
+and
+.IR service /finish's
+standard output to the pipe, switches to the directory
+.IR service /log
+and starts ./run (and ./finish) exactly as described above for the
+.I service
+directory.
+The standard input of the log service is redirected to read from the pipe.
+.P
+.B runsv
+maintains status information in a binary format (compatible to the
+daemontools'
+.B supervise
+program) in
+.IR service /supervise/status
+and
+.IR service /log/supervise/status,
+and in a human-readable format in
+.IR service /supervise/stat,
+.IR service /log/supervise/stat,
+.IR service /supervise/pid,
+.IR service /log/supervise/pid.
+.SH CONTROL
+The named pipes
+.IR service /supervise/control,
+and (optionally)
+.IR service /log/supervise/control
+are provided to give commands to
+.BR runsv .
+You can use
+.BR sv (8)
+to control the service or just write one of the following characters to
+the named pipe:
+.TP
+.B u
+Up.
+If the service is not running, start it.
+If the service stops, restart it.
+.TP
+.B d
+Down.
+If the service is running, send it a TERM signal, and then a CONT signal.
+If ./run exits, start ./finish if it exists.
+After it stops, do not restart service.
+.TP
+.B o
+Once.
+If the service is not running, start it.
+Do not restart it if it stops.
+.TP
+.B p
+Pause.
+If the service is running, send it a STOP signal.
+.TP
+.B c
+Continue.
+If the service is running, send it a CONT signal.
+.TP
+.B h
+Hangup.
+If the service is running, send it a HUP signal.
+.TP
+.B a
+Alarm.
+If the service is running, send it a ALRM signal.
+.TP
+.B i
+Interrupt.
+If the service is running, send it a INT signal.
+.TP
+.B q
+Quit.
+If the service is running, send it a QUIT signal.
+.TP
+.B 1
+User-defined 1.
+If the service is running, send it a USR1 signal.
+.TP
+.B 2
+User-defined 2.
+If the service is running, send it a USR2 signal.
+.TP
+.B t
+Terminate.
+If the service is running, send it a TERM signal.
+.TP
+.B k
+Kill.
+If the service is running, send it a KILL signal.
+.TP
+.B x
+Exit.
+If the service is running, send it a TERM signal, and then a CONT signal.
+Do not restart the service.
+If the service is down, and no log service exists,
+.B runsv
+exits.
+If the service is down and a log service exists,
+.B runsv
+closes the standard input of the log service, and waits for it to terminate.
+If the log service is down,
+.B runsv
+exits.
+This command is ignored if it is given to
+.IR service /log/supervise/control.
+.P
+Example: to send a TERM signal to the socklog-unix service, either do
+  # sv term /service/socklog-unix
+ or
+  # printf t >/service/socklog-unix/supervise/control
+.P
+.BR printf (1)
+usually blocks if no
+.B runsv
+process is running in the service directory.
+.SH CUSTOMIZE CONTROL
+For each control character
+.I c
+sent to the control pipe,
+.B runsv
+first checks if
+.I service\fR/control/\fIc
+exists and is executable.
+If so, it starts
+.I service\fR/control/\fIc
+and waits for it to terminate, before interpreting the command.
+If the program exits with return code 0,
+.B runsv
+refrains from sending the service the corresponding signal.
+The command
+.I o
+is always considered as command
+.IR u .
+On command
+.I d
+first
+.I service\fR/control/t
+is checked, and then
+.I service\fR/control/d.
+On command
+.I x
+first
+.I service\fR/control/t
+is checked, and then
+.I service\fR/control/x.
+The control of the optional log service cannot be customized.
+.SH SIGNALS
+If
+.B runsv
+receives a TERM signal, it acts as if the character x was written to the
+control pipe.
+.SH EXIT CODES
+.B runsv
+exits 111 on an error on startup or if another
+.B runsv
+is running in
+.IR service .
+.P
+.B runsv
+exits 0 if it was told to exit.
+.SH SEE ALSO
+sv(8),
+chpst(8),
+svlogd(8),
+runit(8),
+runit-init(8),
+runsvdir(8),
+runsvchdir(8),
+utmpset(8)
+.P
+http://smarden.org/runit/
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/man/runsvchdir.8 b/runit-2.1.2/man/runsvchdir.8
new file mode 100644
index 0000000..f7f94dc
--- /dev/null
+++ b/runit-2.1.2/man/runsvchdir.8
@@ -0,0 +1,55 @@
+.TH runsvchdir 8
+.SH NAME
+runsvchdir \- change services directory of runsvdir(8)
+.SH SYNOPSIS
+.B runsvchdir
+.I dir
+.SH DESCRIPTION
+.I dir
+is a services directory for the use with
+.BR runsvdir (8).
+If
+.I dir
+does not start with a slash, it is searched in /etc/runit/runsvdir/.
+.I dir
+must not start with a dot.
+.P
+.B runsvchdir
+switches to the directory
+.IR /etc/runit/runsvdir/ ,
+copies
+.I current
+to
+.IR previous ,
+and replaces
+.I current
+with a symlink pointing to
+.IR dir .
+.P
+Normally 
+.I /service
+is a symlink to
+.IR current ,
+and
+.BR runsvdir (8)
+is running
+.IR /service/ .
+.SH EXIT CODES
+.B runsvchdir
+prints an error message and exits 111 on error.
+.B runsvchdir
+exits 0 on success.
+.SH FILES
+ /etc/runit/runsvdir/previous
+ /etc/runit/runsvdir/current
+ /etc/runit/runsvdir/current.new
+.SH SEE ALSO
+runsvdir(8),
+runit(8),
+runit-init(8),
+sv(8),
+runsv(8)
+.P
+http://smarden.org/runit/
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/man/runsvdir.8 b/runit-2.1.2/man/runsvdir.8
new file mode 100644
index 0000000..adfa587
--- /dev/null
+++ b/runit-2.1.2/man/runsvdir.8
@@ -0,0 +1,102 @@
+.TH runsvdir 8
+.SH NAME
+runsvdir \- starts and monitors a collection of runsv(8) processes
+.SH SYNOPSIS
+.B runsvdir
+[\-P]
+.I dir
+[
+.I log
+]
+.SH DESCRIPTION
+.I dir
+must be a directory.
+.I log
+is a space holder for a readproctitle log, and must be at least seven
+characters long or absent.
+.P
+.B runsvdir
+starts a
+.BR runsv (8)
+process for each subdirectory, or symlink to a directory, in the services
+directory
+.IR dir ,
+up to a limit of 1000 subdirectories,
+and restarts a
+.BR runsv (8)
+process if it terminates.
+.B runsvdir
+skips subdirectory names starting with dots.
+.BR runsv (8)
+must be in
+.BR runsvdir 's
+PATH.
+.P
+At least every five seconds
+.B runsvdir
+checks whether the time of last modification, the inode, or the device, of
+the services directory
+.I dir
+has changed.
+If so, it re-scans the service directory, and if it sees a new subdirectory,
+or new symlink to a directory, in
+.IR dir ,
+it starts a new
+.BR runsv (8)
+process;
+if
+.B runsvdir
+sees a subdirectory being removed that was previously there, it sends the
+corresponding
+.BR runsv (8)
+process a TERM signal, stops monitoring this process, and so does not
+restart the
+.BR runsv (8)
+process if it exits.
+.P
+If the
+.I log
+argument is given to
+.BR runsvdir ,
+all output to standard error is redirected to this
+.IR log ,
+which is similar to the daemontools'
+.B readproctitle
+log.
+To see the most recent error messages, use a process-listing tool such as
+.BR ps (1).
+.B runsvdir
+writes a dot to the readproctitle log every 15 minutes so that old error
+messages expire.
+.SH OPTIONS
+.TP
+.B \-P
+use
+.BR setsid (2)
+to run each
+.BR runsv (8)
+process in a new session and separate process group.
+.SH SIGNALS
+If
+.B runsvdir
+receives a TERM signal, it exits with 0 immediately.
+.P
+If
+.B runsvdir
+receives a HUP signal, it sends a TERM signal to each
+.BR runsv (8)
+process it is monitoring and then exits with 111.
+.SH SEE ALSO
+sv(8),
+runsv(8),
+runsvchdir(8),
+runit(8),
+runit-init(8),
+chpst(8),
+svlogd(8),
+utmpset(8),
+setsid(2)
+.P
+http://smarden.org/runit/
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/man/sv.8 b/runit-2.1.2/man/sv.8
new file mode 100644
index 0000000..7ed9852
--- /dev/null
+++ b/runit-2.1.2/man/sv.8
@@ -0,0 +1,285 @@
+.TH sv 8
+.SH NAME
+sv \- control and manage services monitored by
+.BR runsv (8)
+.SH SYNOPSIS
+.B sv
+[\-v] [\-w
+.I sec\fR]
+.I command
+.I services
+.P
+.BI /etc/init.d/ service
+[\-w
+.I sec\fR]
+.I command
+.SH DESCRIPTION
+The
+.B sv
+program reports the current status and controls the state of services
+monitored by the
+.BR runsv (8)
+supervisor.
+.P
+.I services
+consists of one or more arguments, each argument naming a directory
+.I service
+used by
+.BR runsv (8).
+If
+.I service
+doesn't start with a dot or slash and doesn't end with a slash, it is
+searched in the default services directory
+.IR /service/ ,
+otherwise relative to the current directory.
+.P
+.I command
+is one of up, down, status, once, pause, cont, hup, alarm, interrupt, 1, 2,
+term, kill, or exit, or start, stop, restart, shutdown, force-stop,
+force-reload, force-restart, force-shutdown.
+.P
+The
+.B sv
+program can be sym-linked to
+.I /etc/init.d/
+to provide an LSB init script interface.
+The
+.I service
+to be controlled then is specified by the base name of the ``init script''.
+.SH COMMANDS
+.TP
+.B status
+Report the current status of the service, and the appendant log service if
+available, to standard output.
+.TP
+.B up
+If the service is not running, start it.
+If the service stops, restart it.
+.TP
+.B down
+If the service is running, send it the TERM signal, and the CONT signal.
+If ./run exits, start ./finish if it exists.
+After it stops, do not restart service.
+.TP
+.B once
+If the service is not running, start it.
+Do not restart it if it stops.
+.TP
+.B pause cont hup alarm interrupt quit 1 2 term kill
+If the service is running, send it the STOP, CONT, HUP, ALRM, INT, QUIT,
+USR1, USR2, TERM, or KILL signal respectively.
+.TP
+.B exit
+If the service is running, send it the TERM signal, and the CONT signal.
+Do not restart the service.
+If the service is down, and no log service exists,
+.BR runsv (8)
+exits.
+If the service is down and a log service exists,
+.BR runsv (8)
+closes the standard input of the log service and waits for it to terminate.
+If the log service is down,
+.BR runsv (8)
+exits.
+This command is ignored if it is given to an appendant log service.
+.P
+.BR sv
+actually looks only at the first character of these
+.IR command s.
+.SS Commands compatible to LSB init script actions
+.TP
+.B status
+Same as
+.IR status .
+.TP
+.B start
+Same as
+.IR up ,
+but wait up to 7 seconds for the command to take effect.
+Then report the status or timeout.
+If the script
+.I ./check
+exists in the service directory,
+.B sv
+runs this script to check whether the service is up and available;
+it's considered to be available if
+.I ./check
+exits with 0.
+.TP
+.B stop
+Same as
+.IR down ,
+but wait up to 7 seconds for the service to become down.
+Then report the status or timeout.
+.TP
+.B reload
+Same as
+.IR hup ,
+and additionally report the status afterwards.
+.TP
+.B restart
+Send the commands
+.IR term ,
+.IR cont ,
+and
+.I up
+to the service, and wait up to 7 seconds for the service to restart.
+Then report the status or timeout.
+If the script
+.I ./check
+exists in the service directory,
+.B sv
+runs this script to check whether the service is up and available again;
+it's considered to be available if
+.I ./check
+exits with 0.
+.TP
+.B shutdown
+Same as
+.IR exit ,
+but wait up to 7 seconds for the
+.BR runsv (8)
+process to terminate.
+Then report the status or timeout.
+.TP
+.B force-stop
+Same as
+.IR down ,
+but wait up to 7 seconds for the service to become down.
+Then report the status, and on timeout send the service the
+.I kill
+command.
+.TP
+.B force-reload
+Send the service the
+.I term
+and
+.I cont
+commands, and wait up to 7 seconds for the service to restart.
+Then report the status, and on timeout send the service the
+.I kill
+command.
+.TP
+.B force-restart
+Send the service the
+.IR term ,
+.I cont
+and
+.I up
+commands, and wait up to 7 seconds for the service to restart.
+Then report the status, and on timeout send the service the
+.I kill
+command.
+If the script
+.I ./check
+exists in the service directory,
+.B sv
+runs this script to check whether the service is up and available again;
+it's considered to be available if
+.I ./check
+exits with 0.
+.TP
+.B force-shutdown
+Same as
+.IR exit ,
+but wait up to 7 seconds for the
+.BR runsv (8)
+process to terminate.
+Then report the status, and on timeout send the service the
+.I kill
+command.
+.TP
+.B try-restart
+if the service is running, send it the
+.I term
+and
+.I cont
+commands, and wait up to 7 seconds for the service to restart.
+Then report the status or timeout.
+
+.SS Additional Commands
+.TP
+.B check
+Check for the service to be in the state that's been requested.
+Wait up to 7 seconds for the service to reach the requested state, then
+report the status or timeout.
+If the requested state of the service is
+.IR up ,
+and the script
+.I ./check
+exists in the service directory,
+.B sv
+runs this script to check whether the service is up and running; it's
+considered to be up if
+.I ./check
+exits with 0.
+.SH OPTIONS
+.TP
+.B \-v
+If the
+.I command
+is up, down, term, once, cont, or exit, then wait up to 7 seconds for the
+command to take effect.
+Then report the status or timeout.
+.TP
+.B \-w \fIsec
+Override the default timeout of 7 seconds with
+.I sec
+seconds.
+This option implies
+.IR \-v .
+.SH ENVIRONMENT
+.TP
+.B SVDIR
+The environment variable $SVDIR overrides the default services directory
+.IR /service/ .
+.TP
+.B SVWAIT
+The environment variable $SVWAIT overrides the default 7 seconds to wait
+for a command to take effect.
+It is overridden by the \-w option.
+.SH EXIT CODES
+.B sv
+exits 0, if the
+.I command
+was successfully sent to all
+.IR services ,
+and, if it was told to wait, the
+.I command
+has taken effect to all services.
+.P
+For each
+.I service
+that caused an error (e.g. the directory is not controlled by a
+.BR runsv (8)
+process, or
+.B sv
+timed out while waiting),
+.B sv
+increases the exit code by one and exits non zero.
+The maximum is 99.
+.B sv
+exits 100 on error.
+.P
+If
+.B sv
+is called with a base name other than
+.BR sv :
+it exits 1 on timeout or trouble sending the command; if the
+.I command
+is
+.BR status ,
+it exits 3 if the service is down, and 4 if the status is unknown;
+it exits 2 on wrong usage, and 151 on error.
+.SH SEE ALSO
+runsv(8),
+chpst(8),
+svlogd(8),
+runsvdir(8),
+runsvchdir(8),
+runit(8),
+runit-init(8)
+.P
+http://smarden.org/runit/
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/man/svlogd.8 b/runit-2.1.2/man/svlogd.8
new file mode 100644
index 0000000..01b2324
--- /dev/null
+++ b/runit-2.1.2/man/svlogd.8
@@ -0,0 +1,464 @@
+.TH svlogd 8
+.SH NAME
+svlogd \- runit's service logging daemon
+.SH SYNOPSIS
+.B svlogd
+[\-tttv] [\-r
+.I c\fR] [\-R
+.I xyz\fR] [\-l
+.I len\fR] [\-b
+.I buflen\fR]
+.I logs
+.SH DESCRIPTION
+.I logs
+consists of one or more arguments, each specifying a directory.
+.P
+.B svlogd
+continuously reads log data from its standard input, optionally filters log
+messages, and writes the data to one or more automatically rotated
+.IR logs .
+.P
+Recent log files can automatically be processed by an arbitrary processor
+program when they are rotated, and
+.B svlogd
+can be told to alert selected log messages to standard error, and through
+udp.
+.P
+.B svlogd
+runs until it sees end-of-file on standard input or is sent a TERM signal,
+see below.
+.SS LOG DIRECTORY
+A log directory
+.I log
+contains some number of old log files, and the current log file
+.IR current .
+Old log files have a file name starting with
+.I @
+followed by a precise timestamp (see the daemontools'
+.B tai64n
+program), indicating when
+.I current
+was rotated and renamed to this file.
+.P
+A log directory additionally contains the lock file
+.IR lock ,
+maybe
+.I state
+and
+.IR newstate ,
+and optionally the file
+.IR config .
+.B svlogd
+creates necessary files if they don't exist.
+.P
+If
+.B svlogd
+has trouble opening a log directory, it prints a warning, and ignores this
+log directory.
+If
+.B svlogd
+is unable to open all log directories given at the command line, it exits
+with an error.
+This can happen on start-up or after receiving a HUP signal.
+.SS LOG FILE ROTATION
+.B svlogd
+appends selected log messages to the
+.I current
+log file.
+If
+.I current
+has
+.I size
+bytes or more (or there is a new-line within the last
+.I len
+of
+.I size
+bytes), or is older than a specified amount of
+.IR time ,
+.I current
+is rotated:
+.P
+.B svlogd
+closes
+.IR current ,
+changes permission of
+.I current
+to 0755, renames
+.I current
+to
+.RI @ timestamp\fR.s,
+and starts with a new empty
+.IR current .
+If
+.B svlogd
+sees
+.I num
+or more old log files in the log directory, it removes the oldest one.
+Note that this doesn't decrease the number of log files if there are
+already more than
+.I num
+log files, this must be done manually, e.g. for keeping 10 log files:
+.P
+ ls \-1 \\@* |sort |sed \-ne '10,$p' |xargs rm
+.SS PROCESSOR
+If
+.B svlogd
+is told to process recent log files, it saves
+.I current
+to
+.RI @ timestamp\fR.u,
+feeds
+.RI @ timestamp\fR.u
+through ``sh \-c "\fIprocessor\fR"''
+and writes the output to
+.RI @ timestamp\fR.t.
+If the
+.I processor
+finishes successfully,
+.RI @ timestamp\fR.t
+is renamed to
+.RI @ timestamp\fR.s,
+and
+.RI @ timestamp\fR.u
+is deleted; otherwise
+.RI @ timestamp\fR.t
+is deleted and the
+.I processor
+is started again.
+.B svlogd
+also saves any output that the
+.I processor
+writes to file descriptor 5, and makes that output available on file
+descriptor 4 when running
+.I processor
+on the next log file rotation.
+.P
+A
+.I processor
+is run in the background.
+If
+.B svlogd
+sees a previously started
+.I processor
+still running when trying to start a new one for the same
+.IR log ,
+it blocks until the currently running
+.I processor
+has finished successfully.
+Only the HUP signal works in that situation.
+Note that this may block any program feeding its log data to
+.BR svlogd.
+
+.SS CONFIG
+On startup, and after receiving a HUP signal,
+.B svlogd
+checks for each log directory
+.I log
+if the configuration file
+.I log/config
+exists, and if so, reads the file line by line and adjusts configuration for
+.I log
+as follows:
+.P
+If the line is empty, or starts with a ``#'', it is ignored.
+A line of the form
+.TP
+.RI s size
+sets the maximum file size of
+.I current
+when
+.B svlogd
+should rotate the current log file to
+.I size
+bytes.
+Default is 1000000.
+If
+.I size
+is zero,
+.B svlogd
+doesn't rotate log files.
+You should set
+.I size
+to at least (2 *
+.IR len ).
+.TP
+.RI n num
+sets the number of old log files
+.B svlogd
+should maintain to
+.IR num .
+If
+.B svlogd
+sees more that
+.I num
+old log files in
+.I log
+after log file rotation, it deletes the oldest one.
+Default is 10.
+If
+.I num
+is zero,
+.B svlogd
+doesn't remove old log files.
+.TP
+.RI N min
+sets the minimum number of old log files
+.B svlogd
+should maintain to
+.IR min .
+.I min
+must be less than
+.IR num .
+If
+.I min
+is set, and
+.B svlogd
+cannot write to
+.I current
+because the filesystem is full, and it sees more than
+.I min
+old log files, it deletes the oldest one.
+.TP
+.RI t timeout
+sets the maximum age of the
+.I current
+log file when
+.B svlogd
+should rotate the current log file to
+.I timeout
+seconds.
+If
+.I current
+is
+.I timeout
+seconds old, and is not empty,
+.B svlogd
+forces log file rotation.
+.TP
+.RI ! processor
+tells
+.B svlogd
+to feed each recent log file through
+.I processor
+(see above) on log file rotation.
+By default log files are not processed.
+.TP
+.RI u a.b.c.d[:port]
+tells
+.B svlogd
+to transmit the first
+.I len
+characters of selected log messages to the IP address
+.IR a.b.c.d ,
+port number
+.IR port .
+If
+.I port
+isn't set, the default port for syslog is used (514).
+.I len
+can be set through the \-l option, see below.
+If
+.B svlogd
+has trouble sending udp packets, it writes error messages to the log
+directory.
+Attention:
+logging through udp is unreliable, and should be used in private networks
+only.
+.TP
+.RI U a.b.c.d[:port]
+is the same as the
+.I u
+line above, but the log messages are no longer written to the log directory,
+but transmitted through udp only.
+Error messages from
+.B svlogd
+concerning sending udp packages still go to the log directory.
+.TP
+.RI p prefix
+tells
+.B svlogd
+to prefix each line to be written to the log directory, to standard error,
+or through UDP, with
+.IR prefix .
+.P
+If a line starts with a
+.IR \- ,
+.IR + ,
+.IR e ,
+or
+.IR E ,
+.B svlogd
+matches the first
+.I len
+characters of each log message against
+.I pattern
+and acts accordingly:
+.TP
+.RI \- pattern
+the log message is deselected.
+.TP
+.RI + pattern
+the log message is selected.
+.TP
+.RI e pattern
+the log message is selected to be printed to standard error.
+.TP
+.RI E pattern
+the log message is deselected to be printed to standard error.
+.P
+Initially each line is selected to be written to
+.IR log/current .
+Deselected log messages are discarded from
+.IR log .
+Initially each line is deselected to be written to standard err.
+Log messages selected for standard error are written to standard error.
+.SH PATTERN MATCHING
+.B svlogd
+matches a log message against the string
+.I pattern
+as follows:
+.P
+.I pattern
+is applied to the log message one character by one, starting with the first.
+A character not a star (``*'') and not a plus (``+'') matches itself.
+A plus matches the next character in
+.I pattern
+in the log message one or more times.
+A star before the end of
+.I pattern
+matches any string in the log message that does not include the next
+character in
+.IR pattern .
+A star at the end of
+.I pattern
+matches any string.
+.P
+Timestamps optionally added by
+.B svlogd
+are not considered part of the log message.
+.P
+An
+.B svlogd
+pattern is not a regular expression.
+For example consider a log message like this
+.P
+ 2005-12-18_09:13:50.97618 tcpsvd: info: pid 1977 from 10.4.1.14
+.P
+The following pattern doesn't match
+.P
+ -*pid*
+.P
+because the first star matches up to the first p in tcpsvd, and then the
+match fails because i is not s.
+To match this log message, you can use a pattern like this instead
+.P
+ -*: *: pid *
+.SH OPTIONS
+.TP
+.B \-t
+timestamp.
+Prefix each selected line with a precise timestamp (see the daemontools'
+.B tai64n
+program) when writing to
+.I log
+or to standard error.
+.TP
+.B \-tt
+timestamp.
+Prefix each selected line with a human readable, sortable UTC timestamp of
+the form YYYY-MM-DD_HH:MM:SS.xxxxx when writing to
+.I log
+or to standard error.
+.TP
+.B \-ttt
+timestamp.
+Prefix each selected line with a human readable, sortable UTC timestamp of
+the form YYYY-MM-DDTHH:MM:SS.xxxxx when writing to
+.I log
+or to standard error.
+.TP
+.B \-r \fIc
+replace.
+.I c
+must be a single character.
+Replace non-printable characters in log messages with
+.IR c .
+Characters are replaced before pattern matching is applied.
+.TP
+.B \-R \fIxyz
+replace charset.
+Additionally to non-printable characters, replace all characters found in
+.I xyz
+with
+.I c
+(default ``_'').
+.TP
+.B \-l \fIlen
+line length.
+Pattern matching applies to the first
+.I len
+characters of a log message only.
+Default is 1000.
+.TP
+.B \-b \fIbuflen
+buffer size.
+Set the size of the buffer
+.B svlogd
+uses when reading from standard input and writing to
+.I logs
+to
+.IR buflen .
+Default is 1024.
+.I buflen
+must be greater than
+.IR len .
+For
+.B svlogd
+instances that process a lot of data in short time, the buffer size should
+be increased to improve performance.
+.TP
+.B \-v
+verbose.
+Print verbose messages to standard error.
+.SH SIGNALS
+If
+.B svlogd
+is sent a HUP signal, it closes and reopens all
+.IR logs ,
+and updates their configuration according to
+.IR log/config .
+If
+.B svlogd
+has trouble opening a log directory, it prints a warning, and discards this
+log directory.
+If
+.B svlogd
+is unable to open all log directories given at the command line, it exits
+with an error.
+.P
+If
+.B svlogd
+is sent a TERM signal, or if it sees end-of-file on standard input, it stops
+reading standard input, processes the data in the buffer, waits for all
+.I processor
+subprocesses to finish if any, and exits 0 as soon as possible.
+.P
+If
+.B svlogd
+is sent an ALRM signal, it forces log file rotation for all
+.I logs
+with a non empty
+.I current
+log file.
+.SH SEE ALSO
+sv(8),
+runsv(8),
+chpst(8),
+runit(8),
+runit-init(8),
+runsvdir(8),
+runsvchdir(8)
+.P
+http://smarden.org/runit/
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/man/utmpset.8 b/runit-2.1.2/man/utmpset.8
new file mode 100644
index 0000000..4f9b4ef
--- /dev/null
+++ b/runit-2.1.2/man/utmpset.8
@@ -0,0 +1,63 @@
+.TH utmpset 8
+.SH NAME
+utmpset \- logout a line from utmp and wtmp file
+.SH SYNOPSIS
+.B utmpset
+[
+.B \-w
+]
+.I line
+.SH DESCRIPTION
+The
+.B utmpset
+program modifies the user accounting database
+.BR utmp (5)
+and optionally
+.BR wtmp (5)
+to indicate that the user on the terminal
+.I line
+has logged out.
+.P
+Ordinary
+.BR init (8)
+processes handle utmp file records for local login accounting.
+The
+.BR runit (8)
+program doesn't include code to update the utmp file, the
+.BR getty (8)
+processes are handled the same as all other services.
+.P
+To enable local login accounting, add
+.B utmpset
+to the
+.BR getty (8)
+.I finish
+scripts, e.g.:
+.P
+ $ cat /service/getty-5/finish
+ #!/bin/sh
+ exec utmpset \-w tty5
+ $
+.SH OPTIONS
+.TP
+.B \-w
+wtmp. Additionally to the utmp file, write an empty record for
+.I line
+to the wtmp file.
+.SH EXIT CODES
+.B utmpset
+returns 111 on error, 1 on wrong usage, 0 in all other cases.
+.SH SEE ALSO
+sv(8),
+runsv(8),
+runit(8),
+runit-init(8)
+runsvdir(8),
+runsvchdir(8),
+chpst(8),
+svlogd(8),
+getty(8)
+.P
+http://smarden.org/runit/
+.SH AUTHOR
+Gerrit Pape <pape@smarden.org>
diff --git a/runit-2.1.2/package/CHANGES b/runit-2.1.2/package/CHANGES
new file mode 100644
index 0000000..da4ea27
--- /dev/null
+++ b/runit-2.1.2/package/CHANGES
@@ -0,0 +1,688 @@
+2.1.2
+Sun, 10 Aug 2014 18:01:54 +0000
+  * doc/index.html: reorder, cleanup links to distributions; add Linux
+    from Scratch, Finnix, VServer.
+  * sv.c: properly format status command's output on failure cases.
+  * sv.c: support optional LSB init script actions reload and
+    try-restart.
+  * man/sv.8: "sv exit" does not send a TERM signal to the log service
+    (thx Jonathan Nieder).
+  * fmt_ptime.c: 64 bits time_t fix for svlogd (tnx Jérémie
+    Courrèges-Anglas).
+  * sv.c: fix typo that may lead to wrong output from sv when reporting
+    status of multiple service directories.
+  * doc/index.html: add deepOfix Mail Server to list of distributions
+    that include runit (thx Debayan Banerjee).
+  * doc/useinit.html: update description on how to use with upstart
+    (thx Gabriel de Perthuis).
+  * doc/index.html: add Dragora GNU/Linux to list of distributions that
+    use runit as default init scheme (thx Matias A. Fonzo).
+  * doc/index.html: add ArchLinux to list of distributions that include
+    runit (thx Kevin Berry).
+
+2.1.1
+Sun, 04 Oct 2009 20:28:38 +0000
+  * doc/upgrade.html: fix typo.
+  * sv.c: on 'down', send runsv the 'down' command properly if not yet
+    done (e.g. when taken up with 'once').
+
+2.1.0
+Thu, 24 Sep 2009 22:49:33 +0000
+  * pathexec_env.c, pathexec.h: add function pathexec_env_run().
+  * chpst.c, man/chpst.8: new option -b argv0: run prog with different
+    0th argument.
+  * sv.c: fix exit code of status command in lsb mode (thx Mathieu
+    Poumeyrol)
+  * chpst.c, svwaitdown.c, svwaitup.c: fix checks for return value of
+    open_* functions (thx David Reiss).
+  * runsv.c: exit with error if [log/]supervise/control exists, but is
+    not a fifo (thx Charlie Brady).
+  * man/sv.8: clarify which return values apply to the LSB init script
+    interface.
+
+2.0.0
+Sun, 15 Jun 2008 15:31:05 +0000
+
+1.9.0
+Mon, 05 May 2008 22:00:13 +0000
+  * doc/upgrade.html: typo.
+  * sv.c: service name is also relative to the current directory if it
+    ends with a slash.
+  * change default directory for services from /var/service/ to /service/.
+  * runsv.c: create temporary new status files for log/supervise/ actually
+    in log/supervise/.
+  * doc/benefits.html: minor additions.
+
+1.8.0
+Fri, 21 Sep 2007 00:33:56 +0000
+  * man/svlogd.8: add hint on how to manually remove log files after the
+    number of log files svlogd should maintain has been reduced; add hint
+    about increasing the buffer size if lots of data is to be processed
+    in short time.
+  * chpst.c, uidgid.c: improve error reporting if getpwnam() or getgrnam()
+    fails; cleanup.
+  * svlogd.c: don't statically bind local udp socket, but request new
+    source port for each log message sent through udp.
+  * runit.c: fix typo in error messages (thx Matthew R. Dempsky); minor
+    rewording.
+  * doc/useinit.html: add instructions on how to use with upstart (thx
+    Lloyd Zusman).
+  * chpst.c: add explicit braces to avoid ambiguous 'else'.
+  * uw_tmp.h1: fallback to UTMP_FILE if _PATH_UTMP is not defined as seen
+    on AIX 5.2 ML1, AIX 5.3 ML5 (thx Daniel Clark).
+  * sv.c: fix race on check for down if pid is 0 and state is run or finish.
+  * runit.c: speed up collecting zombies.
+  * runit.c: force check for zombies after a 14 second timeout without
+    signals (CHLD, CONT, INT).
+  * doc/index.html: typo.
+  * doc/*.html: remove $Id$.
+
+1.7.2
+Tue, 21 Nov 2006 15:13:47 +0000
+  * doc/index.html: add list of distributions that are known to include
+    or package runit; some reordering.
+  * doc/replaceinit.html: point to faq.html#create, faq.html#tell (thx
+    David Kaufman).
+  * doc/runscripts.html: point to faq.html#createlog.
+  * runit.c: fix arguments to wait_pid() after fork for reboot_system()
+    (thx Jan Kampe).
+  * man/runsv.8: suggest printf t instead of echo -n t.
+  * runsv.c: really don't act on commands in state finish; minor.
+
+1.7.1
+Sat, 04 Nov 2006 19:23:29 +0000
+  * chpst.c, uidgid.c, uidgid.h: support numerical uid gid through
+    chpst -[u|U] :uid:gid...
+  * man/chpst.8: adapt; clarify that users and groups are looked up in
+    /etc/passwd and /etc/group only.
+  * sv.c: properly wait for a service to be restarted on 'restart';
+    support checks through -v for pause, cont, kill.
+  * doc/runscripts.html: add contributed run scripts (thx Kevin, marlowe,
+    ed neville, xavier dutoit).
+
+1.7.0
+Sat, 07 Oct 2006 18:24:17 +0000
+  * svlogd.c, fmt_ptime.*, man/svlogd.8: new option -ttt: prefix log
+    messages with sortable UTC timestamp YYYY-MM-DDTHH:MM:SS.xxxxx.
+  * runsv.c, runsv.8: give two arguments to ./finish: exit code and exit
+    status of ./run (mostly copied from pipe-tools' npt-supervise, thx
+    Laurent Bercot).
+  * runit.c: don't make console the controlling terminal for process 1,
+    but for stage 1 only; fork before initiating system halt or reboot,
+    the linux kernel calls do_exit(0) in kernel/sys.c (thx Jan Kampe).
+
+1.6.0
+Thu, 29 Jun 2006 07:52:35 +0000
+  * svlogd.c: cleanup *.t files possibly leftover by processor when
+    interrupted by signal, also on startup (thx Andras Korn,
+    http://bugs.debian.org/369840); 1st rename .t to .s, then remove .u.
+  * man/svlogd.8: adapt.
+  * svlogd.c: prepend optional timestamp to log messages sent through UDP,
+    as done for messages written to dir and to stderr.
+  * uidgid.c: properly fixup user/group argument on getpwnam() error.
+  * doc/benefits.html: typo; wording.
+
+1.5.1
+Wed, 10 May 2006 20:55:35 +0000
+  * runsv.c: delay restart of log service at least 1 sec, just as the main
+    service.
+  * runsvdir.c: don't double-copy filedescriptor.
+  * package/README, package/COPYING: 2006.
+  * man/runsvctrl.8, man/runsvstat.8, man/svwaitup.8, man/svwaitdown.8,
+    doc/runsvctrl.html, doc/runsvstat.html, doc/svwaitdown.html,
+    doc/svwaitup.html: remove; obsolete.
+
+1.5.0
+Sun, 16 Apr 2006 12:26:50 +0000
+  * man/runsvdir.8: document that the services directory is re-scanned if
+    the time of last modification, the inode, or the device has changed.
+  * sv.c: don't report success on 'sv start' if the service is in state
+    finish (thx Matthew R. Dempsky).
+  * svlogd.c: new config line p: optionally prefix each line written to
+    logs, stderr, or through udp; no longer skip empty lines (just
+    containing '\n'), old behavior can be restored with '-' in config.
+  * man/svlogd.8: document new p config line; adapt.
+
+1.4.1
+Mon, 20 Mar 2006 18:54:41 +0000
+  * doc/faq.html: typos; add usercontrol, userservices; minor.
+  * src/uidgid.h: use uid_t, git_t (fix setting of multiple groups with
+    dietlibc, thx Tino Keitel, http://bugs.debian.org/356016)
+
+runit 1.4.0
+Mon, 06 Mar 2006 12:45:08 +0000
+  * doc/faq.html: new.
+  * doc/benefits.html: use sv program instead of runsvstat, runsvctrl;
+    minor.
+  * doc/replaceinit.html, doc/runlevels.html: put getty service directory
+    into /etc/sv/.
+  * doc/runscripts.html: use sv program instead of svwaitup.
+  * etc/*/3, etc/macosx/StartupItems/runit: use sv program instead of
+    svwaitdown.
+  * man/runsv.8: use sv program instead of runsvctrl.
+  * man/sv.8: minor.
+  * Makefile, package/commands: no longer build/install runsvctrl,
+    runsvstat, svwaitdown, svwaitup.
+  * man/runsvctrl.8, man/runsvstat.8, man/svwaitdown.8, man/svwaitup.8:
+    remove; obsolete.
+  * doc/index.html: add faq; remove runsvctrl, runsvstat, svwaitdown,
+    svwaitup.
+  * sv: fix usage output.
+  * chpst: new option -d, limit data segment per process; don't use nested
+    functions.
+
+runit 1.3.3
+Mon, 02 Jan 2006 20:35:34 +0000
+  * chpst.c: adjust nice value and set limits before dropping permissions.
+  * sv.c: new additional command 'check'; with -v check for CONT through
+    ./check if service is up.
+  * man/sv.8: adapt.
+
+runit 1.3.2
+Sun, 18 Dec 2005 11:22:04 +0000
+  * svlogd.c: don't print extra newlines to the log if additionally writing
+    to the network through udp (thx Andras Korn,
+    http://bugs.debian.org/339030).
+  * runsvdir.c: also process svdir changes if mtime of svdir has changed into
+    the past (thx Martin Dickopp).
+  * doc/index.html: update description; Please contact this list and not me
+    privately.
+  * doc/replaceinit.html, doc/runscripts.html: minor.
+  * man/chpst.8: -U doesn't support a list of groups.
+  * man/svlogd.8: update PATTERN MATCHING section, add example (based on
+    sugesstions from Joshua N Pritikin).
+  * man/*8: update SEE ALSO sections: runsvctrl, runsvstat, svwaitdown,
+    svwaitup will become obsolete; remove references to man pages for
+    programs from the daemontools package.
+
+runit 1.3.1
+Wed, 24 Aug 2005 20:14:17 +0000
+  * doc/runscripts.html: typo; openssh needs absolute path (thx Kevin Berry);
+    exec into dhcpcd.
+  * uidgid.c, uidgid.h, chpst.c: support colon-separated list of groups.
+  * sv.c: utilize optional ./check script in service directory to check for
+    availablity of service.
+  * runsv.c: wait_pid() might be interupted.
+  * man/chpst.8, man/sv.8: adapt.
+
+runit 1.3.0
+Sun, 24 Jul 2005 16:50:55 +0000
+  * man/runsv.8: typo; no longer document the e control character; clarify
+    custom control on d and x.
+  * doc/useinit.html: how to use runit with macosx 10.4 (thx Lars Uffmann).
+  * etc/macosx/org.smarden.runit.plist: new; launchd plist file for
+    runsvdir-start (thx Lars Uffmann).
+  * doc/runscripts.html: don't use absolute pathnames for programs in $PATH;
+    add contributed run scripts (thx Sascha Huedepohl); typos.
+  * runsvchdir.c, runsvstat.c: optimize output buffer handling.
+  * runsvctrl.c: write x control character to runsv on e.
+  * svlogd.c: write to log dir after possibly writing through udp (fixes
+    line break issue).
+  * runsv.c, runsv.check: optimize output buffer handling; porperly run
+    custom t, d, x, k, when stopping service; no longer support e control
+    character.
+  * sv.c: new sv program to control services, optionally can be linked to
+    /etc/init.d/ as lsb "init script" command line interface.
+  * Makefile, TARGETS: adapt.
+  * chpst.c: fix pointer types.
+  * man/sv.8: new.
+  * package/TODO: new.
+
+runit 1.2.3
+Mon, 18 Apr 2005 17:08:35 +0000
+  * doc/runscripts.html: add contributed run scripts (thx Kevin Berry);
+    remove mysql run scripts.
+  * svlogd.dist, svwaitdown.dist, svwaitup.dist: fix program selftest's
+    false alarms (thx Ian Stokes-Rees).
+
+runit 1.2.2
+Sun, 03 Apr 2005 09:21:52 +0000
+  * doc/index.html, doc/replaceinit.html: no longer refer to sysvinit's
+    shutdown program.
+  * man/svlogd.8: svlogd doesn't decrease the number of log files in a log
+    directory; with n0 don't remove any log files.
+  * svlogd.c: properly prefix log messages written to standard error with
+    optional timestamp.
+  * runsvctrl.c, svwaitdown.c, svwaitup.c: supervise not running -> runsv
+    not running.
+  * package/README: 2005.
+
+runit 1.2.1
+Sat, 15 Jan 2005 11:57:46 +0000
+  * chpst.c: typo.
+  * svwaitdown.c: minimum timeout is 1 second; service directories no longer
+    must start with /.
+  * svwaitup.c: minimum uptime of services is 1 second; service directories
+    no longer must start with /; print number of seconds a service is up if
+    verbose.
+  * man/svwaitdown.8, man/svwaitup.8: adapt.
+  * doc/runscripts.html: add contributed run scripts (thx Stefan Karrmann,
+    Kevin Berry, Karl Chen).
+  * runsv.c: typos; bugfix: run optional control/x when receiving SIGTERM
+    (thx Vladimir Smelhaus); minor.
+  * man/runsvctrl.8: minor.
+  * package/COPYING: adapt, 2005.
+
+runit 1.2.0
+Fri, 17 Dec 2004 21:08:50 +0000
+  * doc/upgrade.html: typo.
+  * runsv.c: support custom control commands through control/ directory,
+    optionally switch off sending signal; don't update timestamp in status
+    when running ./finish; only sleep for a second if ./run has been
+    restarted within a second, and after updating status to down, normally
+    up, want up.
+  * man/runsv.8: document custom control commands.
+  * runsv.check, runsv.dist: check custom control commands.
+  * doc/runscripts.html: add contributed run scripts (thx Stefan Karrmann,
+    Kevin Berry).
+
+runit 1.1.0
+Sat, 06 Nov 2004 17:21:11 +0000
+  * svlogd.c: new config option t timeout (thx Enrico Scholz); config
+    options e and E select and deselect lines for stderr respectively (thx
+    Vladimir Smelhaus); new config option N.
+  * man/svlogd.8: adapt.
+  * runsv.c: on commands down and exit send CONT after TERM.
+  * man/runsv.8: adapt.
+  * etc/2: use -P option to runsvdir.
+  * src/svlogd.check: add check for t config option.
+  * chpst.c: new option -n: adjust nice level.
+  * man/chpst.8: adapt.
+
+runit 1.0.5
+Tue, 21 Sep 2004 18:18:14 +0000
+  * svlogd.c: fix line buffer handling for pattern matching (thx Enrico
+    Scholz); properly retry writing to current on error; minor.
+  * doc/index.html: wording; add link to useinit.html; remove link to runit
+    on linuxfromscratch.
+  * doc/runscripts.html: add hint, some getties need to be run in a new
+    session/process group (thx Dan Melomedman).
+  * man/svlogd.8: minor fixes.
+  * man/svwaitdown.8: remove hint about -x option.
+  * package/check, package/compile, package/install, package/install-man,
+    package/upgrade: use set -e instead of #!/bin/sh -e.
+  * runsvdir.c: new option -P, run each runsv process in a new session and
+    process group (thx Charlie Brady).
+  * man/runsvdir.8: adapt; typo.
+
+runit 1.0.4
+Sun, 01 Aug 2004 18:29:36 +0000
+  * doc/runlevels.html, doc/upgrade.html, doc/useinit.html, man/runsvdir.8,
+    man/runsvchdir.8: minor changes in wording, notations.
+  * runsvdir.c: check services dir again after one second until it's
+    unchanged (thx Eric Lammerts); sleep one second before scanning if
+    services dir mtime is now; loop while chdir to starting dir fails;
+    rename log, loglen to rplog, rploglen.
+  * etc/macosx/StartupItems/runit: use -x option to svwaitdown; timeout 14.
+
+runit 1.0.3
+Sat, 26 Jun 2004 14:50:41 +0000
+  * chpst.c, man/chpst.8: new option -/ chroot.
+  * runit.c, man/runit.8: if stage 1 crashes or exits 100, stage 2 will be
+    skipped; if stage 2 crashes or exits 111, it will be restarted.
+  * package/check, package/compile, package/install-man, package/upgrade:
+    minor cleanup.
+  * doc/runscripts.html: add, adapt various run scripts (thx).
+
+runit 1.0.2
+Mon, 29 Mar 2004 17:52:50 +0000
+  * man/svlogd.8: timestamps are not considered when matching patterns (thx
+    Andras KORN).
+  * runsv.c: on exit run the finish scripts when taking the service down
+    (thx X.).
+  * runsv.c, runsvctrl.c: handle sig_quit (thx Wayne Marshall).
+  * svlogd.c: don't crash on zero byte long config file (thx Alex Efros).
+  * man/*: minor cleanup.
+  * doc/index.html: add link to runit on linuxfromscratch doc (thx Richard
+    A Downing FBCS).
+
+runit 1.0.1
+Sun, 07 Mar 2004 10:40:40 +0000
+  * doc/usedietlibc.html: minor.
+  * fmt_ptime.c: create timestamps in UTC, not localtime.
+  * chpst.c: -e dir: silently ignore directories, print warning if verbose.
+  * runsv.c: allow also log/supervise to be a dangling symlink; more
+    meaningful error message if opening lock or locking fails.
+  * check-diff, check-dist, check-local, package/check: new; run checks on
+    programs.
+  * package/install: run package/check.
+  * chpst.check, runit-init.check, runit.check, runsv.check,
+    runsvchdir.check, runsvctrl.check, runsvdir.check, runsvstat.check,
+    svlogd.check, svwaitdown.check, svwaitup.check, utmpset.check: new;
+    check program.
+  * chpst.dist, runit-init.dist, runit.dist, runsv.dist, runsvchdir.dist,
+    runsvctrl.dist, runsvdir.dist, runsvstat.dist, svlogd.dist,
+    svwaitdown.dist, svwaitup.dist, utmpset.dist: new; dist check program
+    output.
+
+runit 1.0.0
+Tue, 10 Feb 2004 13:37:28 +0000
+  * doc/benefits.html, doc/dependencies.html, doc/index.html,
+    doc/replaceinit.html, doc/runlevels.html, doc/upgrade.html,
+    doc/useinit.html: cleanup; minor.
+  * man/utmpset.8: run utmpset in finish script, not run script.
+  * man/runsvdir.8: minor.
+
+runit 0.13.1
+Mon, 19 Jan 2004 18:32:58 +0000
+  * doc/upgrade.html: typo.
+  * svlogd.c: bugfix: properly print new-line character to the log on end
+    of line (thx Pawel Chmielowski).
+  * trysocketlib.c: new; check for libraries needed for socket() on some
+    systems (fixes link failure on solaris, thx Uffe Jakobsen).
+  * Makefile: adapt.
+  * print-cc.sh, print-ld.sh: head -1 -> head -n1.
+
+runit 0.13.0
+Mon, 12 Jan 2004 14:39:38 +0000
+  * doc/runscripts.html: use html named entities (thx Taj Khattra); add
+    more contributed run scripts (thx Marek Bartnikowski, Thomas Schwinge).
+  * svlogd.c: support sending log entries to remote host through udp,
+    configurable through u and U lines in log dir config file; minor.
+  * man/svlogd.8: adapt; document -tt option.
+  * package/compile, package/install-man, package/upgrade: exit 1 on
+    sub-shell failures.
+  * man/runsv.8: fix typos (thx Christian Hammers).
+
+runit 0.12.1
+Tue, 18 Nov 2003 15:42:44 +0000
+  * doc/runscripts: add pppd run script (with chpst) next to the ppp one.
+  * man/chpst.8: typo.
+  * etc/debian/3: test -r -> test -x (thx Alejandro Mery).
+  * runsv.c: don't start new processes while collecting children.
+
+runit 0.12.0
+Wed, 29 Oct 2003 18:27:48 +0000
+  * runsv.c: don't use EOVERFLOW as it is not standard (thx Christoph
+    Scheurer).
+  * reboot_system.h1, reboot_system.h2, tryreboot.c: new; test if reboot()
+    function takes one or two arguments (solaris).
+  * runit.c: fallthrough stage 3: re-get stderr; sync() before reboot().
+  * uw_tmp.h1, uw_tmp.h2, tryuwtmp.c, tryuwtmpx.c: new; test for utmpx or
+    utmp support.
+  * utmpset.c: support systems with utmp or utmpx (solaris).
+  * Makefile: adapt.
+  * supports the solaris platform (thx Uffe Jakobsen).
+  * doc/benefits.html, doc/index.html, doc/replaceinit.html,
+    doc/runlevels.html, doc/useinit.html: default service directory is
+    /var/service; minor.
+  * etc/2, etc/debian/3, etc/freebsd/3, etc/macosx/StartupItems/runit,
+    etc/openbsd/3, man/runsv.8, man/runsvchdir.8, man/runsvdir.8: default
+    service directory is /var/service.
+  * doc/runscripts.html: add more contributed run scripts (thx Tomasz
+    Nidecki).
+
+runit 0.11.2
+Tue, 23 Sep 2003 10:15:32 +0200
+  * doc/useinit.html, etc/macosx/StartupItems/runit: don't use /etc/runit/2
+    when using runit service supervision with traditional init, use
+    /sbin/runsvdir-start instead.
+  * fmt_ptime.c: calculate UTC localtime correctly.
+  * runsv.c: support ./supervise as symbolic link, on dangling symlink create
+    link target.
+
+runit 0.11.1
+Thu,  4 Sep 2003 11:51:02 +0200
+  * src/Makefile: add dependency to sysdeps to target fmt_ptime.o (thx Thomas
+    Schwinge).
+  * svlogd.c: barf if all log directories given at the command line fail.
+  * man/svlogd.8: adapt.
+  * doc/runscripts.html: adaptions (thx Erich Schubert, Lang Martin).
+
+runit 0.11.0
+Fri, 08 Aug 2003 12:37:14 +0200
+  * uidgid.c, uidgid.h: new; get uid/gid by name.
+  * chpst: new; run program with a changed process state (includes envdir,
+    envuidgid, pgrphack, setlock, setuidgid, softlimit functionality).
+  * setuidgid.c: remove; obsolete (replaced by chpst).
+
+runit 0.10.0
+Sun, 22 Jun 2003 20:44:58 +0200
+  * doc/index.html, doc/install.html, doc/replaceinit.html, doc/useinit.html:
+    how to install and configure runit on MacOSX.
+  * svlogd.c: typo; fix incorrect handling of processor's state file; minor
+    code cleanup; correctly calculate size for all types of timestamps.
+  * runit-init.c: exit 0 on wrong usage.
+  * package/versions: new.
+
+runit 0.9.5
+Tue, 17 Jun 2003 10:48:10 +0200
+  * runit.c: use select() on systems that don't provide poll().
+  * svlogd.c: reset match flag in lineflush() in all cases.
+  * Makefile: build setuidgid in default target.
+  * doc/useinit.html: add instruction to create /etc/runit/2 first.
+  * doc/install.html: minor.
+
+runit 0.9.4
+Wed, 04 Jun 2003 13:56:33 +0200
+  * svlogd.c: default log file size is 1M; print verbose message only if
+    -v is set.
+  * man/svlogd.8: document -v option; minor.
+  * etc/freebsd/3, etc/openbsd/3: check if magic files in /etc/runit/ are
+    executable, not readable.
+  * etc/*/getty-tty*/run: remove utmpset from script.
+  * etc/*/getty-tty*/finish: new: run utmpset.
+  * doc/replaceinit.html: adapt.
+  * setuidgid.c: new: daemontools' setuidgid drop in replacement (not
+    installed by default).
+  * Makefile: build setuidgid.
+  * doc/index.html: update.
+
+runit 0.9.3
+Sun, 04 May 2003 11:30:58 +0200
+  * Makefile: actually build runsvstat, runsvctrl before installing them,
+    fixes build failure (thx Lukas Beeler).
+  * runsvctrl.c, runsvstat.c: use _exit().
+
+runit 0.9.2
+Sat, 03 May 2003 17:40:23 +0200
+  * doc/runscripts.html: changes from Jesse Cablek.
+  * doc/dependencies.html, doc/useinit.html: new.
+  * doc/index.html: adapt; reorder programs; runsvstat, runsvctrl installed
+    by default.
+  * doc/install.html: remove dependency on daemontools; create /package.
+  * doc/replaceinit.html, man/runsv.8: typos.
+  * man/svwaitdown.8, man/svwaitup.8: refer to runit and supervise.
+  * svlogd.c: fix counter var namespace.
+  * package/commands: add runsvctrl, runsvstat.
+
+runit 0.9.1
+Wed, 30 Apr 2003 22:10:57 +0200
+  * svlogd.c: reset match flag on deselection, fixes pattern matching.
+ 
+runit 0.9.0
+Fri, 25 Apr 2003 09:22:03 +0200
+  * runsvdir.c: don't propagate sig_term to runsv processes when receiving
+    sig_term; send sig_term to all runsv processes and exit 111 when
+    receiving sig_hangup.
+  * runit.c: print warning for each state that exits non-zero; restart
+    stage 2 if it exits non-zero.
+  * svlogd.c: code cleanup.
+  * svwaitdown.c: send command 'd' (and 'x' if -x is set) to each service if
+    it's not in state 'want down'.
+  * svwaitup.c: minor code cleanup.
+  * man/runsvdir.8, man/svwaitdown.8: adapt.
+  * doc/runscripts.html: add contributed run scripts (thx!).
+  * doc/upgrade.html, doc/index.html: adapt.
+
+runit 0.8.4
+Sun, 20 Apr 2003 19:31:24 +0200
+  * svlogd.c: new; runit's service logging daemon.
+  * fmt_ptime.h, fmt_ptime.c, pmatch.h, pmatch.c: new.
+  * man/svlogd.8, doc/svlogd.8.html: new.
+  * man/runsv.8, man/runsvstat.8, man/utmpset.8: minor cleanup.
+
+runit 0.8.1
+Wed, 12 Mar 2003 15:10:04 +0100
+  * runsvdir.c, runsv.c: close-on-exec file descriptors of current dir and
+    lock files (thx Lukas Beeler).
+  * doc/runscripts.html: add contributed run scripts (thx Robin S. Socha, 
+    Claus Alboege, Paul Jarc, clemens fischer, Jesse Cablek).
+
+runit 0.8.0
+Tue, 25 Feb 2003 16:17:34 +0100
+  * doc/benefits.html: new.
+  * doc/index.html, doc/upgrade.html: adapt.
+  * etc/*/1, etc/*/3, etc/*/ctrlaltdel: set permissions on the magic files
+    instead of creating and removing them (can make them symbolic links
+    now); set PATH.
+  * runit.h: new; centralize runit's compiled in magic file names.
+  * runit.c: check permissions of magic files instead of sole existence;
+    conditionally call reboot(RB_AUTOBOOT), reboot(RB_POWER_OFF),
+    reboot(RB_HALT_SYSTEM) if possible; code cleanup.
+  * runit-init.c: set permissions on magic files instead of creating or
+    removing them; code cleanup.
+  * runsvdir.c: detect and tolerate system time warp; code cleanup.
+  * runsv.c, runsvchdir.c, runsvctrl.c, runsvstat.c, svwaitdown.c,
+    svwaitup.c, utmpset.c: code cleanup.
+  * man/runit.8, man/runit-init.8: adapt.
+
+runit 0.7.2
+Fri, 10 Jan 2003 21:34:13 +0100
+  * runsv.c: close finish script file descriptor.
+  * runsv.c: close logpipe[] instead of sending sigterm to logservice when
+    told to exit, loggers should exit when they see EOF on stdin (thx Paul
+    Jarc).
+  * etc/*/1, etc/*/3: remove explicit 'exit'.
+  * error.h: include <errno.h> (upcoming glibc changes).
+
+runit 0.7.1
+Wed, 23 Oct 2002 11:40:24 +0200
+  * man/runsv.8, doc/runlevels.html: typos.
+  * runsvctrl.c, runsvstat.c: exit 111 on error.
+  * runsvdir.c: continue reading directory when stat() on entry fails.
+  * doc/runsvstat.8.html,doc/runsvctrl.8.html: new.
+  * runsvstat, runsvctrl: new; optional svc, svstat replacements.
+  * doc/index.html: adapt; new example.
+
+runit 0.7.0
+Mon, 07 Oct 2002 11:26:27 +0200
+  * runsvdir.c: check service directory's inode and device in addition
+    to mtime; sleep at least 1 second before restarting runsv processes.
+  * runsv.c: use status[19] for state information; control pipe supports e.
+  * runsvstat.c: new option -l: only show log service if -l is given; use
+    status[19] for state.
+  * runsvchdir: new; change directory runsvdir is running in (switch
+    runlevels).
+  * man/runsvchdir.8, doc/runsvchdir.8.html: new.
+  * svwaitdown.c: -k option: only kill service that still are up on timeout.
+
+runit 0.6.0
+Fri, 27 Sep 2002 16:34:57 +0200
+  * man/runsv.8, man/runsvdir.8: new.
+  * doc: use runsvdir/runsv instead of svscanboot/supervise.
+  * svwaitdown.c, svwaitup.c, man/svwaitdown.8, man/svwaitup.8: services
+    must start with slash.
+  * svwaitdown: new option -x: wait for runsv to exit instead for the
+    service to be down; new option -k: SIGKILL still running services if
+    timeout is reached.
+  * stage 3: use new svwaitdown options.
+
+runit 0.5.3
+Mon, 23 Sep 2002 16:25:07 +0200
+  * runsv, runsvdir: new; svscan/supervise replacement.
+  * etc/runit/2: use runsvdir instead of svscanboot.
+  * runsvstat.c: new; svstat for runsv.
+  * runsvctrl.c: new; svc for runsv.
+  * runsvdir.c, runsv.c: code cleanup.
+  * utmpset.c: setlock utmp and wtmp file.
+
+runit 0.5.0
+Wed, 28 Aug 2002 11:18:28 +0200
+  * utmpset: avoids libutil; compiles with dietlibc; built by default.
+  * doc/usedietlibc.html: fix description.
+  * getty-*/run: add utmpset.
+
+runit 0.4.1
+Mon, 24 Jun 2002 15:53:11 +0200
+  * utmpset.c: new option -w: additionally write wtmp record.
+
+runit 0.4.0
+Sun, 19 May 2002 12:28:29 +0200
+  * src/: include public domain sources to build byte.a, unix.a, time.a:
+    runit builds without having daemontools' sources installed.
+  * utmpset.c: new utmpset program.
+  * doc/utmpset.html: new.
+
+runit 0.3.2
+Wed, 13 Feb 2002 10:56:17 +0100
+  * runit.c: support ctrl-alt-del also on Linux/i386, dietlibc.
+  * runscripts.html: more samples. (thx Alessandro Bono)
+
+runit 0.3.1
+Sun,  3 Feb 2002 16:30:55 +0100
+  * src: cleanup.
+
+runit 0.3.0
+Tue, 29 Jan 2002 19:38:33 +0100
+  * doc: adapted.
+  * runit.8: changes documented.
+  * runscripts.html: more examples.
+
+runit 0.2.9
+Thu, 17 Jan 2002 19:00:44 +0100
+  * reportedly runs on FreeBSD 4.3 (thx clemensF)
+  * svwaitdown: max timeout is 6000, really. (thx ska)
+  * runit.c: stage 1 gets no new session and full control of console; an
+    emergency shell or login program (if present) can be executed.
+  * openbsd, freebsd: support for 'single user' emergency shell in stage 1
+  * runit.c: skip stage 2 if stage 1 crashes.
+
+runit 0.2.7
+Tue,  1 Jan 2002 16:20:14 +0100
+  * tested on fresh freebsd 4.4 installation in vmware
+  * new etc/freebsd: stages and getty service
+  * doc: replaceinit: how to replace bsd init (freebsd)
+  * svwaitup: minor code cleanup
+  * doc: /service/getty-5/ as default getty service.
+  * doc: index: related links added.
+  * package: install-man added for installing manpages in /usr/local/man/
+
+runit 0.2.6
+Sun, 30 Dec 2001 17:29:29 +0100
+  * runs on openbsd 2.9
+  * runit: console init and reinit
+  * runit: sig_pause() on end.
+  * new: etc/openbsd: stages and getty service
+  * doc: replaceinit: how to replace bsd init
+
+runit 0.2.3
+Thu, 27 Dec 2001 14:41:56 +0100
+  * doc: runscripts.html integrated
+
+runit 0.2.2
+Sun, 23 Dec 2001 18:12:29 +0100
+  * runit: checks for pid == 1
+  * new: svwaitdown, svwaitup, svwaitdown.8, svwaitup.8
+  * stage3: uses svwaitdown
+  * doc: runscripts.html added
+
+runit 0.2.0
+Mon, 26 Nov 2001 12:29:44 +0100
+  * runit-halt, runit-reboot removed, integrated into runit-init
+  * tested with dietlibc
+  * doc: usedietlibs.html added.
+  * BSD license.
+
+runit 0.1.2
+Thu, 22 Nov 2001 18:29:05 +0100
+  * collects all terminated children in all stages
+  * sends sigkill to whole process group if stage2 crashes and waits
+    5 seconds before restarting
+  * ctraltdel not automatically shuts down, now respects /etc/runit/stopit
+  * /etc/runit/ctrlaltdel touches /etc/runit/stopit
+  * on shutdown request: send sigterm to stage 2, wait max 5 second, send
+    sigkill if still running, leave stage 2, enter stage 3
+
+runit 0.1.1
+Tue, 20 Nov 2001 11:56:58 +0100
+  * package moved to smarden.org
+
+runit 0.1.0
+Fri, 16 Nov 2001 14:01:27 +0100
+  * documention
+  * debian package
+
+runit 0.0.4
+Sun, 11 Nov 2001 19:07:49 +0100
+  * initial release
diff --git a/runit-2.1.2/package/COPYING b/runit-2.1.2/package/COPYING
new file mode 100644
index 0000000..d24d1d2
--- /dev/null
+++ b/runit-2.1.2/package/COPYING
@@ -0,0 +1,24 @@
+Copyright (c) 2001-2008, Gerrit Pape
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+   3. The name of the author may not be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/runit-2.1.2/package/README b/runit-2.1.2/package/README
new file mode 100644
index 0000000..430fac5
--- /dev/null
+++ b/runit-2.1.2/package/README
@@ -0,0 +1,3 @@
+Copyright 2001-2006
+G. Pape
+http://smarden.org/runit/
diff --git a/runit-2.1.2/package/THANKS b/runit-2.1.2/package/THANKS
new file mode 100644
index 0000000..b84e3fe
--- /dev/null
+++ b/runit-2.1.2/package/THANKS
@@ -0,0 +1,2 @@
+Thanks to D. J. Bernstein for his daemontools package and for putting the
+daemontools' library code into the public domain.
diff --git a/runit-2.1.2/package/TODO b/runit-2.1.2/package/TODO
new file mode 100644
index 0000000..6c2bd6c
--- /dev/null
+++ b/runit-2.1.2/package/TODO
@@ -0,0 +1,8 @@
+rewrite doc/benefits.html
+rewrite doc/index.html
+add doc/uselsb.html
+have sv replace runsvctrl, runsvstat, svwaitdown, svwaitup
+rewrite doc/dependencies.html: weak/string deps
+runsv: provide ./run's return code to ./finish, count startups of ./run and
+  provide number to ./run
+chpst: -u user[:group0[:group1 ...]]
diff --git a/runit-2.1.2/package/check b/runit-2.1.2/package/check
new file mode 100755
index 0000000..7662e74
--- /dev/null
+++ b/runit-2.1.2/package/check
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -e
+
+umask 022
+test -d package || sh -cx '! : Wrong working directory.'
+test -d compile || sh -cx '! : Wrong working directory.'
+
+echo 'Checking commands in ./command...'
+sh -cxe 'cd compile; exec make check'
diff --git a/runit-2.1.2/package/commands b/runit-2.1.2/package/commands
new file mode 100644
index 0000000..043d245
--- /dev/null
+++ b/runit-2.1.2/package/commands
@@ -0,0 +1,9 @@
+chpst
+runit
+runit-init
+runsv
+runsvchdir
+runsvdir
+sv
+svlogd
+utmpset
diff --git a/runit-2.1.2/package/compile b/runit-2.1.2/package/compile
new file mode 100755
index 0000000..0ed142e
--- /dev/null
+++ b/runit-2.1.2/package/compile
@@ -0,0 +1,27 @@
+#!/bin/sh
+set -e
+
+umask 022
+test -d package || sh -cx '! : Wrong working directory.'
+test -d src || sh -cx '! : Wrong working directory.'
+
+here=`env - PATH=$PATH pwd`
+
+mkdir -p compile command
+test -r compile/home || echo $here >compile/home
+test -h compile/src || ln -s $here/src compile/src
+
+echo 'Linking ./src/* into ./compile...'
+for i in `ls src`; do
+  test -h compile/$i || ln -s src/$i compile/$i
+done
+
+echo 'Compiling everything in ./compile...'
+sh -cxe 'cd compile; exec make'
+
+echo 'Copying commands into ./command...'
+for i in `cat package/commands`; do
+  rm -f command/$i'{new}'
+  cp -p compile/$i command/$i'{new}'
+  mv -f command/$i'{new}' command/$i
+done
diff --git a/runit-2.1.2/package/install b/runit-2.1.2/package/install
new file mode 100755
index 0000000..4e3c468
--- /dev/null
+++ b/runit-2.1.2/package/install
@@ -0,0 +1,6 @@
+#!/bin/sh
+set -e
+
+package/compile
+package/check
+package/upgrade
diff --git a/runit-2.1.2/package/install-man b/runit-2.1.2/package/install-man
new file mode 100755
index 0000000..cd49048
--- /dev/null
+++ b/runit-2.1.2/package/install-man
@@ -0,0 +1,26 @@
+#!/bin/sh
+set -e
+
+umask 022
+test -d package || sh -cx '! : Wrong working directory.'
+test -d man || sh -cx '! : Wrong working directory.'
+
+here=`env - PATH=$PATH pwd`
+parent=`dirname $here`
+
+echo 'Compressing manpages...'
+for i in man/*.[1-8]; do
+  gzip -c $i >${i}.gz
+done
+
+echo 'Making manpage links in /usr/local/man...'
+cd man
+for i in 8; do
+  mkdir -p /usr/local/man/man$i
+  for j in *.$i; do
+    rm -f /usr/local/man/man$i/$j.gz'{new}'
+    ln -s $parent/runit/man/$j.gz /usr/local/man/man$i/$j.gz'{new}'
+    mv -f /usr/local/man/man$i/$j.gz'{new}' /usr/local/man/man$i/$j.gz
+  done
+done
+cd ..
diff --git a/runit-2.1.2/package/sharing b/runit-2.1.2/package/sharing
new file mode 100644
index 0000000..303d3de
--- /dev/null
+++ b/runit-2.1.2/package/sharing
@@ -0,0 +1,3 @@
+command:syst
+package:dist
+src:dist
diff --git a/runit-2.1.2/package/upgrade b/runit-2.1.2/package/upgrade
new file mode 100755
index 0000000..fac8902
--- /dev/null
+++ b/runit-2.1.2/package/upgrade
@@ -0,0 +1,29 @@
+#!/bin/sh
+set -e
+
+umask 022
+test -d package || sh -cx '! : Wrong working directory.'
+test -d src || sh -cx '! : Wrong working directory.'
+
+here=`env - PATH=$PATH pwd`
+parent=`dirname $here`
+
+echo 'Creating symlink runit -> runit-2.1.2...'
+rm -f runit
+ln -s runit-2.1.2 runit
+mv -f runit ..
+
+echo 'Making command links in /command...'
+mkdir -p /command
+for i in `cat package/commands`; do
+  rm -f /command/$i'{new}'
+  ln -s $parent/runit/command/$i /command/$i'{new}'
+  mv -f /command/$i'{new}' /command/$i
+done
+echo 'Making compatibility links in /usr/local/bin...'
+mkdir -p /usr/local/bin
+for i in `cat package/commands`; do
+  rm -f /usr/local/bin/$i'{new}'
+  ln -s /command/$i /usr/local/bin/$i'{new}'
+  mv -f /usr/local/bin/$i'{new}' /usr/local/bin/$i
+done
diff --git a/runit-2.1.2/package/versions b/runit-2.1.2/package/versions
new file mode 100644
index 0000000..f1364f2
--- /dev/null
+++ b/runit-2.1.2/package/versions
@@ -0,0 +1,54 @@
+0.4.0
+0.4.1
+0.5.0
+0.5.3
+0.6.0
+0.7.0
+0.7.1
+0.7.2
+0.8.0
+0.8.1
+0.8.4
+0.9.0
+0.9.1
+0.9.2
+0.9.3
+0.9.4
+0.9.5
+0.10.0
+0.11.0
+0.11.1
+0.11.2
+0.12.0
+0.12.1
+0.13.0
+0.13.1
+1.0.0
+1.0.1
+1.0.2
+1.0.3
+1.0.4
+1.0.5
+1.1.0
+1.2.0
+1.2.1
+1.2.2
+1.2.3
+1.3.0
+1.3.1
+1.3.2
+1.3.3
+1.4.0
+1.4.1
+1.5.0
+1.5.1
+1.6.0
+1.7.0
+1.7.1
+1.7.2
+1.8.0
+1.9.0
+2.0.0
+2.1.0
+2.1.1
+2.1.2
diff --git a/runit-2.1.2/src/Makefile b/runit-2.1.2/src/Makefile
new file mode 100644
index 0000000..d9624de
--- /dev/null
+++ b/runit-2.1.2/src/Makefile
@@ -0,0 +1,468 @@
+IT=chpst runit runit-init runsv runsvchdir runsvdir sv svlogd utmpset
+
+default: sysdeps $(IT)
+
+check: $(IT)
+	./check-local $(IT)
+
+runit: load runit.o unix.a byte.a
+	./load runit unix.a byte.a -static
+
+runit-init: load runit-init.o unix.a byte.a
+	./load runit-init unix.a byte.a -static
+
+runsv: load runsv.o unix.a byte.a time.a
+	./load runsv unix.a byte.a time.a
+
+runsvdir: load runsvdir.o unix.a byte.a time.a
+	./load runsvdir unix.a byte.a time.a
+
+runsvstat: load runsvstat.o unix.a byte.a time.a
+	./load runsvstat unix.a byte.a time.a
+
+runsvctrl: load runsvctrl.o unix.a byte.a
+	./load runsvctrl unix.a byte.a
+
+sv: load sv.o unix.a byte.a time.a
+	./load sv unix.a byte.a time.a
+
+svwaitup: load svwaitup.o unix.a byte.a time.a
+	./load svwaitup unix.a byte.a time.a
+
+svwaitdown: load svwaitdown.o unix.a byte.a time.a
+	./load svwaitdown unix.a byte.a time.a
+
+utmpset: load utmpset.o unix.a byte.a
+	./load utmpset unix.a byte.a
+
+runsvchdir: load runsvchdir.o unix.a byte.a
+	./load runsvchdir unix.a byte.a
+
+svlogd: load svlogd.o pmatch.o fmt_ptime.o unix.a byte.a time.a socket.lib
+	./load svlogd pmatch.o fmt_ptime.o unix.a byte.a time.a \
+	`cat socket.lib`
+
+chpst: load chpst.o uidgid.o unix.a byte.a
+	./load chpst uidgid.o unix.a byte.a
+
+runit.o: compile sysdeps runit.c
+	./compile runit.c
+
+runit-init.o: compile runit-init.c
+	./compile runit-init.c
+
+runsv.o: compile sysdeps runsv.c
+	./compile runsv.c
+
+runsvdir.o: compile sysdeps runsvdir.c
+	./compile runsvdir.c
+
+runsvstat.o: compile sysdeps runsvstat.c
+	./compile runsvstat.c
+
+runsvctrl.o: compile runsvctrl.c
+	./compile runsvctrl.c
+
+sv.o: compile sysdeps sv.c
+	./compile sv.c
+
+svwaitup.o: compile sysdeps svwaitup.c
+	./compile svwaitup.c
+
+svwaitdown.o: compile sysdeps svwaitdown.c
+	./compile svwaitdown.c
+
+utmpset.o: compile sysdeps utmpset.c
+	./compile utmpset.c
+
+runsvchdir.o: compile runsvchdir.c
+	./compile runsvchdir.c
+
+svlogd.o: compile sysdeps svlogd.c
+	./compile svlogd.c
+
+chpst.o: compile sysdeps chpst.c
+	./compile chpst.c
+
+
+uidgid.o: compile uidgid.c uidgid.h
+	./compile uidgid.c
+
+pmatch.o: compile pmatch.c
+	./compile pmatch.c
+
+fmt_ptime.o: compile sysdeps fmt_ptime.c
+	./compile fmt_ptime.c
+
+reboot_system.h: choose compile reboot_system.h1 reboot_system.h2
+	./choose c tryreboot reboot_system.h1 reboot_system.h2 > \
+	  reboot_system.h
+
+uw_tmp.h: compile uw_tmp.h1 uw_tmp.h2
+	( ./compile tryuwtmpx.c 2>/dev/null && cat uw_tmp.h2 >uw_tmp.h ) || \
+	( ./compile tryuwtmp.c 2>/dev/null && cat uw_tmp.h1 >uw_tmp.h )
+	rm -f tryuwtmp.o tryuwtmpx.o
+
+socket.lib: compile load trysocketlib.c
+	./compile trysocketlib.c
+	( ./load trysocketlib >/dev/null 2>&1 || \
+	  ( ./load trysocketlib -lxnet >/dev/null 2>&1 && echo '-lxnet' ) || \
+	  ( ./load trysocketlib -lsocket -lnsl >/dev/null 2>&1 && \
+	    echo '-lsocket -lnsl' ) \
+	) >socket.lib
+	rm -f trysocketlib.o trysocketlib
+
+clean:
+	find . -name \*~ -exec rm -f {} \;
+	find . -name .??*~ -exec rm -f {} \;
+	find . -name \#?* -exec rm -f {} \;
+	rm -f `cat TARGETS`
+
+alloc.o: alloc.c alloc.h compile error.h
+	./compile alloc.c
+
+alloc_re.o: alloc.h alloc_re.c byte.h compile
+	./compile alloc_re.c
+
+buffer.o: buffer.c buffer.h compile
+	./compile buffer.c
+
+buffer_0.o: buffer.h buffer_0.c compile
+	./compile buffer_0.c
+
+buffer_1.o: buffer.h buffer_1.c compile
+	./compile buffer_1.c
+
+buffer_2.o: buffer.h buffer_2.c compile
+	./compile buffer_2.c
+
+buffer_get.o: buffer.h buffer_get.c byte.h compile error.h
+	./compile buffer_get.c
+
+buffer_put.o: buffer.h buffer_put.c byte.h compile error.h str.h
+	./compile buffer_put.c
+
+buffer_read.o: buffer.h buffer_read.c compile
+	./compile buffer_read.c
+
+buffer_write.o: buffer.h buffer_write.c compile
+	./compile buffer_write.c
+
+byte.a: byte_chr.o byte_copy.o byte_cr.o byte_diff.o byte_rchr.o \
+fmt_uint.o fmt_uint0.o fmt_ulong.o makelib scan_ulong.o str_chr.o \
+str_diff.o str_len.o str_start.o
+	./makelib byte.a byte_chr.o byte_copy.o byte_cr.o byte_diff.o \
+	byte_rchr.o fmt_uint.o fmt_uint0.o fmt_ulong.o scan_ulong.o str_chr.o \
+	str_diff.o str_len.o str_start.o
+
+byte_chr.o: byte.h byte_chr.c compile
+	./compile byte_chr.c
+
+byte_copy.o: byte.h byte_copy.c compile
+	./compile byte_copy.c
+
+byte_cr.o: byte.h byte_cr.c compile
+	./compile byte_cr.c
+
+byte_diff.o: byte.h byte_diff.c compile
+	./compile byte_diff.c
+
+byte_rchr.o: byte.h byte_rchr.c compile
+	./compile byte_rchr.c
+
+chkshsgr: chkshsgr.o load
+	./load chkshsgr 
+
+chkshsgr.o: chkshsgr.c compile
+	./compile chkshsgr.c
+
+choose: choose.sh warn-auto.sh
+	rm -f choose
+	cat warn-auto.sh choose.sh \
+	> choose
+	chmod 555 choose
+
+coe.o: coe.c coe.h compile
+	./compile coe.c
+
+compile: conf-cc print-cc.sh systype warn-auto.sh
+	rm -f compile
+	sh print-cc.sh > compile
+	chmod 555 compile
+
+direntry.h: choose compile direntry.h1 direntry.h2 trydrent.c
+	./choose c trydrent direntry.h1 direntry.h2 > direntry.h
+
+env.o: compile env.c env.h str.h
+	./compile env.c
+
+error.o: compile error.c error.h
+	./compile error.c
+
+error_str.o: compile error.h error_str.c
+	./compile error_str.c
+
+fd_copy.o: compile fd.h fd_copy.c
+	./compile fd_copy.c
+
+fd_move.o: compile fd.h fd_move.c
+	./compile fd_move.c
+
+fifo.o: compile fifo.c fifo.h hasmkffo.h
+	./compile fifo.c
+
+fmt_uint.o: compile fmt.h fmt_uint.c
+	./compile fmt_uint.c
+
+fmt_uint0.o: compile fmt.h fmt_uint0.c
+	./compile fmt_uint0.c
+
+fmt_ulong.o: compile fmt.h fmt_ulong.c
+	./compile fmt_ulong.c
+
+hasflock.h: choose compile hasflock.h1 hasflock.h2 load tryflock.c
+	./choose cl tryflock hasflock.h1 hasflock.h2 > hasflock.h
+
+hasmkffo.h: choose compile hasmkffo.h1 hasmkffo.h2 load trymkffo.c
+	./choose cl trymkffo hasmkffo.h1 hasmkffo.h2 > hasmkffo.h
+
+hassgact.h: choose compile hassgact.h1 hassgact.h2 load trysgact.c
+	./choose cl trysgact hassgact.h1 hassgact.h2 > hassgact.h
+
+hassgprm.h: choose compile hassgprm.h1 hassgprm.h2 load trysgprm.c
+	./choose cl trysgprm hassgprm.h1 hassgprm.h2 > hassgprm.h
+
+hasshsgr.h: chkshsgr choose compile hasshsgr.h1 hasshsgr.h2 load \
+tryshsgr.c warn-shsgr
+	./chkshsgr || ( cat warn-shsgr; exit 1 )
+	./choose clr tryshsgr hasshsgr.h1 hasshsgr.h2 > hasshsgr.h
+
+haswaitp.h: choose compile haswaitp.h1 haswaitp.h2 load trywaitp.c
+	./choose cl trywaitp haswaitp.h1 haswaitp.h2 > haswaitp.h
+
+iopause.h: choose compile iopause.h1 iopause.h2 load trypoll.c
+	./choose clr trypoll iopause.h1 iopause.h2 > iopause.h
+
+iopause.o: compile iopause.c iopause.h select.h tai.h taia.h uint64.h
+	./compile iopause.c
+
+load: conf-ld print-ld.sh systype warn-auto.sh
+	rm -f load
+	sh print-ld.sh > load
+	chmod 555 load
+
+lock_ex.o: compile hasflock.h lock.h lock_ex.c
+	./compile lock_ex.c
+
+lock_exnb.o: compile hasflock.h lock.h lock_exnb.c
+	./compile lock_exnb.c
+
+makelib: print-ar.sh systype warn-auto.sh
+	rm -f makelib
+	sh print-ar.sh > makelib
+	chmod 555 makelib
+
+ndelay_off.o: compile ndelay.h ndelay_off.c
+	./compile ndelay_off.c
+
+ndelay_on.o: compile ndelay.h ndelay_on.c
+	./compile ndelay_on.c
+
+open_append.o: compile open.h open_append.c
+	./compile open_append.c
+
+open_read.o: compile open.h open_read.c
+	./compile open_read.c
+
+open_trunc.o: compile open.h open_trunc.c
+	./compile open_trunc.c
+
+open_write.o: compile open.h open_write.c
+	./compile open_write.c
+
+openreadclose.o: compile error.h gen_alloc.h open.h openreadclose.c \
+openreadclose.h readclose.h stralloc.h
+	./compile openreadclose.c
+
+pathexec_env.o: alloc.h byte.h compile env.h gen_alloc.h pathexec.h \
+pathexec_env.c str.h stralloc.h
+	./compile pathexec_env.c
+
+pathexec_run.o: compile env.h error.h gen_alloc.h pathexec.h \
+pathexec_run.c str.h stralloc.h
+	./compile pathexec_run.c
+
+prot.o: compile hasshsgr.h prot.c prot.h
+	./compile prot.c
+
+readclose.o: compile error.h gen_alloc.h readclose.c readclose.h \
+stralloc.h
+	./compile readclose.c
+
+scan_ulong.o: compile scan.h scan_ulong.c
+	./compile scan_ulong.c
+
+seek_set.o: compile seek.h seek_set.c
+	./compile seek_set.c
+
+select.h: choose compile select.h1 select.h2 trysysel.c
+	./choose c trysysel select.h1 select.h2 > select.h
+
+sgetopt.o: buffer.h compile sgetopt.c sgetopt.h subgetopt.h
+	./compile sgetopt.c
+
+sig.o: compile sig.c sig.h
+	./compile sig.c
+
+sig_block.o: compile hassgprm.h sig.h sig_block.c
+	./compile sig_block.c
+
+sig_catch.o: compile hassgact.h sig.h sig_catch.c
+	./compile sig_catch.c
+
+sig_pause.o: compile hassgprm.h sig.h sig_pause.c
+	./compile sig_pause.c
+
+str_chr.o: compile str.h str_chr.c
+	./compile str_chr.c
+
+str_diff.o: compile str.h str_diff.c
+	./compile str_diff.c
+
+str_len.o: compile str.h str_len.c
+	./compile str_len.c
+
+str_start.o: compile str.h str_start.c
+	./compile str_start.c
+
+stralloc_cat.o: byte.h compile gen_alloc.h stralloc.h stralloc_cat.c
+	./compile stralloc_cat.c
+
+stralloc_catb.o: byte.h compile gen_alloc.h stralloc.h \
+stralloc_catb.c
+	./compile stralloc_catb.c
+
+stralloc_cats.o: byte.h compile gen_alloc.h str.h stralloc.h \
+stralloc_cats.c
+	./compile stralloc_cats.c
+
+stralloc_eady.o: alloc.h compile gen_alloc.h gen_allocdefs.h \
+stralloc.h stralloc_eady.c
+	./compile stralloc_eady.c
+
+stralloc_opyb.o: byte.h compile gen_alloc.h stralloc.h \
+stralloc_opyb.c
+	./compile stralloc_opyb.c
+
+stralloc_opys.o: byte.h compile gen_alloc.h str.h stralloc.h \
+stralloc_opys.c
+	./compile stralloc_opys.c
+
+stralloc_pend.o: alloc.h compile gen_alloc.h gen_allocdefs.h \
+stralloc.h stralloc_pend.c
+	./compile stralloc_pend.c
+
+strerr_die.o: buffer.h compile strerr.h strerr_die.c
+	./compile strerr_die.c
+
+strerr_sys.o: compile error.h strerr.h strerr_sys.c
+	./compile strerr_sys.c
+
+subgetopt.o: compile subgetopt.c subgetopt.h
+	./compile subgetopt.c
+
+sysdeps: compile direntry.h hasflock.h hasmkffo.h hassgact.h \
+hassgprm.h hasshsgr.h haswaitp.h iopause.h load select.h systype \
+uint64.h reboot_system.h uw_tmp.h socket.lib
+	rm -f sysdeps
+	cat systype compile load socket.lib >>sysdeps
+	grep sysdep direntry.h >>sysdeps
+	grep sysdep haswaitp.h >>sysdeps
+	grep sysdep hassgact.h >>sysdeps
+	grep sysdep hassgprm.h >>sysdeps
+	grep sysdep select.h >>sysdeps
+	grep sysdep uint64.h >>sysdeps
+	grep sysdep iopause.h >>sysdeps
+	grep sysdep hasmkffo.h >>sysdeps
+	grep sysdep hasflock.h >>sysdeps
+	grep sysdep hasshsgr.h >>sysdeps
+	grep sysdep reboot_system.h >>sysdeps
+	grep sysdep uw_tmp.h >>sysdeps
+	cat sysdeps
+
+systype: find-systype.sh trycpp.c x86cpuid.c
+	sh find-systype.sh > systype
+
+tai_now.o: compile tai.h tai_now.c uint64.h
+	./compile tai_now.c
+
+tai_pack.o: compile tai.h tai_pack.c uint64.h
+	./compile tai_pack.c
+
+tai_sub.o: compile tai.h tai_sub.c uint64.h
+	./compile tai_sub.c
+
+tai_unpack.o: compile tai.h tai_unpack.c uint64.h
+	./compile tai_unpack.c
+
+taia_add.o: compile tai.h taia.h taia_add.c uint64.h
+	./compile taia_add.c
+
+taia_approx.o: compile tai.h taia.h taia_approx.c uint64.h
+	./compile taia_approx.c
+
+taia_frac.o: compile tai.h taia.h taia_frac.c uint64.h
+	./compile taia_frac.c
+
+taia_less.o: compile tai.h taia.h taia_less.c uint64.h
+	./compile taia_less.c
+
+taia_now.o: compile tai.h taia.h taia_now.c uint64.h
+	./compile taia_now.c
+
+taia_pack.o: compile tai.h taia.h taia_pack.c uint64.h
+	./compile taia_pack.c
+
+taia_sub.o: compile tai.h taia.h taia_sub.c uint64.h
+	./compile taia_sub.c
+
+taia_uint.o: compile tai.h taia.h taia_uint.c uint64.h
+	./compile taia_uint.c
+
+time.a: iopause.o makelib tai_now.o tai_pack.o tai_sub.o tai_unpack.o \
+taia_add.o taia_approx.o taia_frac.o taia_less.o taia_now.o \
+taia_pack.o taia_sub.o taia_uint.o
+	./makelib time.a iopause.o tai_now.o tai_pack.o tai_sub.o \
+	tai_unpack.o taia_add.o taia_approx.o taia_frac.o taia_less.o \
+	taia_now.o taia_pack.o taia_sub.o taia_uint.o
+
+uint64.h: choose compile load tryulong64.c uint64.h1 uint64.h2
+	./choose clr tryulong64 uint64.h1 uint64.h2 > uint64.h
+
+unix.a: alloc.o alloc_re.o buffer.o buffer_0.o buffer_1.o buffer_2.o \
+buffer_get.o buffer_put.o buffer_read.o buffer_write.o coe.o env.o \
+error.o error_str.o fd_copy.o fd_move.o fifo.o lock_ex.o lock_exnb.o \
+makelib ndelay_off.o ndelay_on.o open_append.o open_read.o \
+open_trunc.o open_write.o openreadclose.o pathexec_env.o \
+pathexec_run.o prot.o readclose.o seek_set.o sgetopt.o sig.o \
+sig_block.o sig_catch.o sig_pause.o stralloc_cat.o stralloc_catb.o \
+stralloc_cats.o stralloc_eady.o stralloc_opyb.o stralloc_opys.o \
+stralloc_pend.o strerr_die.o strerr_sys.o subgetopt.o wait_nohang.o \
+wait_pid.o
+	./makelib unix.a alloc.o alloc_re.o buffer.o buffer_0.o buffer_1.o \
+	buffer_2.o buffer_get.o buffer_put.o buffer_read.o buffer_write.o \
+	coe.o env.o error.o error_str.o fd_copy.o fd_move.o fifo.o lock_ex.o \
+	lock_exnb.o ndelay_off.o ndelay_on.o open_append.o open_read.o \
+	open_trunc.o open_write.o openreadclose.o pathexec_env.o \
+	pathexec_run.o prot.o readclose.o seek_set.o sgetopt.o sig.o \
+	sig_block.o sig_catch.o sig_pause.o stralloc_cat.o stralloc_catb.o \
+	stralloc_cats.o stralloc_eady.o stralloc_opyb.o stralloc_opys.o \
+	stralloc_pend.o strerr_die.o strerr_sys.o subgetopt.o wait_nohang.o \
+	wait_pid.o
+
+wait_nohang.o: compile haswaitp.h wait_nohang.c
+	./compile wait_nohang.c
+
+wait_pid.o: compile error.h haswaitp.h wait_pid.c
+	./compile wait_pid.c
+
diff --git a/runit-2.1.2/src/TARGETS b/runit-2.1.2/src/TARGETS
new file mode 100644
index 0000000..46981ce
--- /dev/null
+++ b/runit-2.1.2/src/TARGETS
@@ -0,0 +1,143 @@
+runit
+runit.o
+runit-init
+runit-init.o
+runsv
+runsv.o
+runsvdir
+runsvdir.o
+runsvstat
+runsvstat.o
+runsvctrl
+runsvctrl.o
+sv
+sv.o
+svwaitdown
+svwaitdown.o
+svwaitup
+svwaitup.o
+utmpset
+utmpset.o
+runsvchdir
+runsvchdir.o
+svlogd
+svlogd.o
+chpst
+chpst.o
+pmatch.o
+fmt_ptime.o
+uidgid.o
+reboot_system.h
+uw_tmp.h
+socket.lib
+trysocketlib
+trysocketlib.o
+check
+alloc.o
+alloc_re.o
+buffer.o
+buffer_0.o
+buffer_1.o
+buffer_2.o
+buffer_get.o
+buffer_put.o
+buffer_read.o
+buffer_write.o
+byte.a
+byte_chr.o
+byte_copy.o
+byte_cr.o
+byte_diff.o
+byte_rchr.o
+chkshsgr
+chkshsgr.o
+choose
+coe.o
+compile
+direntry.h
+env.o
+error.o
+error_str.o
+fd_copy.o
+fd_move.o
+fifo.o
+fmt_uint.o
+fmt_uint0.o
+fmt_ulong.o
+hasflock.h
+hasmkffo.h
+hassgact.h
+hassgprm.h
+hasshsgr.h
+haswaitp.h
+iopause.h
+iopause.o
+load
+lock_ex.o
+lock_exnb.o
+makelib
+ndelay_off.o
+ndelay_on.o
+open_append.o
+open_read.o
+open_trunc.o
+open_write.o
+openreadclose.o
+pathexec_env.o
+pathexec_run.o
+prot.o
+readclose.o
+scan_ulong.o
+seek_set.o
+select.h
+sgetopt.o
+sig.o
+sig_block.o
+sig_catch.o
+sig_pause.o
+str_chr.o
+str_diff.o
+str_len.o
+str_start.o
+stralloc_cat.o
+stralloc_catb.o
+stralloc_cats.o
+stralloc_eady.o
+stralloc_opyb.o
+stralloc_opys.o
+stralloc_pend.o
+strerr_die.o
+strerr_sys.o
+subgetopt.o
+sysdeps
+systype
+tai_now.o
+tai_pack.o
+tai_sub.o
+tai_unpack.o
+taia_add.o
+taia_approx.o
+taia_frac.o
+taia_less.o
+taia_now.o
+taia_pack.o
+taia_sub.o
+taia_uint.o
+time.a
+uint64.h
+unix.a
+wait_nohang.o
+wait_pid.o
+chpst.local
+runit-init.local
+runit.local
+runsv.local
+runsvchdir.local
+runsvctrl.local
+runsvdir.local
+runsvstat.local
+sv.local
+svlogd.local
+svwaitdown.local
+svwaitup.local
+utmpset.local
diff --git a/runit-2.1.2/src/alloc.c b/runit-2.1.2/src/alloc.c
new file mode 100644
index 0000000..c741aa4
--- /dev/null
+++ b/runit-2.1.2/src/alloc.c
@@ -0,0 +1,33 @@
+/* Public domain. */
+
+#include <stdlib.h>
+#include "alloc.h"
+#include "error.h"
+
+#define ALIGNMENT 16 /* XXX: assuming that this alignment is enough */
+#define SPACE 2048 /* must be multiple of ALIGNMENT */
+
+typedef union { char irrelevant[ALIGNMENT]; double d; } aligned;
+static aligned realspace[SPACE / ALIGNMENT];
+#define space ((char *) realspace)
+static unsigned int avail = SPACE; /* multiple of ALIGNMENT; 0<=avail<=SPACE */
+
+/*@null@*//*@out@*/char *alloc(n)
+unsigned int n;
+{
+  char *x;
+  n = ALIGNMENT + n - (n & (ALIGNMENT - 1)); /* XXX: could overflow */
+  if (n <= avail) { avail -= n; return space + avail; }
+  x = malloc(n);
+  if (!x) errno = error_nomem;
+  return x;
+}
+
+void alloc_free(x)
+char *x;
+{
+  if (x >= space)
+    if (x < space + SPACE)
+      return; /* XXX: assuming that pointers are flat */
+  free(x);
+}
diff --git a/runit-2.1.2/src/alloc.h b/runit-2.1.2/src/alloc.h
new file mode 100644
index 0000000..21122fc
--- /dev/null
+++ b/runit-2.1.2/src/alloc.h
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#ifndef ALLOC_H
+#define ALLOC_H
+
+extern /*@null@*//*@out@*/char *alloc();
+extern void alloc_free();
+extern int alloc_re();
+
+#endif
diff --git a/runit-2.1.2/src/alloc_re.c b/runit-2.1.2/src/alloc_re.c
new file mode 100644
index 0000000..1074609
--- /dev/null
+++ b/runit-2.1.2/src/alloc_re.c
@@ -0,0 +1,19 @@
+/* Public domain. */
+
+#include "alloc.h"
+#include "byte.h"
+
+int alloc_re(x,m,n)
+char **x;
+unsigned int m;
+unsigned int n;
+{
+  char *y;
+ 
+  y = alloc(n);
+  if (!y) return 0;
+  byte_copy(y,m,*x);
+  alloc_free(*x);
+  *x = y;
+  return 1;
+}
diff --git a/runit-2.1.2/src/buffer.c b/runit-2.1.2/src/buffer.c
new file mode 100644
index 0000000..38e6d77
--- /dev/null
+++ b/runit-2.1.2/src/buffer.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#include "buffer.h"
+
+void buffer_init(buffer *s,int (*op)(),int fd,char *buf,unsigned int len)
+{
+  s->x = buf;
+  s->fd = fd;
+  s->op = op;
+  s->p = 0;
+  s->n = len;
+}
diff --git a/runit-2.1.2/src/buffer.h b/runit-2.1.2/src/buffer.h
new file mode 100644
index 0000000..8f2e572
--- /dev/null
+++ b/runit-2.1.2/src/buffer.h
@@ -0,0 +1,61 @@
+/* Public domain. */
+
+#ifndef BUFFER_H
+#define BUFFER_H
+
+typedef struct buffer {
+  char *x;
+  unsigned int p;
+  unsigned int n;
+  int fd;
+  int (*op)();
+} buffer;
+
+#define BUFFER_INIT(op,fd,buf,len) { (buf), 0, (len), (fd), (op) }
+#define BUFFER_INSIZE 8192
+#define BUFFER_OUTSIZE 8192
+
+extern void buffer_init(buffer *,int (*)(),int,char *,unsigned int);
+
+extern int buffer_flush(buffer *);
+extern int buffer_put(buffer *,const char *,unsigned int);
+extern int buffer_putalign(buffer *,const char *,unsigned int);
+extern int buffer_putflush(buffer *,const char *,unsigned int);
+extern int buffer_puts(buffer *,const char *);
+extern int buffer_putsalign(buffer *,const char *);
+extern int buffer_putsflush(buffer *,const char *);
+
+#define buffer_PUTC(s,c) \
+  ( ((s)->n != (s)->p) \
+    ? ( (s)->x[(s)->p++] = (c), 0 ) \
+    : buffer_put((s),&(c),1) \
+  )
+
+extern int buffer_get(buffer *,char *,unsigned int);
+extern int buffer_bget(buffer *,char *,unsigned int);
+extern int buffer_feed(buffer *);
+
+extern char *buffer_peek(buffer *);
+extern void buffer_seek(buffer *,unsigned int);
+
+#define buffer_PEEK(s) ( (s)->x + (s)->n )
+#define buffer_SEEK(s,len) ( ( (s)->p -= (len) ) , ( (s)->n += (len) ) )
+
+#define buffer_GETC(s,c) \
+  ( ((s)->p > 0) \
+    ? ( *(c) = (s)->x[(s)->n], buffer_SEEK((s),1), 1 ) \
+    : buffer_get((s),(c),1) \
+  )
+
+extern int buffer_copy(buffer *,buffer *);
+
+extern int buffer_unixread(int,char *,unsigned int);
+extern int buffer_unixwrite(int,const char *,unsigned int);
+
+extern buffer *buffer_0;
+extern buffer *buffer_0small;
+extern buffer *buffer_1;
+extern buffer *buffer_1small;
+extern buffer *buffer_2;
+
+#endif
diff --git a/runit-2.1.2/src/buffer_0.c b/runit-2.1.2/src/buffer_0.c
new file mode 100644
index 0000000..47d3263
--- /dev/null
+++ b/runit-2.1.2/src/buffer_0.c
@@ -0,0 +1,13 @@
+/* Public domain. */
+
+#include "buffer.h"
+
+int buffer_0_read(fd,buf,len) int fd; char *buf; int len;
+{
+  if (buffer_flush(buffer_1) == -1) return -1;
+  return buffer_unixread(fd,buf,len);
+}
+
+char buffer_0_space[BUFFER_INSIZE];
+static buffer it = BUFFER_INIT(buffer_0_read,0,buffer_0_space,sizeof buffer_0_space);
+buffer *buffer_0 = &it;
diff --git a/runit-2.1.2/src/buffer_1.c b/runit-2.1.2/src/buffer_1.c
new file mode 100644
index 0000000..f4bac3d
--- /dev/null
+++ b/runit-2.1.2/src/buffer_1.c
@@ -0,0 +1,7 @@
+/* Public domain. */
+
+#include "buffer.h"
+
+char buffer_1_space[BUFFER_OUTSIZE];
+static buffer it = BUFFER_INIT(buffer_unixwrite,1,buffer_1_space,sizeof buffer_1_space);
+buffer *buffer_1 = &it;
diff --git a/runit-2.1.2/src/buffer_2.c b/runit-2.1.2/src/buffer_2.c
new file mode 100644
index 0000000..f255a92
--- /dev/null
+++ b/runit-2.1.2/src/buffer_2.c
@@ -0,0 +1,7 @@
+/* Public domain. */
+
+#include "buffer.h"
+
+char buffer_2_space[256];
+static buffer it = BUFFER_INIT(buffer_unixwrite,2,buffer_2_space,sizeof buffer_2_space);
+buffer *buffer_2 = &it;
diff --git a/runit-2.1.2/src/buffer_get.c b/runit-2.1.2/src/buffer_get.c
new file mode 100644
index 0000000..3a6e1b6
--- /dev/null
+++ b/runit-2.1.2/src/buffer_get.c
@@ -0,0 +1,69 @@
+/* Public domain. */
+
+#include "buffer.h"
+#include "byte.h"
+#include "error.h"
+
+static int oneread(int (*op)(),int fd,char *buf,unsigned int len)
+{
+  int r;
+
+  for (;;) {
+    r = op(fd,buf,len);
+    if (r == -1) if (errno == error_intr) continue;
+    return r;
+  }
+}
+
+static int getthis(buffer *s,char *buf,unsigned int len)
+{
+  if (len > s->p) len = s->p;
+  s->p -= len;
+  byte_copy(buf,len,s->x + s->n);
+  s->n += len;
+  return len;
+}
+
+int buffer_feed(buffer *s)
+{
+  int r;
+
+  if (s->p) return s->p;
+  r = oneread(s->op,s->fd,s->x,s->n);
+  if (r <= 0) return r;
+  s->p = r;
+  s->n -= r;
+  if (s->n > 0) byte_copyr(s->x + s->n,r,s->x);
+  return r;
+}
+
+int buffer_bget(buffer *s,char *buf,unsigned int len)
+{
+  int r;
+ 
+  if (s->p > 0) return getthis(s,buf,len);
+  if (s->n <= len) return oneread(s->op,s->fd,buf,s->n);
+  r = buffer_feed(s); if (r <= 0) return r;
+  return getthis(s,buf,len);
+}
+
+int buffer_get(buffer *s,char *buf,unsigned int len)
+{
+  int r;
+ 
+  if (s->p > 0) return getthis(s,buf,len);
+  if (s->n <= len) return oneread(s->op,s->fd,buf,len);
+  r = buffer_feed(s); if (r <= 0) return r;
+  return getthis(s,buf,len);
+}
+
+char *buffer_peek(buffer *s)
+{
+  return s->x + s->n;
+}
+
+void buffer_seek(buffer *s,unsigned int len)
+{
+  s->n += len;
+  s->p -= len;
+}
diff --git a/runit-2.1.2/src/buffer_put.c b/runit-2.1.2/src/buffer_put.c
new file mode 100644
index 0000000..23164b3
--- /dev/null
+++ b/runit-2.1.2/src/buffer_put.c
@@ -0,0 +1,90 @@
+/* Public domain. */
+
+#include "buffer.h"
+#include "str.h"
+#include "byte.h"
+#include "error.h"
+
+static int allwrite(int (*op)(),int fd,const char *buf,unsigned int len)
+{
+  int w;
+
+  while (len) {
+    w = op(fd,buf,len);
+    if (w == -1) {
+      if (errno == error_intr) continue;
+      return -1; /* note that some data may have been written */
+    }
+    if (w == 0) ; /* luser's fault */
+    buf += w;
+    len -= w;
+  }
+  return 0;
+}
+
+int buffer_flush(buffer *s)
+{
+  int p;
+ 
+  p = s->p;
+  if (!p) return 0;
+  s->p = 0;
+  return allwrite(s->op,s->fd,s->x,p);
+}
+
+int buffer_putalign(buffer *s,const char *buf,unsigned int len)
+{
+  unsigned int n;
+ 
+  while (len > (n = s->n - s->p)) {
+    byte_copy(s->x + s->p,n,buf); s->p += n; buf += n; len -= n;
+    if (buffer_flush(s) == -1) return -1;
+  }
+  /* now len <= s->n - s->p */
+  byte_copy(s->x + s->p,len,buf);
+  s->p += len;
+  return 0;
+}
+
+int buffer_put(buffer *s,const char *buf,unsigned int len)
+{
+  unsigned int n;
+ 
+  n = s->n;
+  if (len > n - s->p) {
+    if (buffer_flush(s) == -1) return -1;
+    /* now s->p == 0 */
+    if (n < BUFFER_OUTSIZE) n = BUFFER_OUTSIZE;
+    while (len > s->n) {
+      if (n > len) n = len;
+      if (allwrite(s->op,s->fd,buf,n) == -1) return -1;
+      buf += n;
+      len -= n;
+    }
+  }
+  /* now len <= s->n - s->p */
+  byte_copy(s->x + s->p,len,buf);
+  s->p += len;
+  return 0;
+}
+
+int buffer_putflush(buffer *s,const char *buf,unsigned int len)
+{
+  if (buffer_flush(s) == -1) return -1;
+  return allwrite(s->op,s->fd,buf,len);
+}
+
+int buffer_putsalign(buffer *s,const char *buf)
+{
+  return buffer_putalign(s,buf,str_len(buf));
+}
+
+int buffer_puts(buffer *s,const char *buf)
+{
+  return buffer_put(s,buf,str_len(buf));
+}
+
+int buffer_putsflush(buffer *s,const char *buf)
+{
+  return buffer_putflush(s,buf,str_len(buf));
+}
diff --git a/runit-2.1.2/src/buffer_read.c b/runit-2.1.2/src/buffer_read.c
new file mode 100644
index 0000000..09db05f
--- /dev/null
+++ b/runit-2.1.2/src/buffer_read.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#include <unistd.h>
+#include "buffer.h"
+
+int buffer_unixread(int fd,char *buf,unsigned int len)
+{
+  return read(fd,buf,len);
+}
diff --git a/runit-2.1.2/src/buffer_write.c b/runit-2.1.2/src/buffer_write.c
new file mode 100644
index 0000000..4ba13ef
--- /dev/null
+++ b/runit-2.1.2/src/buffer_write.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#include <unistd.h>
+#include "buffer.h"
+
+int buffer_unixwrite(int fd,const char *buf,unsigned int len)
+{
+  return write(fd,buf,len);
+}
diff --git a/runit-2.1.2/src/byte.h b/runit-2.1.2/src/byte.h
new file mode 100644
index 0000000..09aab61
--- /dev/null
+++ b/runit-2.1.2/src/byte.h
@@ -0,0 +1,15 @@
+/* Public domain. */
+
+#ifndef BYTE_H
+#define BYTE_H
+
+extern unsigned int byte_chr();
+extern unsigned int byte_rchr();
+extern void byte_copy();
+extern void byte_copyr();
+extern int byte_diff();
+extern void byte_zero();
+
+#define byte_equal(s,n,t) (!byte_diff((s),(n),(t)))
+
+#endif
diff --git a/runit-2.1.2/src/byte_chr.c b/runit-2.1.2/src/byte_chr.c
new file mode 100644
index 0000000..fd56056
--- /dev/null
+++ b/runit-2.1.2/src/byte_chr.c
@@ -0,0 +1,22 @@
+/* Public domain. */
+
+#include "byte.h"
+
+unsigned int byte_chr(s,n,c)
+char *s;
+register unsigned int n;
+int c;
+{
+  register char ch;
+  register char *t;
+
+  ch = c;
+  t = s;
+  for (;;) {
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+    if (!n) break; if (*t == ch) break; ++t; --n;
+  }
+  return t - s;
+}
diff --git a/runit-2.1.2/src/byte_copy.c b/runit-2.1.2/src/byte_copy.c
new file mode 100644
index 0000000..74c9e4a
--- /dev/null
+++ b/runit-2.1.2/src/byte_copy.c
@@ -0,0 +1,16 @@
+/* Public domain. */
+
+#include "byte.h"
+
+void byte_copy(to,n,from)
+register char *to;
+register unsigned int n;
+register char *from;
+{
+  for (;;) {
+    if (!n) return; *to++ = *from++; --n;
+    if (!n) return; *to++ = *from++; --n;
+    if (!n) return; *to++ = *from++; --n;
+    if (!n) return; *to++ = *from++; --n;
+  }
+}
diff --git a/runit-2.1.2/src/byte_cr.c b/runit-2.1.2/src/byte_cr.c
new file mode 100644
index 0000000..52dc251
--- /dev/null
+++ b/runit-2.1.2/src/byte_cr.c
@@ -0,0 +1,18 @@
+/* Public domain. */
+
+#include "byte.h"
+
+void byte_copyr(to,n,from)
+register char *to;
+register unsigned int n;
+register char *from;
+{
+  to += n;
+  from += n;
+  for (;;) {
+    if (!n) return; *--to = *--from; --n;
+    if (!n) return; *--to = *--from; --n;
+    if (!n) return; *--to = *--from; --n;
+    if (!n) return; *--to = *--from; --n;
+  }
+}
diff --git a/runit-2.1.2/src/byte_diff.c b/runit-2.1.2/src/byte_diff.c
new file mode 100644
index 0000000..0c4d17b
--- /dev/null
+++ b/runit-2.1.2/src/byte_diff.c
@@ -0,0 +1,18 @@
+/* Public domain. */
+
+#include "byte.h"
+
+int byte_diff(s,n,t)
+register char *s;
+register unsigned int n;
+register char *t;
+{
+  for (;;) {
+    if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+    if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+    if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+    if (!n) return 0; if (*s != *t) break; ++s; ++t; --n;
+  }
+  return ((int)(unsigned int)(unsigned char) *s)
+       - ((int)(unsigned int)(unsigned char) *t);
+}
diff --git a/runit-2.1.2/src/byte_rchr.c b/runit-2.1.2/src/byte_rchr.c
new file mode 100644
index 0000000..7ea9948
--- /dev/null
+++ b/runit-2.1.2/src/byte_rchr.c
@@ -0,0 +1,25 @@
+/* Public domain. */
+
+#include "byte.h"
+
+unsigned int byte_rchr(s,n,c)
+char *s;
+register unsigned int n;
+int c;
+{
+  register char ch;
+  register char *t;
+  register char *u;
+
+  ch = c;
+  t = s;
+  u = 0;
+  for (;;) {
+    if (!n) break; if (*t == ch) u = t; ++t; --n;
+    if (!n) break; if (*t == ch) u = t; ++t; --n;
+    if (!n) break; if (*t == ch) u = t; ++t; --n;
+    if (!n) break; if (*t == ch) u = t; ++t; --n;
+  }
+  if (!u) u = t;
+  return u - s;
+}
diff --git a/runit-2.1.2/src/check-diff b/runit-2.1.2/src/check-diff
new file mode 100755
index 0000000..d334238
--- /dev/null
+++ b/runit-2.1.2/src/check-diff
@@ -0,0 +1,5 @@
+#!/bin/sh
+while read i; do
+  read j 0<&7 || exit 1
+  test "$i" = "$j" || exit 1
+done 7<$1.dist <$1.local
diff --git a/runit-2.1.2/src/check-dist b/runit-2.1.2/src/check-dist
new file mode 100755
index 0000000..f0c5dd5
--- /dev/null
+++ b/runit-2.1.2/src/check-dist
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+PATH=`pwd`:$PATH
+
+for i in `cat ../package/commands`; do
+  echo "Creating new $i.dist..."
+  env - PATH="$PATH" ctmp="`pwd`/check-tmp" $i.check 2>&1 |cat -v >$i.dist
+done
diff --git a/runit-2.1.2/src/check-local b/runit-2.1.2/src/check-local
new file mode 100755
index 0000000..36b3ed4
--- /dev/null
+++ b/runit-2.1.2/src/check-local
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+PATH=`pwd`:$PATH
+
+for i in ${1+"$@"}; do
+  echo "Checking $i..."
+  env - PATH="$PATH" ctmp="`pwd`/check-tmp" $i.check 2>&1 |cat -v >$i.local
+  ./check-diff $i || ( cat $i.local; echo "$i failed."; exit 1 ) || exit 1
+done
diff --git a/runit-2.1.2/src/chkshsgr.c b/runit-2.1.2/src/chkshsgr.c
new file mode 100644
index 0000000..38c352d
--- /dev/null
+++ b/runit-2.1.2/src/chkshsgr.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#include <unistd.h>
+
+int main()
+{
+  short x[4];
+
+  x[0] = x[1] = 0;
+  if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1);
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/choose.sh b/runit-2.1.2/src/choose.sh
new file mode 100644
index 0000000..feff2da
--- /dev/null
+++ b/runit-2.1.2/src/choose.sh
@@ -0,0 +1,18 @@
+
+result="$4"
+
+case "$1" in
+  *c*) ./compile $2.c >/dev/null 2>&1 || result="$3" ;;
+esac
+
+case "$1" in
+  *l*) ./load $2 >/dev/null 2>&1 || result="$3" ;;
+esac
+
+case "$1" in
+  *r*) ./$2 >/dev/null 2>&1 || result="$3" ;;
+esac
+
+rm -f $2.o $2
+
+exec cat "$result"
diff --git a/runit-2.1.2/src/chpst.c b/runit-2.1.2/src/chpst.c
new file mode 100644
index 0000000..f1b8ed9
--- /dev/null
+++ b/runit-2.1.2/src/chpst.c
@@ -0,0 +1,475 @@
+#include <sys/types.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include "sgetopt.h"
+#include "error.h"
+#include "strerr.h"
+#include "str.h"
+#include "uidgid.h"
+#include "prot.h"
+#include "strerr.h"
+#include "scan.h"
+#include "fmt.h"
+#include "lock.h"
+#include "pathexec.h"
+#include "stralloc.h"
+#include "byte.h"
+#include "open.h"
+#include "openreadclose.h"
+#include "direntry.h"
+
+#define USAGE_MAIN " [-vP012] [-u user[:group]] [-U user[:group]] [-b argv0] [-e dir] [-/ root] [-n nice] [-l|-L lock] [-m n] [-d n] [-o n] [-p n] [-f n] [-c n] prog"
+#define FATAL "chpst: fatal: "
+#define WARNING "chpst: warning: "
+
+const char *progname;
+static stralloc sa;
+
+void fatal(const char *m) { strerr_die3sys(111, FATAL, m, ": "); }
+void fatal2(const char *m0, const char *m1) {
+  strerr_die5sys(111, FATAL, m0, ": ", m1, ": ");
+}
+void fatalx(const char *m0, const char *m1) {
+  strerr_die4x(111, FATAL, m0, ": ", m1);
+}
+void warn(const char *m) { strerr_warn2(WARNING, m, 0); }
+void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); }
+void usage() { strerr_die4x(100, "usage: ", progname, USAGE_MAIN, "\n"); }
+
+char *set_user =0;
+char *env_user =0;
+const char *argv0 =0;
+const char *env_dir =0;
+unsigned int verbose =0;
+unsigned int pgrp =0;
+unsigned int nostdin =0;
+unsigned int nostdout =0;
+unsigned int nostderr =0;
+long limitd =-2;
+long limits =-2;
+long limitl =-2;
+long limita =-2;
+long limito =-2;
+long limitp =-2;
+long limitf =-2;
+long limitc =-2;
+long limitr =-2;
+long limitt =-2;
+long nicelvl =0;
+const char *lock =0;
+const char *root =0;
+unsigned int lockdelay;
+
+void suidgid(char *user, unsigned int ext) {
+  struct uidgid ugid;
+
+  if (ext) {
+    if (! uidgids_get(&ugid, user)) {
+      if (*user == ':') fatalx("invalid uid/gids", user +1);
+      if (errno) fatal("unable to get password/group file entry");
+      fatalx("unknown user/group", user);
+    }
+  }
+  else
+    if (! uidgid_get(&ugid, user)) {
+      if (errno) fatal("unable to get password file entry");
+      fatalx("unknown account", user);
+    }
+  if (setgroups(ugid.gids, ugid.gid) == -1) fatal("unable to setgroups");
+  if (setgid(*ugid.gid) == -1) fatal("unable to setgid");
+  if (prot_uid(ugid.uid) == -1) fatal("unable to setuid");
+}
+
+void euidgid(char *user, unsigned int ext) {
+  struct uidgid ugid;
+  char bufnum[FMT_ULONG];
+
+  if (ext) {
+    if (! uidgids_get(&ugid, user)) {
+      if (*user == ':') fatalx("invalid uid/gids", user +1);
+      if (errno) fatal("unable to get password/group file entry");
+      fatalx("unknown user/group", user);
+    }
+  }
+  else
+    if (! uidgid_get(&ugid, user)) {
+      if (errno) fatal("unable to get password file entry");
+      fatalx("unknown account", user);
+    }
+  bufnum[fmt_ulong(bufnum, *ugid.gid)] =0;
+  if (! pathexec_env("GID", bufnum)) die_nomem();
+  bufnum[fmt_ulong(bufnum, ugid.uid)] =0;
+  if (! pathexec_env("UID", bufnum)) die_nomem();
+}
+
+void edir(const char *dirname) {
+  int wdir;
+  DIR *dir;
+  direntry *d;
+  int i;
+
+  if ((wdir =open_read(".")) == -1)
+    fatal("unable to open current working directory");
+  if (chdir(dirname)) fatal2("unable to switch to directory", dirname);
+  if (! (dir =opendir("."))) fatal2("unable to open directory", dirname);
+  for (;;) {
+    errno =0;
+    d =readdir(dir);
+    if (! d) {
+      if (errno) fatal2("unable to read directory", dirname);
+      break;
+    }
+    if (d->d_name[0] == '.') continue;
+    if (openreadclose(d->d_name, &sa, 256) == -1) {
+      if ((errno == error_isdir) && env_dir) {
+        if (verbose)
+          strerr_warn6(WARNING, "unable to read ", dirname, "/",
+                       d->d_name, ": ", &strerr_sys);
+        continue;
+      }
+      else
+        strerr_die6sys(111, FATAL, "unable to read ", dirname, "/",
+                             d->d_name, ": ");
+    }
+    if (sa.len) {
+      sa.len =byte_chr(sa.s, sa.len, '\n');
+      while (sa.len && (sa.s[sa.len -1] == ' ' || sa.s[sa.len -1] == '\t'))
+        --sa.len;
+      for (i =0; i < sa.len; ++i) if (! sa.s[i]) sa.s[i] ='\n';
+      if (! stralloc_0(&sa)) die_nomem();
+      if (! pathexec_env(d->d_name, sa.s)) die_nomem();
+    }
+    else
+      if (! pathexec_env(d->d_name, 0)) die_nomem();
+  }
+  closedir(dir);
+  if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
+  close(wdir);
+}
+
+void slock_die(const char *m, const char *f, unsigned int x) {
+  if (! x) fatal2(m, f);
+  _exit(0);
+}
+void slock(const char *f, unsigned int d, unsigned int x) {
+  int fd;
+
+  if ((fd =open_append(f)) == -1) slock_die("unable to open lock", f, x);
+  if (d) {
+    if (lock_ex(fd) == -1) slock_die("unable to lock", f, x);
+    return;
+  }
+  if (lock_exnb(fd) == -1) slock_die("unable to lock", f, x);
+}
+
+void limit(int what, long l) {
+  struct rlimit r;
+
+  if (getrlimit(what, &r) == -1) fatal("unable to getrlimit()");
+  if ((l < 0) || (l > r.rlim_max))
+    r.rlim_cur =r.rlim_max;
+  else
+    r.rlim_cur =l;
+  if (setrlimit(what, &r) == -1) fatal("unable to setrlimit()");
+}
+void slimit() {
+  if (limitd >= -1) {
+#ifdef RLIMIT_DATA
+    limit(RLIMIT_DATA, limitd);
+#else
+    if (verbose) warn("system does not support RLIMIT_DATA");
+#endif
+  }
+  if (limits >= -1) {
+#ifdef RLIMIT_STACK
+    limit(RLIMIT_STACK, limits);
+#else
+    if (verbose) warn("system does not support RLIMIT_STACK");
+#endif
+  }
+  if (limitl >= -1) {
+#ifdef RLIMIT_MEMLOCK
+    limit(RLIMIT_MEMLOCK, limitl);
+#else
+    if (verbose) warn("system does not support RLIMIT_MEMLOCK");
+#endif
+  }
+  if (limita >= -1) {
+#ifdef RLIMIT_VMEM
+    limit(RLIMIT_VMEM, limita);
+#else
+#ifdef RLIMIT_AS
+    limit(RLIMIT_AS, limita);
+#else
+    if (verbose)
+      warn("system does neither support RLIMIT_VMEM nor RLIMIT_AS");
+#endif
+#endif
+  }
+  if (limito >= -1) {
+#ifdef RLIMIT_NOFILE
+    limit(RLIMIT_NOFILE, limito);
+#else
+#ifdef RLIMIT_OFILE
+    limit(RLIMIT_OFILE, limito);
+#else
+    if (verbose)
+      warn("system does neither support RLIMIT_NOFILE nor RLIMIT_OFILE");
+#endif
+#endif
+  }
+  if (limitp >= -1) {
+#ifdef RLIMIT_NPROC
+    limit(RLIMIT_NPROC, limitp);
+#else
+    if (verbose) warn("system does not support RLIMIT_NPROC");
+#endif
+  }
+  if (limitf >= -1) {
+#ifdef RLIMIT_FSIZE
+    limit(RLIMIT_FSIZE, limitf);
+#else
+    if (verbose) warn("system does not support RLIMIT_FSIZE");
+#endif
+  }
+  if (limitc >= -1) {
+#ifdef RLIMIT_CORE
+    limit(RLIMIT_CORE, limitc);
+#else
+    if (verbose) warn("system does not support RLIMIT_CORE");
+#endif
+  }
+  if (limitr >= -1) {
+#ifdef RLIMIT_RSS
+    limit(RLIMIT_RSS, limitr);
+#else
+    if (verbose) warn("system does not support RLIMIT_RSS");
+#endif
+  }
+  if (limitt >= -1) {
+#ifdef RLIMIT_CPU
+    limit(RLIMIT_CPU, limitt);
+#else
+    if (verbose) warn("system does not support RLIMIT_CPU");
+#endif
+  }
+}
+
+/* argv[0] */
+void setuidgid(int, const char *const *);
+void envuidgid(int, const char *const *);
+void envdir(int, const char *const *);
+void pgrphack(int, const char *const *);
+void setlock(int, const char *const *);
+void softlimit(int, const char *const *);
+
+int main(int argc, const char **argv) {
+  int opt;
+  int i;
+  unsigned long ul;
+
+  progname =argv[0];
+  for (i =str_len(progname); i; --i)
+    if (progname[i -1] == '/') {
+      progname +=i;
+      break;
+    }
+  if (progname[0] == 'd') ++progname;
+
+  /* argv[0] */
+  if (str_equal(progname, "setuidgid")) setuidgid(argc, argv);
+  if (str_equal(progname, "envuidgid")) envuidgid(argc, argv);
+  if (str_equal(progname, "envdir")) envdir(argc, argv);
+  if (str_equal(progname, "pgrphack")) pgrphack(argc, argv);
+  if (str_equal(progname, "setlock")) setlock(argc, argv);
+  if (str_equal(progname, "softlimit")) softlimit(argc, argv);
+
+  while ((opt =getopt(argc, argv, "u:U:b:e:m:d:o:p:f:c:r:t:/:n:l:L:vP012V"))
+         != opteof)
+    switch(opt) {
+    case 'u': set_user =(char*)optarg; break;
+    case 'U': env_user =(char*)optarg; break;
+    case 'b': argv0 =(char*)optarg; break;
+    case 'e': env_dir =optarg; break;
+    case 'm':
+      if (optarg[scan_ulong(optarg, &ul)]) usage();
+      limits =limitl =limita =limitd =ul;
+      break;
+    case 'd': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitd =ul; break;
+    case 'o': if (optarg[scan_ulong(optarg, &ul)]) usage(); limito =ul; break;
+    case 'p': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitp =ul; break;
+    case 'f': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitf =ul; break;
+    case 'c': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitc =ul; break;
+    case 'r': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitr =ul; break;
+    case 't': if (optarg[scan_ulong(optarg, &ul)]) usage(); limitt =ul; break;
+    case '/': root =optarg; break;
+    case 'n':
+      switch (*optarg) {
+        case '-':
+          if (optarg[scan_ulong(++optarg, &ul)]) usage(); nicelvl =ul;
+          nicelvl *=-1;
+          break;
+        case '+': ++optarg;
+        default:
+          if (optarg[scan_ulong(optarg, &ul)]) usage(); nicelvl =ul;
+          break;
+      }
+      break;
+    case 'l': if (lock) usage(); lock =optarg; lockdelay =1; break;
+    case 'L': if (lock) usage(); lock =optarg; lockdelay =0; break;
+    case 'v': verbose =1; break;
+    case 'P': pgrp =1; break;
+    case '0': nostdin =1; break;
+    case '1': nostdout =1; break;
+    case '2': nostderr =1; break;
+    case 'V': strerr_warn1("$Id: f279d44141c981dd7535a12260efcf1ef7beed26 $", 0);
+    case '?': usage();
+    }
+  argv +=optind;
+  if (! argv || ! *argv) usage();
+
+  if (pgrp) setsid();
+  if (env_dir) edir(env_dir);
+  if (root) {
+    if (chdir(root) == -1) fatal2("unable to change directory", root);
+    if (chroot(".") == -1) fatal("unable to change root directory");
+  }
+  if (nicelvl) {
+    errno =0;
+    if (nice(nicelvl) == -1) if (errno) fatal("unable to set nice level");
+  }
+  if (env_user) euidgid(env_user, 1);
+  if (set_user) suidgid(set_user, 1);
+  if (lock) slock(lock, lockdelay, 0);
+  if (nostdin) if (close(0) == -1) fatal("unable to close stdin");
+  if (nostdout) if (close(1) == -1) fatal("unable to close stdout");
+  if (nostderr) if (close(2) == -1) fatal("unable to close stderr");
+  slimit();
+
+  progname =*argv;
+  if (argv0) *argv =argv0;
+  pathexec_env_run(progname, argv);
+  fatal2("unable to run", *argv);
+  return(0);
+}
+
+/* argv[0] */
+#define USAGE_SETUIDGID " account child"
+#define USAGE_ENVUIDGID " account child"
+#define USAGE_ENVDIR " dir child"
+#define USAGE_PGRPHACK " child"
+#define USAGE_SETLOCK " [ -nNxX ] file program [ arg ... ]"
+#define USAGE_SOFTLIMIT " [-a allbytes] [-c corebytes] [-d databytes] [-f filebytes] [-l lockbytes] [-m membytes] [-o openfiles] [-p processes] [-r residentbytes] [-s stackbytes] [-t cpusecs] child"
+
+void setuidgid_usage() {
+  strerr_die4x(100, "usage: ", progname, USAGE_SETUIDGID, "\n");
+}
+void setuidgid(int argc, const char *const *argv) {
+  const char *account;
+
+  if (! (account =*++argv)) setuidgid_usage();
+  if (! *++argv) setuidgid_usage();
+  suidgid((char*)account, 0);
+  pathexec(argv);
+  fatal2("unable to run", *argv);
+}
+
+void envuidgid_usage() {
+  strerr_die4x(100, "usage: ", progname, USAGE_ENVUIDGID, "\n");
+}
+void envuidgid(int argc, const char *const *argv) {
+  const char *account;
+
+  if (! (account =*++argv)) envuidgid_usage();
+  if (! *++argv) envuidgid_usage();
+  euidgid((char*)account, 0);
+  pathexec(argv);
+  fatal2("unable to run", *argv);
+}
+
+void envdir_usage() {
+  strerr_die4x(100, "usage: ", progname, USAGE_ENVDIR, "\n");
+}
+void envdir(int argc, const char *const *argv) {
+  const char *dir;
+
+  if (! (dir =*++argv)) envdir_usage();
+  if (! *++argv) envdir_usage();
+  edir(dir);
+  pathexec(argv);
+  fatal2("unable to run", *argv);
+}
+
+void pgrphack_usage() {
+  strerr_die4x(100, "usage: ", progname, USAGE_PGRPHACK, "\n");
+}
+void pgrphack(int argc, const char *const *argv) {
+  if (! *++argv) pgrphack_usage();
+  setsid();
+  pathexec(argv);
+  fatal2("unable to run", *argv);
+}
+
+void setlock_usage() {
+  strerr_die4x(100, "usage: ", progname, USAGE_SETLOCK, "\n");
+}
+void setlock(int argc, const char *const *argv) {
+  int opt;
+  unsigned int delay =0;
+  unsigned int x =0;
+  const char *fn;
+
+  while ((opt =getopt(argc, argv, "nNxX")) != opteof)
+    switch(opt) {
+      case 'n': delay =1; break;
+      case 'N': delay =0; break;
+      case 'x': x =1; break;
+      case 'X': x =0; break;
+      default: setlock_usage();
+    }
+  argv +=optind;
+  if (! (fn =*argv)) setlock_usage();
+  if (! *++argv) setlock_usage();
+
+  slock(fn, delay, x);
+  pathexec(argv);
+  if (! x) fatal2("unable to run", *argv);
+  _exit(0);
+}
+
+void softlimit_usage() {
+  strerr_die4x(100, "usage: ", progname, USAGE_SOFTLIMIT, "\n");
+}
+void getlarg(long *l) {
+  unsigned long ul;
+
+  if (str_equal(optarg, "=")) { *l =-1; return; }
+  if (optarg[scan_ulong(optarg, &ul)]) usage();
+  *l =ul;
+}
+void softlimit(int argc, const char *const *argv) {
+  int opt;
+  
+  while ((opt =getopt(argc,argv,"a:c:d:f:l:m:o:p:r:s:t:")) != opteof)
+    switch(opt) {
+    case '?': softlimit_usage();
+    case 'a': getlarg(&limita); break;
+    case 'c': getlarg(&limitc); break;
+    case 'd': getlarg(&limitd); break;
+    case 'f': getlarg(&limitf); break;
+    case 'l': getlarg(&limitl); break;
+    case 'm': getlarg(&limitd); limits =limitl =limita =limitd; break;
+    case 'o': getlarg(&limito); break;
+    case 'p': getlarg(&limitp); break;
+    case 'r': getlarg(&limitr); break;
+    case 's': getlarg(&limits); break;
+    case 't': getlarg(&limitt); break;
+    }
+  argv +=optind;
+  if (!*argv) softlimit_usage();
+  slimit();
+  pathexec(argv);
+  fatal2("unable to run", *argv);
+}
diff --git a/runit-2.1.2/src/chpst.check b/runit-2.1.2/src/chpst.check
new file mode 100755
index 0000000..384113e
--- /dev/null
+++ b/runit-2.1.2/src/chpst.check
@@ -0,0 +1,36 @@
+#!/bin/sh
+rm -rf "${ctmp}"
+
+chpst
+echo $?
+chpst -V
+echo $?
+
+# -u
+# -U
+
+mkdir "${ctmp}"
+echo 1 >"${ctmp}"/test
+chpst -e"${ctmp}" env |sed -ne '/^test=1$/p'
+echo $?
+rm -rf "${ctmp}"
+
+chpst -l"${ctmp}" true
+echo $?
+rm -f "${ctmp}"
+
+chpst -L"${ctmp}" true
+echo $?
+rm -f "${ctmp}"
+
+# -m
+# -o
+# -p
+# -f
+# -c
+
+chpst -P true
+echo $?
+
+chpst -012 true
+echo $?
diff --git a/runit-2.1.2/src/chpst.dist b/runit-2.1.2/src/chpst.dist
new file mode 100644
index 0000000..6779bfd
--- /dev/null
+++ b/runit-2.1.2/src/chpst.dist
@@ -0,0 +1,13 @@
+usage: chpst [-vP012] [-u user[:group]] [-U user[:group]] [-b argv0] [-e dir] [-/ root] [-n nice] [-l|-L lock] [-m n] [-d n] [-o n] [-p n] [-f n] [-c n] prog
+
+100
+$Id: f279d44141c981dd7535a12260efcf1ef7beed26 $
+usage: chpst [-vP012] [-u user[:group]] [-U user[:group]] [-b argv0] [-e dir] [-/ root] [-n nice] [-l|-L lock] [-m n] [-d n] [-o n] [-p n] [-f n] [-c n] prog
+
+100
+test=1
+0
+0
+0
+0
+0
diff --git a/runit-2.1.2/src/coe.c b/runit-2.1.2/src/coe.c
new file mode 100644
index 0000000..50b2397
--- /dev/null
+++ b/runit-2.1.2/src/coe.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#include <fcntl.h>
+#include "coe.h"
+
+int coe(int fd)
+{
+  return fcntl(fd,F_SETFD,1);
+}
diff --git a/runit-2.1.2/src/coe.h b/runit-2.1.2/src/coe.h
new file mode 100644
index 0000000..b17db54
--- /dev/null
+++ b/runit-2.1.2/src/coe.h
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#ifndef COE_H
+#define COE_H
+
+extern int coe(int);
+
+#endif
diff --git a/runit-2.1.2/src/conf-cc b/runit-2.1.2/src/conf-cc
new file mode 100644
index 0000000..984024f
--- /dev/null
+++ b/runit-2.1.2/src/conf-cc
@@ -0,0 +1,5 @@
+gcc -O2 -Wall
+
+gcc -O2 -Wimplicit -Wunused -Wcomment -Wchar-subscripts -Wuninitialized -Wshadow -Wcast-qual -Wcast-align -Wwrite-strings
+
+This will be used to compile .c files.
diff --git a/runit-2.1.2/src/conf-ld b/runit-2.1.2/src/conf-ld
new file mode 100644
index 0000000..59a0de7
--- /dev/null
+++ b/runit-2.1.2/src/conf-ld
@@ -0,0 +1,3 @@
+gcc -s
+
+This will be used to link .o files into an executable.
diff --git a/runit-2.1.2/src/direntry.h1 b/runit-2.1.2/src/direntry.h1
new file mode 100644
index 0000000..6cb088d
--- /dev/null
+++ b/runit-2.1.2/src/direntry.h1
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#ifndef DIRENTRY_H
+#define DIRENTRY_H
+
+/* sysdep: -dirent */
+
+#include <sys/types.h>
+#include <sys/dir.h>
+#define direntry struct direct
+
+#endif
diff --git a/runit-2.1.2/src/direntry.h2 b/runit-2.1.2/src/direntry.h2
new file mode 100644
index 0000000..bfd4d19
--- /dev/null
+++ b/runit-2.1.2/src/direntry.h2
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#ifndef DIRENTRY_H
+#define DIRENTRY_H
+
+/* sysdep: +dirent */
+
+#include <sys/types.h>
+#include <dirent.h>
+#define direntry struct dirent
+
+#endif
diff --git a/runit-2.1.2/src/env.c b/runit-2.1.2/src/env.c
new file mode 100644
index 0000000..1b3ef62
--- /dev/null
+++ b/runit-2.1.2/src/env.c
@@ -0,0 +1,17 @@
+/* Public domain. */
+
+#include "str.h"
+#include "env.h"
+
+extern /*@null@*/char *env_get(const char *s)
+{
+  int i;
+  unsigned int len;
+
+  if (!s) return 0;
+  len = str_len(s);
+  for (i = 0;environ[i];++i)
+    if (str_start(environ[i],s) && (environ[i][len] == '='))
+      return environ[i] + len + 1;
+  return 0;
+}
diff --git a/runit-2.1.2/src/env.h b/runit-2.1.2/src/env.h
new file mode 100644
index 0000000..834d331
--- /dev/null
+++ b/runit-2.1.2/src/env.h
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#ifndef ENV_H
+#define ENV_H
+
+extern char **environ;
+
+extern /*@null@*/char *env_get(const char *);
+
+#endif
diff --git a/runit-2.1.2/src/error.c b/runit-2.1.2/src/error.c
new file mode 100644
index 0000000..ea5f9c2
--- /dev/null
+++ b/runit-2.1.2/src/error.c
@@ -0,0 +1,132 @@
+/* Public domain. */
+
+#include <errno.h>
+#include "error.h"
+
+/* warning: as coverage improves here, should update error_{str,temp} */
+
+int error_intr =
+#ifdef EINTR
+EINTR;
+#else
+-1;
+#endif
+
+int error_nomem =
+#ifdef ENOMEM
+ENOMEM;
+#else
+-2;
+#endif
+
+int error_noent = 
+#ifdef ENOENT
+ENOENT;
+#else
+-3;
+#endif
+
+int error_txtbsy =
+#ifdef ETXTBSY
+ETXTBSY;
+#else
+-4;
+#endif
+
+int error_io =
+#ifdef EIO
+EIO;
+#else
+-5;
+#endif
+
+int error_exist =
+#ifdef EEXIST
+EEXIST;
+#else
+-6;
+#endif
+
+int error_timeout =
+#ifdef ETIMEDOUT
+ETIMEDOUT;
+#else
+-7;
+#endif
+
+int error_inprogress =
+#ifdef EINPROGRESS
+EINPROGRESS;
+#else
+-8;
+#endif
+
+int error_wouldblock =
+#ifdef EWOULDBLOCK
+EWOULDBLOCK;
+#else
+-9;
+#endif
+
+int error_again =
+#ifdef EAGAIN
+EAGAIN;
+#else
+-10;
+#endif
+
+int error_pipe =
+#ifdef EPIPE
+EPIPE;
+#else
+-11;
+#endif
+
+int error_perm =
+#ifdef EPERM
+EPERM;
+#else
+-12;
+#endif
+
+int error_acces =
+#ifdef EACCES
+EACCES;
+#else
+-13;
+#endif
+
+int error_nodevice =
+#ifdef ENXIO
+ENXIO;
+#else
+-14;
+#endif
+
+int error_proto =
+#ifdef EPROTO
+EPROTO;
+#else
+-15;
+#endif
+
+int error_isdir =
+#ifdef EISDIR
+EISDIR;
+#else
+-16;
+#endif
+
+int error_connrefused =
+#ifdef ECONNREFUSED
+ECONNREFUSED;
+#else
+-17;
+#endif
+
+int error_notdir =
+#ifdef ENOTDIR
+ENOTDIR;
+#else
+-18;
+#endif
diff --git a/runit-2.1.2/src/error.h b/runit-2.1.2/src/error.h
new file mode 100644
index 0000000..8ecb400
--- /dev/null
+++ b/runit-2.1.2/src/error.h
@@ -0,0 +1,33 @@
+/* Public domain. */
+
+#ifndef ERROR_H
+#define ERROR_H
+
+/* 20030124: include <errno.h> -upcoming glibc changes */
+#include <errno.h>
+ 
+/* extern int errno; */
+
+extern int error_intr;
+extern int error_nomem;
+extern int error_noent;
+extern int error_txtbsy;
+extern int error_io;
+extern int error_exist;
+extern int error_timeout;
+extern int error_inprogress;
+extern int error_wouldblock;
+extern int error_again;
+extern int error_pipe;
+extern int error_perm;
+extern int error_acces;
+extern int error_nodevice;
+extern int error_proto;
+extern int error_isdir;
+extern int error_connrefused;
+extern int error_notdir;
+
+extern const char *error_str(int);
+extern int error_temp(int);
+
+#endif
diff --git a/runit-2.1.2/src/error_str.c b/runit-2.1.2/src/error_str.c
new file mode 100644
index 0000000..e002efe
--- /dev/null
+++ b/runit-2.1.2/src/error_str.c
@@ -0,0 +1,267 @@
+/* Public domain. */
+
+#include <errno.h>
+#include "error.h"
+
+#define X(e,s) if (i == e) return s;
+
+const char *error_str(int i)
+{
+  X(0,"no error")
+  X(error_intr,"interrupted system call")
+  X(error_nomem,"out of memory")
+  X(error_noent,"file does not exist")
+  X(error_txtbsy,"text busy")
+  X(error_io,"input/output error")
+  X(error_exist,"file already exists")
+  X(error_timeout,"timed out")
+  X(error_inprogress,"operation in progress")
+  X(error_again,"temporary failure")
+  X(error_wouldblock,"input/output would block")
+  X(error_pipe,"broken pipe")
+  X(error_perm,"permission denied")
+  X(error_acces,"access denied")
+  X(error_nodevice,"device not configured")
+  X(error_proto,"protocol error")
+  X(error_isdir,"is a directory")
+  X(error_connrefused,"connection refused")
+  X(error_notdir,"not a directory")
+#ifdef ESRCH
+  X(ESRCH,"no such process")
+#endif
+#ifdef E2BIG
+  X(E2BIG,"argument list too long")
+#endif
+#ifdef ENOEXEC
+  X(ENOEXEC,"exec format error")
+#endif
+#ifdef EBADF
+  X(EBADF,"file descriptor not open")
+#endif
+#ifdef ECHILD
+  X(ECHILD,"no child processes")
+#endif
+#ifdef EDEADLK
+  X(EDEADLK,"operation would cause deadlock")
+#endif
+#ifdef EFAULT
+  X(EFAULT,"bad address")
+#endif
+#ifdef ENOTBLK
+  X(ENOTBLK,"not a block device")
+#endif
+#ifdef EBUSY
+  X(EBUSY,"device busy")
+#endif
+#ifdef EXDEV
+  X(EXDEV,"cross-device link")
+#endif
+#ifdef ENODEV
+  X(ENODEV,"device does not support operation")
+#endif
+#ifdef EINVAL
+  X(EINVAL,"invalid argument")
+#endif
+#ifdef ENFILE
+  X(ENFILE,"system cannot open more files")
+#endif
+#ifdef EMFILE
+  X(EMFILE,"process cannot open more files")
+#endif
+#ifdef ENOTTY
+  X(ENOTTY,"not a tty")
+#endif
+#ifdef EFBIG
+  X(EFBIG,"file too big")
+#endif
+#ifdef ENOSPC
+  X(ENOSPC,"out of disk space")
+#endif
+#ifdef ESPIPE
+  X(ESPIPE,"unseekable descriptor")
+#endif
+#ifdef EROFS
+  X(EROFS,"read-only file system")
+#endif
+#ifdef EMLINK
+  X(EMLINK,"too many links")
+#endif
+#ifdef EDOM
+  X(EDOM,"input out of range")
+#endif
+#ifdef ERANGE
+  X(ERANGE,"output out of range")
+#endif
+#ifdef EALREADY
+  X(EALREADY,"operation already in progress")
+#endif
+#ifdef ENOTSOCK
+  X(ENOTSOCK,"not a socket")
+#endif
+#ifdef EDESTADDRREQ
+  X(EDESTADDRREQ,"destination address required")
+#endif
+#ifdef EMSGSIZE
+  X(EMSGSIZE,"message too long")
+#endif
+#ifdef EPROTOTYPE
+  X(EPROTOTYPE,"incorrect protocol type")
+#endif
+#ifdef ENOPROTOOPT
+  X(ENOPROTOOPT,"protocol not available")
+#endif
+#ifdef EPROTONOSUPPORT
+  X(EPROTONOSUPPORT,"protocol not supported")
+#endif
+#ifdef ESOCKTNOSUPPORT
+  X(ESOCKTNOSUPPORT,"socket type not supported")
+#endif
+#ifdef EOPNOTSUPP
+  X(EOPNOTSUPP,"operation not supported")
+#endif
+#ifdef EPFNOSUPPORT
+  X(EPFNOSUPPORT,"protocol family not supported")
+#endif
+#ifdef EAFNOSUPPORT
+  X(EAFNOSUPPORT,"address family not supported")
+#endif
+#ifdef EADDRINUSE
+  X(EADDRINUSE,"address already used")
+#endif
+#ifdef EADDRNOTAVAIL
+  X(EADDRNOTAVAIL,"address not available")
+#endif
+#ifdef ENETDOWN
+  X(ENETDOWN,"network down")
+#endif
+#ifdef ENETUNREACH
+  X(ENETUNREACH,"network unreachable")
+#endif
+#ifdef ENETRESET
+  X(ENETRESET,"network reset")
+#endif
+#ifdef ECONNABORTED
+  X(ECONNABORTED,"connection aborted")
+#endif
+#ifdef ECONNRESET
+  X(ECONNRESET,"connection reset")
+#endif
+#ifdef ENOBUFS
+  X(ENOBUFS,"out of buffer space")
+#endif
+#ifdef EISCONN
+  X(EISCONN,"already connected")
+#endif
+#ifdef ENOTCONN
+  X(ENOTCONN,"not connected")
+#endif
+#ifdef ESHUTDOWN
+  X(ESHUTDOWN,"socket shut down")
+#endif
+#ifdef ETOOMANYREFS
+  X(ETOOMANYREFS,"too many references")
+#endif
+#ifdef ELOOP
+  X(ELOOP,"symbolic link loop")
+#endif
+#ifdef ENAMETOOLONG
+  X(ENAMETOOLONG,"file name too long")
+#endif
+#ifdef EHOSTDOWN
+  X(EHOSTDOWN,"host down")
+#endif
+#ifdef EHOSTUNREACH
+  X(EHOSTUNREACH,"host unreachable")
+#endif
+#ifdef ENOTEMPTY
+  X(ENOTEMPTY,"directory not empty")
+#endif
+#ifdef EPROCLIM
+  X(EPROCLIM,"too many processes")
+#endif
+#ifdef EUSERS
+  X(EUSERS,"too many users")
+#endif
+#ifdef EDQUOT
+  X(EDQUOT,"disk quota exceeded")
+#endif
+#ifdef ESTALE
+  X(ESTALE,"stale NFS file handle")
+#endif
+#ifdef EREMOTE
+  X(EREMOTE,"too many levels of remote in path")
+#endif
+#ifdef EBADRPC
+  X(EBADRPC,"RPC structure is bad")
+#endif
+#ifdef ERPCMISMATCH
+  X(ERPCMISMATCH,"RPC version mismatch")
+#endif
+#ifdef EPROGUNAVAIL
+  X(EPROGUNAVAIL,"RPC program unavailable")
+#endif
+#ifdef EPROGMISMATCH
+  X(EPROGMISMATCH,"program version mismatch")
+#endif
+#ifdef EPROCUNAVAIL
+  X(EPROCUNAVAIL,"bad procedure for program")
+#endif
+#ifdef ENOLCK
+  X(ENOLCK,"no locks available")
+#endif
+#ifdef ENOSYS
+  X(ENOSYS,"system call not available")
+#endif
+#ifdef EFTYPE
+  X(EFTYPE,"bad file type")
+#endif
+#ifdef EAUTH
+  X(EAUTH,"authentication error")
+#endif
+#ifdef ENEEDAUTH
+  X(ENEEDAUTH,"not authenticated")
+#endif
+#ifdef ENOSTR
+  X(ENOSTR,"not a stream device")
+#endif
+#ifdef ETIME
+  X(ETIME,"timer expired")
+#endif
+#ifdef ENOSR
+  X(ENOSR,"out of stream resources")
+#endif
+#ifdef ENOMSG
+  X(ENOMSG,"no message of desired type")
+#endif
+#ifdef EBADMSG
+  X(EBADMSG,"bad message type")
+#endif
+#ifdef EIDRM
+  X(EIDRM,"identifier removed")
+#endif
+#ifdef ENONET
+  X(ENONET,"machine not on network")
+#endif
+#ifdef ERREMOTE
+  X(ERREMOTE,"object not local")
+#endif
+#ifdef ENOLINK
+  X(ENOLINK,"link severed")
+#endif
+#ifdef EADV
+  X(EADV,"advertise error")
+#endif
+#ifdef ESRMNT
+  X(ESRMNT,"srmount error")
+#endif
+#ifdef ECOMM
+  X(ECOMM,"communication error")
+#endif
+#ifdef EMULTIHOP
+  X(EMULTIHOP,"multihop attempted")
+#endif
+#ifdef EREMCHG
+  X(EREMCHG,"remote address changed")
+#endif
+  return "unknown error";
+}
diff --git a/runit-2.1.2/src/fd.h b/runit-2.1.2/src/fd.h
new file mode 100644
index 0000000..1c7a035
--- /dev/null
+++ b/runit-2.1.2/src/fd.h
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#ifndef FD_H
+#define FD_H
+
+extern int fd_copy(int,int);
+extern int fd_move(int,int);
+
+#endif
diff --git a/runit-2.1.2/src/fd_copy.c b/runit-2.1.2/src/fd_copy.c
new file mode 100644
index 0000000..80e9d15
--- /dev/null
+++ b/runit-2.1.2/src/fd_copy.c
@@ -0,0 +1,14 @@
+/* Public domain. */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include "fd.h"
+
+int fd_copy(int to,int from)
+{
+  if (to == from) return 0;
+  if (fcntl(from,F_GETFL,0) == -1) return -1;
+  close(to);
+  if (fcntl(from,F_DUPFD,to) == -1) return -1;
+  return 0;
+}
diff --git a/runit-2.1.2/src/fd_move.c b/runit-2.1.2/src/fd_move.c
new file mode 100644
index 0000000..49f723f
--- /dev/null
+++ b/runit-2.1.2/src/fd_move.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#include <unistd.h>
+#include "fd.h"
+
+int fd_move(int to,int from)
+{
+  if (to == from) return 0;
+  if (fd_copy(to,from) == -1) return -1;
+  close(from);
+  return 0;
+}
diff --git a/runit-2.1.2/src/fifo.c b/runit-2.1.2/src/fifo.c
new file mode 100644
index 0000000..c14f683
--- /dev/null
+++ b/runit-2.1.2/src/fifo.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "hasmkffo.h"
+#include "fifo.h"
+
+#ifdef HASMKFIFO
+int fifo_make(const char *fn,int mode) { return mkfifo(fn,mode); }
+#else
+int fifo_make(const char *fn,int mode) { return mknod(fn,S_IFIFO | mode,0); }
+#endif
diff --git a/runit-2.1.2/src/fifo.h b/runit-2.1.2/src/fifo.h
new file mode 100644
index 0000000..ba75678
--- /dev/null
+++ b/runit-2.1.2/src/fifo.h
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#ifndef FIFO_H
+#define FIFO_H
+
+extern int fifo_make(const char *,int);
+
+#endif
diff --git a/runit-2.1.2/src/find-systype.sh b/runit-2.1.2/src/find-systype.sh
new file mode 100644
index 0000000..9f6e565
--- /dev/null
+++ b/runit-2.1.2/src/find-systype.sh
@@ -0,0 +1,143 @@
+# oper-:arch-:syst-:chip-:kern-
+# oper = operating system type; e.g., sunos-4.1.4
+# arch = machine language; e.g., sparc
+# syst = which binaries can run; e.g., sun4
+# chip = chip model; e.g., micro-2-80
+# kern = kernel version; e.g., sun4m
+# dependence: arch --- chip
+#                 \        \
+#          oper --- syst --- kern
+# so, for example, syst is interpreted in light of oper, but chip is not.
+# anyway, no slashes, no extra colons, no uppercase letters.
+# the point of the extra -'s is to ease parsing: can add hierarchies later.
+# e.g., *:i386-*:*:pentium-*:* would handle pentium-100 as well as pentium,
+# and i386-486 (486s do have more instructions, you know) as well as i386.
+# the idea here is to include ALL useful available information.
+
+exec 2>/dev/null
+
+sys="`uname -s | tr '/:[A-Z]' '..[a-z]'`"
+if [ x"$sys" != x ]
+then
+  unamer="`uname -r | tr /: ..`"
+  unamem="`uname -m | tr /: ..`"
+  unamev="`uname -v | tr /: ..`"
+
+  case "$sys" in
+  bsd.os|freebsd|netbsd|openbsd)
+    # in bsd 4.4, uname -v does not have useful info.
+    # in bsd 4.4, uname -m is arch, not chip.
+    oper="$sys-$unamer"
+    arch="$unamem"
+    syst=""
+    chip="`sysctl -n hw.model`" # hopefully
+    kern=""
+    ;;
+  linux)
+    # as in bsd 4.4, uname -v does not have useful info.
+    oper="$sys-$unamer"
+    syst=""
+    chip="$unamem"
+    kern=""
+    case "$chip" in
+    i386|i486|i586|i686)
+      arch="i386"
+      ;;
+    alpha)
+      arch="alpha"
+      ;;
+    esac
+    ;;
+  aix)
+    # naturally IBM has to get uname -r and uname -v backwards. dorks.
+    oper="$sys-$unamev-$unamer"
+    arch="`arch | tr /: ..`"
+    syst=""
+    chip="$unamem"
+    kern=""
+    ;;
+  sunos)
+    oper="$sys-$unamer-$unamev"
+    arch="`(uname -p || mach) | tr /: ..`"
+    syst="`arch | tr /: ..`"
+    chip="$unamem" # this is wrong; is there any way to get the real info?
+    kern="`arch -k | tr /: ..`"
+    ;;
+  unix_sv)
+    oper="$sys-$unamer-$unamev"
+    arch="`uname -m`"
+    syst=""
+    chip="$unamem"
+    kern=""
+    ;;
+  *)
+    oper="$sys-$unamer-$unamev"
+    arch="`arch | tr /: ..`"
+    syst=""
+    chip="$unamem"
+    kern=""
+    ;;
+  esac
+else
+  gcc -c trycpp.c
+  gcc -o trycpp trycpp.o
+  case `./trycpp` in
+  nextstep)
+    oper="nextstep-`hostinfo | sed -n 's/^[ 	]*NeXT Mach \([^:]*\):.*$/\1/p'`"
+    arch="`hostinfo | sed -n 's/^Processor type: \(.*\) (.*)$/\1/p' | tr /: ..`"
+    syst=""
+    chip="`hostinfo | sed -n 's/^Processor type: .* (\(.*\))$/\1/p' | tr ' /:' '...'`"
+    kern=""
+    ;;
+  *)
+    oper="unknown"
+    arch=""
+    syst=""
+    chip=""
+    kern=""
+    ;;
+  esac
+  rm -f trycpp.o trycpp
+fi
+
+case "$chip" in
+80486)
+  # let's try to be consistent here. (BSD/OS)
+  chip=i486
+  ;;
+i486DX)
+  # respect the hyphen hierarchy. (FreeBSD)
+  chip=i486-dx
+  ;;
+i486.DX2)
+  # respect the hyphen hierarchy. (FreeBSD)
+  chip=i486-dx2
+  ;;
+Intel.586)
+  # no, you nitwits, there is no such chip. (NeXTStep)
+  chip=pentium
+  ;;
+i586)
+  # no, you nitwits, there is no such chip. (Linux)
+  chip=pentium
+  ;;
+i686)
+  # STOP SAYING THAT! (Linux)
+  chip=ppro
+esac
+
+if gcc -c x86cpuid.c
+then
+  if gcc -o x86cpuid x86cpuid.o
+  then
+    x86cpuid="`./x86cpuid | tr /: ..`"
+    case "$x86cpuid" in
+      ?*)
+        chip="$x86cpuid"
+        ;;
+    esac
+  fi
+fi
+rm -f x86cpuid x86cpuid.o
+
+echo "$oper-:$arch-:$syst-:$chip-:$kern-" | tr ' [A-Z]' '.[a-z]'
diff --git a/runit-2.1.2/src/fmt.h b/runit-2.1.2/src/fmt.h
new file mode 100644
index 0000000..8847fa6
--- /dev/null
+++ b/runit-2.1.2/src/fmt.h
@@ -0,0 +1,27 @@
+/* Public domain. */
+
+#ifndef FMT_H
+#define FMT_H
+
+#define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */
+#define FMT_LEN ((char *) 0) /* convenient abbreviation */
+
+extern unsigned int fmt_uint(char *,unsigned int);
+extern unsigned int fmt_uint0(char *,unsigned int,unsigned int);
+extern unsigned int fmt_xint(char *,unsigned int);
+extern unsigned int fmt_nbbint(char *,unsigned int,unsigned int,unsigned int,unsigned int);
+extern unsigned int fmt_ushort(char *,unsigned short);
+extern unsigned int fmt_xshort(char *,unsigned short);
+extern unsigned int fmt_nbbshort(char *,unsigned int,unsigned int,unsigned int,unsigned short);
+extern unsigned int fmt_ulong(char *,unsigned long);
+extern unsigned int fmt_xlong(char *,unsigned long);
+extern unsigned int fmt_nbblong(char *,unsigned int,unsigned int,unsigned int,unsigned long);
+
+extern unsigned int fmt_plusminus(char *,int);
+extern unsigned int fmt_minus(char *,int);
+extern unsigned int fmt_0x(char *,int);
+
+extern unsigned int fmt_str(char *,const char *);
+extern unsigned int fmt_strn(char *,const char *,unsigned int);
+
+#endif
diff --git a/runit-2.1.2/src/fmt_ptime.c b/runit-2.1.2/src/fmt_ptime.c
new file mode 100644
index 0000000..2ab5725
--- /dev/null
+++ b/runit-2.1.2/src/fmt_ptime.c
@@ -0,0 +1,42 @@
+#include <time.h>
+#include "fmt_ptime.h"
+#include "fmt.h"
+
+unsigned int fmt_ptime2(char *s, struct taia *ta, char sep) {
+  struct tm *t;
+  time_t u;
+
+  if (ta->sec.x < 4611686018427387914ULL) return(0); /* impossible? */
+  u =ta->sec.x -4611686018427387914ULL;
+  if (! (t =gmtime((time_t*)&u))) return(0);
+  fmt_ulong(s, 1900 +t->tm_year);
+  s[4] ='-'; fmt_uint0(&s[5], t->tm_mon +1, 2);
+  s[7] ='-'; fmt_uint0(&s[8], t->tm_mday, 2);
+  s[10] =sep; fmt_uint0(&s[11], t->tm_hour, 2);
+  s[13] =':'; fmt_uint0(&s[14], t->tm_min, 2);
+  s[16] =':'; fmt_uint0(&s[17], t->tm_sec, 2);
+  s[19] ='.'; fmt_uint0(&s[20], ta->nano, 9);
+  return(25);
+}
+
+unsigned int fmt_ptime(char *s, struct taia *ta) {
+  return(fmt_ptime2(s, ta, '_'));
+}
+
+unsigned int fmt_ptime_iso8601(char *s, struct taia *ta) {
+  return(fmt_ptime2(s, ta, 'T'));
+}
+
+unsigned int fmt_taia(char *s, struct taia *t) {
+  static char hex[16] ="0123456789abcdef";
+  static char pack[TAIA_PACK];
+  int i;
+
+  taia_pack(pack, t);
+  s[0] ='@';
+  for (i =0; i < 12; ++i) {
+    s[i *2 +1] =hex[(pack[i] >>4) &15];
+    s[i *2 +2] =hex[pack[i] &15];
+  }
+  return(25);
+}
diff --git a/runit-2.1.2/src/fmt_ptime.h b/runit-2.1.2/src/fmt_ptime.h
new file mode 100644
index 0000000..72ea008
--- /dev/null
+++ b/runit-2.1.2/src/fmt_ptime.h
@@ -0,0 +1,14 @@
+#ifndef FMT_PTIME_H
+#define FMT_PTIME_H
+
+#define FMT_PTIME 30
+
+#include <time.h>
+#include <sys/time.h>
+#include "taia.h"
+
+extern unsigned int fmt_ptime(char *, struct taia *);
+extern unsigned int fmt_ptime_iso8601(char *, struct taia *);
+extern unsigned int fmt_taia(char *, struct taia *);
+
+#endif
diff --git a/runit-2.1.2/src/fmt_uint.c b/runit-2.1.2/src/fmt_uint.c
new file mode 100644
index 0000000..b8ec0b7
--- /dev/null
+++ b/runit-2.1.2/src/fmt_uint.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include "fmt.h"
+
+unsigned int fmt_uint(register char *s,register unsigned int u)
+{
+  return fmt_ulong(s,u);
+}
diff --git a/runit-2.1.2/src/fmt_uint0.c b/runit-2.1.2/src/fmt_uint0.c
new file mode 100644
index 0000000..728a5aa
--- /dev/null
+++ b/runit-2.1.2/src/fmt_uint0.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#include "fmt.h"
+
+unsigned int fmt_uint0(char *s,unsigned int u,unsigned int n)
+{
+  unsigned int len;
+  len = fmt_uint(FMT_LEN,u);
+  while (len < n) { if (s) *s++ = '0'; ++len; }
+  if (s) fmt_uint(s,u);
+  return len;
+}
diff --git a/runit-2.1.2/src/fmt_ulong.c b/runit-2.1.2/src/fmt_ulong.c
new file mode 100644
index 0000000..168572f
--- /dev/null
+++ b/runit-2.1.2/src/fmt_ulong.c
@@ -0,0 +1,15 @@
+/* Public domain. */
+
+#include "fmt.h"
+
+unsigned int fmt_ulong(register char *s,register unsigned long u)
+{
+  register unsigned int len; register unsigned long q;
+  len = 1; q = u;
+  while (q > 9) { ++len; q /= 10; }
+  if (s) {
+    s += len;
+    do { *--s = '0' + (u % 10); u /= 10; } while(u); /* handles u == 0 */
+  }
+  return len;
+}
diff --git a/runit-2.1.2/src/gen_alloc.h b/runit-2.1.2/src/gen_alloc.h
new file mode 100644
index 0000000..bd55e5b
--- /dev/null
+++ b/runit-2.1.2/src/gen_alloc.h
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#ifndef GEN_ALLOC_H
+#define GEN_ALLOC_H
+
+#define GEN_ALLOC_typedef(ta,type,field,len,a) \
+  typedef struct ta { type *field; unsigned int len; unsigned int a; } ta;
+
+#endif
diff --git a/runit-2.1.2/src/gen_allocdefs.h b/runit-2.1.2/src/gen_allocdefs.h
new file mode 100644
index 0000000..3afd92b
--- /dev/null
+++ b/runit-2.1.2/src/gen_allocdefs.h
@@ -0,0 +1,36 @@
+/* Public domain. */
+
+#ifndef GEN_ALLOC_DEFS_H
+#define GEN_ALLOC_DEFS_H
+
+#define GEN_ALLOC_ready(ta,type,field,len,a,i,n,x,base,ta_ready) \
+int ta_ready(register ta *x,register unsigned int n) \
+{ register unsigned int i; \
+  if (x->field) { \
+    i = x->a; \
+    if (n > i) { \
+      x->a = base + n + (n >> 3); \
+      if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \
+      x->a = i; return 0; } \
+    return 1; } \
+  x->len = 0; \
+  return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); }
+
+#define GEN_ALLOC_readyplus(ta,type,field,len,a,i,n,x,base,ta_rplus) \
+int ta_rplus(register ta *x,register unsigned int n) \
+{ register unsigned int i; \
+  if (x->field) { \
+    i = x->a; n += x->len; \
+    if (n > i) { \
+      x->a = base + n + (n >> 3); \
+      if (alloc_re(&x->field,i * sizeof(type),x->a * sizeof(type))) return 1; \
+      x->a = i; return 0; } \
+    return 1; } \
+  x->len = 0; \
+  return !!(x->field = (type *) alloc((x->a = n) * sizeof(type))); }
+
+#define GEN_ALLOC_append(ta,type,field,len,a,i,n,x,base,ta_rplus,ta_append) \
+int ta_append(register ta *x,register const type *i) \
+{ if (!ta_rplus(x,1)) return 0; x->field[x->len++] = *i; return 1; }
+
+#endif
diff --git a/runit-2.1.2/src/hasflock.h1 b/runit-2.1.2/src/hasflock.h1
new file mode 100644
index 0000000..ac7dfc3
--- /dev/null
+++ b/runit-2.1.2/src/hasflock.h1
@@ -0,0 +1,3 @@
+/* Public domain. */
+
+/* sysdep: -flock */
diff --git a/runit-2.1.2/src/hasflock.h2 b/runit-2.1.2/src/hasflock.h2
new file mode 100644
index 0000000..1878f64
--- /dev/null
+++ b/runit-2.1.2/src/hasflock.h2
@@ -0,0 +1,4 @@
+/* Public domain. */
+
+/* sysdep: +flock */
+#define HASFLOCK 1
diff --git a/runit-2.1.2/src/hasmkffo.h1 b/runit-2.1.2/src/hasmkffo.h1
new file mode 100644
index 0000000..a562451
--- /dev/null
+++ b/runit-2.1.2/src/hasmkffo.h1
@@ -0,0 +1,3 @@
+/* Public domain. */
+
+/* sysdep: -mkfifo */
diff --git a/runit-2.1.2/src/hasmkffo.h2 b/runit-2.1.2/src/hasmkffo.h2
new file mode 100644
index 0000000..8ac8943
--- /dev/null
+++ b/runit-2.1.2/src/hasmkffo.h2
@@ -0,0 +1,4 @@
+/* Public domain. */
+
+/* sysdep: +mkfifo */
+#define HASMKFIFO 1
diff --git a/runit-2.1.2/src/hassgact.h1 b/runit-2.1.2/src/hassgact.h1
new file mode 100644
index 0000000..7639d24
--- /dev/null
+++ b/runit-2.1.2/src/hassgact.h1
@@ -0,0 +1,3 @@
+/* Public domain. */
+
+/* sysdep: -sigaction */
diff --git a/runit-2.1.2/src/hassgact.h2 b/runit-2.1.2/src/hassgact.h2
new file mode 100644
index 0000000..60ff776
--- /dev/null
+++ b/runit-2.1.2/src/hassgact.h2
@@ -0,0 +1,4 @@
+/* Public domain. */
+
+/* sysdep: +sigaction */
+#define HASSIGACTION 1
diff --git a/runit-2.1.2/src/hassgprm.h1 b/runit-2.1.2/src/hassgprm.h1
new file mode 100644
index 0000000..ef3eee9
--- /dev/null
+++ b/runit-2.1.2/src/hassgprm.h1
@@ -0,0 +1,3 @@
+/* Public domain. */
+
+/* sysdep: -sigprocmask */
diff --git a/runit-2.1.2/src/hassgprm.h2 b/runit-2.1.2/src/hassgprm.h2
new file mode 100644
index 0000000..be9d0d7
--- /dev/null
+++ b/runit-2.1.2/src/hassgprm.h2
@@ -0,0 +1,4 @@
+/* Public domain. */
+
+/* sysdep: +sigprocmask */
+#define HASSIGPROCMASK 1
diff --git a/runit-2.1.2/src/hasshsgr.h1 b/runit-2.1.2/src/hasshsgr.h1
new file mode 100644
index 0000000..3806277
--- /dev/null
+++ b/runit-2.1.2/src/hasshsgr.h1
@@ -0,0 +1,3 @@
+/* Public domain. */
+
+/* sysdep: -shortsetgroups */
diff --git a/runit-2.1.2/src/hasshsgr.h2 b/runit-2.1.2/src/hasshsgr.h2
new file mode 100644
index 0000000..5624ed0
--- /dev/null
+++ b/runit-2.1.2/src/hasshsgr.h2
@@ -0,0 +1,4 @@
+/* Public domain. */
+
+/* sysdep: +shortsetgroups */
+#define HASSHORTSETGROUPS 1
diff --git a/runit-2.1.2/src/haswaitp.h1 b/runit-2.1.2/src/haswaitp.h1
new file mode 100644
index 0000000..0d6f82c
--- /dev/null
+++ b/runit-2.1.2/src/haswaitp.h1
@@ -0,0 +1,3 @@
+/* Public domain. */
+
+/* sysdep: -waitpid */
diff --git a/runit-2.1.2/src/haswaitp.h2 b/runit-2.1.2/src/haswaitp.h2
new file mode 100644
index 0000000..015413f
--- /dev/null
+++ b/runit-2.1.2/src/haswaitp.h2
@@ -0,0 +1,4 @@
+/* Public domain. */
+
+/* sysdep: +waitpid */
+#define HASWAITPID 1
diff --git a/runit-2.1.2/src/iopause.c b/runit-2.1.2/src/iopause.c
new file mode 100644
index 0000000..ea5a426
--- /dev/null
+++ b/runit-2.1.2/src/iopause.c
@@ -0,0 +1,78 @@
+/* Public domain. */
+
+#include "taia.h"
+#include "select.h"
+#include "iopause.h"
+
+void iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp)
+{
+  struct taia t;
+  int millisecs;
+  double d;
+  int i;
+
+  if (taia_less(deadline,stamp))
+    millisecs = 0;
+  else {
+    t = *stamp;
+    taia_sub(&t,deadline,&t);
+    d = taia_approx(&t);
+    if (d > 1000.0) d = 1000.0;
+    millisecs = d * 1000.0 + 20.0;
+  }
+
+  for (i = 0;i < len;++i)
+    x[i].revents = 0;
+
+#ifdef IOPAUSE_POLL
+
+  poll(x,len,millisecs);
+  /* XXX: some kernels apparently need x[0] even if len is 0 */
+  /* XXX: how to handle EAGAIN? are kernels really this dumb? */
+  /* XXX: how to handle EINVAL? when exactly can this happen? */
+
+#else
+{
+
+  struct timeval tv;
+  fd_set rfds;
+  fd_set wfds;
+  int nfds;
+  int fd;
+
+  FD_ZERO(&rfds);
+  FD_ZERO(&wfds);
+
+  nfds = 1;
+  for (i = 0;i < len;++i) {
+    fd = x[i].fd;
+    if (fd < 0) continue;
+    if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
+
+    if (fd >= nfds) nfds = fd + 1;
+    if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds);
+    if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds);
+  }
+
+  tv.tv_sec = millisecs / 1000;
+  tv.tv_usec = 1000 * (millisecs % 1000);
+
+  if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) <= 0)
+    return;
+    /* XXX: for EBADF, could seek out and destroy the bad descriptor */
+
+  for (i = 0;i < len;++i) {
+    fd = x[i].fd;
+    if (fd < 0) continue;
+    if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
+
+    if (x[i].events & IOPAUSE_READ)
+      if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ;
+    if (x[i].events & IOPAUSE_WRITE)
+      if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE;
+  }
+
+}
+#endif
+
+}
diff --git a/runit-2.1.2/src/iopause.h1 b/runit-2.1.2/src/iopause.h1
new file mode 100644
index 0000000..5c53de7
--- /dev/null
+++ b/runit-2.1.2/src/iopause.h1
@@ -0,0 +1,21 @@
+/* Public domain. */
+
+#ifndef IOPAUSE_H
+#define IOPAUSE_H
+
+/* sysdep: -poll */
+
+typedef struct {
+  int fd;
+  short events;
+  short revents;
+} iopause_fd;
+
+#define IOPAUSE_READ 1
+#define IOPAUSE_WRITE 4
+
+#include "taia.h"
+
+extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *);
+
+#endif
diff --git a/runit-2.1.2/src/iopause.h2 b/runit-2.1.2/src/iopause.h2
new file mode 100644
index 0000000..8e58452
--- /dev/null
+++ b/runit-2.1.2/src/iopause.h2
@@ -0,0 +1,20 @@
+/* Public domain. */
+
+#ifndef IOPAUSE_H
+#define IOPAUSE_H
+
+/* sysdep: +poll */
+#define IOPAUSE_POLL
+
+#include <sys/types.h>
+#include <poll.h>
+
+typedef struct pollfd iopause_fd;
+#define IOPAUSE_READ POLLIN
+#define IOPAUSE_WRITE POLLOUT
+
+#include "taia.h"
+
+extern void iopause(iopause_fd *,unsigned int,struct taia *,struct taia *);
+
+#endif
diff --git a/runit-2.1.2/src/lock.h b/runit-2.1.2/src/lock.h
new file mode 100644
index 0000000..4a96cdc
--- /dev/null
+++ b/runit-2.1.2/src/lock.h
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#ifndef LOCK_H
+#define LOCK_H
+
+extern int lock_ex(int);
+extern int lock_un(int);
+extern int lock_exnb(int);
+
+#endif
diff --git a/runit-2.1.2/src/lock_ex.c b/runit-2.1.2/src/lock_ex.c
new file mode 100644
index 0000000..b75a764
--- /dev/null
+++ b/runit-2.1.2/src/lock_ex.c
@@ -0,0 +1,13 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include "hasflock.h"
+#include "lock.h"
+
+#ifdef HASFLOCK
+int lock_ex(int fd) { return flock(fd,LOCK_EX); }
+#else
+int lock_ex(int fd) { return lockf(fd,1,0); }
+#endif
diff --git a/runit-2.1.2/src/lock_exnb.c b/runit-2.1.2/src/lock_exnb.c
new file mode 100644
index 0000000..9ec2b9c
--- /dev/null
+++ b/runit-2.1.2/src/lock_exnb.c
@@ -0,0 +1,13 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include "hasflock.h"
+#include "lock.h"
+
+#ifdef HASFLOCK
+int lock_exnb(int fd) { return flock(fd,LOCK_EX | LOCK_NB); }
+#else
+int lock_exnb(int fd) { return lockf(fd,2,0); }
+#endif
diff --git a/runit-2.1.2/src/ndelay.h b/runit-2.1.2/src/ndelay.h
new file mode 100644
index 0000000..dbe91b2
--- /dev/null
+++ b/runit-2.1.2/src/ndelay.h
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#ifndef NDELAY_H
+#define NDELAY_H
+
+extern int ndelay_on(int);
+extern int ndelay_off(int);
+
+#endif
diff --git a/runit-2.1.2/src/ndelay_off.c b/runit-2.1.2/src/ndelay_off.c
new file mode 100644
index 0000000..92d3244
--- /dev/null
+++ b/runit-2.1.2/src/ndelay_off.c
@@ -0,0 +1,14 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "ndelay.h"
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK O_NDELAY
+#endif
+
+int ndelay_off(int fd)
+{
+  return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NONBLOCK);
+}
diff --git a/runit-2.1.2/src/ndelay_on.c b/runit-2.1.2/src/ndelay_on.c
new file mode 100644
index 0000000..b96a6b2
--- /dev/null
+++ b/runit-2.1.2/src/ndelay_on.c
@@ -0,0 +1,14 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "ndelay.h"
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK O_NDELAY
+#endif
+
+int ndelay_on(int fd)
+{
+  return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NONBLOCK);
+}
diff --git a/runit-2.1.2/src/open.h b/runit-2.1.2/src/open.h
new file mode 100644
index 0000000..9939663
--- /dev/null
+++ b/runit-2.1.2/src/open.h
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#ifndef OPEN_H
+#define OPEN_H
+
+extern int open_read(const char *);
+extern int open_excl(const char *);
+extern int open_append(const char *);
+extern int open_trunc(const char *);
+extern int open_write(const char *);
+
+#endif
diff --git a/runit-2.1.2/src/open_append.c b/runit-2.1.2/src/open_append.c
new file mode 100644
index 0000000..d1b241b
--- /dev/null
+++ b/runit-2.1.2/src/open_append.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_append(const char *fn)
+{ return open(fn,O_WRONLY | O_NDELAY | O_APPEND | O_CREAT,0600); }
diff --git a/runit-2.1.2/src/open_read.c b/runit-2.1.2/src/open_read.c
new file mode 100644
index 0000000..99b3cd1
--- /dev/null
+++ b/runit-2.1.2/src/open_read.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_read(const char *fn)
+{ return open(fn,O_RDONLY | O_NDELAY); }
diff --git a/runit-2.1.2/src/open_trunc.c b/runit-2.1.2/src/open_trunc.c
new file mode 100644
index 0000000..6e0c4c2
--- /dev/null
+++ b/runit-2.1.2/src/open_trunc.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_trunc(const char *fn)
+{ return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644); }
diff --git a/runit-2.1.2/src/open_write.c b/runit-2.1.2/src/open_write.c
new file mode 100644
index 0000000..34cfa9b
--- /dev/null
+++ b/runit-2.1.2/src/open_write.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include "open.h"
+
+int open_write(const char *fn)
+{ return open(fn,O_WRONLY | O_NDELAY); }
diff --git a/runit-2.1.2/src/openreadclose.c b/runit-2.1.2/src/openreadclose.c
new file mode 100644
index 0000000..635933b
--- /dev/null
+++ b/runit-2.1.2/src/openreadclose.c
@@ -0,0 +1,18 @@
+/* Public domain. */
+
+#include "error.h"
+#include "open.h"
+#include "readclose.h"
+#include "openreadclose.h"
+
+int openreadclose(const char *fn,stralloc *sa,unsigned int bufsize)
+{
+  int fd;
+  fd = open_read(fn);
+  if (fd == -1) {
+    if (errno == error_noent) return 0;
+    return -1;
+  }
+  if (readclose(fd,sa,bufsize) == -1) return -1;
+  return 1;
+}
diff --git a/runit-2.1.2/src/openreadclose.h b/runit-2.1.2/src/openreadclose.h
new file mode 100644
index 0000000..728899c
--- /dev/null
+++ b/runit-2.1.2/src/openreadclose.h
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#ifndef OPENREADCLOSE_H
+#define OPENREADCLOSE_H
+
+#include "stralloc.h"
+
+extern int openreadclose(const char *,stralloc *,unsigned int);
+
+#endif
diff --git a/runit-2.1.2/src/pathexec.h b/runit-2.1.2/src/pathexec.h
new file mode 100644
index 0000000..d46ab17
--- /dev/null
+++ b/runit-2.1.2/src/pathexec.h
@@ -0,0 +1,11 @@
+/* Public domain. */
+
+#ifndef PATHEXEC_H
+#define PATHEXEC_H
+
+extern void pathexec_run(const char *,const char * const *,const char * const *);
+extern int pathexec_env(const char *,const char *);
+extern void pathexec_env_run(const char *, const char * const *);
+extern void pathexec(const char * const *);
+
+#endif
diff --git a/runit-2.1.2/src/pathexec_env.c b/runit-2.1.2/src/pathexec_env.c
new file mode 100644
index 0000000..1305469
--- /dev/null
+++ b/runit-2.1.2/src/pathexec_env.c
@@ -0,0 +1,74 @@
+/* Public domain. */
+
+#include "stralloc.h"
+#include "alloc.h"
+#include "str.h"
+#include "byte.h"
+#include "env.h"
+#include "pathexec.h"
+
+static stralloc plus;
+static stralloc tmp;
+
+int pathexec_env(const char *s,const char *t)
+{
+  if (!s) return 1;
+  if (!stralloc_copys(&tmp,s)) return 0;
+  if (t) {
+    if (!stralloc_cats(&tmp,"=")) return 0;
+    if (!stralloc_cats(&tmp,t)) return 0;
+  }
+  if (!stralloc_0(&tmp)) return 0;
+  return stralloc_cat(&plus,&tmp);
+}
+
+void pathexec_env_run(const char *file, const char *const *argv)
+{
+  const char **e;
+  unsigned int elen;
+  unsigned int i;
+  unsigned int j;
+  unsigned int split;
+  unsigned int t;
+
+  if (!stralloc_cats(&plus,"")) return;
+
+  elen = 0;
+  for (i = 0;environ[i];++i)
+    ++elen;
+  for (i = 0;i < plus.len;++i)
+    if (!plus.s[i])
+      ++elen;
+
+  e = (const char **) alloc((elen + 1) * sizeof(char *));
+  if (!e) return;
+
+  elen = 0;
+  for (i = 0;environ[i];++i)
+    e[elen++] = environ[i];
+
+  j = 0;
+  for (i = 0;i < plus.len;++i)
+    if (!plus.s[i]) {
+      split = str_chr(plus.s + j,'=');
+      for (t = 0;t < elen;++t)
+        if (byte_equal(plus.s + j,split,e[t]))
+          if (e[t][split] == '=') {
+            --elen;
+            e[t] = e[elen];
+            break;
+          }
+      if (plus.s[j + split])
+        e[elen++] = plus.s + j;
+      j = i + 1;
+    }
+  e[elen] = 0;
+
+  pathexec_run(file,argv,e);
+  alloc_free(e);
+}
+
+void pathexec(const char *const *argv)
+{
+  return pathexec_env_run(*argv, argv);
+}
diff --git a/runit-2.1.2/src/pathexec_run.c b/runit-2.1.2/src/pathexec_run.c
new file mode 100644
index 0000000..1770ac7
--- /dev/null
+++ b/runit-2.1.2/src/pathexec_run.c
@@ -0,0 +1,48 @@
+/* Public domain. */
+
+#include "error.h"
+#include "stralloc.h"
+#include "str.h"
+#include "env.h"
+#include "pathexec.h"
+
+static stralloc tmp;
+
+void pathexec_run(const char *file,const char * const *argv,const char * const *envp)
+{
+  const char *path;
+  unsigned int split;
+  int savederrno;
+
+  if (file[str_chr(file,'/')]) {
+    execve(file,argv,envp);
+    return;
+  }
+
+  path = env_get("PATH");
+  if (!path) path = "/bin:/usr/bin";
+
+  savederrno = 0;
+  for (;;) {
+    split = str_chr(path,':');
+    if (!stralloc_copyb(&tmp,path,split)) return;
+    if (!split)
+      if (!stralloc_cats(&tmp,".")) return;
+    if (!stralloc_cats(&tmp,"/"))  return;
+    if (!stralloc_cats(&tmp,file)) return;
+    if (!stralloc_0(&tmp)) return;
+
+    execve(tmp.s,argv,envp);
+    if (errno != error_noent) {
+      savederrno = errno;
+      if ((errno != error_acces) && (errno != error_perm) && (errno != error_isdir)) return;
+    }
+
+    if (!path[split]) {
+      if (savederrno) errno = savederrno;
+      return;
+    }
+    path += split;
+    path += 1;
+  }
+}
diff --git a/runit-2.1.2/src/pmatch.c b/runit-2.1.2/src/pmatch.c
new file mode 100644
index 0000000..2fc9a53
--- /dev/null
+++ b/runit-2.1.2/src/pmatch.c
@@ -0,0 +1,40 @@
+
+int pmatch(const char *p, const char *s, unsigned int len) {
+  for (;;) {
+    char c =*p++;
+    if (! c) return(! len);
+    switch(c) {
+    case '*':
+      if (! (c =*p)) return(1);
+      for (;;) {
+        if (! len) return(0);
+        if (*s == c) break;
+        ++s; --len;
+      }
+      continue;
+    case '+':
+      if ((c =*p++) != *s) return(0);
+      for (;;) {
+        if (! len) return(1);
+        if (*s != c) break;
+        ++s; --len;
+      }
+      continue;
+      /*
+    case '?':
+      if (*p == '?') {
+        if (*s != '?') return(0);
+        ++p;
+      }
+      ++s; --len;
+      continue;
+      */
+    default:
+      if (! len) return(0);
+      if (*s != c) return(0);
+      ++s; --len;
+      continue;
+    }
+  }
+  return(0);
+}
diff --git a/runit-2.1.2/src/pmatch.h b/runit-2.1.2/src/pmatch.h
new file mode 100644
index 0000000..8d4eb8b
--- /dev/null
+++ b/runit-2.1.2/src/pmatch.h
@@ -0,0 +1,6 @@
+#ifndef PMATCH_H
+#define PMATCH_H
+
+extern unsigned int pmatch(const char *, const char *, unsigned int);
+
+#endif
diff --git a/runit-2.1.2/src/print-ar.sh b/runit-2.1.2/src/print-ar.sh
new file mode 100644
index 0000000..99bc116
--- /dev/null
+++ b/runit-2.1.2/src/print-ar.sh
@@ -0,0 +1,14 @@
+cat warn-auto.sh
+echo 'main="$1"; shift'
+echo 'rm -f "$main"'
+echo 'ar cr "$main" ${1+"$@"}'
+case "`cat systype`" in
+  sunos-5.*) ;;
+  unix_sv*) ;;
+  irix64-*) ;;
+  irix-*) ;;
+  dgux-*) ;;
+  hp-ux-*) ;;
+  sco*) ;;
+  *) echo 'ranlib "$main"' ;;
+esac
diff --git a/runit-2.1.2/src/print-cc.sh b/runit-2.1.2/src/print-cc.sh
new file mode 100644
index 0000000..31f4ed3
--- /dev/null
+++ b/runit-2.1.2/src/print-cc.sh
@@ -0,0 +1,5 @@
+cc="`head -n1 conf-cc`"
+systype="`cat systype`"
+
+cat warn-auto.sh
+echo exec "$cc" '-c ${1+"$@"}'
diff --git a/runit-2.1.2/src/print-ld.sh b/runit-2.1.2/src/print-ld.sh
new file mode 100644
index 0000000..59489a8
--- /dev/null
+++ b/runit-2.1.2/src/print-ld.sh
@@ -0,0 +1,6 @@
+ld="`head -n1 conf-ld`"
+systype="`cat systype`"
+
+cat warn-auto.sh
+echo 'main="$1"; shift'
+echo exec "$ld" '-o "$main" "$main".o ${1+"$@"}'
diff --git a/runit-2.1.2/src/prot.c b/runit-2.1.2/src/prot.c
new file mode 100644
index 0000000..79a88c5
--- /dev/null
+++ b/runit-2.1.2/src/prot.c
@@ -0,0 +1,21 @@
+/* Public domain. */
+
+#include "hasshsgr.h"
+#include "prot.h"
+
+int prot_gid(int gid)
+{
+#ifdef HASSHORTSETGROUPS
+  short x[2];
+  x[0] = gid; x[1] = 73; /* catch errors */
+  if (setgroups(1,x) == -1) return -1;
+#else
+  if (setgroups(1,&gid) == -1) return -1;
+#endif
+  return setgid(gid); /* _should_ be redundant, but on some systems it isn't */
+}
+
+int prot_uid(int uid)
+{
+  return setuid(uid);
+}
diff --git a/runit-2.1.2/src/prot.h b/runit-2.1.2/src/prot.h
new file mode 100644
index 0000000..2e5cb81
--- /dev/null
+++ b/runit-2.1.2/src/prot.h
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#ifndef PROT_H
+#define PROT_H
+
+extern int prot_gid(int);
+extern int prot_uid(int);
+
+#endif
diff --git a/runit-2.1.2/src/readclose.c b/runit-2.1.2/src/readclose.c
new file mode 100644
index 0000000..9d83007
--- /dev/null
+++ b/runit-2.1.2/src/readclose.c
@@ -0,0 +1,23 @@
+/* Public domain. */
+
+#include <unistd.h>
+#include "error.h"
+#include "readclose.h"
+
+int readclose_append(int fd,stralloc *sa,unsigned int bufsize)
+{
+  int r;
+  for (;;) {
+    if (!stralloc_readyplus(sa,bufsize)) { close(fd); return -1; }
+    r = read(fd,sa->s + sa->len,bufsize);
+    if (r == -1) if (errno == error_intr) continue;
+    if (r <= 0) { close(fd); return r; }
+    sa->len += r;
+  }
+}
+
+int readclose(int fd,stralloc *sa,unsigned int bufsize)
+{
+  if (!stralloc_copys(sa,"")) { close(fd); return -1; }
+  return readclose_append(fd,sa,bufsize);
+}
diff --git a/runit-2.1.2/src/readclose.h b/runit-2.1.2/src/readclose.h
new file mode 100644
index 0000000..bde9889
--- /dev/null
+++ b/runit-2.1.2/src/readclose.h
@@ -0,0 +1,11 @@
+/* Public domain. */
+
+#ifndef READCLOSE_H
+#define READCLOSE_H
+
+#include "stralloc.h"
+
+extern int readclose_append(int,stralloc *,unsigned int);
+extern int readclose(int,stralloc *,unsigned int);
+
+#endif
diff --git a/runit-2.1.2/src/reboot_system.h1 b/runit-2.1.2/src/reboot_system.h1
new file mode 100644
index 0000000..d4950c9
--- /dev/null
+++ b/runit-2.1.2/src/reboot_system.h1
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include <sys/reboot.h>
+
+/* sysdep: -std reboot */
+
+int reboot_system(int what) {
+  return(reboot(what, (char *)0));
+}
diff --git a/runit-2.1.2/src/reboot_system.h2 b/runit-2.1.2/src/reboot_system.h2
new file mode 100644
index 0000000..b30d1e9
--- /dev/null
+++ b/runit-2.1.2/src/reboot_system.h2
@@ -0,0 +1,8 @@
+#include <unistd.h>
+#include <sys/reboot.h>
+
+/* sysdep: +std reboot */
+
+int reboot_system(int what) {
+  return(reboot(what));
+}
diff --git a/runit-2.1.2/src/runit-init.c b/runit-2.1.2/src/runit-init.c
new file mode 100644
index 0000000..00dc3c9
--- /dev/null
+++ b/runit-2.1.2/src/runit-init.c
@@ -0,0 +1,76 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <unistd.h>
+#include "runit.h"
+#include "strerr.h"
+#include "sig.h"
+#include "open.h"
+#include "error.h"
+
+#define USAGE " 0|6"
+#define FATAL "init: fatal: "
+/* #define WARNING "init: warning: " */
+
+const char *progname;
+
+void usage(void) { strerr_die4x(0, "usage: ", progname, USAGE, "\n"); }
+
+void runit_halt () {
+  if (open_trunc(STOPIT) == -1)
+    strerr_die4sys(111, FATAL, "unable to create ", STOPIT, ": ");
+  if (chmod(STOPIT, 0100) == -1)
+    strerr_die4sys(111, FATAL, "unable to chmod ", STOPIT, ": ");
+  if (chmod(REBOOT, 0) == -1)
+    if (errno != error_noent)
+      strerr_die4sys(111, FATAL, "unable to chmod ", REBOOT, ": ");
+  kill(1, sig_cont);
+  _exit(0);
+}
+
+void runit_reboot () {
+  if (open_trunc(STOPIT) == -1)
+    strerr_die4sys(111, FATAL, "unable to create ", STOPIT, ": ");
+  if (chmod(STOPIT, 0100) == -1)
+    strerr_die4sys(111, FATAL, "unable to chmod ", STOPIT, ": ");
+  if (open_trunc(REBOOT) == -1)
+    strerr_die4sys(111, FATAL, "unable to create ", REBOOT, ": ");
+  if (chmod(REBOOT, 0100) == -1)
+    strerr_die4sys(111, FATAL, "unable to chmod ", REBOOT, ": ");
+  kill(1, sig_cont);
+  _exit(0);
+}
+
+int main (int argc, const char * const *argv, char * const *envp) {
+  const char *prog[2];
+
+  progname =*argv++;
+
+  if (getpid() == 1) {
+    prog[1] =0;
+    prog[0] ="runit";
+
+    /* kernel is starting init, runit does the job. */
+    execve(RUNIT, (char *const *)prog, envp);
+
+    /* serious error */
+    strerr_die4sys(111, FATAL, "unable to start ", prog[0], ": ");
+  }
+
+  if (! *argv || ! **argv) usage();
+  switch (**argv) {
+  case '0':
+    runit_halt();
+    break;
+  case '6':
+    runit_reboot();
+    break;
+  case '-':
+    if ((*argv)[1] == 'V')
+      strerr_warn1("$Id: f075d98bf7dd17c893021f9572cbb970cdad8dcf $\n", 0);
+  default:
+    usage();
+  }
+  /* not reached */
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/runit-init.check b/runit-2.1.2/src/runit-init.check
new file mode 100755
index 0000000..088e833
--- /dev/null
+++ b/runit-2.1.2/src/runit-init.check
@@ -0,0 +1,3 @@
+#!/bin/sh
+runit-init
+echo $?
diff --git a/runit-2.1.2/src/runit-init.dist b/runit-2.1.2/src/runit-init.dist
new file mode 100644
index 0000000..cca0307
--- /dev/null
+++ b/runit-2.1.2/src/runit-init.dist
@@ -0,0 +1,3 @@
+usage: runit-init 0|6
+
+0
diff --git a/runit-2.1.2/src/runit.c b/runit-2.1.2/src/runit.c
new file mode 100644
index 0000000..48620b3
--- /dev/null
+++ b/runit-2.1.2/src/runit.c
@@ -0,0 +1,346 @@
+#include <sys/types.h>
+#include <sys/reboot.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "runit.h"
+#include "sig.h"
+#include "strerr.h"
+#include "error.h"
+#include "iopause.h"
+#include "coe.h"
+#include "ndelay.h"
+#include "wait.h"
+#include "open.h"
+#include "reboot_system.h"
+
+/* #define DEBUG */
+
+#define INFO "- runit: "
+#define WARNING "- runit: warning: "
+#define FATAL "- runit: fatal: "
+
+const char * const stage[3] ={
+  "/etc/runit/1",
+  "/etc/runit/2",
+  "/etc/runit/3" };
+
+int selfpipe[2];
+int sigc =0;
+int sigi =0;
+
+void sig_cont_handler (void) {
+  sigc++;
+  write(selfpipe[1], "", 1);
+}
+void sig_int_handler (void) {
+  sigi++;
+  write(selfpipe[1], "", 1);
+}
+void sig_child_handler (void) { write(selfpipe[1], "", 1); }
+
+int main (int argc, const char * const *argv, char * const *envp) {
+  const char * prog[2];
+  int pid, pid2;
+  int wstat;
+  int st;
+  iopause_fd x;
+#ifndef IOPAUSE_POLL
+  fd_set rfds;
+  struct timeval t;
+#endif
+  char ch;
+  int ttyfd;
+  struct stat s;
+
+  if (getpid() != 1) strerr_die2x(111, FATAL, "must be run as process no 1.");
+  setsid();
+
+  sig_block(sig_alarm);
+  sig_block(sig_child);
+  sig_catch(sig_child, sig_child_handler);
+  sig_block(sig_cont);
+  sig_catch(sig_cont, sig_cont_handler);
+  sig_block(sig_hangup);
+  sig_block(sig_int);
+  sig_catch(sig_int, sig_int_handler);
+  sig_block(sig_pipe);
+  sig_block(sig_term);
+
+  /* console */
+  if ((ttyfd =open_write("/dev/console")) != -1) {
+    dup2(ttyfd, 0); dup2(ttyfd, 1); dup2(ttyfd, 2);
+    if (ttyfd > 2) close(ttyfd);
+  }
+
+  /* create selfpipe */
+  while (pipe(selfpipe) == -1) {
+    strerr_warn2(FATAL, "unable to create selfpipe, pausing: ", &strerr_sys);
+    sleep(5);
+  }
+  coe(selfpipe[0]);
+  coe(selfpipe[1]);
+  ndelay_on(selfpipe[0]);
+  ndelay_on(selfpipe[1]);
+
+#ifdef RB_DISABLE_CAD
+  /* activate ctrlaltdel handling, glibc, dietlibc */
+  if (RB_DISABLE_CAD == 0) reboot_system(0);
+#endif
+
+  strerr_warn3(INFO, "$Id: 25da3b86f7bed4038b8a039d2f8e8c9bbcf0822b $",
+               ": booting.", 0);
+
+  /* runit */
+  for (st =0; st < 3; st++) {
+    /* if (st == 2) logwtmp("~", "reboot", ""); */
+    while ((pid =fork()) == -1) {
+      strerr_warn4(FATAL, "unable to fork for \"", stage[st], "\" pausing: ",
+                   &strerr_sys);
+      sleep(5);
+    }
+    if (!pid) {
+      /* child */
+      prog[0] =stage[st];
+      prog[1] =0;
+
+      /* stage 1 gets full control of console */
+      if (st == 0) {
+        if ((ttyfd =open("/dev/console", O_RDWR)) != -1) {
+#ifdef TIOCSCTTY 
+          ioctl(ttyfd, TIOCSCTTY, (char *)0);
+#endif
+          dup2(ttyfd, 0);
+          if (ttyfd > 2) close(ttyfd);
+        }
+        else
+          strerr_warn2(WARNING, "unable to open /dev/console: ", &strerr_sys);
+      }
+      else
+        setsid();
+
+      sig_unblock(sig_alarm);
+      sig_unblock(sig_child);
+      sig_uncatch(sig_child);
+      sig_unblock(sig_cont);
+      sig_ignore(sig_cont);
+      sig_unblock(sig_hangup);
+      sig_unblock(sig_int);
+      sig_uncatch(sig_int);
+      sig_unblock(sig_pipe);
+      sig_unblock(sig_term);
+            
+      strerr_warn3(INFO, "enter stage: ", stage[st], 0);
+      execve(*prog, (char *const *)prog, envp);
+      strerr_die4sys(0, FATAL, "unable to start child: ", stage[st], ": ");
+    }
+
+    x.fd =selfpipe[0];
+    x.events =IOPAUSE_READ;
+    for (;;) {
+      int child;
+
+      sig_unblock(sig_child);
+      sig_unblock(sig_cont);
+      sig_unblock(sig_int);
+#ifdef IOPAUSE_POLL
+      poll(&x, 1, 14000);
+#else
+      t.tv_sec =14; t.tv_usec =0;
+      FD_ZERO(&rfds);
+      FD_SET(x.fd, &rfds);
+      select(x.fd +1, &rfds, (fd_set*)0, (fd_set*)0, &t);
+#endif
+      sig_block(sig_cont);
+      sig_block(sig_child);
+      sig_block(sig_int);
+      
+      while (read(selfpipe[0], &ch, 1) == 1) {}
+      while ((child =wait_nohang(&wstat)) > 0)
+        if (child == pid) break;
+      if (child == -1) {
+        strerr_warn2(WARNING, "wait_nohang, pausing: ", &strerr_sys);
+        sleep(5);
+      }
+
+      /* reget stderr */
+      if ((ttyfd =open_write("/dev/console")) != -1) {
+        dup2(ttyfd, 2);
+        if (ttyfd > 2) close(ttyfd);
+      }
+
+      if (child == pid) {
+        if (wait_exitcode(wstat) != 0) {
+          if (wait_crashed(wstat))
+            strerr_warn3(WARNING, "child crashed: ", stage[st], 0);
+          else
+            strerr_warn3(WARNING, "child failed: ", stage[st], 0);
+          if (st == 0)
+            /* this is stage 1 */
+            if (wait_crashed(wstat) || (wait_exitcode(wstat) == 100)) {
+              strerr_warn3(INFO, "leave stage: ", stage[st], 0);
+              strerr_warn2(WARNING, "skipping stage 2...", 0);
+              st++;
+              break;
+            }
+          if (st == 1)
+            /* this is stage 2 */
+            if (wait_crashed(wstat) || (wait_exitcode(wstat) == 111)) {
+              strerr_warn2(WARNING, "killing all processes in stage 2...", 0);
+              kill(-pid, 9);
+              sleep(5);
+              strerr_warn2(WARNING, "restarting.", 0);
+              st--;
+              break;
+            }
+        }
+        strerr_warn3(INFO, "leave stage: ", stage[st], 0);
+        break;
+      }
+      if (child != 0) {
+        /* collect terminated children */
+        write(selfpipe[1], "", 1);
+        continue;
+      }
+
+      /* sig? */
+      if (!sigc  && !sigi) {
+#ifdef DEBUG
+        strerr_warn2(WARNING, "poll: ", &strerr_sys);
+#endif
+        continue;
+      }
+      if (st != 1) {
+        strerr_warn2(WARNING, "signals only work in stage 2.", 0);
+        sigc =sigi =0;
+        continue;
+      }
+      if (sigi && (stat(CTRLALTDEL, &s) != -1) && (s.st_mode & S_IXUSR)) {
+        strerr_warn2(INFO, "ctrl-alt-del request...", 0);
+        prog[0] =CTRLALTDEL; prog[1] =0;
+        while ((pid2 =fork()) == -1) {
+          strerr_warn4(FATAL, "unable to fork for \"", CTRLALTDEL,
+                       "\" pausing: ", &strerr_sys);
+          sleep(5);
+        }
+        if (!pid2) {
+          /* child */
+          strerr_warn3(INFO, "enter stage: ", prog[0], 0);
+          execve(*prog, (char *const *) prog, envp);
+          strerr_die4sys(0, FATAL, "unable to start child: ", prog[0], ": ");
+        }
+        if (wait_pid(&wstat, pid2) == -1)
+          strerr_warn2(FATAL, "wait_pid: ", &strerr_sys);
+        if (wait_crashed(wstat))
+          strerr_warn3(WARNING, "child crashed: ", CTRLALTDEL, 0);
+        strerr_warn3(INFO, "leave stage: ", prog[0], 0);
+        sigi =0;
+        sigc++;
+      }
+      if (sigc && (stat(STOPIT, &s) != -1) && (s.st_mode & S_IXUSR)) {
+        int i;
+        /* unlink(STOPIT); */
+        chmod(STOPIT, 0);
+
+        /* kill stage 2 */
+#ifdef DEBUG
+        strerr_warn2(WARNING, "sending sigterm...", 0);
+#endif
+        kill(pid, sig_term);
+        i =0;
+        while (i < 5) {
+          if ((child =wait_nohang(&wstat)) == pid) {
+#ifdef DEBUG
+            strerr_warn2(WARNING, "stage 2 terminated.", 0);
+#endif
+            pid =0;
+            break;
+          }
+          if (child) continue;
+          if (child == -1) 
+            strerr_warn2(WARNING, "wait_nohang: ", &strerr_sys);
+#ifdef DEBUG
+          strerr_warn2(WARNING, "waiting...", 0);
+#endif
+          sleep(1);
+          i++;
+        }
+        if (pid) {
+          /* still there */
+          strerr_warn2(WARNING,
+                       "stage 2 not terminated, sending sigkill...", 0);
+          kill(pid, 9);
+          if (wait_pid(&wstat, pid) == -1)
+            strerr_warn2(WARNING, "wait_pid: ", &strerr_sys);
+        }
+        sigc =0;
+        strerr_warn3(INFO, "leave stage: ", stage[st], 0);
+
+        /* enter stage 3 */
+        break;
+      }
+      sigc =sigi =0;
+#ifdef DEBUG
+      strerr_warn2(WARNING, "no request.", 0);
+#endif
+    }
+  }
+
+  /* reget stderr */
+  if ((ttyfd =open_write("/dev/console")) != -1) {
+    dup2(ttyfd, 2);
+    if (ttyfd > 2) close(ttyfd);
+  }
+
+#ifdef RB_AUTOBOOT
+  /* fallthrough stage 3 */
+  strerr_warn2(INFO, "sending KILL signal to all processes...", 0);
+  kill(-1, SIGKILL);
+
+  pid =fork();
+  switch (pid) {
+  case  0:
+  case -1:
+  if ((stat(REBOOT, &s) != -1) && (s.st_mode & S_IXUSR)) {
+    strerr_warn2(INFO, "system reboot.", 0);
+    sync();
+    reboot_system(RB_AUTOBOOT);
+  }
+  else {
+#ifdef RB_POWER_OFF
+    strerr_warn2(INFO, "power off...", 0);
+    sync();
+    reboot_system(RB_POWER_OFF);
+    sleep(2);
+#endif
+#ifdef RB_HALT_SYSTEM
+    strerr_warn2(INFO, "system halt.", 0);
+    sync();
+    reboot_system(RB_HALT_SYSTEM);
+#else
+#ifdef RB_HALT
+    strerr_warn2(INFO, "system halt.", 0);
+    sync();
+    reboot_system(RB_HALT);
+#else
+    strerr_warn2(INFO, "system reboot.", 0);
+    sync();
+    reboot_system(RB_AUTOBOOT);
+#endif
+#endif
+  }
+  if (pid == 0) _exit(0);
+  break;
+  default:
+  sig_unblock(sig_child);
+  while (wait_pid(0, pid) == -1);
+  }
+#endif
+
+  for (;;) sig_pause();
+  /* not reached */
+  strerr_die2x(0, INFO, "exit.");
+  return(0);
+}
diff --git a/runit-2.1.2/src/runit.check b/runit-2.1.2/src/runit.check
new file mode 100755
index 0000000..87f02d3
--- /dev/null
+++ b/runit-2.1.2/src/runit.check
@@ -0,0 +1,3 @@
+#!/bin/sh
+runit
+echo $?
diff --git a/runit-2.1.2/src/runit.dist b/runit-2.1.2/src/runit.dist
new file mode 100644
index 0000000..135c411
--- /dev/null
+++ b/runit-2.1.2/src/runit.dist
@@ -0,0 +1,2 @@
+- runit: fatal: must be run as process no 1.
+111
diff --git a/runit-2.1.2/src/runit.h b/runit-2.1.2/src/runit.h
new file mode 100644
index 0000000..ba98386
--- /dev/null
+++ b/runit-2.1.2/src/runit.h
@@ -0,0 +1,4 @@
+#define RUNIT "/sbin/runit"
+#define STOPIT "/etc/runit/stopit"
+#define REBOOT "/etc/runit/reboot"
+#define CTRLALTDEL "/etc/runit/ctrlaltdel"
diff --git a/runit-2.1.2/src/runsv.c b/runit-2.1.2/src/runsv.c
new file mode 100644
index 0000000..0de2803
--- /dev/null
+++ b/runit-2.1.2/src/runsv.c
@@ -0,0 +1,607 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <signal.h>
+#include "strerr.h"
+#include "error.h"
+#include "taia.h"
+#include "sig.h"
+#include "env.h"
+#include "coe.h"
+#include "ndelay.h"
+#include "fifo.h"
+#include "open.h"
+#include "lock.h"
+#include "iopause.h"
+#include "wait.h"
+#include "fd.h"
+#include "buffer.h"
+#include "fmt.h"
+#include "byte.h"
+
+#define USAGE " dir"
+
+#define VERSION "$Id: ecf467746d7b97ff0fddb88b9d44cca201c74160 $"
+
+char *progname;
+int selfpipe[2];
+
+/* state */
+#define S_DOWN 0
+#define S_RUN 1
+#define S_FINISH 2
+/* ctrl */
+#define C_NOOP 0
+#define C_TERM 1
+#define C_PAUSE 2
+/* want */
+#define W_UP 0
+#define W_DOWN 1
+#define W_EXIT 2
+
+struct svdir {
+  int pid;
+  int state;
+  int ctrl;
+  int want;
+  struct taia start;
+  int wstat;
+  int fdlock;
+  int fdcontrol;
+  int fdcontrolwrite;
+  int islog;
+};
+struct svdir svd[2];
+
+int sigterm =0;
+int haslog =0;
+int pidchanged =1;
+int logpipe[2];
+char *dir;
+
+void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+
+void fatal(char *m) {
+  strerr_die5sys(111, "runsv ", dir, ": fatal: ", m, ": ");
+}
+void fatal2(char *m1, char *m2) {
+  strerr_die6sys(111, "runsv ", dir, ": fatal: ", m1, m2, ": ");
+}
+void fatalx(char *m1, char *m2) {
+  strerr_die5x(111, "runsv ", dir, ": fatal: ", m1, m2);
+}
+void warn(char *m) {
+  strerr_warn5("runsv ", dir, ": warning: ", m, ": ", &strerr_sys);
+}
+void warn2(char *m1, char *m2) {
+  strerr_warn6("runsv ", dir, ": warning: ", m1, m2, ": ", &strerr_sys);
+}
+void warnx(char *m1, char *m2, char *m3) {
+  strerr_warn6("runsv ", dir, ": warning: ", m1, m2, m3, 0);
+}
+
+void stopservice(struct svdir *);
+
+void s_child() { write(selfpipe[1], "", 1); }
+void s_term() {
+  sigterm =1;
+  write(selfpipe[1], "", 1); /* XXX */
+}
+
+void update_status(struct svdir *s) {
+  unsigned long l;
+  int fd;
+  char status[20];
+  char bspace[64];
+  buffer b;
+  char spid[FMT_ULONG];
+  char *fstatus ="supervise/status";
+  char *fstatusnew ="supervise/status.new";
+  char *fstat ="supervise/stat";
+  char *fstatnew ="supervise/stat.new";
+  char *fpid ="supervise/pid";
+  char *fpidnew ="supervise/pid.new";
+
+  if (s->islog) {
+    fstatus ="log/supervise/status";
+    fstatusnew ="log/supervise/status.new";
+    fstat ="log/supervise/stat";
+    fstatnew ="log/supervise/stat.new";
+    fpid ="log/supervise/pid";
+    fpidnew ="log/supervise/pid.new";
+  }
+
+  /* pid */
+  if (pidchanged) {
+    if ((fd =open_trunc(fpidnew)) == -1) {
+      warn2("unable to open ", fpidnew);
+      return;
+    }
+    buffer_init(&b, buffer_unixwrite, fd, bspace, sizeof bspace);
+    spid[fmt_ulong(spid, (unsigned long)s->pid)] =0;
+    if (s->pid) {
+      buffer_puts(&b, spid);
+      buffer_puts(&b, "\n");
+      buffer_flush(&b);
+    }
+    close(fd);
+    if (rename(fpidnew, fpid) == -1) {
+      warn2("unable to rename pid.new to ", fpid);
+      return;
+    }
+    pidchanged =0;
+  }
+
+  /* stat */
+  if ((fd =open_trunc(fstatnew)) == -1) {
+    warn2("unable to open ", fstatnew);
+    return;
+  }
+  buffer_init(&b, buffer_unixwrite, fd, bspace, sizeof bspace);
+  switch (s->state) {
+  case S_DOWN:
+    buffer_puts(&b, "down");
+    break;
+  case S_RUN:
+    buffer_puts(&b, "run");
+    break;
+  case S_FINISH:
+    buffer_puts(&b, "finish");
+    break;
+  }
+  if (s->ctrl & C_PAUSE) buffer_puts(&b, ", paused");
+  if (s->ctrl & C_TERM) buffer_puts(&b, ", got TERM");
+  if (s->state != S_DOWN)
+    switch(s->want) {
+    case W_DOWN:
+      buffer_puts(&b, ", want down");
+      break;
+    case W_EXIT:
+      buffer_puts(&b, ", want exit");
+      break;
+    }
+  buffer_puts(&b, "\n");
+  buffer_flush(&b);
+  close(fd);
+  if (rename(fstatnew, fstat) == -1)
+    warn2("unable to rename stat.new to ", fstat);
+
+  /* supervise compatibility */
+  taia_pack(status, &s->start);
+  l =(unsigned long)s->pid;
+  status[12] =l; l >>=8;
+  status[13] =l; l >>=8;
+  status[14] =l; l >>=8;
+  status[15] =l;
+  if (s->ctrl & C_PAUSE)
+    status[16] =1;
+  else
+    status[16] =0;
+  if (s->want == W_UP)
+    status[17] ='u';
+  else
+    status[17] ='d';
+  if (s->ctrl & C_TERM)
+    status[18] =1;
+  else
+    status[18] =0;
+  status[19] =s->state;
+  if ((fd =open_trunc(fstatusnew)) == -1) {
+    warn2("unable to open ", fstatusnew);
+    return;
+  }
+  if ((l =write(fd, status, sizeof status)) == -1) {
+    warn2("unable to write ", fstatusnew);
+    close(fd);
+    unlink(fstatusnew);
+    return;
+  }
+  close(fd);
+  if (l < sizeof status) {
+    warnx("unable to write ", fstatusnew, ": partial write.");
+    return;
+  }
+  if (rename(fstatusnew, fstatus) == -1)
+    warn2("unable to rename status.new to ", fstatus);
+}
+unsigned int custom(struct svdir *s, char c) {
+  int pid;
+  int w;
+  char a[10];
+  struct stat st;
+  char *prog[2];
+
+  if (s->islog) return(0);
+  byte_copy(a, 10, "control/?");
+  a[8] =c;
+  if (stat(a, &st) == 0) {
+    if (st.st_mode & S_IXUSR) {
+      if ((pid =fork()) == -1) {
+        warn2("unable to fork for ", a);
+        return(0);
+      }
+      if (! pid) {
+        if (haslog && fd_copy(1, logpipe[1]) == -1)
+          warn2("unable to setup stdout for ", a);
+        prog[0] =a;
+        prog[1] =0;
+        execve(a, prog, environ);
+        fatal("unable to run control/?");
+      }
+      while (wait_pid(&w, pid) == -1) {
+        if (errno == error_intr) continue;
+        warn2("unable to wait for child ", a);
+        return(0);
+      }
+      return(! wait_exitcode(w));
+    }
+  }
+  else {
+    if (errno == error_noent) return(0);
+    warn2("unable to stat ", a);
+  }
+  return(0);
+}
+void stopservice(struct svdir *s) {
+  if (s->pid && ! custom(s, 't')) {
+    kill(s->pid, SIGTERM);
+    s->ctrl |=C_TERM;
+    update_status(s);
+  }
+  if (s->want == W_DOWN) {
+    kill(s->pid, SIGCONT);
+    custom(s, 'd'); return;
+  }
+  if (s->want == W_EXIT) {
+    kill(s->pid, SIGCONT);
+    custom(s, 'x');
+  }
+}
+
+void startservice(struct svdir *s) {
+  int p;
+  char *run[4];
+  char code[FMT_ULONG];
+  char stat[FMT_ULONG];
+
+  if (s->state == S_FINISH) {
+    run[0] ="./finish";
+    code[fmt_ulong(code, wait_exitcode(s->wstat))] =0;
+    run[1] =wait_crashed(s->wstat) ? "-1" : code;
+    stat[fmt_ulong(stat, s->wstat & 0xff)] =0;
+    run[2] =stat;
+    run[3] =0;
+  }
+  else {
+    run[0] ="./run";
+    custom(s, 'u');
+    run[1] =0;
+  }
+
+  if (s->pid != 0) stopservice(s); /* should never happen */
+  while ((p =fork()) == -1) {
+    warn("unable to fork, sleeping");
+    sleep(5);
+  }
+  if (p == 0) {
+    /* child */
+    if (haslog) {
+      if (s->islog) {
+        if (fd_copy(0, logpipe[0]) == -1)
+          fatal("unable to setup filedescriptor for ./log/run");
+        close(logpipe[1]);
+        if (chdir("./log") == -1)
+          fatal("unable to change directory to ./log");        
+      }
+      else {
+        if (fd_copy(1, logpipe[1]) == -1)
+          fatal("unable to setup filedescriptor for ./run");
+        close(logpipe[0]);
+      }
+    }
+    sig_uncatch(sig_child);
+    sig_unblock(sig_child);
+    sig_uncatch(sig_term);
+    sig_unblock(sig_term);
+    execve(*run, run, environ);
+    if (s->islog)
+      fatal2("unable to start log/", *run);
+    else
+      fatal2("unable to start ", *run);
+  }
+  if (s->state != S_FINISH) {
+    taia_now(&s->start);
+    s->state =S_RUN;
+  }
+  s->pid =p;
+  pidchanged =1;
+  s->ctrl =C_NOOP;
+  update_status(s);
+}
+int ctrl(struct svdir *s, char c) {
+  switch(c) {
+  case 'd': /* down */
+    s->want =W_DOWN;
+    update_status(s);
+    if (s->state == S_RUN) stopservice(s);
+    break;
+  case 'u': /* up */
+    s->want =W_UP;
+    update_status(s);
+    if (s->state == S_DOWN) startservice(s);
+    break;
+  case 'x': /* exit */
+    if (s->islog) break;
+    s->want =W_EXIT;
+    update_status(s);
+    if (s->state == S_RUN) stopservice(s);
+    break;
+  case 't': /* sig term */
+    if (s->state == S_RUN) stopservice(s);
+    break;
+  case 'k': /* sig kill */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGKILL);
+    s->state =S_DOWN;
+    break;
+  case 'p': /* sig pause */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGSTOP);
+    s->ctrl |=C_PAUSE;
+    update_status(s);
+    break;
+  case 'c': /* sig cont */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGCONT);
+    if (s->ctrl & C_PAUSE) s->ctrl &=~C_PAUSE;
+    update_status(s);
+    break;
+  case 'o': /* once */
+    s->want =W_DOWN;
+    update_status(s);
+    if (s->state == S_DOWN) startservice(s);
+    break;
+  case 'a': /* sig alarm */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGALRM);
+    break;
+  case 'h': /* sig hup */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGHUP);
+    break;
+  case 'i': /* sig int */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGINT);
+    break;
+  case 'q': /* sig quit */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGQUIT);
+    break;
+  case '1': /* sig usr1 */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGUSR1);
+    break;
+  case '2': /* sig usr2 */
+    if ((s->state == S_RUN) && ! custom(s, c)) kill(s->pid, SIGUSR2);
+    break;
+  }
+  return(1);
+}
+
+int main(int argc, char **argv) {
+  struct stat s;
+  int fd;
+  int r;
+  char buf[256];
+
+  progname =argv[0];
+  if (! argv[1] || argv[2]) usage();
+  dir =argv[1];
+
+  if (pipe(selfpipe) == -1) fatal("unable to create selfpipe");
+  coe(selfpipe[0]);
+  coe(selfpipe[1]);
+  ndelay_on(selfpipe[0]);
+  ndelay_on(selfpipe[1]);
+  
+  sig_block(sig_child);
+  sig_catch(sig_child, s_child);
+  sig_block(sig_term);
+  sig_catch(sig_term, s_term);
+
+  if (chdir(dir) == -1) fatal("unable to change to directory");
+  svd[0].pid =0;
+  svd[0].state =S_DOWN;
+  svd[0].ctrl =C_NOOP;
+  svd[0].want =W_UP;
+  svd[0].islog =0;
+  svd[1].pid =0;
+  taia_now(&svd[0].start);
+  if (stat("down", &s) != -1) svd[0].want =W_DOWN;
+
+  if (stat("log", &s) == -1) {
+    if (errno != error_noent)
+      warn("unable to stat() ./log: ");
+  }
+  else {
+    if (! S_ISDIR(s.st_mode))
+      warnx("./log", 0, ": not a directory.");
+    else {
+      haslog =1;
+      svd[1].state =S_DOWN;
+      svd[1].ctrl =C_NOOP;
+      svd[1].want =W_UP;
+      svd[1].islog =1;
+      taia_now(&svd[1].start);
+      if (stat("log/down", &s) != -1)
+        svd[1].want =W_DOWN;
+      if (pipe(logpipe) == -1)
+        fatal("unable to create log pipe");
+      coe(logpipe[0]);
+      coe(logpipe[1]);
+    }
+  }
+
+  if (mkdir("supervise", 0700) == -1) {
+    if ((r =readlink("supervise", buf, 256)) != -1) {
+      if (r == 256)
+        fatalx("unable to readlink ./supervise: ", "name too long");
+      buf[r] =0;
+      mkdir(buf, 0700);
+    }
+    else {
+      if ((errno != ENOENT) && (errno != EINVAL))
+        fatal("unable to readlink ./supervise");
+    }
+  }
+  if ((svd[0].fdlock =open_append("supervise/lock")) == -1)
+    fatal("unable to open supervise/lock");
+  if (lock_exnb(svd[0].fdlock) == -1) fatal("unable to lock supervise/lock");
+  coe(svd[0].fdlock);
+  if (haslog) {
+    if (mkdir("log/supervise", 0700) == -1) {
+      if ((r =readlink("log/supervise", buf, 256)) != -1) {
+        if (r == 256)
+          fatalx("unable to readlink ./log/supervise: ", "name too long");
+        buf[r] =0;
+        if ((fd =open_read(".")) == -1)
+          fatal("unable to open current directory");
+        if (chdir("./log") == -1)
+          fatal("unable to change directory to ./log"); 
+        mkdir(buf, 0700);
+        if (fchdir(fd) == -1)
+          fatal("unable to change back to service directory");
+        close(fd);
+      }
+      else {
+        if ((errno != ENOENT) && (errno != EINVAL))
+          fatal("unable to readlink ./log/supervise");
+      }
+    }
+    if ((svd[1].fdlock =open_append("log/supervise/lock")) == -1)
+      fatal("unable to open log/supervise/lock");
+    if (lock_ex(svd[1].fdlock) == -1)
+      fatal("unable to lock log/supervise/lock");
+    coe(svd[1].fdlock);
+  }
+
+  fifo_make("supervise/control", 0600);
+  if (stat("supervise/control", &s) == -1)
+    fatal("unable to stat supervise/control");
+  if (!S_ISFIFO(s.st_mode))
+    fatalx("supervise/control exists but is not a fifo", "");
+  if ((svd[0].fdcontrol =open_read("supervise/control")) == -1)
+    fatal("unable to open supervise/control");
+  coe(svd[0].fdcontrol);
+  if ((svd[0].fdcontrolwrite =open_write("supervise/control")) == -1)
+    fatal("unable to open supervise/control");
+  coe(svd[0].fdcontrolwrite);
+  update_status(&svd[0]);
+  if (haslog) {
+    fifo_make("log/supervise/control", 0600);
+    if (stat("supervise/control", &s) == -1)
+      fatal("unable to stat log/supervise/control");
+    if (!S_ISFIFO(s.st_mode))
+      fatalx("log/supervise/control exists but is not a fifo", "");
+    if ((svd[1].fdcontrol =open_read("log/supervise/control")) == -1)
+      fatal("unable to open log/supervise/control");
+    coe(svd[1].fdcontrol);
+    if ((svd[1].fdcontrolwrite =open_write("log/supervise/control")) == -1)
+      fatal("unable to open log/supervise/control");
+    coe(svd[1].fdcontrolwrite);
+    update_status(&svd[1]);
+  }
+  fifo_make("supervise/ok",0600);
+  if ((fd =open_read("supervise/ok")) == -1)
+    fatal("unable to read supervise/ok");
+  coe(fd);
+  if (haslog) {
+    fifo_make("log/supervise/ok",0600);
+    if ((fd =open_read("log/supervise/ok")) == -1)
+      fatal("unable to read log/supervise/ok");
+    coe(fd);
+  }
+  for (;;) {
+    iopause_fd x[3];
+    struct taia deadline;
+    struct taia now;
+    char ch;
+
+    if (haslog)
+      if (! svd[1].pid && (svd[1].want == W_UP)) startservice(&svd[1]);
+    if (! svd[0].pid)
+      if ((svd[0].want == W_UP) || (svd[0].state == S_FINISH))
+        startservice(&svd[0]);
+
+    x[0].fd =selfpipe[0];
+    x[0].events =IOPAUSE_READ;
+    x[1].fd =svd[0].fdcontrol;
+    x[1].events =IOPAUSE_READ;
+    if (haslog) {
+      x[2].fd =svd[1].fdcontrol;
+      x[2].events =IOPAUSE_READ;
+    }
+    taia_now(&now);
+    taia_uint(&deadline, 3600);
+    taia_add(&deadline, &now, &deadline);
+
+    sig_unblock(sig_term);
+    sig_unblock(sig_child);
+    iopause(x, 2 +haslog, &deadline, &now);
+    sig_block(sig_term);
+    sig_block(sig_child);
+
+    while (read(selfpipe[0], &ch, 1) == 1)
+      ;
+    for (;;) {
+      int child;
+      int wstat;
+      
+      child =wait_nohang(&wstat);
+      if (!child) break;
+      if ((child == -1) && (errno != error_intr)) break;
+      if (child == svd[0].pid) {
+        svd[0].pid =0;
+        pidchanged =1;
+        svd[0].wstat =wstat;
+        svd[0].ctrl &=~C_TERM;
+        if (svd[0].state != S_FINISH)
+          if ((fd =open_read("finish")) != -1) {
+            close(fd);
+            svd[0].state =S_FINISH;
+            update_status(&svd[0]);
+            continue;
+          }
+        svd[0].state =S_DOWN;
+        taia_uint(&deadline, 1);
+        taia_add(&deadline, &svd[0].start, &deadline);
+        taia_now(&svd[0].start);
+        update_status(&svd[0]);
+        if (taia_less(&svd[0].start, &deadline)) sleep(1);
+      }
+      if (haslog) {
+        if (child == svd[1].pid) {
+          svd[1].pid =0;
+          pidchanged =1;
+          svd[1].state =S_DOWN;
+          svd[1].ctrl &=~C_TERM;
+          taia_uint(&deadline, 1);
+          taia_add(&deadline, &svd[1].start, &deadline);
+          taia_now(&svd[1].start);
+          update_status(&svd[1]);
+          if (taia_less(&svd[1].start, &deadline)) sleep(1);
+        }
+      }
+    }
+    if (read(svd[0].fdcontrol, &ch, 1) == 1) ctrl(&svd[0], ch);
+    if (haslog)
+      if (read(svd[1].fdcontrol, &ch, 1) == 1) ctrl(&svd[1], ch);
+
+    if (sigterm) { ctrl(&svd[0], 'x'); sigterm =0; }
+
+    if ((svd[0].want == W_EXIT) && (svd[0].state == S_DOWN)) {
+      if (svd[1].pid == 0) _exit(0);
+      if (svd[1].want != W_EXIT) {
+        svd[1].want =W_EXIT;
+        /* stopservice(&svd[1]); */
+        update_status(&svd[1]);
+        if (close(logpipe[1]) == -1) warn("unable to close logpipe[1]");
+        if (close(logpipe[0]) == -1) warn("unable to close logpipe[0]");
+      }
+    }
+  }
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/runsv.check b/runit-2.1.2/src/runsv.check
new file mode 100755
index 0000000..edfd0c9
--- /dev/null
+++ b/runit-2.1.2/src/runsv.check
@@ -0,0 +1,59 @@
+#!/bin/sh
+rm -rf "${ctmp}"
+
+runsv
+echo $?
+
+mkdir "${ctmp}"
+echo '#!/bin/sh' >"${ctmp}"/run
+echo 'echo starting' >>"${ctmp}"/run
+echo 'exec sleep 14' >>"${ctmp}"/run
+chmod 700 "${ctmp}"/run
+runsv "${ctmp}" &
+sleep 1
+test -r "${ctmp}"/supervise/stat || sleep 2
+cat "${ctmp}"/supervise/stat
+mkdir -p "${ctmp}"/control
+echo '#!/bin/sh' >"${ctmp}"/control/t
+echo 'echo term' >>"${ctmp}"/control/t
+echo 'exit 1' >>"${ctmp}"/control/t
+chmod 700 "${ctmp}"/control/t
+echo t >"${ctmp}"/supervise/control
+sleep 2
+echo x >"${ctmp}"/supervise/control
+wait
+echo $?
+
+mkdir "${ctmp}"/log
+echo '#!/bin/sh' >"${ctmp}"/log/run
+echo 'exec cat >foo' >>"${ctmp}"/log/run
+chmod 700 "${ctmp}"/log/run
+runsv "${ctmp}" &
+sleep 1
+test -r "${ctmp}"/log/supervise/stat || sleep 2
+mkdir -p "${ctmp}"/control
+echo '#!/bin/sh' >"${ctmp}"/control/i
+echo 'echo no interrupt' >>"${ctmp}"/control/i
+echo 'exit 0' >>"${ctmp}"/control/i
+chmod 700 "${ctmp}"/control/i
+echo i >"${ctmp}"/supervise/control
+sleep 1
+echo x >"${ctmp}"/supervise/control
+wait
+echo $?
+cat "${ctmp}"/log/foo
+
+rm -rf "${ctmp}"/supervise
+rm -rf "${ctmp}"/log/supervise
+rm -f "${ctmp}"/log/foo
+ln -s foo "${ctmp}"/supervise
+ln -s bar "${ctmp}"/log/supervise
+runsv "${ctmp}" &
+sleep 1
+test -r "${ctmp}"/supervise/stat || sleep 2
+test -r "${ctmp}"/log/supervise/stat || sleep 2
+echo x >"${ctmp}"/foo/control
+wait
+echo $?
+cat "${ctmp}"/log/foo
+rm -rf "${ctmp}"
diff --git a/runit-2.1.2/src/runsv.dist b/runit-2.1.2/src/runsv.dist
new file mode 100644
index 0000000..d2b05b7
--- /dev/null
+++ b/runit-2.1.2/src/runsv.dist
@@ -0,0 +1,16 @@
+usage: runsv dir
+
+1
+starting
+run
+term
+starting
+term
+0
+0
+starting
+no interrupt
+term
+0
+starting
+term
diff --git a/runit-2.1.2/src/runsvchdir.c b/runit-2.1.2/src/runsvchdir.c
new file mode 100644
index 0000000..fe7e987
--- /dev/null
+++ b/runit-2.1.2/src/runsvchdir.c
@@ -0,0 +1,76 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "strerr.h"
+#include "error.h"
+#include "buffer.h"
+
+#define USAGE " dir"
+#define SVDIR "/etc/runit/runsvdir"
+
+#define VERSION "$Id: 9bf17f77e33c6b961e060aacffa3c8abd38fc64a $"
+
+char *progname;
+char *new;
+
+void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+
+void fatal(char *m1, char *m2) {
+  strerr_die5sys(111, progname, ": fatal: ", m1, m2, ": ");
+}
+void fatalx(char *m1, char *m2) {
+  strerr_die4x(111, progname, ": fatal: ", m1, m2);
+}
+void warn(char *m1, char *m2) {
+  strerr_warn5(progname, ": fatal: ", m1, m2, ": ", &strerr_sys);
+}
+
+int main (int argc, char **argv) {
+  struct stat s;
+  int dev;
+  int ino;
+
+  progname =*argv++;
+  if (! argv || ! *argv) usage();
+
+  new =*argv;
+  if (new[0] == '.') fatalx(new, ": must not start with a dot.");
+  if (chdir(SVDIR) == -1) fatal("unable to chdir: ", SVDIR);
+
+  if (stat(new, &s) == -1) {
+    if (errno == error_noent) fatal(new, 0);
+    fatal("unable to stat: ", new);
+  }
+  if (! S_ISDIR(s.st_mode)) fatalx(new, "not a directory.");
+  ino =s.st_ino;
+  dev =s.st_dev;
+  if (stat("current", &s) == -1) fatal("unable to stat: ", "current");
+  if ((s.st_ino == ino) && (s.st_dev == dev)) {
+    buffer_puts(buffer_1, "runsvchdir: ");
+    buffer_puts(buffer_1, new);
+    buffer_puts(buffer_1, ": current.\n");
+    buffer_flush(buffer_1);
+    _exit(0);
+  }
+
+  if (unlink("current.new") == -1)
+    if (errno != error_noent) fatal("unable to unlink: ", "current.new");
+  if (symlink(new, "current.new") == -1)
+    fatal("unable to create: current.new -> ", new);
+  if (unlink("previous") == -1)
+    if (errno != error_noent) fatal("unable to unlink: ", "previous");
+  if (rename("current", "previous") == -1)
+    fatal("unable to copy: current to ", "previous");
+  if (rename("current.new", "current") == -1) {
+    warn("unable to move: current.new to ", "current");
+    if (rename("previous", "current") == -1)
+      fatal("unable to move previous back to ", "current");
+    _exit(111);
+  }
+  buffer_puts(buffer_1, "runsvchdir: ");
+  buffer_puts(buffer_1, new);
+  buffer_puts(buffer_1, ": now current.\n");
+  buffer_flush(buffer_1);
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/runsvchdir.check b/runit-2.1.2/src/runsvchdir.check
new file mode 100755
index 0000000..a8de02b
--- /dev/null
+++ b/runit-2.1.2/src/runsvchdir.check
@@ -0,0 +1,3 @@
+#!/bin/sh
+runsvchdir
+echo $?
diff --git a/runit-2.1.2/src/runsvchdir.dist b/runit-2.1.2/src/runsvchdir.dist
new file mode 100644
index 0000000..7664608
--- /dev/null
+++ b/runit-2.1.2/src/runsvchdir.dist
@@ -0,0 +1,3 @@
+usage: runsvchdir dir
+
+1
diff --git a/runit-2.1.2/src/runsvctrl.c b/runit-2.1.2/src/runsvctrl.c
new file mode 100644
index 0000000..d8eb2c4
--- /dev/null
+++ b/runit-2.1.2/src/runsvctrl.c
@@ -0,0 +1,82 @@
+#include <unistd.h>
+#include "strerr.h"
+#include "error.h"
+#include "open.h"
+
+#define USAGE " u|d|o|p|c|h|a|i|q|1|2|t|k|x|e service ..."
+
+#define VERSION "$Id: ccf8fc8ee3c340d8de97b5ddd9270b55e0f437cb $"
+
+#define FATAL "runsvctrl: fatal: "
+#define WARNING "runsvctrl: warning: "
+
+char *progname;
+unsigned int rc =0;
+
+void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+
+void fatal(char *m1) { strerr_die3sys(111, FATAL, m1, ": "); }
+void warn(char *m1, char *m2) {
+  rc++;
+  strerr_warn5(WARNING, m1, ": ", m2, ": ", &strerr_sys);
+}
+void warnx(char *m1, char *m2) {
+  rc++;
+  strerr_warn4(WARNING, m1, ": ", m2, 0);
+}
+
+int ctrl(char *name, char c) {
+  int fd;
+
+  if ((fd =open_write("supervise/control")) == -1) {
+    if (errno == error_nodevice)
+      warnx(name, "runsv not running.");
+    else
+      warn(name, "unable to open supervise/control");
+    return(-1);
+  }
+  if (write(fd, &c, 1) != 1) {
+    warn(name, "unable to write to supervise/control");
+    return(-1);
+  }
+  return(1);
+}
+
+int main(int argc, char **argv) {
+  char **dir;
+  int curdir;
+  char c;
+
+  progname =*argv++;
+
+  if (! argv || ! *argv) usage();
+
+  switch ((c =**argv)) {
+  case 'e': c ='x';
+  case 'u': case 'd': case 'o': case 'x': case 'p': case 'c': case 'h':
+  case 'a': case 'i': case 't': case 'k': case 'q': case '1': case '2':
+    break;
+  default:
+    usage();
+  }
+  dir =++argv;
+  if (! dir || ! *dir) usage();
+
+  if ((curdir =open_read(".")) == -1) {
+    rc =100;
+    fatal("unable to open current directory");
+  }
+  for (; dir && *dir; dir++) {
+    if (chdir(*dir) == -1) {
+      warn(*dir, "unable to change directory");
+      continue;
+    }
+    ctrl(*dir, c);
+    if (fchdir(curdir) == -1) {
+      rc =100;
+      fatal("unable to change directory");
+    }
+  }
+  if (rc > 100) rc =100;
+  _exit(rc);
+}
diff --git a/runit-2.1.2/src/runsvctrl.check b/runit-2.1.2/src/runsvctrl.check
new file mode 100755
index 0000000..7911074
--- /dev/null
+++ b/runit-2.1.2/src/runsvctrl.check
@@ -0,0 +1,23 @@
+#!/bin/sh
+rm -rf "${ctmp}"
+
+runsvctrl
+echo $?
+
+mkdir "${ctmp}"
+echo '#!/bin/sh' >"${ctmp}"/run
+echo 'echo starting' >>"${ctmp}"/run
+echo 'exec sleep 14' >>"${ctmp}"/run
+chmod 700 "${ctmp}"/run
+runsv "${ctmp}" &
+sleep 1
+test -r "${ctmp}"/supervise/stat || sleep 2
+runsvctrl down "${ctmp}"
+echo $?
+sleep 1
+cat "${ctmp}"/supervise/stat
+runsvctrl exit "${ctmp}"
+echo $?
+wait
+echo $?
+rm -rf "${ctmp}"
diff --git a/runit-2.1.2/src/runsvctrl.dist b/runit-2.1.2/src/runsvctrl.dist
new file mode 100644
index 0000000..b07cf8a
--- /dev/null
+++ b/runit-2.1.2/src/runsvctrl.dist
@@ -0,0 +1,8 @@
+usage: runsvctrl u|d|o|p|c|h|a|i|q|1|2|t|k|x|e service ...
+
+1
+starting
+0
+down
+0
+0
diff --git a/runit-2.1.2/src/runsvdir.c b/runit-2.1.2/src/runsvdir.c
new file mode 100644
index 0000000..07c1d8e
--- /dev/null
+++ b/runit-2.1.2/src/runsvdir.c
@@ -0,0 +1,286 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <signal.h>
+#include "direntry.h"
+#include "strerr.h"
+#include "error.h"
+#include "wait.h"
+#include "env.h"
+#include "open.h"
+#include "pathexec.h"
+#include "fd.h"
+#include "str.h"
+#include "coe.h"
+#include "iopause.h"
+#include "sig.h"
+#include "ndelay.h"
+
+#define USAGE " [-P] dir"
+#define VERSION "$Id: ecebd0a50510e91639c6a45dda8b0947aa8eb885 $"
+
+#define MAXSERVICES 1000
+
+char *progname;
+char *svdir;
+unsigned long dev =0;
+unsigned long ino =0;
+struct {
+  unsigned long dev;
+  unsigned long ino;
+  int pid;
+  int isgone;
+} sv[MAXSERVICES];
+int svnum =0;
+int check =1;
+char *rplog =0;
+int rploglen;
+int logpipe[2];
+iopause_fd io[1];
+struct taia stamplog;
+int exitsoon =0;
+int pgrp =0;
+
+void usage () { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+void fatal(char *m1, char *m2) {
+  strerr_die6sys(100, "runsvdir ", svdir, ": fatal: ", m1, m2, ": ");
+}
+void warn(char *m1, char *m2) {
+  strerr_warn6("runsvdir ", svdir, ": warning: ", m1, m2, ": ", &strerr_sys);
+}
+void warn3x(char *m1, char *m2, char *m3) {
+  strerr_warn6("runsvdir ", svdir, ": warning: ", m1, m2, m3, 0);
+} 
+void s_term() { exitsoon =1; }
+void s_hangup() { exitsoon =2; }
+
+void runsv(int no, char *name) {
+  int pid;
+
+  if ((pid =fork()) == -1) {
+    warn("unable to fork for ", name);
+    return;
+  }
+  if (pid == 0) {
+    /* child */
+    const char *prog[3];
+
+    prog[0] ="runsv";
+    prog[1] =name;
+    prog[2] =0;
+    sig_uncatch(sig_hangup);
+    sig_uncatch(sig_term);
+    if (pgrp) setsid();
+    pathexec_run(*prog, prog, (const char* const*)environ);
+    fatal("unable to start runsv ", name);
+  }
+  sv[no].pid =pid;
+}
+
+void runsvdir() {
+  DIR *dir;
+  direntry *d;
+  int i;
+  struct stat s;
+
+  if (! (dir =opendir("."))) {
+    warn("unable to open directory ", svdir);
+    return;
+  }
+  for (i =0; i < svnum; i++) sv[i].isgone =1;
+  errno =0;
+  while ((d =readdir(dir))) {
+    if (d->d_name[0] == '.') continue;
+    if (stat(d->d_name, &s) == -1) {
+      warn("unable to stat ", d->d_name);
+      errno =0;
+      continue;
+    }
+    if (! S_ISDIR(s.st_mode)) continue;
+    for (i =0; i < svnum; i++) {
+      if ((sv[i].ino == s.st_ino) && (sv[i].dev == s.st_dev)) {
+        sv[i].isgone =0;
+        if (! sv[i].pid) runsv(i, d->d_name);
+        break;
+      }
+    }
+    if (i == svnum) {
+      /* new service */
+      if (svnum >= MAXSERVICES) {
+        warn3x("unable to start runsv ", d->d_name, ": too many services.");
+        continue;
+      }
+      sv[i].ino =s.st_ino;
+      sv[i].dev =s.st_dev;
+      sv[i].pid =0;
+      sv[i].isgone =0;
+      svnum++;
+      runsv(i, d->d_name);
+      check =1;
+    }
+  }
+  if (errno) {
+    warn("unable to read directory ", svdir);
+    closedir(dir);
+    check =1;
+    return;
+  }
+  closedir(dir);
+
+  /* SIGTERM removed runsv's */
+  for (i =0; i < svnum; i++) {
+    if (! sv[i].isgone) continue;
+    if (sv[i].pid) kill(sv[i].pid, SIGTERM);
+    sv[i] =sv[--svnum];
+    check =1;
+  }
+}
+
+int setup_log() {
+  if ((rploglen =str_len(rplog)) < 7) {
+    warn3x("log must have at least seven characters.", 0, 0);
+    return(0);
+  }
+  if (pipe(logpipe) == -1) {
+    warn3x("unable to create pipe for log.", 0, 0);
+    return(-1);
+  }
+  coe(logpipe[1]);
+  coe(logpipe[0]);
+  ndelay_on(logpipe[0]);
+  ndelay_on(logpipe[1]);
+  if (fd_copy(2, logpipe[1]) == -1) {
+    warn3x("unable to set filedescriptor for log.", 0, 0);
+    return(-1);
+  }
+  io[0].fd =logpipe[0];
+  io[0].events =IOPAUSE_READ;
+  taia_now(&stamplog);
+  return(1);
+}
+
+int main(int argc, char **argv) {
+  struct stat s;
+  time_t mtime =0;
+  int wstat;
+  int curdir;
+  int pid;
+  struct taia deadline;
+  struct taia now;
+  struct taia stampcheck;
+  char ch;
+  int i;
+
+  progname =*argv++;
+  if (! argv || ! *argv) usage();
+  if (**argv == '-') {
+    switch (*(*argv +1)) {
+    case 'P': pgrp =1;
+    case '-': ++argv;
+    }
+    if (! argv || ! *argv) usage();
+  }
+
+  sig_catch(sig_term, s_term);
+  sig_catch(sig_hangup, s_hangup);
+  svdir =*argv++;
+  if (argv && *argv) {
+    rplog =*argv;
+    if (setup_log() != 1) {
+      rplog =0;
+      warn3x("log service disabled.", 0, 0);
+    }
+  }
+  if ((curdir =open_read(".")) == -1) 
+    fatal("unable to open current directory", 0);
+  coe(curdir);
+
+  taia_now(&stampcheck);
+
+  for (;;) {
+    /* collect children */
+    for (;;) {
+      if ((pid =wait_nohang(&wstat)) <= 0) break;
+      for (i =0; i < svnum; i++) {
+        if (pid == sv[i].pid) {
+          /* runsv has gone */
+          sv[i].pid =0;
+          check =1;
+          break;
+        }
+      }
+    }
+
+    taia_now(&now);
+    if (now.sec.x < (stampcheck.sec.x -3)) {
+      /* time warp */
+      warn3x("time warp: resetting time stamp.", 0, 0);
+      taia_now(&stampcheck);
+      taia_now(&now);
+      if (rplog) taia_now(&stamplog);
+    }
+    if (taia_less(&now, &stampcheck) == 0) {
+      /* wait at least a second */
+      taia_uint(&deadline, 1);
+      taia_add(&stampcheck, &now, &deadline);
+      
+      if (stat(svdir, &s) != -1) {
+        if (check || \
+            s.st_mtime != mtime || s.st_ino != ino || s.st_dev != dev) {
+          /* svdir modified */
+          if (chdir(svdir) != -1) {
+            mtime =s.st_mtime;
+            dev =s.st_dev;
+            ino =s.st_ino;
+            check =0;
+            if (now.sec.x <= (4611686018427387914ULL +(uint64)mtime))
+              sleep(1);
+            runsvdir();
+            while (fchdir(curdir) == -1) {
+              warn("unable to change directory, pausing", 0);
+              sleep(5);
+            }
+          }
+          else
+            warn("unable to change directory to ", svdir);
+        }
+      }
+      else
+        warn("unable to stat ", svdir);
+    }
+
+    if (rplog)
+      if (taia_less(&now, &stamplog) == 0) {
+        write(logpipe[1], ".", 1);
+        taia_uint(&deadline, 900);
+        taia_add(&stamplog, &now, &deadline);
+      }
+    taia_uint(&deadline, check ? 1 : 5);
+    taia_add(&deadline, &now, &deadline);
+
+    sig_block(sig_child);
+    if (rplog)
+      iopause(io, 1, &deadline, &now);
+    else
+      iopause(0, 0, &deadline, &now);
+    sig_unblock(sig_child);
+
+    if (rplog && (io[0].revents | IOPAUSE_READ))
+      while (read(logpipe[0], &ch, 1) > 0)
+        if (ch) {
+          for (i =6; i < rploglen; i++)
+            rplog[i -1] =rplog[i];
+          rplog[rploglen -1] =ch;
+        }
+
+    switch(exitsoon) {
+    case 1:
+      _exit(0);
+    case 2:
+      for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM);
+      _exit(111);
+    }
+  }
+  /* not reached */
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/runsvdir.check b/runit-2.1.2/src/runsvdir.check
new file mode 100755
index 0000000..a7927eb
--- /dev/null
+++ b/runit-2.1.2/src/runsvdir.check
@@ -0,0 +1,3 @@
+#!/bin/sh
+runsvdir
+echo $?
diff --git a/runit-2.1.2/src/runsvdir.dist b/runit-2.1.2/src/runsvdir.dist
new file mode 100644
index 0000000..c553363
--- /dev/null
+++ b/runit-2.1.2/src/runsvdir.dist
@@ -0,0 +1,3 @@
+usage: runsvdir [-P] dir
+
+1
diff --git a/runit-2.1.2/src/runsvstat.c b/runit-2.1.2/src/runsvstat.c
new file mode 100644
index 0000000..c0c0233
--- /dev/null
+++ b/runit-2.1.2/src/runsvstat.c
@@ -0,0 +1,167 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "strerr.h"
+#include "error.h"
+#include "sgetopt.h"
+#include "open.h"
+#include "buffer.h"
+#include "tai.h"
+#include "fmt.h"
+
+#define USAGE " [ -l ] service ..."
+
+#define VERSION "$Id: c17bbd3eda6f3c57027dfb47ff676bdd3fefff9f $"
+
+#define FATAL "runsvstat: fatal: "
+#define WARNING "runsvstat: warning: "
+
+const char *progname;
+unsigned int rc =0;
+struct stat s;
+int showlog =0;
+
+void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+
+void fatal(char *m1) { strerr_die3sys(111, FATAL, m1, ": "); }
+void warn(char *m1, char *m2) {
+  rc++;
+  strerr_warn5(WARNING, m1, ": ", m2, ": ", &strerr_sys);
+}
+void warnx(char *m1, char *m2) {
+  rc++;
+  strerr_warn4(WARNING, m1, ": ", m2, 0);
+}
+
+int show_status(char *name) {
+  char status[20];
+  int pid;
+  int fd;
+  int normallyup =0;
+  char sulong[FMT_ULONG];
+  struct tai when;
+  struct tai now;
+
+  if (stat("down", &s) == -1) {
+    if (errno != error_noent) {
+      warn(name, "unable to stat down");
+      return(-1);
+    }
+    normallyup = 1;
+  }
+  if ((fd =open_write("supervise/ok")) == -1) {
+    if (errno == error_nodevice)
+      warnx(name, "runsv not running.");
+    else
+      warn(name, "unable to open supervise/ok");
+    return(-1);
+  }
+  close(fd);
+  if ((fd =open_read("supervise/status")) == -1) {
+    warn(name, "unable to open supervise/status");
+    return(-1);
+  }
+  switch(read(fd, status, 20)) {
+  case 20: break;
+  case -1:
+    warn(name, "unable to read supervise/status");
+    return(-1);
+  default:
+    warnx(name, "unable to read supervise/status: bad format.");
+    return(-1);
+  }
+  pid =(unsigned char) status[15];
+  pid <<=8; pid +=(unsigned char)status[14];
+  pid <<=8; pid +=(unsigned char)status[13];
+  pid <<=8; pid +=(unsigned char)status[12];
+
+  tai_unpack(status,&when);
+  tai_now(&now);
+  if (tai_less(&now,&when)) when =now;
+  tai_sub(&when,&now,&when);
+
+  buffer_puts(buffer_1, name);
+  buffer_puts(buffer_1, ": ");
+  if (pid) {
+    switch (status[19]) {
+    case 1: buffer_puts(buffer_1, "run "); break;
+    case 2: buffer_puts(buffer_1, "finish "); break;
+    }
+    buffer_puts(buffer_1, "(pid ");
+    buffer_put(buffer_1, sulong, fmt_ulong(sulong, pid));
+    buffer_puts(buffer_1, ") ");
+  }
+  else
+    buffer_puts(buffer_1, "down ");
+  buffer_put(buffer_1, sulong, fmt_ulong(sulong, tai_approx(&when)));
+  buffer_puts(buffer_1, " seconds");
+  if (pid && !normallyup) buffer_puts(buffer_1,", normally down");
+  if (!pid && normallyup) buffer_puts(buffer_1,", normally up");
+  if (pid && status[16]) buffer_puts(buffer_1,", paused");
+  if (!pid && (status[17] == 'u')) buffer_puts(buffer_1,", want up");
+  if (pid && (status[17] == 'd')) buffer_puts(buffer_1,", want down");
+  if (pid && status[18]) buffer_puts(buffer_1, ", got TERM");
+  /* buffer_putsflush(buffer_1, "\n"); */
+  return(1);
+}
+
+int main(int argc, char **argv) {
+  int opt;
+  int curdir;
+  char **dir;
+
+  progname =*argv;
+
+  while ((opt =getopt(argc, (const char * const *)argv, "lV")) != opteof) {
+    switch(opt) {
+    case 'l':
+      showlog =1;
+      break;
+    case 'V':
+      strerr_warn1(VERSION, 0);
+    case '?':
+      usage();
+    }
+  }
+  argv +=optind;
+
+  dir =argv;
+  if (! dir || ! *dir) usage();
+
+  if ((curdir =open_read(".")) == -1) {
+    rc =100;
+    fatal("unable to open current directory");
+  }
+  for (; dir && *dir; dir++) {
+    if (chdir(*dir) == -1) {
+      warn(*dir, "unable to change directory");
+      continue;
+    }
+    if (show_status(*dir) == 1) {
+      if (showlog) {
+        if (stat("log", &s) == -1) {
+          if (errno != error_noent)
+            warn("unable to stat()", "./log");
+        }
+        else {
+          if (! S_ISDIR(s.st_mode))
+            warnx("./log", "not a directory.");
+          else {
+            if (chdir("log") == -1) {
+              warn(*dir, "unable to change directory");
+              continue;
+            }
+            show_status("\n  log");
+          }
+        }
+      }
+      buffer_puts(buffer_1, "\n"); buffer_flush(buffer_1);
+    }
+    if (fchdir(curdir) == -1) {
+      rc =100;
+      fatal("unable to change directory");
+    }
+  }
+  if (rc > 100) rc =100;
+  _exit(rc);
+}
diff --git a/runit-2.1.2/src/runsvstat.check b/runit-2.1.2/src/runsvstat.check
new file mode 100755
index 0000000..6ccde11
--- /dev/null
+++ b/runit-2.1.2/src/runsvstat.check
@@ -0,0 +1,26 @@
+#!/bin/sh
+rm -rf "${ctmp}"
+
+runsvstat
+echo $?
+runsvstat -V
+echo $?
+
+mkdir "${ctmp}"
+echo '#!/bin/sh' >"${ctmp}"/run
+echo 'echo starting' >>"${ctmp}"/run
+echo 'exec sleep 14' >>"${ctmp}"/run
+chmod 700 "${ctmp}"/run
+chpst -2 runsvstat "${ctmp}"
+echo $?
+runsv "${ctmp}" &
+sleep 1
+test -r "${ctmp}"/supervise/stat || sleep 2
+chpst -1 runsvstat "${ctmp}"
+echo $?
+runsvctrl exit "${ctmp}"
+wait
+echo $?
+chpst -2 runsvstat "${ctmp}"
+echo $?
+rm -rf "${ctmp}"
diff --git a/runit-2.1.2/src/runsvstat.dist b/runit-2.1.2/src/runsvstat.dist
new file mode 100644
index 0000000..24b9ed4
--- /dev/null
+++ b/runit-2.1.2/src/runsvstat.dist
@@ -0,0 +1,12 @@
+usage: runsvstat [ -l ] service ...
+
+1
+$Id$
+usage: runsvstat [ -l ] service ...
+
+1
+1
+starting
+0
+0
+1
diff --git a/runit-2.1.2/src/scan.h b/runit-2.1.2/src/scan.h
new file mode 100644
index 0000000..3db49d3
--- /dev/null
+++ b/runit-2.1.2/src/scan.h
@@ -0,0 +1,30 @@
+/* Public domain. */
+
+#ifndef SCAN_H
+#define SCAN_H
+
+extern unsigned int scan_uint(const char *,unsigned int *);
+extern unsigned int scan_xint(const char *,unsigned int *);
+extern unsigned int scan_nbbint(const char *,unsigned int,unsigned int,unsigned int,unsigned int *);
+extern unsigned int scan_ushort(const char *,unsigned short *);
+extern unsigned int scan_xshort(const char *,unsigned short *);
+extern unsigned int scan_nbbshort(const char *,unsigned int,unsigned int,unsigned int,unsigned short *);
+extern unsigned int scan_ulong(const char *,unsigned long *);
+extern unsigned int scan_xlong(const char *,unsigned long *);
+extern unsigned int scan_nbblong(const char *,unsigned int,unsigned int,unsigned int,unsigned long *);
+
+extern unsigned int scan_plusminus(const char *,int *);
+extern unsigned int scan_0x(const char *,unsigned int *);
+
+extern unsigned int scan_whitenskip(const char *,unsigned int);
+extern unsigned int scan_nonwhitenskip(const char *,unsigned int);
+extern unsigned int scan_charsetnskip(const char *,const char *,unsigned int);
+extern unsigned int scan_noncharsetnskip(const char *,const char *,unsigned int);
+
+extern unsigned int scan_strncmp(const char *,const char *,unsigned int);
+extern unsigned int scan_memcmp(const char *,const char *,unsigned int);
+
+extern unsigned int scan_long(const char *,long *);
+extern unsigned int scan_8long(const char *,unsigned long *);
+
+#endif
diff --git a/runit-2.1.2/src/scan_ulong.c b/runit-2.1.2/src/scan_ulong.c
new file mode 100644
index 0000000..af19701
--- /dev/null
+++ b/runit-2.1.2/src/scan_ulong.c
@@ -0,0 +1,16 @@
+/* Public domain. */
+
+#include "scan.h"
+
+unsigned int scan_ulong(register const char *s,register unsigned long *u)
+{
+  register unsigned int pos = 0;
+  register unsigned long result = 0;
+  register unsigned long c;
+  while ((c = (unsigned long) (unsigned char) (s[pos] - '0')) < 10) {
+    result = result * 10 + c;
+    ++pos;
+  }
+  *u = result;
+  return pos;
+}
diff --git a/runit-2.1.2/src/seek.h b/runit-2.1.2/src/seek.h
new file mode 100644
index 0000000..8011701
--- /dev/null
+++ b/runit-2.1.2/src/seek.h
@@ -0,0 +1,17 @@
+/* Public domain. */
+
+#ifndef SEEK_H
+#define SEEK_H
+
+typedef unsigned long seek_pos;
+
+extern seek_pos seek_cur(int);
+
+extern int seek_set(int,seek_pos);
+extern int seek_end(int);
+
+extern int seek_trunc(int,seek_pos);
+
+#define seek_begin(fd) (seek_set((fd),(seek_pos) 0))
+
+#endif
diff --git a/runit-2.1.2/src/seek_set.c b/runit-2.1.2/src/seek_set.c
new file mode 100644
index 0000000..19b8265
--- /dev/null
+++ b/runit-2.1.2/src/seek_set.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include "seek.h"
+
+#define SET 0 /* sigh */
+
+int seek_set(int fd,seek_pos pos)
+{ if (lseek(fd,(off_t) pos,SET) == -1) return -1; return 0; }
diff --git a/runit-2.1.2/src/select.h1 b/runit-2.1.2/src/select.h1
new file mode 100644
index 0000000..68e971f
--- /dev/null
+++ b/runit-2.1.2/src/select.h1
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#ifndef SELECT_H
+#define SELECT_H
+
+/* sysdep: -sysselect */
+
+#include <sys/types.h>
+#include <sys/time.h>
+extern int select();
+
+#endif
diff --git a/runit-2.1.2/src/select.h2 b/runit-2.1.2/src/select.h2
new file mode 100644
index 0000000..4bd4fcf
--- /dev/null
+++ b/runit-2.1.2/src/select.h2
@@ -0,0 +1,13 @@
+/* Public domain. */
+
+#ifndef SELECT_H
+#define SELECT_H
+
+/* sysdep: +sysselect */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/select.h>
+extern int select();
+
+#endif
diff --git a/runit-2.1.2/src/sgetopt.c b/runit-2.1.2/src/sgetopt.c
new file mode 100644
index 0000000..8bb608f
--- /dev/null
+++ b/runit-2.1.2/src/sgetopt.c
@@ -0,0 +1,53 @@
+/* Public domain. */
+
+/* sgetopt.c, sgetopt.h: (yet another) improved getopt clone, outer layer
+D. J. Bernstein, djb@pobox.com.
+Depends on subgetopt.h, buffer.h.
+No system requirements.
+19991219: Switched to buffer.h.
+19970208: Cleanups.
+931201: Baseline.
+No known patent problems.
+
+Documentation in sgetopt.3.
+*/
+
+#include "buffer.h"
+#define SGETOPTNOSHORT
+#include "sgetopt.h"
+#define SUBGETOPTNOSHORT
+#include "subgetopt.h"
+
+#define getopt sgetoptmine
+#define optind subgetoptind
+#define opterr sgetopterr
+#define optproblem subgetoptproblem
+#define optprogname sgetoptprogname
+
+int opterr = 1;
+const char *optprogname = 0;
+
+int getopt(int argc,const char *const *argv,const char *opts)
+{
+  int c;
+  const char *s;
+
+  if (!optprogname) {
+    optprogname = *argv;
+    if (!optprogname) optprogname = "";
+    for (s = optprogname;*s;++s) if (*s == '/') optprogname = s + 1;
+  }
+  c = subgetopt(argc,argv,opts);
+  if (opterr)
+    if (c == '?') {
+      char chp[2]; chp[0] = optproblem; chp[1] = '\n';
+      buffer_puts(buffer_2,optprogname);
+      if (argv[optind] && (optind < argc))
+        buffer_puts(buffer_2,": illegal option -- ");
+      else
+        buffer_puts(buffer_2,": option requires an argument -- ");
+      buffer_put(buffer_2,chp,2);
+      buffer_flush(buffer_2);
+    }
+  return c;
+}
diff --git a/runit-2.1.2/src/sgetopt.h b/runit-2.1.2/src/sgetopt.h
new file mode 100644
index 0000000..bf8bce6
--- /dev/null
+++ b/runit-2.1.2/src/sgetopt.h
@@ -0,0 +1,23 @@
+/* Public domain. */
+
+#ifndef SGETOPT_H
+#define SGETOPT_H
+
+#ifndef SGETOPTNOSHORT
+#define getopt sgetoptmine
+#define optarg subgetoptarg
+#define optind subgetoptind
+#define optpos subgetoptpos
+#define opterr sgetopterr
+#define optproblem subgetoptproblem
+#define optprogname sgetoptprogname
+#define opteof subgetoptdone
+#endif
+
+#include "subgetopt.h"
+
+extern int sgetoptmine(int,const char *const *,const char *);
+extern int sgetopterr;
+extern const char *sgetoptprogname;
+
+#endif
diff --git a/runit-2.1.2/src/sig.c b/runit-2.1.2/src/sig.c
new file mode 100644
index 0000000..423d18e
--- /dev/null
+++ b/runit-2.1.2/src/sig.c
@@ -0,0 +1,15 @@
+/* Public domain. */
+
+#include <signal.h>
+#include "sig.h"
+
+int sig_alarm = SIGALRM;
+int sig_child = SIGCHLD;
+int sig_cont = SIGCONT;
+int sig_hangup = SIGHUP;
+int sig_int = SIGINT;
+int sig_pipe = SIGPIPE;
+int sig_term = SIGTERM;
+
+void (*sig_defaulthandler)() = SIG_DFL;
+void (*sig_ignorehandler)() = SIG_IGN;
diff --git a/runit-2.1.2/src/sig.h b/runit-2.1.2/src/sig.h
new file mode 100644
index 0000000..2a3c780
--- /dev/null
+++ b/runit-2.1.2/src/sig.h
@@ -0,0 +1,28 @@
+/* Public domain. */
+
+#ifndef SIG_H
+#define SIG_H
+
+extern int sig_alarm;
+extern int sig_child;
+extern int sig_cont;
+extern int sig_hangup;
+extern int sig_int;
+extern int sig_pipe;
+extern int sig_term;
+
+extern void (*sig_defaulthandler)();
+extern void (*sig_ignorehandler)();
+
+extern void sig_catch(int,void (*)());
+#define sig_ignore(s) (sig_catch((s),sig_ignorehandler))
+#define sig_uncatch(s) (sig_catch((s),sig_defaulthandler))
+
+extern void sig_block(int);
+extern void sig_unblock(int);
+extern void sig_blocknone(void);
+extern void sig_pause(void);
+
+extern void sig_dfl(int);
+
+#endif
diff --git a/runit-2.1.2/src/sig_block.c b/runit-2.1.2/src/sig_block.c
new file mode 100644
index 0000000..a46c860
--- /dev/null
+++ b/runit-2.1.2/src/sig_block.c
@@ -0,0 +1,40 @@
+/* Public domain. */
+
+#include <signal.h>
+#include "sig.h"
+#include "hassgprm.h"
+
+void sig_block(int sig)
+{
+#ifdef HASSIGPROCMASK
+  sigset_t ss;
+  sigemptyset(&ss);
+  sigaddset(&ss,sig);
+  sigprocmask(SIG_BLOCK,&ss,(sigset_t *) 0);
+#else
+  sigblock(1 << (sig - 1));
+#endif
+}
+
+void sig_unblock(int sig)
+{
+#ifdef HASSIGPROCMASK
+  sigset_t ss;
+  sigemptyset(&ss);
+  sigaddset(&ss,sig);
+  sigprocmask(SIG_UNBLOCK,&ss,(sigset_t *) 0);
+#else
+  sigsetmask(sigsetmask(~0) & ~(1 << (sig - 1)));
+#endif
+}
+
+void sig_blocknone(void)
+{
+#ifdef HASSIGPROCMASK
+  sigset_t ss;
+  sigemptyset(&ss);
+  sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0);
+#else
+  sigsetmask(0);
+#endif
+}
diff --git a/runit-2.1.2/src/sig_catch.c b/runit-2.1.2/src/sig_catch.c
new file mode 100644
index 0000000..7b5bd89
--- /dev/null
+++ b/runit-2.1.2/src/sig_catch.c
@@ -0,0 +1,18 @@
+/* Public domain. */
+
+#include <signal.h>
+#include "sig.h"
+#include "hassgact.h"
+
+void sig_catch(int sig,void (*f)())
+{
+#ifdef HASSIGACTION
+  struct sigaction sa;
+  sa.sa_handler = f;
+  sa.sa_flags = 0;
+  sigemptyset(&sa.sa_mask);
+  sigaction(sig,&sa,(struct sigaction *) 0);
+#else
+  signal(sig,f); /* won't work under System V, even nowadays---dorks */
+#endif
+}
diff --git a/runit-2.1.2/src/sig_pause.c b/runit-2.1.2/src/sig_pause.c
new file mode 100644
index 0000000..3d1a793
--- /dev/null
+++ b/runit-2.1.2/src/sig_pause.c
@@ -0,0 +1,16 @@
+/* Public domain. */
+
+#include <signal.h>
+#include "sig.h"
+#include "hassgprm.h"
+
+void sig_pause(void)
+{
+#ifdef HASSIGPROCMASK
+  sigset_t ss;
+  sigemptyset(&ss);
+  sigsuspend(&ss);
+#else
+  sigpause(0);
+#endif
+}
diff --git a/runit-2.1.2/src/str.h b/runit-2.1.2/src/str.h
new file mode 100644
index 0000000..f65b8f6
--- /dev/null
+++ b/runit-2.1.2/src/str.h
@@ -0,0 +1,16 @@
+/* Public domain. */
+
+#ifndef STR_H
+#define STR_H
+
+extern unsigned int str_copy(char *,const char *);
+extern int str_diff(const char *,const char *);
+extern int str_diffn(const char *,const char *,unsigned int);
+extern unsigned int str_len(const char *);
+extern unsigned int str_chr(const char *,int);
+extern unsigned int str_rchr(const char *,int);
+extern int str_start(const char *,const char *);
+
+#define str_equal(s,t) (!str_diff((s),(t)))
+
+#endif
diff --git a/runit-2.1.2/src/str_chr.c b/runit-2.1.2/src/str_chr.c
new file mode 100644
index 0000000..9b467eb
--- /dev/null
+++ b/runit-2.1.2/src/str_chr.c
@@ -0,0 +1,19 @@
+/* Public domain. */
+
+#include "str.h"
+
+unsigned int str_chr(register const char *s,int c)
+{
+  register char ch;
+  register const char *t;
+
+  ch = c;
+  t = s;
+  for (;;) {
+    if (!*t) break; if (*t == ch) break; ++t;
+    if (!*t) break; if (*t == ch) break; ++t;
+    if (!*t) break; if (*t == ch) break; ++t;
+    if (!*t) break; if (*t == ch) break; ++t;
+  }
+  return t - s;
+}
diff --git a/runit-2.1.2/src/str_diff.c b/runit-2.1.2/src/str_diff.c
new file mode 100644
index 0000000..47dff22
--- /dev/null
+++ b/runit-2.1.2/src/str_diff.c
@@ -0,0 +1,17 @@
+/* Public domain. */
+
+#include "str.h"
+
+int str_diff(register const char *s,register const char *t)
+{
+  register char x;
+
+  for (;;) {
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+    x = *s; if (x != *t) break; if (!x) break; ++s; ++t;
+  }
+  return ((int)(unsigned int)(unsigned char) x)
+       - ((int)(unsigned int)(unsigned char) *t);
+}
diff --git a/runit-2.1.2/src/str_len.c b/runit-2.1.2/src/str_len.c
new file mode 100644
index 0000000..dedd005
--- /dev/null
+++ b/runit-2.1.2/src/str_len.c
@@ -0,0 +1,16 @@
+/* Public domain. */
+
+#include "str.h"
+
+unsigned int str_len(const char *s)
+{
+  register const char *t;
+
+  t = s;
+  for (;;) {
+    if (!*t) return t - s; ++t;
+    if (!*t) return t - s; ++t;
+    if (!*t) return t - s; ++t;
+    if (!*t) return t - s; ++t;
+  }
+}
diff --git a/runit-2.1.2/src/str_start.c b/runit-2.1.2/src/str_start.c
new file mode 100644
index 0000000..017efc7
--- /dev/null
+++ b/runit-2.1.2/src/str_start.c
@@ -0,0 +1,15 @@
+/* Public domain. */
+
+#include "str.h"
+
+int str_start(register const char *s,register const char *t)
+{
+  register char x;
+
+  for (;;) {
+    x = *t++; if (!x) return 1; if (x != *s++) return 0;
+    x = *t++; if (!x) return 1; if (x != *s++) return 0;
+    x = *t++; if (!x) return 1; if (x != *s++) return 0;
+    x = *t++; if (!x) return 1; if (x != *s++) return 0;
+  }
+}
diff --git a/runit-2.1.2/src/stralloc.h b/runit-2.1.2/src/stralloc.h
new file mode 100644
index 0000000..51d61bd
--- /dev/null
+++ b/runit-2.1.2/src/stralloc.h
@@ -0,0 +1,31 @@
+/* Public domain. */
+
+#ifndef STRALLOC_H
+#define STRALLOC_H
+
+#include "gen_alloc.h"
+
+GEN_ALLOC_typedef(stralloc,char,s,len,a)
+
+extern int stralloc_ready(stralloc *,unsigned int);
+extern int stralloc_readyplus(stralloc *,unsigned int);
+extern int stralloc_copy(stralloc *,const stralloc *);
+extern int stralloc_cat(stralloc *,const stralloc *);
+extern int stralloc_copys(stralloc *,const char *);
+extern int stralloc_cats(stralloc *,const char *);
+extern int stralloc_copyb(stralloc *,const char *,unsigned int);
+extern int stralloc_catb(stralloc *,const char *,unsigned int);
+extern int stralloc_append(stralloc *,const char *); /* beware: this takes a pointer to 1 char */
+extern int stralloc_starts(stralloc *,const char *);
+
+#define stralloc_0(sa) stralloc_append(sa,"")
+
+extern int stralloc_catulong0(stralloc *,unsigned long,unsigned int);
+extern int stralloc_catlong0(stralloc *,long,unsigned int);
+
+#define stralloc_catlong(sa,l) (stralloc_catlong0((sa),(l),0))
+#define stralloc_catuint0(sa,i,n) (stralloc_catulong0((sa),(i),(n)))
+#define stralloc_catint0(sa,i,n) (stralloc_catlong0((sa),(i),(n)))
+#define stralloc_catint(sa,i) (stralloc_catlong0((sa),(i),0))
+
+#endif
diff --git a/runit-2.1.2/src/stralloc_cat.c b/runit-2.1.2/src/stralloc_cat.c
new file mode 100644
index 0000000..2c6ad58
--- /dev/null
+++ b/runit-2.1.2/src/stralloc_cat.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#include "byte.h"
+#include "stralloc.h"
+
+int stralloc_cat(stralloc *sato,const stralloc *safrom)
+{
+  return stralloc_catb(sato,safrom->s,safrom->len);
+}
diff --git a/runit-2.1.2/src/stralloc_catb.c b/runit-2.1.2/src/stralloc_catb.c
new file mode 100644
index 0000000..8ee0af4
--- /dev/null
+++ b/runit-2.1.2/src/stralloc_catb.c
@@ -0,0 +1,14 @@
+/* Public domain. */
+
+#include "stralloc.h"
+#include "byte.h"
+
+int stralloc_catb(stralloc *sa,const char *s,unsigned int n)
+{
+  if (!sa->s) return stralloc_copyb(sa,s,n);
+  if (!stralloc_readyplus(sa,n + 1)) return 0;
+  byte_copy(sa->s + sa->len,n,s);
+  sa->len += n;
+  sa->s[sa->len] = 'Z'; /* ``offensive programming'' */
+  return 1;
+}
diff --git a/runit-2.1.2/src/stralloc_cats.c b/runit-2.1.2/src/stralloc_cats.c
new file mode 100644
index 0000000..ea1e290
--- /dev/null
+++ b/runit-2.1.2/src/stralloc_cats.c
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#include "byte.h"
+#include "str.h"
+#include "stralloc.h"
+
+int stralloc_cats(stralloc *sa,const char *s)
+{
+  return stralloc_catb(sa,s,str_len(s));
+}
diff --git a/runit-2.1.2/src/stralloc_eady.c b/runit-2.1.2/src/stralloc_eady.c
new file mode 100644
index 0000000..81dbb85
--- /dev/null
+++ b/runit-2.1.2/src/stralloc_eady.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include "alloc.h"
+#include "stralloc.h"
+#include "gen_allocdefs.h"
+
+GEN_ALLOC_ready(stralloc,char,s,len,a,i,n,x,30,stralloc_ready)
+GEN_ALLOC_readyplus(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus)
diff --git a/runit-2.1.2/src/stralloc_opyb.c b/runit-2.1.2/src/stralloc_opyb.c
new file mode 100644
index 0000000..bbcff48
--- /dev/null
+++ b/runit-2.1.2/src/stralloc_opyb.c
@@ -0,0 +1,13 @@
+/* Public domain. */
+
+#include "stralloc.h"
+#include "byte.h"
+
+int stralloc_copyb(stralloc *sa,const char *s,unsigned int n)
+{
+  if (!stralloc_ready(sa,n + 1)) return 0;
+  byte_copy(sa->s,n,s);
+  sa->len = n;
+  sa->s[n] = 'Z'; /* ``offensive programming'' */
+  return 1;
+}
diff --git a/runit-2.1.2/src/stralloc_opys.c b/runit-2.1.2/src/stralloc_opys.c
new file mode 100644
index 0000000..075b6f8
--- /dev/null
+++ b/runit-2.1.2/src/stralloc_opys.c
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#include "byte.h"
+#include "str.h"
+#include "stralloc.h"
+
+int stralloc_copys(stralloc *sa,const char *s)
+{
+  return stralloc_copyb(sa,s,str_len(s));
+}
diff --git a/runit-2.1.2/src/stralloc_pend.c b/runit-2.1.2/src/stralloc_pend.c
new file mode 100644
index 0000000..70cb55c
--- /dev/null
+++ b/runit-2.1.2/src/stralloc_pend.c
@@ -0,0 +1,7 @@
+/* Public domain. */
+
+#include "alloc.h"
+#include "stralloc.h"
+#include "gen_allocdefs.h"
+
+GEN_ALLOC_append(stralloc,char,s,len,a,i,n,x,30,stralloc_readyplus,stralloc_append)
diff --git a/runit-2.1.2/src/strerr.h b/runit-2.1.2/src/strerr.h
new file mode 100644
index 0000000..21d812d
--- /dev/null
+++ b/runit-2.1.2/src/strerr.h
@@ -0,0 +1,80 @@
+/* Public domain. */
+
+#ifndef STRERR_H
+#define STRERR_H
+
+struct strerr {
+  struct strerr *who;
+  const char *x;
+  const char *y;
+  const char *z;
+} ;
+
+extern struct strerr strerr_sys;
+extern void strerr_sysinit(void);
+
+extern const char *strerr(const struct strerr *);
+extern void strerr_warn(const char *,const char *,const char *,const char *,const char *,const char *,const struct strerr *);
+extern void strerr_die(int,const char *,const char *,const char *,const char *,const char *,const char *,const struct strerr *);
+
+#define STRERR(r,se,a) \
+{ se.who = 0; se.x = a; se.y = 0; se.z = 0; return r; }
+
+#define STRERR_SYS(r,se,a) \
+{ se.who = &strerr_sys; se.x = a; se.y = 0; se.z = 0; return r; }
+#define STRERR_SYS3(r,se,a,b,c) \
+{ se.who = &strerr_sys; se.x = a; se.y = b; se.z = c; return r; }
+
+#define strerr_warn6(x1,x2,x3,x4,x5,x6,se) \
+strerr_warn((x1),(x2),(x3),(x4),(x5),(x6),(se))
+#define strerr_warn5(x1,x2,x3,x4,x5,se) \
+strerr_warn((x1),(x2),(x3),(x4),(x5),0,(se))
+#define strerr_warn4(x1,x2,x3,x4,se) \
+strerr_warn((x1),(x2),(x3),(x4),0,0,(se))
+#define strerr_warn3(x1,x2,x3,se) \
+strerr_warn((x1),(x2),(x3),0,0,0,(se))
+#define strerr_warn2(x1,x2,se) \
+strerr_warn((x1),(x2),0,0,0,0,(se))
+#define strerr_warn1(x1,se) \
+strerr_warn((x1),0,0,0,0,0,(se))
+
+#define strerr_die6(e,x1,x2,x3,x4,x5,x6,se) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),(se))
+#define strerr_die5(e,x1,x2,x3,x4,x5,se) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,(se))
+#define strerr_die4(e,x1,x2,x3,x4,se) \
+strerr_die((e),(x1),(x2),(x3),(x4),0,0,(se))
+#define strerr_die3(e,x1,x2,x3,se) \
+strerr_die((e),(x1),(x2),(x3),0,0,0,(se))
+#define strerr_die2(e,x1,x2,se) \
+strerr_die((e),(x1),(x2),0,0,0,0,(se))
+#define strerr_die1(e,x1,se) \
+strerr_die((e),(x1),0,0,0,0,0,(se))
+
+#define strerr_die6sys(e,x1,x2,x3,x4,x5,x6) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),&strerr_sys)
+#define strerr_die5sys(e,x1,x2,x3,x4,x5) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,&strerr_sys)
+#define strerr_die4sys(e,x1,x2,x3,x4) \
+strerr_die((e),(x1),(x2),(x3),(x4),0,0,&strerr_sys)
+#define strerr_die3sys(e,x1,x2,x3) \
+strerr_die((e),(x1),(x2),(x3),0,0,0,&strerr_sys)
+#define strerr_die2sys(e,x1,x2) \
+strerr_die((e),(x1),(x2),0,0,0,0,&strerr_sys)
+#define strerr_die1sys(e,x1) \
+strerr_die((e),(x1),0,0,0,0,0,&strerr_sys)
+
+#define strerr_die6x(e,x1,x2,x3,x4,x5,x6) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),(x6),0)
+#define strerr_die5x(e,x1,x2,x3,x4,x5) \
+strerr_die((e),(x1),(x2),(x3),(x4),(x5),0,0)
+#define strerr_die4x(e,x1,x2,x3,x4) \
+strerr_die((e),(x1),(x2),(x3),(x4),0,0,0)
+#define strerr_die3x(e,x1,x2,x3) \
+strerr_die((e),(x1),(x2),(x3),0,0,0,0)
+#define strerr_die2x(e,x1,x2) \
+strerr_die((e),(x1),(x2),0,0,0,0,0)
+#define strerr_die1x(e,x1) \
+strerr_die((e),(x1),0,0,0,0,0,0)
+
+#endif
diff --git a/runit-2.1.2/src/strerr_die.c b/runit-2.1.2/src/strerr_die.c
new file mode 100644
index 0000000..f226b80
--- /dev/null
+++ b/runit-2.1.2/src/strerr_die.c
@@ -0,0 +1,33 @@
+/* Public domain. */
+
+#include <unistd.h>
+#include "buffer.h"
+#include "strerr.h"
+
+void strerr_warn(const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,const struct strerr *se)
+{
+  strerr_sysinit();
+ 
+  if (x1) buffer_puts(buffer_2,x1);
+  if (x2) buffer_puts(buffer_2,x2);
+  if (x3) buffer_puts(buffer_2,x3);
+  if (x4) buffer_puts(buffer_2,x4);
+  if (x5) buffer_puts(buffer_2,x5);
+  if (x6) buffer_puts(buffer_2,x6);
+ 
+  while(se) {
+    if (se->x) buffer_puts(buffer_2,se->x);
+    if (se->y) buffer_puts(buffer_2,se->y);
+    if (se->z) buffer_puts(buffer_2,se->z);
+    se = se->who;
+  }
+ 
+  buffer_puts(buffer_2,"\n");
+  buffer_flush(buffer_2);
+}
+
+void strerr_die(int e,const char *x1,const char *x2,const char *x3,const char *x4,const char *x5,const char *x6,const struct strerr *se)
+{
+  strerr_warn(x1,x2,x3,x4,x5,x6,se);
+  _exit(e);
+}
diff --git a/runit-2.1.2/src/strerr_sys.c b/runit-2.1.2/src/strerr_sys.c
new file mode 100644
index 0000000..84b302f
--- /dev/null
+++ b/runit-2.1.2/src/strerr_sys.c
@@ -0,0 +1,14 @@
+/* Public domain. */
+
+#include "error.h"
+#include "strerr.h"
+
+struct strerr strerr_sys;
+
+void strerr_sysinit(void)
+{
+  strerr_sys.who = 0;
+  strerr_sys.x = error_str(errno);
+  strerr_sys.y = "";
+  strerr_sys.z = "";
+}
diff --git a/runit-2.1.2/src/subgetopt.c b/runit-2.1.2/src/subgetopt.c
new file mode 100644
index 0000000..85ace96
--- /dev/null
+++ b/runit-2.1.2/src/subgetopt.c
@@ -0,0 +1,67 @@
+/* Public domain. */
+
+#define SUBGETOPTNOSHORT
+#include "subgetopt.h"
+
+#define sgopt subgetopt
+#define optind subgetoptind
+#define optpos subgetoptpos
+#define optarg subgetoptarg
+#define optproblem subgetoptproblem
+#define optdone subgetoptdone
+
+int optind = 1;
+int optpos = 0;
+const char *optarg = 0;
+int optproblem = 0;
+int optdone = SUBGETOPTDONE;
+
+int sgopt(int argc,const char *const *argv,const char *opts)
+{
+  int c;
+  const char *s;
+
+  optarg = 0;
+  if (!argv || (optind >= argc) || !argv[optind]) return optdone;
+  if (optpos && !argv[optind][optpos]) {
+    ++optind;
+    optpos = 0;
+    if ((optind >= argc) || !argv[optind]) return optdone;
+  }
+  if (!optpos) {
+    if (argv[optind][0] != '-') return optdone;
+    ++optpos;
+    c = argv[optind][1];
+    if ((c == '-') || (c == 0)) {
+      if (c) ++optind;
+      optpos = 0;
+      return optdone;
+    }
+    /* otherwise c is reassigned below */
+  }
+  c = argv[optind][optpos];
+  ++optpos;
+  s = opts;
+  while (*s) {
+    if (c == *s) {
+      if (s[1] == ':') {
+        optarg = argv[optind] + optpos;
+        ++optind;
+        optpos = 0;
+        if (!*optarg) {
+          optarg = argv[optind];
+          if ((optind >= argc) || !optarg) { /* argument past end */
+            optproblem = c;
+            return '?';
+          }
+          ++optind;
+        }
+      }
+      return c;
+    }
+    ++s;
+    if (*s == ':') ++s;
+  }
+  optproblem = c;
+  return '?';
+}
diff --git a/runit-2.1.2/src/subgetopt.h b/runit-2.1.2/src/subgetopt.h
new file mode 100644
index 0000000..41ad26a
--- /dev/null
+++ b/runit-2.1.2/src/subgetopt.h
@@ -0,0 +1,26 @@
+/* Public domain. */
+
+#ifndef SUBGETOPT_H
+#define SUBGETOPT_H
+
+#ifndef SUBGETOPTNOSHORT
+#define sgopt subgetopt
+#define sgoptarg subgetoptarg
+#define sgoptind subgetoptind
+#define sgoptpos subgetoptpos
+#define sgoptproblem subgetoptproblem
+#define sgoptprogname subgetoptprogname
+#define sgoptdone subgetoptdone
+#endif
+
+#define SUBGETOPTDONE -1
+
+extern int subgetopt(int,const char *const *,const char *);
+extern const char *subgetoptarg;
+extern int subgetoptind;
+extern int subgetoptpos;
+extern int subgetoptproblem;
+extern const char *subgetoptprogname;
+extern int subgetoptdone;
+
+#endif
diff --git a/runit-2.1.2/src/sv.c b/runit-2.1.2/src/sv.c
new file mode 100644
index 0000000..0125795
--- /dev/null
+++ b/runit-2.1.2/src/sv.c
@@ -0,0 +1,394 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "str.h"
+#include "strerr.h"
+#include "error.h"
+#include "sgetopt.h"
+#include "open.h"
+#include "env.h"
+#include "buffer.h"
+#include "fmt.h"
+#include "scan.h"
+#include "tai.h"
+#include "taia.h"
+#include "wait.h"
+
+#define USAGE " [-v] [-w sec] command service ..."
+#define USAGELSB " [-w sec] command"
+
+#define VERSION "$Id: 900314260c6d52c986c5357673bea2f3bd3f4698 $"
+
+#define FATAL   "fatal: "
+#define FAIL    "fail: "
+#define WARN    "warning: "
+#define OK      "ok: "
+#define RUN     "run: "
+#define FINISH  "finish: "
+#define DOWN    "down: "
+#define TIMEOUT "timeout: "
+#define KILL    "kill: "
+
+char *progname;
+char *action;
+char *acts;
+char *varservice ="/service/";
+char **service;
+char **servicex;
+unsigned int services;
+unsigned int rc =0;
+unsigned int lsb;
+unsigned int verbose =0;
+unsigned long wait =7;
+unsigned int kll =0;
+unsigned int islog =0;
+struct taia tstart, tnow, tdiff;
+struct tai tstatus;
+
+int (*act)(char*) =0;
+int (*cbk)(char*) =0;
+
+int curdir, fd, r;
+char svstatus[20];
+char sulong[FMT_ULONG];
+
+void usage() {
+  if (!lsb) strerr_die4x(100, "usage: ", progname, USAGE, "\n");
+  strerr_die4x(2, "usage: ", progname, USAGELSB, "\n");
+}
+void done(unsigned int e) { if (curdir != -1) fchdir(curdir); _exit(e); }
+void fatal(char *m1) {
+  strerr_warn3(FATAL, m1, ": ", &strerr_sys);
+  done(lsb ? 151 : 100);
+}
+void fatal2(char *m1, char *m2) {
+  strerr_warn4(FATAL, m1, m2, ": ", &strerr_sys);
+  done(lsb ? 151 : 100);
+}
+void out(char *p, char *m1) {
+  buffer_puts(buffer_1, p);
+  buffer_puts(buffer_1, *service);
+  if (islog) buffer_puts(buffer_1, "/log");
+  buffer_puts(buffer_1, ": ");
+  buffer_puts(buffer_1, m1);
+  if (errno) {
+    buffer_puts(buffer_1, ": ");
+    buffer_puts(buffer_1, error_str(errno));
+  }
+  buffer_puts(buffer_1, "\n");
+  buffer_flush(buffer_1);
+}
+void fail(char *m1) { ++rc; out(FAIL, m1); }
+void failx(char *m1) { errno =0; fail(m1); }
+void warn(char *m1) { ++rc; out(WARN, m1); }
+void warnx(char *m1) { errno =0; warn(m1); }
+void ok(char *m1) { errno =0; out(OK, m1); }
+
+void outs(const char *s) { buffer_puts(buffer_1, s); }
+void flush(const char *s) { outs(s); buffer_flush(buffer_1); }
+void outs2(const char *s) { buffer_puts(buffer_2, s); }
+void flush2(const char *s) { outs2(s); buffer_flush(buffer_2); }
+
+int svstatus_get() {
+  if ((fd =open_write("supervise/ok")) == -1) {
+    if (errno == error_nodevice) {
+      *acts == 'x' ? ok("runsv not running") : failx("runsv not running");
+      return(0);
+    }
+    warn("unable to open supervise/ok");
+    return(-1);
+  }
+  close(fd);
+  if ((fd =open_read("supervise/status")) == -1) {
+    warn("unable to open supervise/status");
+    return(-1);
+  }
+  r =read(fd, svstatus, 20);
+  close(fd);
+  switch(r) {
+  case 20: break;
+  case -1: warn("unable to read supervise/status"); return(-1);
+  default: warnx("unable to read supervise/status: bad format"); return(-1);
+  }
+  return(1);
+}
+unsigned int svstatus_print(char *m) {
+  int pid;
+  int normallyup =0;
+  struct stat s;
+ 
+  if (stat("down", &s) == -1) {
+    if (errno != error_noent) {
+      outs2(WARN); outs2("unable to stat "); outs2(*service); outs2("/down: ");
+      outs2(error_str(errno)); flush2("\n");
+      return(0);
+    }
+    normallyup =1;
+  }
+  pid =(unsigned char) svstatus[15];
+  pid <<=8; pid +=(unsigned char)svstatus[14];
+  pid <<=8; pid +=(unsigned char)svstatus[13];
+  pid <<=8; pid +=(unsigned char)svstatus[12];
+  tai_unpack(svstatus, &tstatus);
+  switch (svstatus[19]) {
+  case 0: outs(DOWN); break;
+  case 1: outs(RUN); break;
+  case 2: outs(FINISH); break;
+  }
+  outs(m); outs(": ");
+  if (svstatus[19]) {
+    outs("(pid "); sulong[fmt_ulong(sulong, pid)] =0;
+    outs(sulong); outs(") ");
+  }
+  buffer_put(buffer_1, sulong,
+    fmt_ulong(sulong, tnow.sec.x < tstatus.x ? 0 : tnow.sec.x -tstatus.x));
+  outs("s");
+  if (pid && !normallyup) outs(", normally down");
+  if (!pid && normallyup) outs(", normally up");
+  if (pid && svstatus[16]) outs(", paused");
+  if (!pid && (svstatus[17] == 'u')) outs(", want up");
+  if (pid && (svstatus[17] == 'd')) outs(", want down");
+  if (pid && svstatus[18]) outs(", got TERM");
+  return(pid ? 1 : 2);
+}
+int status(char *unused) {
+  int rc;
+
+  rc =svstatus_get();
+  switch(rc) { case -1: if (lsb) done(4); case 0: return(0); }
+  rc =svstatus_print(*service);
+  islog =1;
+  if (chdir("log") == -1) {
+    if (errno != error_noent) {
+      outs("; ");
+      warn("unable to change directory");
+    }
+    else outs("\n");
+  }
+  else {
+    outs("; ");
+    if (svstatus_get()) { rc =svstatus_print("log"); outs("\n"); }
+  }
+  islog =0;
+  flush("");
+  if (lsb) switch(rc) { case 1: done(0); case 2: done(3); case 0: done(4); }
+  return(rc);
+}
+
+int checkscript() {
+  char *prog[2];
+  struct stat s;
+  int pid, w;
+
+  if (stat("check", &s) == -1) {
+    if (errno == error_noent) return(1);
+    outs2(WARN); outs2("unable to stat "); outs2(*service); outs2("/check: ");
+    outs2(error_str(errno)); flush2("\n");
+    return(0);
+  }
+  /* if (!(s.st_mode & S_IXUSR)) return(1); */
+  if ((pid =fork()) == -1) {
+    outs2(WARN); outs2("unable to fork for "); outs2(*service);
+    outs2("/check: "); outs2(error_str(errno)); flush2("\n");
+    return(0);
+  }
+  if (!pid) {
+    prog[0] ="./check";
+    prog[1] =0;
+    close(1);
+    execve("check", prog, environ);
+    outs2(WARN); outs2("unable to run "); outs2(*service); outs2("/check: ");
+    outs2(error_str(errno)); flush2("\n");
+    _exit(0);
+  }
+  while (wait_pid(&w, pid) == -1) {
+    if (errno == error_intr) continue;
+    outs2(WARN); outs2("unable to wait for child "); outs2(*service);
+    outs2("/check: "); outs2(error_str(errno)); flush2("\n");
+    return(0);
+  }
+  return(!wait_exitcode(w));
+}
+
+int check(char *a) {
+  unsigned int pid;
+
+  if ((r =svstatus_get()) == -1) return(-1);
+  while (*a) {
+    if (r == 0) { if (*a == 'x') return(1); return(-1); }
+    pid =(unsigned char)svstatus[15];
+    pid <<=8; pid +=(unsigned char)svstatus[14];
+    pid <<=8; pid +=(unsigned char)svstatus[13];
+    pid <<=8; pid +=(unsigned char)svstatus[12];
+    switch (*a) {
+    case 'x': return(0);
+    case 'u':
+      if (!pid || svstatus[19] != 1) return(0);
+      if (!checkscript()) return(0);
+      break;
+    case 'd': if (pid || svstatus[19] != 0) return(0); break;
+    case 'C': if (pid) if (!checkscript()) return(0); break;
+    case 't':
+    case 'k':
+      if (!pid && svstatus[17] == 'd') break;
+      tai_unpack(svstatus, &tstatus);
+      if ((tstart.sec.x > tstatus.x) || !pid || svstatus[18] || !checkscript())
+        return(0);
+      break;
+    case 'o':
+      tai_unpack(svstatus, &tstatus);
+      if ((!pid && tstart.sec.x > tstatus.x) || (pid && svstatus[17] != 'd'))
+        return(0);
+      break;
+    case 'p': if (pid && !svstatus[16]) return(0); break;
+    case 'c': if (pid && svstatus[16]) return(0); break;
+    }
+    ++a;
+  }
+  outs(OK); svstatus_print(*service); flush("\n");
+  return(1);
+}
+int control(char *a) {
+  if (svstatus_get() <= 0) return(-1);
+  if (svstatus[17] == *a)
+    if (*a != 'd' || svstatus[18] == 1) return(0); /* once w/o term */
+  if ((fd =open_write("supervise/control")) == -1) {
+    if (errno != error_nodevice)
+      warn("unable to open supervise/control");
+    else
+      *a == 'x' ? ok("runsv not running") : failx("runsv not running");
+    return(-1);
+  }
+  r =write(fd, a, str_len(a));
+  close(fd);
+  if (r != str_len(a)) {
+    warn("unable to write to supervise/control");
+    return(-1);
+  }
+  return(1);
+}
+
+int main(int argc, char **argv) {
+  unsigned int i, done;
+  char *x;
+
+  progname =*argv;
+  for (i =str_len(*argv); i; --i) if ((*argv)[i -1] == '/') break;
+  *argv +=i;
+  optprogname =progname =*argv;
+  service =argv;
+  services =1;
+  lsb =(str_diff(progname, "sv"));
+  if ((x =env_get("SVDIR"))) varservice =x;
+  if ((x =env_get("SVWAIT"))) scan_ulong(x, &wait);
+  while ((i =getopt(argc, (const char* const*)argv, "w:vV")) != opteof) {
+    switch(i) {
+    case 'w': scan_ulong(optarg, &wait);
+    case 'v': verbose =1; break;
+    case 'V': strerr_warn1(VERSION, 0);
+    case '?': usage();
+    }
+  }
+  argv +=optind; argc -=optind;
+  if (!(action =*argv++)) usage(); --argc;
+  if (!lsb) { service =argv; services =argc; }
+  if (!*service) usage();
+
+  taia_now(&tnow); tstart =tnow;
+  if ((curdir =open_read(".")) == -1)
+    fatal("unable to open current directory");
+
+  act =&control; acts ="s";
+  if (verbose) cbk =&check;
+  switch (*action) {
+  case 'x': case 'e':
+    acts ="x"; break;
+  case 'X': case 'E':
+    acts ="x"; kll =1; cbk =&check; break;
+  case 'D':
+    acts ="d"; kll =1; cbk =&check; break;
+  case 'T':
+    acts ="tc"; kll =1; cbk =&check; break;
+  case 't':
+    if (!str_diff(action, "try-restart")) { acts ="tc"; cbk =&check; break; }
+  case 'c':
+    if (!str_diff(action, "check")) { act =0; acts ="C"; cbk =&check; break; }
+  case 'u': case 'd': case 'o': case 'p': case 'h':
+  case 'a': case 'i': case 'k': case 'q': case '1': case '2':
+    action[1] =0; acts =action; break;
+  case 's':
+    if (!str_diff(action, "shutdown")) { acts ="x"; cbk =&check; break; }
+    if (!str_diff(action, "start")) { acts ="u"; cbk =&check; break; }
+    if (!str_diff(action, "stop")) { acts ="d"; cbk =&check; break; }
+    if (lsb && str_diff(action, "status")) usage();
+    act =&status; cbk =0; break;
+  case 'r':
+    if (!str_diff(action, "restart")) { acts ="tcu"; cbk =&check; break; }
+    if (!str_diff(action, "reload")) { acts ="h"; cbk =&check; break; }
+    usage();
+  case 'f':
+    if (!str_diff(action, "force-reload"))
+      { acts ="tc"; kll =1; cbk =&check; break; }
+    if (!str_diff(action, "force-restart"))
+      { acts ="tcu"; kll =1; cbk =&check; break; }
+    if (!str_diff(action, "force-shutdown"))
+      { acts ="x"; kll =1; cbk =&check; break; }
+    if (!str_diff(action, "force-stop"))
+      { acts ="d"; kll =1; cbk =&check; break; }
+  default:
+    usage();
+  }
+
+  servicex =service;
+  for (i =0; i < services; ++i) {
+    if ((**service != '/') && (**service != '.') && **service &&
+        ((*service)[str_len(*service) -1] != '/')) {
+      if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
+        fail("unable to change to service directory");
+        *service =0;
+      }
+    }
+    else
+      if (chdir(*service) == -1) {
+        fail("unable to change to service directory");
+        *service =0;
+      }
+    if (*service) if (act && (act(acts) == -1)) *service =0;
+    if (fchdir(curdir) == -1) fatal("unable to change to original directory");
+    service++;
+  }
+
+  if (*cbk)
+    for (;;) {
+      taia_sub(&tdiff, &tnow, &tstart);
+      service =servicex; done =1;
+      for (i =0; i < services; ++i, ++service) {
+        if (!*service) continue;
+        if ((**service != '/') && (**service != '.')) {
+          if ((chdir(varservice) == -1) || (chdir(*service) == -1)) {
+            fail("unable to change to service directory");
+            *service =0;
+          }
+        }
+        else
+          if (chdir(*service) == -1) {
+            fail("unable to change to service directory");
+            *service =0;
+          }
+        if (*service) { if (cbk(acts) != 0) *service =0; else done =0; }
+        if (*service && taia_approx(&tdiff) > wait) {
+          kll ? outs(KILL) : outs(TIMEOUT);
+          if (svstatus_get() > 0) { svstatus_print(*service); ++rc; }
+          flush("\n");
+          if (kll) control("k");
+          *service =0;
+        }
+        if (fchdir(curdir) == -1)
+          fatal("unable to change to original directory");
+      }
+      if (done) break;
+      usleep(420000);
+      taia_now(&tnow);
+    }
+  return(rc > 99 ? 99 : rc);
+}
diff --git a/runit-2.1.2/src/sv.check b/runit-2.1.2/src/sv.check
new file mode 100755
index 0000000..d3c277c
--- /dev/null
+++ b/runit-2.1.2/src/sv.check
@@ -0,0 +1,27 @@
+#!/bin/sh
+rm -rf "${ctmp}"
+trap 'rm -rf "${ctmp}"' EXIT
+
+sv
+echo $?
+sv -V
+echo $?
+
+mkdir "${ctmp}"
+cat >"${ctmp}"/run <<-\EOT
+	#!/bin/sh
+	echo starting
+	exec sleep 14
+	EOT
+chmod 700 "${ctmp}"/run
+runsv "${ctmp}" &
+sleep 1
+test -r "${ctmp}"/supervise/stat || sleep 2
+sv down "${ctmp}"
+echo $?
+sleep 1
+cat "${ctmp}"/supervise/stat
+sv exit "${ctmp}"
+echo $?
+wait
+echo $?
diff --git a/runit-2.1.2/src/sv.dist b/runit-2.1.2/src/sv.dist
new file mode 100644
index 0000000..5b6c3ee
--- /dev/null
+++ b/runit-2.1.2/src/sv.dist
@@ -0,0 +1,12 @@
+usage: sv [-v] [-w sec] command service ...
+
+100
+$Id: 900314260c6d52c986c5357673bea2f3bd3f4698 $
+usage: sv [-v] [-w sec] command service ...
+
+100
+starting
+0
+down
+0
+0
diff --git a/runit-2.1.2/src/svlogd.c b/runit-2.1.2/src/svlogd.c
new file mode 100644
index 0000000..90a3321
--- /dev/null
+++ b/runit-2.1.2/src/svlogd.c
@@ -0,0 +1,848 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <time.h>
+#include <sys/time.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <stdio.h>
+#include "pmatch.h"
+#include "fmt_ptime.h"
+#include "alloc.h"
+#include "stralloc.h"
+#include "strerr.h"
+#include "buffer.h"
+#include "sig.h"
+#include "env.h"
+#include "fd.h"
+#include "wait.h"
+#include "error.h"
+#include "sgetopt.h"
+#include "open.h"
+#include "openreadclose.h"
+#include "coe.h"
+#include "lock.h"
+#include "str.h"
+#include "byte.h"
+#include "scan.h"
+#include "direntry.h"
+#include "taia.h"
+#include "fmt.h"
+#include "ndelay.h"
+#include "iopause.h"
+
+#define USAGE " [-ttv] [-r c] [-R abc] [-l len] [-b buflen] dir ..."
+#define VERSION "$Id: 5e55a90e0a1b35ec47fed3021453c50675ea1117 $"
+
+#define FATAL "svlogd: fatal: "
+#define WARNING "svlogd: warning: "
+#define PAUSE "svlogd: pausing: "
+#define INFO "svlogd: info: "
+
+const char *progname;
+
+unsigned int verbose =0;
+unsigned int timestamp =0;
+unsigned long linemax =1000;
+unsigned long buflen =1024;
+unsigned long linelen;
+
+const char *replace ="";
+char repl =0;
+
+const char **fndir;
+int fdwdir;
+struct stat st;
+stralloc sa;
+int wstat;
+struct taia now;
+struct taia trotate;
+
+char *databuf;
+buffer data;
+char *line;
+char stamp[FMT_PTIME];
+unsigned int exitasap =0;
+unsigned int rotateasap =0;
+unsigned int reopenasap =0;
+unsigned int linecomplete =1;
+unsigned int tmaxflag =0;
+int fdudp =-1;
+iopause_fd in;
+
+struct logdir {
+  int fddir;
+  char *btmp;
+  buffer b;
+  stralloc inst;
+  unsigned long size;
+  unsigned long sizemax;
+  unsigned long nmax;
+  unsigned long nmin;
+  unsigned long tmax;
+  struct taia trotate;
+  stralloc processor;
+  int ppid;
+  char fnsave[FMT_PTIME];
+  char *name;
+  int fdcur;
+  int fdlock;
+  char match;
+  char matcherr;
+  struct sockaddr_in udpaddr;
+  unsigned int udponly;
+  stralloc prefix;
+} *dir;
+unsigned int dirn =0;
+
+void usage() { strerr_die4x(111, "usage: ", progname, USAGE, "\n"); }
+void die_nomem() { strerr_die2x(111, FATAL, "out of memory."); }
+void fatal(char *m0) { strerr_die3sys(111, FATAL, m0, ": "); }
+void fatalx(char *m0) { strerr_die2x(111, FATAL, m0); }
+void fatal2(char *m0, char *m1) {
+  strerr_die5sys(111, FATAL, m0, ": ", m1, ": ");
+}
+void warn(char *m0) { strerr_warn3(WARNING, m0, ": ", &strerr_sys); }
+void warn2(char *m0, char *m1) {
+  strerr_warn5(WARNING, m0, ": ", m1, ": ", &strerr_sys);
+}
+void warnx(char *m0, char *m1) { strerr_warn4(WARNING, m0, ": ", m1, 0); }
+void pause_nomem() { strerr_warn2(PAUSE, "out of memory.", 0); sleep(3); }
+void pause1(char *m0) { strerr_warn3(PAUSE, m0, ": ", &strerr_sys); sleep(3); }
+void pause2(char *m0, char *m1) {
+  strerr_warn5(PAUSE, m0, ": ", m1, ": ", &strerr_sys);
+  sleep(3);
+}
+
+unsigned int processorstart(struct logdir *ld) {
+  int pid;
+
+  if (! ld->processor.len) return(0);
+  if (ld->ppid) {
+    warnx("processor already running", ld->name);
+    return(0);
+  }
+  while ((pid =fork()) == -1)
+    pause2("unable to fork for processor", ld->name);
+  if (! pid) {
+    char *prog[4];
+    int fd;
+
+    /* child */
+    sig_uncatch(sig_term);
+    sig_uncatch(sig_alarm);
+    sig_uncatch(sig_hangup);
+    sig_unblock(sig_term);
+    sig_unblock(sig_alarm);
+    sig_unblock(sig_hangup);
+    
+    if (verbose)
+      strerr_warn5(INFO, "processing: ", ld->name, "/", ld->fnsave, 0);
+    if ((fd =open_read(ld->fnsave)) == -1)
+      fatal2("unable to open input for processor", ld->name);
+    if (fd_move(0, fd) == -1)
+      fatal2("unable to move filedescriptor for processor", ld->name);
+    ld->fnsave[26] ='t';
+    if ((fd =open_trunc(ld->fnsave)) == -1)
+      fatal2("unable to open output for processor", ld->name);
+    if (fd_move(1, fd) == -1)
+      fatal2("unable to move filedescriptor for processor", ld->name);
+    if ((fd =open_read("state")) == -1) {
+      if (errno == error_noent) {
+        if ((fd =open_trunc("state")) == -1)
+          fatal2("unable to create empty state for processor", ld->name);
+        close(fd);
+        if ((fd =open_read("state")) == -1)
+          fatal2("unable to open state for processor", ld->name);
+      }
+      else
+        fatal2("unable to open state for processor", ld->name);
+    }
+    if (fd_move(4, fd) == -1)
+      fatal2("unable to move filedescriptor for processor", ld->name);
+    if ((fd =open_trunc("newstate")) == -1)
+      fatal2("unable to open newstate for processor", ld->name);
+    if (fd_move(5, fd) == -1)
+      fatal2("unable to move filedescriptor for processor", ld->name);
+
+    prog[0] = "sh";
+    prog[1] = "-c";
+    prog[2] = ld->processor.s;
+    prog[3] = 0;
+    execve("/bin/sh", prog, environ);
+    fatal2("unable to run processor", ld->name);
+  }
+  ld->ppid =pid;
+  return(1);
+}
+unsigned int processorstop(struct logdir *ld) {
+  char f[28];
+
+  if (ld->ppid) {
+    sig_unblock(sig_hangup);
+    while (wait_pid(&wstat, ld->ppid) == -1)
+      pause2("error waiting for processor", ld->name);
+    sig_block(sig_hangup);
+    ld->ppid =0;
+  }
+  if (ld->fddir == -1) return(1);
+  while (fchdir(ld->fddir) == -1)
+    pause2("unable to change directory, want processor", ld->name);
+  if (wait_exitcode(wstat) != 0) {
+    warnx("processor failed, restart", ld->name);
+    ld->fnsave[26] ='t';
+    unlink(ld->fnsave);
+    ld->fnsave[26] ='u';
+    processorstart(ld);
+    while (fchdir(fdwdir) == -1)
+      pause1("unable to change to initial working directory");
+    return(ld->processor.len ? 0 : 1);
+  }
+  ld->fnsave[26] ='t';
+  byte_copy(f, 26, ld->fnsave);
+  f[26] ='s'; f[27] =0;
+  while (rename(ld->fnsave, f) == -1)
+    pause2("unable to rename processed", ld->name);
+  while (chmod(f, 0744) == -1)
+    pause2("unable to set mode of processed", ld->name);
+  ld->fnsave[26] ='u';
+  if (unlink(ld->fnsave) == -1)
+    strerr_warn5(WARNING, "unable to unlink: ", ld->name, "/", ld->fnsave, 0);
+  while (rename("newstate", "state") == -1)
+    pause2("unable to rename state", ld->name);
+  if (verbose) strerr_warn5(INFO, "processed: ", ld->name, "/", f, 0);
+  while (fchdir(fdwdir) == -1)
+    pause1("unable to change to initial working directory");
+  return(1);
+}
+
+void rmoldest(struct logdir *ld) {
+  DIR *d;
+  direntry *f;
+  char oldest[FMT_PTIME];
+  int n =0;
+
+  oldest[0] ='A'; oldest[1] =oldest[27] =0;
+  while (! (d =opendir(".")))
+    pause2("unable to open directory, want rotate", ld->name);
+  errno =0;
+  while ((f =readdir(d)))
+    if ((f->d_name[0] == '@') && (str_len(f->d_name) == 27)) {
+      if (f->d_name[26] == 't') {
+        if (unlink(f->d_name) == -1)
+          warn2("unable to unlink processor leftover", f->d_name);
+      }
+      else {
+        ++n;
+        if (str_diff(f->d_name, oldest) < 0) byte_copy(oldest, 27, f->d_name);
+      }
+      errno =0;
+    }
+  if (errno) warn2("unable to read directory", ld->name);
+  closedir(d);
+
+  if (ld->nmax && (n > ld->nmax)) {
+    if (verbose) strerr_warn5(INFO, "delete: ", ld->name, "/", oldest, 0);
+    if ((*oldest == '@') && (unlink(oldest) == -1))
+      warn2("unable to unlink oldest logfile", ld->name);
+  }
+}
+
+unsigned int rotate(struct logdir *ld) {
+  char tmp[FMT_ULONG +1];
+
+  if (ld->fddir == -1) { ld->tmax =0; return(0); }
+  if (ld->ppid) while(! processorstop(ld));
+
+  while (fchdir(ld->fddir) == -1)
+    pause2("unable to change directory, want rotate", ld->name);
+
+  /* create new filename */
+  ld->fnsave[25] ='.';
+  if (ld->processor.len)
+    ld->fnsave[26] ='u';
+  else
+    ld->fnsave[26] ='s';
+  ld->fnsave[27] =0;
+  do {
+    taia_now(&now);
+    fmt_taia(ld->fnsave, &now);
+    errno =0;
+  } while ((stat(ld->fnsave, &st) != -1) || (errno != error_noent));
+
+  if (ld->tmax && taia_less(&ld->trotate, &now)) {
+    taia_uint(&ld->trotate, ld->tmax);
+    taia_add(&ld->trotate, &now, &ld->trotate);
+    if (taia_less(&ld->trotate, &trotate)) trotate =ld->trotate;
+  }
+
+  if (ld->size > 0) {
+    buffer_flush(&ld->b);
+    while (fsync(ld->fdcur) == -1)
+      pause2("unable to fsync current logfile", ld->name);
+    while (fchmod(ld->fdcur, 0744) == -1)
+      pause2("unable to set mode of current", ld->name);
+    close(ld->fdcur);
+    if (verbose) {
+      tmp[0] =' '; tmp[fmt_ulong(tmp +1, ld->size) +1] =0;
+      strerr_warn6(INFO, "rename: ", ld->name, "/current ",
+                   ld->fnsave, tmp, 0);
+    }
+    while (rename("current", ld->fnsave) == -1)
+      pause2("unable to rename current", ld->name);
+    while ((ld->fdcur =open_append("current")) == -1)
+      pause2("unable to create new current", ld->name);
+    coe(ld->fdcur);
+    ld->size =0;
+    while (fchmod(ld->fdcur, 0644) == -1)
+      pause2("unable to set mode of current", ld->name);
+    rmoldest(ld);
+    processorstart(ld);
+  }
+
+  while (fchdir(fdwdir) == -1)
+    pause1("unable to change to initial working directory");
+  return(1);
+}
+
+int buffer_pwrite(int n, char *s, unsigned int len) {
+  int i;
+
+  if ((dir +n)->sizemax) {
+    if ((dir +n)->size >= (dir +n)->sizemax) rotate(dir +n);
+    if (len > ((dir +n)->sizemax -(dir +n)->size))
+      len =(dir +n)->sizemax -(dir +n)->size;
+  }
+  while ((i =write((dir +n)->fdcur, s, len)) == -1) {
+    if ((errno == ENOSPC) && ((dir +n)->nmin < (dir +n)->nmax)) {
+      DIR *d;
+      direntry *f;
+      char oldest[FMT_PTIME];
+      int j =0;
+
+      while (fchdir((dir +n)->fddir) == -1)
+        pause2("unable to change directory, want remove old logfile",
+               (dir +n)->name);
+      oldest[0] ='A'; oldest[1] =oldest[27] =0;
+      while (! (d =opendir(".")))
+        pause2("unable to open directory, want remove old logfile",
+               (dir +n)->name);
+      errno =0;
+      while ((f =readdir(d)))
+        if ((f->d_name[0] == '@') && (str_len(f->d_name) == 27)) {
+          ++j;
+          if (str_diff(f->d_name, oldest) < 0)
+            byte_copy(oldest, 27, f->d_name);
+        }
+      if (errno) warn2("unable to read directory, want remove old logfile",
+                       (dir +n)->name);
+      closedir(d);
+      errno =ENOSPC;
+      if (j > (dir +n)->nmin)
+        if (*oldest == '@') {
+          strerr_warn5(WARNING, "out of disk space, delete: ", (dir +n)->name,
+                       "/", oldest, 0);
+          errno =0;
+          if (unlink(oldest) == -1) {
+            warn2("unable to unlink oldest logfile", (dir +n)->name);
+            errno =ENOSPC;
+          }
+          while (fchdir(fdwdir) == -1)
+            pause1("unable to change to initial working directory");
+        }
+    }
+    if (errno) pause2("unable to write to current", (dir +n)->name);
+  }
+
+  (dir +n)->size +=i;
+  if ((dir +n)->sizemax)
+    if (s[i -1] == '\n')
+      if ((dir +n)->size >= ((dir +n)->sizemax -linemax)) rotate(dir +n);
+  return(i);
+}
+
+void logdir_close(struct logdir *ld) {
+  if (ld->fddir == -1) return;
+  if (verbose) strerr_warn3(INFO, "close: ", ld->name, 0);
+  close(ld->fddir);
+  ld->fddir =-1;
+  if (ld->fdcur == -1) return; /* impossible */
+  buffer_flush(&ld->b);
+  while (fsync(ld->fdcur) == -1)
+    pause2("unable to fsync current logfile", ld->name);
+  while (fchmod(ld->fdcur, 0744) == -1)
+    pause2("unable to set mode of current", ld->name);
+  close(ld->fdcur);
+  ld->fdcur =-1;
+  if (ld->fdlock == -1) return; /* impossible */
+  close(ld->fdlock);
+  ld->fdlock =-1;
+  while (! stralloc_copys(&ld->processor, "")) pause_nomem();
+}
+
+/* taken from libdjbdns */
+unsigned int ip4_scan(const char *s,char ip[4])
+{
+  unsigned int i;
+  unsigned int len;
+  unsigned long u;
+ 
+  len = 0;
+  i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i;
+  if (*s != '.') return 0; ++s; ++len;
+  i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i;
+  if (*s != '.') return 0; ++s; ++len;
+  i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i;
+  if (*s != '.') return 0; ++s; ++len;
+  i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i;
+  return len;
+}
+
+unsigned int logdir_open(struct logdir *ld, const char *fn) {
+  int i;
+
+  if ((ld->fddir =open_read(fn)) == -1) {
+    warn2("unable to open log directory", (char*)fn);
+    return(0);
+  }
+  coe(ld->fddir);
+  if (fchdir(ld->fddir) == -1) {
+    logdir_close(ld);
+    warn2("unable to change directory", (char*)fn);
+    return(0);
+  }
+  ld->fdlock =open_append("lock");
+  if ((ld->fdlock == -1) || (lock_exnb(ld->fdlock) == -1)) {
+    logdir_close(ld);
+    warn2("unable to lock directory", (char*)fn);
+    while (fchdir(fdwdir) == -1)
+      pause1("unable to change to initial working directory");
+    return(0);
+  }
+  coe(ld->fdlock);
+
+  ld->size =0;
+  ld->sizemax =1000000;
+  ld->nmax =ld->nmin =10;
+  ld->tmax =0;
+  ld->name =(char*)fn;
+  ld->ppid =0;
+  ld->match ='+';
+  ld->udpaddr.sin_port =0;
+  ld->udponly =0;
+  while (! stralloc_copys(&ld->prefix, "")) pause_nomem();
+  while (! stralloc_copys(&ld->inst, "")) pause_nomem();
+  while (! stralloc_copys(&ld->processor, "")) pause_nomem();
+
+  /* read config */
+  if ((i =openreadclose("config", &sa, 128)) == -1)
+    warn2("unable to read config", ld->name);
+  if (i != 0) {
+    int len, c;
+    unsigned long port;
+
+    if (verbose) strerr_warn4(INFO, "read: ", ld->name, "/config", 0);
+    for (i =0; i +1 < sa.len; ++i) {
+      len =byte_chr(&sa.s[i], sa.len -i, '\n');
+      sa.s[len +i] =0;
+      switch(sa.s[i]) {
+      case '\n':
+      case '#':
+         break;
+      case '+':
+      case '-':
+      case 'e':
+      case 'E':
+        while (! stralloc_catb(&ld->inst, &sa.s[i], len)) pause_nomem();
+        while (! stralloc_0(&ld->inst)) pause_nomem();
+        break;
+      case 's':
+        switch (sa.s[scan_ulong(&sa.s[i +1], &ld->sizemax) +i +1]) {
+        case 'm': ld->sizemax *=1024;
+        case 'k': ld->sizemax *=1024;
+        }
+        break;
+      case 'n':
+        scan_ulong(&sa.s[i +1], &ld->nmax);
+        break;
+      case 'N':
+        scan_ulong(&sa.s[i +1], &ld->nmin);
+        break;
+      case 't':
+        switch (sa.s[scan_ulong(&sa.s[i +1], &ld->tmax) +i +1]) {
+        /* case 'd': ld->tmax *=24; */
+        case 'h': ld->tmax *=60;
+        case 'm': ld->tmax *=60;
+        }
+        if (ld->tmax) {
+          taia_uint(&ld->trotate, ld->tmax);
+          taia_add(&ld->trotate, &now, &ld->trotate);
+          if (! tmaxflag || taia_less(&ld->trotate, &trotate))
+            trotate =ld->trotate;
+          tmaxflag =1;
+        }
+        break;
+      case '!':
+        if (len > 1) {
+          while (! stralloc_copys(&ld->processor, &sa.s[i +1])) pause_nomem();
+          while (! stralloc_0(&ld->processor)) pause_nomem();
+        }
+        break;
+      case 'U':
+        ld->udponly =1;
+      case 'u':
+        if (! (c =ip4_scan(sa.s +i +1, (char *)&ld->udpaddr.sin_addr))) {
+          warnx("unable to scan ip address", sa.s +i +1);
+          break;
+        }
+        if (sa.s[i +1 +c] == ':') {
+          scan_ulong(sa.s +i +c +2, &port);
+          if (port == 0) {
+            warnx("unable to scan port number", sa.s +i +c +2);
+            break;
+          }
+        }
+        else
+          port =514;
+        ld->udpaddr.sin_port =htons(port);
+        break;
+      case 'p':
+        if (len > 1) {
+          while (! stralloc_copys(&ld->prefix, &sa.s[i +1])) pause_nomem();
+          while (! stralloc_0(&ld->prefix)) pause_nomem();
+        }
+        break;
+      }
+      i +=len;
+    }
+  }
+
+  /* open current */
+  if ((i =stat("current", &st)) != -1) {
+    if (st.st_size && ! (st.st_mode & S_IXUSR)) {
+      ld->fnsave[25] ='.'; ld->fnsave[26] ='u'; ld->fnsave[27] =0;
+      do {
+        taia_now(&now);
+        fmt_taia(ld->fnsave, &now);
+        errno =0;
+      } while ((stat(ld->fnsave, &st) != -1) || (errno != error_noent));
+      while (rename("current", ld->fnsave) == -1)
+        pause2("unable to rename current", ld->name);
+      rmoldest(ld);
+      i =-1;
+    }
+    else
+      ld->size =st.st_size;
+  }
+  else
+    if (errno != error_noent) {
+      logdir_close(ld);
+      warn2("unable to stat current", ld->name);
+      while (fchdir(fdwdir) == -1)
+        pause1("unable to change to initial working directory");
+      return(0);
+    }
+  while ((ld->fdcur =open_append("current")) == -1)
+    pause2("unable to open current", ld->name);
+  coe(ld->fdcur);
+  while (fchmod(ld->fdcur, 0644) == -1)
+    pause2("unable to set mode of current", ld->name);
+  buffer_init(&ld->b, buffer_pwrite, ld -dir, ld->btmp, buflen);
+  
+  if (verbose) {
+    if (i == 0) strerr_warn4(INFO, "append: ", ld->name, "/current", 0);
+    else strerr_warn4(INFO, "new: ", ld->name, "/current", 0);
+  }
+  
+  while (fchdir(fdwdir) == -1)
+    pause1("unable to change to initial working directory");
+  return(1);
+}
+
+void logdirs_reopen(void) {
+  int l;
+  int ok =0;
+
+  tmaxflag =0;
+  taia_now(&now);
+  for (l =0; l < dirn; ++l) {
+    logdir_close(&dir[l]);    
+    if (logdir_open(&dir[l], fndir[l])) ok =1;
+  }
+  if (! ok) fatalx("no functional log directories.");
+}
+
+int buffer_pread(int fd, char *s, unsigned int len) {
+  int i;
+
+  for (i =0; i < dirn; ++i) buffer_flush(&dir[i].b);
+  if (rotateasap) {
+    for (i =0; i < dirn; ++i) rotate(dir +i);
+    rotateasap =0;
+  }
+  if (exitasap) {
+    if (linecomplete) return(0);
+    len =1;
+  }
+  if (reopenasap) {
+    logdirs_reopen();
+    reopenasap =0;
+  }
+  taia_now(&now);
+  taia_uint(&trotate, 2744);
+  taia_add(&trotate, &now, &trotate);
+  for (i =0; i < dirn; ++i)
+    if ((dir +i)->tmax) {
+      if (taia_less(&dir[i].trotate, &now)) rotate(dir +i);
+      if (taia_less(&dir[i].trotate, &trotate)) trotate =dir[i].trotate;
+    }
+  sig_unblock(sig_term);
+  sig_unblock(sig_child);
+  sig_unblock(sig_alarm);
+  sig_unblock(sig_hangup);
+  iopause(&in, 1, &trotate, &now);
+  sig_block(sig_term);
+  sig_block(sig_child);
+  sig_block(sig_alarm);
+  sig_block(sig_hangup);
+  i =read(fd, s, len);
+  if (i == -1) {
+    if (errno == error_again) errno =error_intr;
+    if (errno != error_intr) warn("unable to read standard input");
+  }
+  if (i > 0) linecomplete =(s[i -1] == '\n');
+  return(i);
+}
+void sig_term_handler(void) {
+  if (verbose) strerr_warn2(INFO, "sigterm received.", 0);
+  exitasap =1;
+}
+void sig_child_handler(void) {
+  int pid, l;
+
+  if (verbose) strerr_warn2(INFO, "sigchild received.", 0);
+  while ((pid =wait_nohang(&wstat)) > 0)
+    for (l =0; l < dirn; ++l)
+      if (dir[l].ppid == pid) {
+        dir[l].ppid =0;
+        processorstop(&dir[l]);
+        break;
+      }
+}
+void sig_alarm_handler(void) {
+  if (verbose) strerr_warn2(INFO, "sigalarm received.", 0);
+  rotateasap =1;
+}
+void sig_hangup_handler(void) {
+  if (verbose) strerr_warn2(INFO, "sighangup received.", 0);
+  reopenasap =1;
+}
+
+void logmatch(struct logdir *ld) {
+  int i;
+
+  ld->match ='+';
+  ld->matcherr ='E';
+  for (i =0; i < ld->inst.len; ++i) {
+    switch(ld->inst.s[i]) {
+    case '+':
+    case '-':
+      if (pmatch(&ld->inst.s[i +1], line, linelen))
+        ld->match =ld->inst.s[i];
+      break;
+    case 'e':
+    case 'E':
+      if (pmatch(&ld->inst.s[i +1], line, linelen))
+        ld->matcherr =ld->inst.s[i];
+      break;
+    }
+    i +=byte_chr(&ld->inst.s[i], ld->inst.len -i, 0);
+  }
+}
+int main(int argc, const char **argv) {
+  int i;
+  int opt;
+
+  progname =*argv;
+
+  while ((opt =getopt(argc, argv, "R:r:l:b:tvV")) != opteof) {
+    switch(opt) {
+    case 'R':
+      replace =optarg;
+      if (! repl) repl ='_';
+      break;
+    case 'r':
+      repl =*optarg;
+      if (! repl || *(optarg +1)) usage();
+      break;
+    case 'l':
+      scan_ulong(optarg, &linemax);
+      if (linemax == 0) linemax =1000;
+      break;
+    case 'b':
+      scan_ulong(optarg, &buflen);
+      if (buflen == 0) buflen =1024;
+      break;
+    case 't':
+      if (++timestamp > 3) timestamp =3;
+      break;
+    case 'v':
+      ++verbose;
+      break;
+    case 'V': strerr_warn1(VERSION, 0);
+    case '?': usage();
+    }
+  }
+  argv +=optind;
+
+  dirn =argc -optind;
+  if (dirn <= 0) usage();
+  if (buflen <= linemax) usage();
+  if ((fdwdir =open_read(".")) == -1)
+    fatal("unable to open current working directory");
+  coe(fdwdir);
+  dir =(struct logdir*)alloc(dirn *sizeof(struct logdir));
+  if (! dir) die_nomem();
+  for (i =0; i < dirn; ++i) {
+    dir[i].fddir =-1; dir[i].fdcur =-1;
+    dir[i].btmp =(char*)alloc(buflen *sizeof(char));
+    if (! dir[i].btmp) die_nomem();
+    dir[i].ppid =0;
+  }
+  databuf =(char*)alloc(buflen *sizeof(char));
+  if (! databuf) die_nomem();
+  buffer_init(&data, buffer_pread, 0, databuf, buflen);
+  line =(char*)alloc(linemax *sizeof(char));
+  if (! line) die_nomem();
+  fndir =argv;
+  in.fd =0;
+  in.events =IOPAUSE_READ;
+  ndelay_on(in.fd);
+
+  sig_block(sig_term);
+  sig_block(sig_child);
+  sig_block(sig_alarm);
+  sig_block(sig_hangup);
+  sig_catch(sig_term, sig_term_handler);
+  sig_catch(sig_child, sig_child_handler);
+  sig_catch(sig_alarm, sig_alarm_handler);
+  sig_catch(sig_hangup, sig_hangup_handler);
+
+  logdirs_reopen();
+
+  for(;;) {
+    char ch;
+
+    linelen =0;
+    for (linelen =0; linelen < linemax; ++linelen) {
+      if (buffer_GETC(&data, &ch) <= 0) {
+        exitasap =1;
+        break;
+      }
+      if (! linelen && timestamp) {
+        taia_now(&now);
+        switch (timestamp) {
+        case 1: fmt_taia(stamp, &now); break;
+        case 2: fmt_ptime(stamp, &now); break;
+        case 3: fmt_ptime_iso8601(stamp, &now); break;
+        }
+        stamp[25] =' '; stamp[26] =0;
+      }
+      if (ch == '\n') break;
+      if (repl) {
+        if ((ch < 32) || (ch > 126))
+          ch =repl;
+        else
+          for (i =0; replace[i]; ++i)
+            if (ch == replace[i]) {
+              ch =repl;
+              break;
+            }
+      }
+      line[linelen] =ch;
+    }
+    if (exitasap && ! data.p) break; /* data buffer is empty */
+    for (i =0; i < dirn; ++i)
+      if (dir[i].fddir != -1) {
+        if (dir[i].inst.len) logmatch(&dir[i]);
+        if (dir[i].matcherr == 'e') {
+          if (timestamp) buffer_puts(buffer_2, stamp);
+          if (dir[i].prefix.len) buffer_puts(buffer_2, dir[i].prefix.s);
+          buffer_put(buffer_2, line, linelen);
+          if (linelen == linemax) buffer_puts(buffer_2, "...");
+          buffer_put(buffer_2, "\n", 1); buffer_flush(buffer_2);
+        }
+        if (dir[i].match != '+') continue;
+        if (dir[i].udpaddr.sin_port != 0) {
+          fdudp =socket(AF_INET, SOCK_DGRAM, 0);
+          if (fdudp)
+            if (ndelay_on(fdudp) == -1) {
+              close(fdudp);
+              fdudp =-1;
+            }
+          if (fdudp == -1) {
+            buffer_puts(&dir[i].b, "warning: no udp socket available: ");
+            if (timestamp) buffer_puts(&dir[i].b, stamp);
+            if (dir[i].prefix.len) buffer_puts(&dir[i].b, dir[i].prefix.s);
+            buffer_put(&dir[i].b, line, linelen);
+            buffer_put(&dir[i].b, "\n", 1);
+            buffer_flush(&dir[i].b);
+          }
+          else {
+            while (! stralloc_copys(&sa, "")) pause_nomem();
+            if (timestamp)
+              while (! stralloc_cats(&sa, stamp)) pause_nomem();
+            if (dir[i].prefix.len)
+              while (! stralloc_cats(&sa, dir[i].prefix.s)) pause_nomem();
+            while (! stralloc_catb(&sa, line, linelen)) pause_nomem();
+            if (linelen == linemax)
+              while (! stralloc_cats(&sa, "...")) pause_nomem();
+            while (! stralloc_append(&sa, "\n")) pause_nomem();
+            if (sendto(fdudp, sa.s, sa.len, 0,
+                       (struct sockaddr *)&dir[i].udpaddr,
+                       sizeof(dir[i].udpaddr)) != sa.len) {
+              buffer_puts(&dir[i].b, "warning: failure sending through udp: ");
+              buffer_put(&dir[i].b, sa.s, sa.len);
+              buffer_flush(&dir[i].b);
+            }
+            close(fdudp);
+          }
+        }
+        if (! dir[i].udponly) {
+          if (timestamp) buffer_puts(&dir[i].b, stamp);
+          if (dir[i].prefix.len) buffer_puts(&dir[i].b, dir[i].prefix.s);
+          buffer_put(&dir[i].b, line, linelen);
+        }
+      }
+    if (linelen == linemax)
+      for (;;) {
+        if (buffer_GETC(&data, &ch) <= 0) {
+          exitasap =1;
+          break;
+        }
+        if (ch == '\n') break;
+        for (i =0; i < dirn; ++i)
+          if (dir[i].fddir != -1) {
+            if (dir[i].match != '+') continue;
+            if (! dir[i].udponly) buffer_PUTC(&dir[i].b, ch);
+          }
+      }
+    for (i =0; i < dirn; ++i)
+      if (dir[i].fddir != -1) {
+        if (dir[i].match != '+') continue;
+        if (! dir[i].udponly) {
+          ch ='\n';
+          buffer_PUTC(&dir[i].b, ch);
+          buffer_flush(&dir[i].b);
+        }
+      }
+  }
+  
+  for (i =0; i < dirn; ++i) {
+    if (dir[i].ppid) while (! processorstop(&dir[i]));
+    logdir_close(&dir[i]);
+  }
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/svlogd.check b/runit-2.1.2/src/svlogd.check
new file mode 100755
index 0000000..7d926ef
--- /dev/null
+++ b/runit-2.1.2/src/svlogd.check
@@ -0,0 +1,27 @@
+#!/bin/sh
+rm -rf "${ctmp}"
+
+svlogd
+echo $?
+svlogd -V
+echo $?
+
+mkdir "${ctmp}"
+echo foo |svlogd "${ctmp}"
+echo $?
+cat "${ctmp}"/current
+
+( echo bar; echo baz ) |svlogd "${ctmp}"
+echo $?
+cat "${ctmp}"/current
+
+( echo foo; echo bar; echo baz ) |svlogd -r: -R fb "${ctmp}"
+echo $?
+cat "${ctmp}"/current
+
+echo t2 >"${ctmp}"/config
+( echo foo; sleep 3 ) |svlogd "${ctmp}"
+echo $?
+cat "${ctmp}"/current
+
+rm -rf "${ctmp}"
diff --git a/runit-2.1.2/src/svlogd.dist b/runit-2.1.2/src/svlogd.dist
new file mode 100644
index 0000000..b3329e6
--- /dev/null
+++ b/runit-2.1.2/src/svlogd.dist
@@ -0,0 +1,21 @@
+usage: svlogd [-ttv] [-r c] [-R abc] [-l len] [-b buflen] dir ...
+
+111
+$Id: 5e55a90e0a1b35ec47fed3021453c50675ea1117 $
+usage: svlogd [-ttv] [-r c] [-R abc] [-l len] [-b buflen] dir ...
+
+111
+0
+foo
+0
+foo
+bar
+baz
+0
+foo
+bar
+baz
+:oo
+:ar
+:az
+0
diff --git a/runit-2.1.2/src/svwaitdown.c b/runit-2.1.2/src/svwaitdown.c
new file mode 100644
index 0000000..21a2c2c
--- /dev/null
+++ b/runit-2.1.2/src/svwaitdown.c
@@ -0,0 +1,177 @@
+#include <unistd.h>
+#include "strerr.h"
+#include "error.h"
+#include "sgetopt.h"
+#include "scan.h"
+#include "open.h"
+#include "tai.h"
+#include "buffer.h"
+
+#define FATAL "svwaitdown: fatal: "
+#define WARN "svwaitdown: warning: "
+#define INFO "svwaitdown: "
+#define USAGE " [-v] [-t 1..6000] service ..."
+
+#define VERSION "$Id: 6cd3efc2e15e5e3d2fa60cd0c028e60958676ec7 $"
+
+const char *progname;
+const char * const *dir;
+unsigned int rc =0;
+
+void fatal(const char *m) { strerr_die3sys(111, FATAL, m, ": "); }
+void warn(const char *s1, const char *s2, struct strerr *e) {
+  dir++; rc++;
+  strerr_warn3(WARN, s1, s2, e);
+}
+void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+
+int main(int argc, const char * const *argv) {
+  int opt;
+  unsigned long sec =600;
+  int verbose =0;
+  int doexit =0;
+  int dokill =0;
+  int wdir;
+  int fd;
+  char status[20];
+  int r;
+  unsigned long pid;
+  struct tai start;
+  struct tai now;
+  
+  progname =*argv;
+  
+  while ((opt =getopt(argc, argv, "t:xkvV")) != opteof) {
+    switch(opt) {
+    case 't':
+      scan_ulong(optarg, &sec);
+      if ((sec < 1) || (sec > 6000)) usage();
+      break;
+    case 'x':
+      doexit =1;
+      break;
+    case 'k':
+      dokill =1;
+      break;
+    case 'v':
+      verbose =1;
+      break;
+    case 'V':
+      strerr_warn1(VERSION, 0);
+    case '?':
+      usage();
+    }
+  }
+  argv +=optind;
+  if (! argv || ! *argv) usage();
+
+  if ((wdir =open_read(".")) == -1)
+    fatal("unable to open current working directory");
+
+  for (dir =argv; *dir; ++dir) {
+    if (dir != argv)
+      if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
+    if (chdir(*dir) == -1) continue; /* bummer */
+    if ((fd =open_write("supervise/control")) == -1) continue; /* bummer */
+    if (write(fd, "dx", 1 +doexit) != (1 +doexit)) {
+      close(fd); continue; /* bummer */
+    }
+    close(fd);
+  }
+  dir =argv;
+
+  tai_now(&start);
+  while (*dir) {
+    if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
+    if (chdir(*dir) == -1) {
+      warn(*dir, ": unable to change directory: ", &strerr_sys);
+      continue;
+    }
+    if ((fd =open_write("supervise/ok")) == -1) {
+      if (errno == error_nodevice) {
+        if (verbose) strerr_warn3(INFO, *dir, ": runsv not running.", 0);
+        dir++;
+      }
+      else
+        warn(*dir, ": unable to open supervise/ok: ", &strerr_sys);
+      continue;
+    }
+    close(fd);
+
+    if ((fd =open_read("supervise/status")) == -1) {
+      warn(*dir, "unable to open supervise/status: ", &strerr_sys);
+      continue;
+    }
+    r =buffer_unixread(fd, status, 20);
+    close(fd);
+    if ((r < 18) || (r == 19)) { /* supervise compatibility */
+      if (r == -1)
+        warn(*dir, "unable to read supervise/status: ", &strerr_sys);
+      else
+        warn(*dir, ": unable to read supervise/status: bad format.", 0);
+      continue;
+    }
+    pid =(unsigned char)status[15];
+    pid <<=8; pid +=(unsigned char)status[14];
+    pid <<=8; pid +=(unsigned char)status[13];
+    pid <<=8; pid +=(unsigned char)status[12];
+
+    if (! doexit && ! pid) {
+      /* ok, service is down */
+      if (verbose) strerr_warn3(INFO, *dir, ": down.", 0);
+      dir++;
+      continue;
+    }
+
+    if (status[17] != 'd') { /* catch previous failures */
+      if ((fd =open_write("supervise/control")) == -1) {
+        warn(*dir, ": unable to open supervise/control: ", &strerr_sys);
+        continue;
+      }
+      if (write(fd, "dx", 1 +doexit) != (1 +doexit)) {
+        warn(*dir, ": unable to write to supervise/control: ", &strerr_sys);
+        close(fd);
+        continue;
+      }
+      close(fd);
+    }
+  
+    tai_now(&now);
+    tai_sub(&now, &now, &start);
+    if (tai_approx(&now) >= sec) {
+      /* timeout */
+      if (verbose) strerr_warn2(INFO, "timeout.", 0);
+      if (dokill) {
+        if (chdir(*dir) == -1) {
+          warn(*dir, ": unable to change directory: ", &strerr_sys);
+          continue;
+        }
+        if ((fd =open_write("supervise/control")) == -1) {
+          if (errno == error_nodevice) {
+            if (verbose)
+              strerr_warn3(INFO, *dir, ": runsv not running.", 0);
+            dir++;
+          }
+          else
+            warn(*argv, ": unable to open supervise/control: ", &strerr_sys);
+          continue;
+        }
+        if (write(fd, "k", 1) != 1)
+          warn(*argv, ": unable to write to supervise/control: ", &strerr_sys);
+        else
+          strerr_warn3(INFO, *dir, ": killed.", 0);
+        close(fd);
+        dir++;
+        if (! *dir) _exit(111);
+        continue;
+      }
+      _exit(111);
+    }
+    sleep(1);
+  }
+  if (fchdir(wdir) == -1) 
+    strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys);
+  close(wdir);
+  if (rc > 100) rc =100;
+  _exit(rc);
+}
diff --git a/runit-2.1.2/src/svwaitdown.check b/runit-2.1.2/src/svwaitdown.check
new file mode 100755
index 0000000..5cf6c21
--- /dev/null
+++ b/runit-2.1.2/src/svwaitdown.check
@@ -0,0 +1,24 @@
+#!/bin/sh
+rm -rf "${ctmp}"
+
+svwaitdown
+echo $?
+svwaitdown -V
+echo $?
+
+mkdir "${ctmp}"
+echo '#!/bin/sh' >"${ctmp}"/run
+echo 'echo starting' >>"${ctmp}"/run
+echo 'exec sleep 14' >>"${ctmp}"/run
+chmod 700 "${ctmp}"/run
+runsv "${ctmp}" &
+sleep 1
+test -r "${ctmp}"/supervise/stat || sleep 2
+svwaitdown "${ctmp}"
+echo $?
+svwaitdown -x "${ctmp}"
+echo $?
+cat "${ctmp}"/supervise/stat
+wait
+echo $?
+rm -rf "${ctmp}"
diff --git a/runit-2.1.2/src/svwaitdown.dist b/runit-2.1.2/src/svwaitdown.dist
new file mode 100644
index 0000000..2d83839
--- /dev/null
+++ b/runit-2.1.2/src/svwaitdown.dist
@@ -0,0 +1,12 @@
+usage: svwaitdown [-v] [-t 1..6000] service ...
+
+1
+$Id$
+usage: svwaitdown [-v] [-t 1..6000] service ...
+
+1
+starting
+0
+0
+down
+0
diff --git a/runit-2.1.2/src/svwaitup.c b/runit-2.1.2/src/svwaitup.c
new file mode 100644
index 0000000..e682bbe
--- /dev/null
+++ b/runit-2.1.2/src/svwaitup.c
@@ -0,0 +1,126 @@
+#include <unistd.h>
+#include "strerr.h"
+#include "error.h"
+#include "sgetopt.h"
+#include "scan.h"
+#include "open.h"
+#include "tai.h"
+#include "buffer.h"
+#include "fmt.h"
+
+#define FATAL "svwaitup: fatal: "
+#define WARN "svwaitup: warning: "
+#define INFO "svwaitup: "
+#define USAGE " [-v] [-s 1..600] service ..."
+
+const char *progname;
+unsigned long sec =2;
+unsigned int rc =0;
+const char * const *dir;
+
+void fatal(const char *m) { strerr_die3sys(111, FATAL, m, ": "); }
+void warn(const char *s1, const char *s2, struct strerr *e) {
+  dir++; rc++;
+  strerr_warn3(WARN, s1, s2, e);
+}
+void usage() { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+
+int main(int argc, const char * const *argv) {
+  int opt;
+  int verbose =0;
+  char status[18];
+  int fd;
+  int is;
+  int r;
+  int wdir;
+  unsigned long pid;
+  struct tai when;
+  struct tai now;
+  char sulong[FMT_ULONG];
+
+  progname =*argv;
+  
+  while ((opt =getopt(argc, argv, "s:vV")) != opteof) {
+    switch(opt) {
+    case 's': 
+      scan_ulong(optarg, &sec);
+      if ((sec < 1) || (sec > 600)) usage();
+      break;
+    case 'v':
+      verbose =1;
+      break;
+    case 'V':
+      strerr_warn1("$Id: e2d6c574c5e56f9931323fbc0e539c7f9b829b73 $", 0);
+    case '?':
+      usage();
+    }
+  }
+  argv +=optind;
+  if (! argv || ! *argv) usage();
+
+  if ((wdir =open_read(".")) == -1)
+    fatal("unable to open current working directory");
+
+  dir =argv;
+  while (*dir) {
+    if (dir != argv)
+      if (fchdir(wdir) == -1) fatal("unable to switch to starting directory");
+    if (chdir(*dir) == -1) {
+      warn(*dir, ": unable to change directory: ", &strerr_sys);
+      continue;
+    }
+    if ((fd =open_write("supervise/ok")) == -1) {
+      if (errno == error_nodevice)
+        warn(*dir, ": runsv not running.", 0);
+      else
+        warn(*dir, ": unable to open supervise/ok: ", &strerr_sys);
+      continue;
+    }
+    close(fd);
+    
+    if ((fd =open_read("supervise/status")) == -1) {
+      warn(*dir, "unable to open supervise/status: ", &strerr_sys);
+      continue;
+    }
+    r =buffer_unixread(fd, status, sizeof status);
+    close(fd);
+    if (r < sizeof status) {
+      if (r == -1)
+        warn(*dir, "unable to read supervise/status: ", &strerr_sys);
+      else
+        warn(*dir, ": unable to read supervise/status: bad format.", 0);
+      continue;
+    }
+    
+    pid =(unsigned char)status[15];
+    pid <<=8; pid +=(unsigned char)status[14];
+    pid <<=8; pid +=(unsigned char)status[13];
+    pid <<=8; pid +=(unsigned char)status[12];
+    if (! pid) {
+      warn(*dir, ": is down.", 0);
+      continue;
+    }
+    
+    tai_unpack(status, &when);
+    tai_now(&now);
+    if (tai_less(&now, &when)) when =now;
+    tai_sub(&when, &now, &when);
+    is =tai_approx(&when);
+    
+    if (is >= sec) {
+      /* ok */
+      if (verbose) {
+        sulong[fmt_ulong(sulong, is)] =0;
+        strerr_warn5(INFO, *dir, ": is up (", sulong, " seconds)", 0);
+      }
+      dir++;
+      continue;
+    }
+    sleep(sec -is);
+  }
+  if (fchdir(wdir) == -1) 
+    strerr_warn2(WARN, "unable to switch to starting directory: ", &strerr_sys);
+  close(wdir);
+  if (rc > 100) rc =100;
+  _exit(rc);
+}
diff --git a/runit-2.1.2/src/svwaitup.check b/runit-2.1.2/src/svwaitup.check
new file mode 100755
index 0000000..a1be802
--- /dev/null
+++ b/runit-2.1.2/src/svwaitup.check
@@ -0,0 +1,28 @@
+#!/bin/sh
+rm -rf "${ctmp}"
+
+svwaitup
+echo $?
+svwaitup -V
+echo $?
+
+mkdir "${ctmp}"
+echo '#!/bin/sh' >"${ctmp}"/run
+echo 'echo starting' >>"${ctmp}"/run
+echo 'exec sleep 14' >>"${ctmp}"/run
+chmod 700 "${ctmp}"/run
+runsv "${ctmp}" &
+sleep 1
+test -r "${ctmp}"/supervise/stat || sleep 2
+svwaitup "${ctmp}"
+echo $?
+cat "${ctmp}"/supervise/stat
+svwaitup -s2 "${ctmp}"
+echo $?
+cat "${ctmp}"/supervise/stat
+runsvctrl exit "${ctmp}"
+wait
+echo $?
+chpst -2 svwaitup -s2 "${ctmp}"
+echo $?
+rm -rf "${ctmp}"
diff --git a/runit-2.1.2/src/svwaitup.dist b/runit-2.1.2/src/svwaitup.dist
new file mode 100644
index 0000000..692990f
--- /dev/null
+++ b/runit-2.1.2/src/svwaitup.dist
@@ -0,0 +1,14 @@
+usage: svwaitup [-v] [-s 1..600] service ...
+
+1
+$Id$
+usage: svwaitup [-v] [-s 1..600] service ...
+
+1
+starting
+0
+run
+0
+run
+0
+1
diff --git a/runit-2.1.2/src/tai.h b/runit-2.1.2/src/tai.h
new file mode 100644
index 0000000..1839f76
--- /dev/null
+++ b/runit-2.1.2/src/tai.h
@@ -0,0 +1,28 @@
+/* Public domain. */
+
+#ifndef TAI_H
+#define TAI_H
+
+#include "uint64.h"
+
+struct tai {
+  uint64 x;
+} ;
+
+#define tai_unix(t,u) ((void) ((t)->x = 4611686018427387914ULL + (uint64) (u)))
+
+extern void tai_now(struct tai *);
+
+#define tai_approx(t) ((double) ((t)->x))
+
+extern void tai_add(struct tai *,const struct tai *,const struct tai *);
+extern void tai_sub(struct tai *,const struct tai *,const struct tai *);
+#define tai_less(t,u) ((t)->x < (u)->x)
+
+#define TAI_PACK 8
+extern void tai_pack(char *,const struct tai *);
+extern void tai_unpack(const char *,struct tai *);
+
+extern void tai_uint(struct tai *,unsigned int);
+
+#endif
diff --git a/runit-2.1.2/src/tai_now.c b/runit-2.1.2/src/tai_now.c
new file mode 100644
index 0000000..217ba75
--- /dev/null
+++ b/runit-2.1.2/src/tai_now.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#include <time.h>
+#include "tai.h"
+
+void tai_now(struct tai *t)
+{
+  tai_unix(t,time((time_t *) 0));
+}
diff --git a/runit-2.1.2/src/tai_pack.c b/runit-2.1.2/src/tai_pack.c
new file mode 100644
index 0000000..641fa5b
--- /dev/null
+++ b/runit-2.1.2/src/tai_pack.c
@@ -0,0 +1,18 @@
+/* Public domain. */
+
+#include "tai.h"
+
+void tai_pack(char *s,const struct tai *t)
+{
+  uint64 x;
+
+  x = t->x;
+  s[7] = x & 255; x >>= 8;
+  s[6] = x & 255; x >>= 8;
+  s[5] = x & 255; x >>= 8;
+  s[4] = x & 255; x >>= 8;
+  s[3] = x & 255; x >>= 8;
+  s[2] = x & 255; x >>= 8;
+  s[1] = x & 255; x >>= 8;
+  s[0] = x;
+}
diff --git a/runit-2.1.2/src/tai_sub.c b/runit-2.1.2/src/tai_sub.c
new file mode 100644
index 0000000..e891600
--- /dev/null
+++ b/runit-2.1.2/src/tai_sub.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include "tai.h"
+
+void tai_sub(struct tai *t,const struct tai *u,const struct tai *v)
+{
+  t->x = u->x - v->x;
+}
diff --git a/runit-2.1.2/src/tai_unpack.c b/runit-2.1.2/src/tai_unpack.c
new file mode 100644
index 0000000..4541ff5
--- /dev/null
+++ b/runit-2.1.2/src/tai_unpack.c
@@ -0,0 +1,18 @@
+/* Public domain. */
+
+#include "tai.h"
+
+void tai_unpack(const char *s,struct tai *t)
+{
+  uint64 x;
+
+  x = (unsigned char) s[0];
+  x <<= 8; x += (unsigned char) s[1];
+  x <<= 8; x += (unsigned char) s[2];
+  x <<= 8; x += (unsigned char) s[3];
+  x <<= 8; x += (unsigned char) s[4];
+  x <<= 8; x += (unsigned char) s[5];
+  x <<= 8; x += (unsigned char) s[6];
+  x <<= 8; x += (unsigned char) s[7];
+  t->x = x;
+}
diff --git a/runit-2.1.2/src/taia.h b/runit-2.1.2/src/taia.h
new file mode 100644
index 0000000..3882d1d
--- /dev/null
+++ b/runit-2.1.2/src/taia.h
@@ -0,0 +1,36 @@
+/* Public domain. */
+
+#ifndef TAIA_H
+#define TAIA_H
+
+#include "tai.h"
+
+struct taia {
+  struct tai sec;
+  unsigned long nano; /* 0...999999999 */
+  unsigned long atto; /* 0...999999999 */
+} ;
+
+extern void taia_tai(const struct taia *,struct tai *);
+
+extern void taia_now(struct taia *);
+
+extern double taia_approx(const struct taia *);
+extern double taia_frac(const struct taia *);
+
+extern void taia_add(struct taia *,const struct taia *,const struct taia *);
+extern void taia_addsec(struct taia *,const struct taia *,int);
+extern void taia_sub(struct taia *,const struct taia *,const struct taia *);
+extern void taia_half(struct taia *,const struct taia *);
+extern int taia_less(const struct taia *,const struct taia *);
+
+#define TAIA_PACK 16
+extern void taia_pack(char *,const struct taia *);
+extern void taia_unpack(const char *,struct taia *);
+
+#define TAIA_FMTFRAC 19
+extern unsigned int taia_fmtfrac(char *,const struct taia *);
+
+extern void taia_uint(struct taia *,unsigned int);
+
+#endif
diff --git a/runit-2.1.2/src/taia_add.c b/runit-2.1.2/src/taia_add.c
new file mode 100644
index 0000000..0ac8e6b
--- /dev/null
+++ b/runit-2.1.2/src/taia_add.c
@@ -0,0 +1,20 @@
+/* Public domain. */
+
+#include "taia.h"
+
+/* XXX: breaks tai encapsulation */
+
+void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
+{
+  t->sec.x = u->sec.x + v->sec.x;
+  t->nano = u->nano + v->nano;
+  t->atto = u->atto + v->atto;
+  if (t->atto > 999999999UL) {
+    t->atto -= 1000000000UL;
+    ++t->nano;
+  }
+  if (t->nano > 999999999UL) {
+    t->nano -= 1000000000UL;
+    ++t->sec.x;
+  }
+}
diff --git a/runit-2.1.2/src/taia_approx.c b/runit-2.1.2/src/taia_approx.c
new file mode 100644
index 0000000..c6f5f27
--- /dev/null
+++ b/runit-2.1.2/src/taia_approx.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include "taia.h"
+
+double taia_approx(const struct taia *t)
+{
+  return tai_approx(&t->sec) + taia_frac(t);
+}
diff --git a/runit-2.1.2/src/taia_frac.c b/runit-2.1.2/src/taia_frac.c
new file mode 100644
index 0000000..f709f3e
--- /dev/null
+++ b/runit-2.1.2/src/taia_frac.c
@@ -0,0 +1,8 @@
+/* Public domain. */
+
+#include "taia.h"
+
+double taia_frac(const struct taia *t)
+{
+  return (t->atto * 0.000000001 + t->nano) * 0.000000001;
+}
diff --git a/runit-2.1.2/src/taia_less.c b/runit-2.1.2/src/taia_less.c
new file mode 100644
index 0000000..18a9378
--- /dev/null
+++ b/runit-2.1.2/src/taia_less.c
@@ -0,0 +1,14 @@
+/* Public domain. */
+
+#include "taia.h"
+
+/* XXX: breaks tai encapsulation */
+
+int taia_less(const struct taia *t,const struct taia *u)
+{
+  if (t->sec.x < u->sec.x) return 1;
+  if (t->sec.x > u->sec.x) return 0;
+  if (t->nano < u->nano) return 1;
+  if (t->nano > u->nano) return 0;
+  return t->atto < u->atto;
+}
diff --git a/runit-2.1.2/src/taia_now.c b/runit-2.1.2/src/taia_now.c
new file mode 100644
index 0000000..3a951a9
--- /dev/null
+++ b/runit-2.1.2/src/taia_now.c
@@ -0,0 +1,15 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <time.h>
+#include <sys/time.h>
+#include "taia.h"
+
+void taia_now(struct taia *t)
+{
+  struct timeval now;
+  gettimeofday(&now,(struct timezone *) 0);
+  tai_unix(&t->sec,now.tv_sec);
+  t->nano = 1000 * now.tv_usec + 500;
+  t->atto = 0;
+}
diff --git a/runit-2.1.2/src/taia_pack.c b/runit-2.1.2/src/taia_pack.c
new file mode 100644
index 0000000..9047da1
--- /dev/null
+++ b/runit-2.1.2/src/taia_pack.c
@@ -0,0 +1,22 @@
+/* Public domain. */
+
+#include "taia.h"
+
+void taia_pack(char *s,const struct taia *t)
+{
+  unsigned long x;
+
+  tai_pack(s,&t->sec);
+  s += 8;
+
+  x = t->atto;
+  s[7] = x & 255; x >>= 8;
+  s[6] = x & 255; x >>= 8;
+  s[5] = x & 255; x >>= 8;
+  s[4] = x;
+  x = t->nano;
+  s[3] = x & 255; x >>= 8;
+  s[2] = x & 255; x >>= 8;
+  s[1] = x & 255; x >>= 8;
+  s[0] = x;
+}
diff --git a/runit-2.1.2/src/taia_sub.c b/runit-2.1.2/src/taia_sub.c
new file mode 100644
index 0000000..d902e50
--- /dev/null
+++ b/runit-2.1.2/src/taia_sub.c
@@ -0,0 +1,23 @@
+/* Public domain. */
+
+#include "taia.h"
+
+/* XXX: breaks tai encapsulation */
+
+void taia_sub(struct taia *t,const struct taia *u,const struct taia *v)
+{
+  unsigned long unano = u->nano;
+  unsigned long uatto = u->atto;
+  
+  t->sec.x = u->sec.x - v->sec.x;
+  t->nano = unano - v->nano;
+  t->atto = uatto - v->atto;
+  if (t->atto > uatto) {
+    t->atto += 1000000000UL;
+    --t->nano;
+  }
+  if (t->nano > unano) {
+    t->nano += 1000000000UL;
+    --t->sec.x;
+  }
+}
diff --git a/runit-2.1.2/src/taia_uint.c b/runit-2.1.2/src/taia_uint.c
new file mode 100644
index 0000000..8b7f2d4
--- /dev/null
+++ b/runit-2.1.2/src/taia_uint.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#include "taia.h"
+
+/* XXX: breaks tai encapsulation */
+
+void taia_uint(struct taia *t,unsigned int s)
+{
+  t->sec.x = s;
+  t->nano = 0;
+  t->atto = 0;
+}
diff --git a/runit-2.1.2/src/trycpp.c b/runit-2.1.2/src/trycpp.c
new file mode 100644
index 0000000..e4503d4
--- /dev/null
+++ b/runit-2.1.2/src/trycpp.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+int main()
+{
+#ifdef NeXT
+  printf("nextstep\n"); exit(0);
+#endif
+  printf("unknown\n"); exit(0);
+}
diff --git a/runit-2.1.2/src/trydrent.c b/runit-2.1.2/src/trydrent.c
new file mode 100644
index 0000000..3333ac0
--- /dev/null
+++ b/runit-2.1.2/src/trydrent.c
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <dirent.h>
+
+void foo()
+{
+  DIR *dir;
+  struct dirent *d;
+}
diff --git a/runit-2.1.2/src/tryflock.c b/runit-2.1.2/src/tryflock.c
new file mode 100644
index 0000000..a82ffc2
--- /dev/null
+++ b/runit-2.1.2/src/tryflock.c
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <fcntl.h>
+
+main()
+{
+  flock(0,LOCK_EX | LOCK_UN | LOCK_NB);
+}
diff --git a/runit-2.1.2/src/trymkffo.c b/runit-2.1.2/src/trymkffo.c
new file mode 100644
index 0000000..9356342
--- /dev/null
+++ b/runit-2.1.2/src/trymkffo.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+void main()
+{
+  mkfifo("temp-trymkffo",0);
+}
diff --git a/runit-2.1.2/src/trypoll.c b/runit-2.1.2/src/trypoll.c
new file mode 100644
index 0000000..6506617
--- /dev/null
+++ b/runit-2.1.2/src/trypoll.c
@@ -0,0 +1,20 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <fcntl.h>
+#include <poll.h>
+
+int main()
+{
+  struct pollfd x;
+
+  x.fd = open("trypoll.c",O_RDONLY);
+  if (x.fd == -1) _exit(111);
+  x.events = POLLIN;
+  if (poll(&x,1,10) == -1) _exit(1);
+  if (x.revents != POLLIN) _exit(1);
+
+  /* XXX: try to detect and avoid poll() imitation libraries */
+
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/tryreboot.c b/runit-2.1.2/src/tryreboot.c
new file mode 100644
index 0000000..aefc703
--- /dev/null
+++ b/runit-2.1.2/src/tryreboot.c
@@ -0,0 +1,6 @@
+#include <unistd.h>
+#include <sys/reboot.h>
+
+int main(void) {
+  return(reboot(0));
+}
diff --git a/runit-2.1.2/src/trysgact.c b/runit-2.1.2/src/trysgact.c
new file mode 100644
index 0000000..e264ef2
--- /dev/null
+++ b/runit-2.1.2/src/trysgact.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#include <signal.h>
+
+main()
+{
+  struct sigaction sa;
+  sa.sa_handler = 0;
+  sa.sa_flags = 0;
+  sigemptyset(&sa.sa_mask);
+  sigaction(0,&sa,(struct sigaction *) 0);
+}
diff --git a/runit-2.1.2/src/trysgprm.c b/runit-2.1.2/src/trysgprm.c
new file mode 100644
index 0000000..a46c82c
--- /dev/null
+++ b/runit-2.1.2/src/trysgprm.c
@@ -0,0 +1,12 @@
+/* Public domain. */
+
+#include <signal.h>
+
+main()
+{
+  sigset_t ss;
+ 
+  sigemptyset(&ss);
+  sigaddset(&ss,SIGCHLD);
+  sigprocmask(SIG_SETMASK,&ss,(sigset_t *) 0);
+}
diff --git a/runit-2.1.2/src/tryshsgr.c b/runit-2.1.2/src/tryshsgr.c
new file mode 100644
index 0000000..c5ed6d6
--- /dev/null
+++ b/runit-2.1.2/src/tryshsgr.c
@@ -0,0 +1,16 @@
+/* Public domain. */
+
+int main()
+{
+  short x[4];
+ 
+  x[0] = x[1] = 1;
+  if (getgroups(1,x) == 0) if (setgroups(1,x) == -1) _exit(1);
+ 
+  if (getgroups(1,x) == -1) _exit(1);
+  if (x[1] != 1) _exit(1);
+  x[1] = 2;
+  if (getgroups(1,x) == -1) _exit(1);
+  if (x[1] != 2) _exit(1);
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/trysocketlib.c b/runit-2.1.2/src/trysocketlib.c
new file mode 100644
index 0000000..0fe5d06
--- /dev/null
+++ b/runit-2.1.2/src/trysocketlib.c
@@ -0,0 +1,12 @@
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+int main(void) {
+  int s;
+
+  s =socket(AF_INET, SOCK_STREAM, 0);
+  return(close(s));
+}
diff --git a/runit-2.1.2/src/trysysel.c b/runit-2.1.2/src/trysysel.c
new file mode 100644
index 0000000..5be862d
--- /dev/null
+++ b/runit-2.1.2/src/trysysel.c
@@ -0,0 +1,11 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/select.h> /* SVR4 silliness */
+
+void foo()
+{
+  ;
+}
diff --git a/runit-2.1.2/src/tryulong64.c b/runit-2.1.2/src/tryulong64.c
new file mode 100644
index 0000000..003548a
--- /dev/null
+++ b/runit-2.1.2/src/tryulong64.c
@@ -0,0 +1,13 @@
+/* Public domain. */
+
+int main()
+{
+  unsigned long u;
+  u = 1;
+  u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
+  u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
+  u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
+  u += u; u += u; u += u; u += u; u += u; u += u; u += u; u += u;
+  if (!u) _exit(1);
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/tryuwtmp.c b/runit-2.1.2/src/tryuwtmp.c
new file mode 100644
index 0000000..2192a1e
--- /dev/null
+++ b/runit-2.1.2/src/tryuwtmp.c
@@ -0,0 +1,9 @@
+#include <sys/types.h>
+#include <utmp.h>
+
+struct utmp ut;
+
+int main(void) {
+  char *s =ut.ut_name;
+  return(0);
+}
diff --git a/runit-2.1.2/src/tryuwtmpx.c b/runit-2.1.2/src/tryuwtmpx.c
new file mode 100644
index 0000000..d711c01
--- /dev/null
+++ b/runit-2.1.2/src/tryuwtmpx.c
@@ -0,0 +1,9 @@
+#include <sys/types.h>
+#include <utmpx.h>
+
+struct futmpx ut;
+
+int main(void) {
+  char *s =ut.ut_name;
+  return(0);
+}
diff --git a/runit-2.1.2/src/trywaitp.c b/runit-2.1.2/src/trywaitp.c
new file mode 100644
index 0000000..319b81f
--- /dev/null
+++ b/runit-2.1.2/src/trywaitp.c
@@ -0,0 +1,9 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+main()
+{
+  waitpid(0,0,0);
+}
diff --git a/runit-2.1.2/src/uidgid.c b/runit-2.1.2/src/uidgid.c
new file mode 100644
index 0000000..befa754
--- /dev/null
+++ b/runit-2.1.2/src/uidgid.c
@@ -0,0 +1,74 @@
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include "uidgid.h"
+#include "str.h"
+#include "scan.h"
+
+/* user */
+unsigned int uidgid_get(struct uidgid *u, char *ug) {
+  struct passwd *pwd =0;
+
+  if (! (pwd =getpwnam(ug))) return(0);
+  u->gid[0] =pwd->pw_gid; u->gids =1;
+  u->uid =pwd->pw_uid;
+  return(1);
+}
+
+/* uid:gid[:gid[:gid]...] */
+unsigned int uidgids_set(struct uidgid *u, char *ug) {
+  unsigned long id;
+  int i;
+
+  if (*(ug +=scan_ulong(ug, &id)) != ':') return(0);
+  u->uid =(uid_t)id;
+  ++ug;
+  for (i =0; i < 60; ++i, ++ug) {
+    ug +=scan_ulong(ug, &id);
+    u->gid[i] =(gid_t)id;
+    if (*ug != ':') { ++i; break; }
+  }
+  u->gid[i] =0;
+  u->gids =i;
+  if (*ug) return(0);
+  return(1);
+}
+
+/* [:]user[:group[:group]...] */
+unsigned int uidgids_get(struct uidgid *u, char *ug) {
+  char *g =0;
+  struct passwd *pwd =0;
+  struct group *gr =0;
+  int i, d =0;
+
+  if (*ug == ':') return(uidgids_set(u, ug +1));
+  if (ug[(d =str_chr(ug, ':'))] == ':') {
+    ug[d] =0;
+    g =ug +d +1;
+  }
+  if (! (pwd =getpwnam(ug))) { if (g) ug[d] =':'; return(0); }
+  u->uid =pwd->pw_uid;
+  if (! g) {
+    u->gid[0] =pwd->pw_gid;
+    u->gids =1;
+    return(1);
+  }
+  ug[d] =':';
+  for (i =0; i < 60; ++i) {
+    if (g[(d =str_chr(g, ':'))] == ':') {
+      g[d] =0;
+      if (! (gr =getgrnam(g))) { g[d] =':'; return(0); }
+      g[d] =':';
+      u->gid[i] =gr->gr_gid;
+      g +=d +1;
+    }
+    else {
+      if (! (gr =getgrnam(g))) return(0);
+      u->gid[i++] =gr->gr_gid;
+      break;
+    }
+  }
+  u->gid[i] =0;
+  u->gids =i;
+  return(1);
+}
diff --git a/runit-2.1.2/src/uidgid.h b/runit-2.1.2/src/uidgid.h
new file mode 100644
index 0000000..13cacbc
--- /dev/null
+++ b/runit-2.1.2/src/uidgid.h
@@ -0,0 +1,18 @@
+#ifndef UIDGID_H
+#define UIDGID_H
+
+#include <sys/types.h>
+
+struct uidgid {
+  uid_t uid;
+  gid_t gid[61];
+  int gids;
+};
+
+/* user */
+extern unsigned int uidgid_get(struct uidgid *, char *);
+
+/* [:]user[:group[:group]...] */
+extern unsigned int uidgids_get(struct uidgid *, char *);
+
+#endif
diff --git a/runit-2.1.2/src/uint64.h1 b/runit-2.1.2/src/uint64.h1
new file mode 100644
index 0000000..486a380
--- /dev/null
+++ b/runit-2.1.2/src/uint64.h1
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#ifndef UINT64_H
+#define UINT64_H
+
+/* sysdep: -ulong64 */
+
+typedef unsigned long long uint64;
+
+#endif
diff --git a/runit-2.1.2/src/uint64.h2 b/runit-2.1.2/src/uint64.h2
new file mode 100644
index 0000000..8869e43
--- /dev/null
+++ b/runit-2.1.2/src/uint64.h2
@@ -0,0 +1,10 @@
+/* Public domain. */
+
+#ifndef UINT64_H
+#define UINT64_H
+
+/* sysdep: +ulong64 */
+
+typedef unsigned long uint64;
+
+#endif
diff --git a/runit-2.1.2/src/utmpset.c b/runit-2.1.2/src/utmpset.c
new file mode 100644
index 0000000..eea41a5
--- /dev/null
+++ b/runit-2.1.2/src/utmpset.c
@@ -0,0 +1,112 @@
+#include <fcntl.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include "uw_tmp.h"
+#include "strerr.h"
+#include "sgetopt.h"
+#include "seek.h"
+#include "str.h"
+#include "open.h"
+#include "byte.h"
+#include "lock.h"
+
+#define USAGE " [-w] line"
+#define FATAL "utmpset: fatal: "
+#define WARNING "utmpset: warning: "
+
+const char *progname;
+
+void usage(void) { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
+
+int utmp_logout(const char *line) {
+  int fd;
+  uw_tmp ut;
+  int ok =-1;
+
+  if ((fd =open(UW_TMP_UFILE, O_RDWR, 0)) < 0)
+    strerr_die4sys(111, FATAL, "unable to open ", UW_TMP_UFILE, ": ");
+  if (lock_ex(fd) == -1)
+    strerr_die4sys(111, FATAL, "unable to lock: ", UW_TMP_UFILE, ": ");
+
+  while (read(fd, &ut, sizeof(uw_tmp)) == sizeof(uw_tmp)) {
+    if (!ut.ut_name[0] || (str_diff(ut.ut_line, line) != 0)) continue;
+    memset(ut.ut_name, 0, sizeof ut.ut_name);
+    memset(ut.ut_host, 0, sizeof ut.ut_host);
+    if (time(&ut.ut_time) == -1) break;
+#ifdef DEAD_PROCESS
+    ut.ut_type =DEAD_PROCESS;
+#endif
+    if (lseek(fd, -(off_t)sizeof(uw_tmp), SEEK_CUR) == -1) break;
+    if (write(fd, &ut, sizeof(uw_tmp)) != sizeof(uw_tmp)) break;
+    ok =1;
+    break;
+  }
+  close(fd);
+  return(ok);
+}
+int wtmp_logout(const char *line) {
+  int fd;
+  int len;
+  struct stat st;
+  uw_tmp ut;
+
+  if ((fd = open_append(UW_TMP_WFILE)) == -1)
+    strerr_die4sys(111, FATAL, "unable to open ", UW_TMP_WFILE, ": ");
+  if (lock_ex(fd) == -1)
+    strerr_die4sys(111, FATAL, "unable to lock ", UW_TMP_WFILE, ": ");
+
+  if (fstat(fd, &st) == -1) {
+    close(fd);
+    return(-1);
+  }
+  memset(&ut, 0, sizeof(uw_tmp));
+  if ((len =str_len(line)) > sizeof ut.ut_line) len =sizeof ut.ut_line -2;
+  byte_copy(ut.ut_line, len, line);
+  if (time(&ut.ut_time) == -1) {
+    close(fd);
+    return(-1);
+  }
+#ifdef DEAD_PROCESS
+  ut.ut_type =DEAD_PROCESS;
+#endif
+  if (write(fd, &ut, sizeof(uw_tmp)) != sizeof(uw_tmp)) {
+    ftruncate(fd, st.st_size);
+    close(fd);
+    return(-1);
+  }
+  close(fd);
+  return(1);
+}
+
+int main (int argc, const char * const *argv, const char * const *envp) {
+  int opt;
+  int wtmp =0;
+
+  progname =*argv;
+
+  while ((opt =getopt(argc, argv, "wV")) != opteof) {
+    switch(opt) {
+    case 'w':
+      wtmp =1;
+      break;
+    case 'V':
+      strerr_warn1("$Id: cb399098f794012a7f5e6a3a7090b2d53b86c08c $", 0);
+    case '?':
+      usage();
+    }
+  }
+  argv +=optind;
+
+  if (! argv || ! *argv) usage();
+  if (utmp_logout(*argv) == -1)
+    strerr_die4x(111, WARNING, "unable to logout line ", *argv,
+                 " in utmp: no such entry");
+  if (wtmp)
+    if (wtmp_logout(*argv) == -1)
+      strerr_die4sys(111, WARNING,
+                     "unable to logout line ", *argv, " in wtmp: ");
+  _exit(0);
+}
diff --git a/runit-2.1.2/src/utmpset.check b/runit-2.1.2/src/utmpset.check
new file mode 100755
index 0000000..51cf1a4
--- /dev/null
+++ b/runit-2.1.2/src/utmpset.check
@@ -0,0 +1,5 @@
+#!/bin/sh
+utmpset
+echo $?
+utmpset -V
+echo $?
diff --git a/runit-2.1.2/src/utmpset.dist b/runit-2.1.2/src/utmpset.dist
new file mode 100644
index 0000000..d5c0370
--- /dev/null
+++ b/runit-2.1.2/src/utmpset.dist
@@ -0,0 +1,7 @@
+usage: utmpset [-w] line
+
+1
+$Id: cb399098f794012a7f5e6a3a7090b2d53b86c08c $
+usage: utmpset [-w] line
+
+1
diff --git a/runit-2.1.2/src/uw_tmp.h1 b/runit-2.1.2/src/uw_tmp.h1
new file mode 100644
index 0000000..2d5e994
--- /dev/null
+++ b/runit-2.1.2/src/uw_tmp.h1
@@ -0,0 +1,19 @@
+#include <sys/types.h>
+#include <utmp.h>
+
+/* sysdep: -utmpx */
+
+#ifdef _PATH_UTMP
+#define UW_TMP_UFILE _PATH_UTMP
+#define UW_TMP_WFILE _PATH_WTMP
+#else
+/* AIX only has UTMP_FILE */
+#ifdef UTMP_FILE
+#define UW_TMP_UFILE UTMP_FILE
+#define UW_TMP_WFILE WTMP_FILE
+#else
+#error neither _PATH_UTMP nor UTMP_FILE defined.
+#endif
+#endif
+
+typedef struct utmp uw_tmp;
diff --git a/runit-2.1.2/src/uw_tmp.h2 b/runit-2.1.2/src/uw_tmp.h2
new file mode 100644
index 0000000..ae9542e
--- /dev/null
+++ b/runit-2.1.2/src/uw_tmp.h2
@@ -0,0 +1,13 @@
+#include <sys/types.h>
+#include <utmpx.h>
+
+/* sysdep: +utmpx */
+
+#define UW_TMP_UFILE _UTMPX_FILE
+#define UW_TMP_WFILE _WTMPX_FILE
+
+#ifndef ut_time
+#define ut_time ut_tv.tv_sec
+#endif
+
+typedef struct futmpx uw_tmp;
diff --git a/runit-2.1.2/src/wait.h b/runit-2.1.2/src/wait.h
new file mode 100644
index 0000000..d294e9d
--- /dev/null
+++ b/runit-2.1.2/src/wait.h
@@ -0,0 +1,16 @@
+/* Public domain. */
+
+#ifndef WAIT_H
+#define WAIT_H
+
+extern int wait_pid();
+extern int wait_nohang();
+extern int wait_stop();
+extern int wait_stopnohang();
+
+#define wait_crashed(w) ((w) & 127)
+#define wait_exitcode(w) ((w) >> 8)
+#define wait_stopsig(w) ((w) >> 8)
+#define wait_stopped(w) (((w) & 127) == 127)
+
+#endif
diff --git a/runit-2.1.2/src/wait_nohang.c b/runit-2.1.2/src/wait_nohang.c
new file mode 100644
index 0000000..5c9c53d
--- /dev/null
+++ b/runit-2.1.2/src/wait_nohang.c
@@ -0,0 +1,14 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "haswaitp.h"
+
+int wait_nohang(wstat) int *wstat;
+{
+#ifdef HASWAITPID
+  return waitpid(-1,wstat,WNOHANG);
+#else
+  return wait3(wstat,WNOHANG,(struct rusage *) 0);
+#endif
+}
diff --git a/runit-2.1.2/src/wait_pid.c b/runit-2.1.2/src/wait_pid.c
new file mode 100644
index 0000000..c2869b8
--- /dev/null
+++ b/runit-2.1.2/src/wait_pid.c
@@ -0,0 +1,41 @@
+/* Public domain. */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "error.h"
+#include "haswaitp.h"
+
+#ifdef HASWAITPID
+
+int wait_pid(wstat,pid) int *wstat; int pid;
+{
+  int r;
+
+  do
+    r = waitpid(pid,wstat,0);
+  while ((r == -1) && (errno == error_intr));
+  return r;
+}
+
+#else
+
+/* XXX untested */
+/* XXX breaks down with more than two children */
+static int oldpid = 0;
+static int oldwstat; /* defined if(oldpid) */
+
+int wait_pid(wstat,pid) int *wstat; int pid;
+{
+  int r;
+
+  if (pid == oldpid) { *wstat = oldwstat; oldpid = 0; return pid; }
+
+  do {
+    r = wait(wstat);
+    if ((r != pid) && (r != -1)) { oldwstat = *wstat; oldpid = r; continue; }
+  }
+  while ((r == -1) && (errno == error_intr));
+  return r;
+}
+
+#endif
diff --git a/runit-2.1.2/src/warn-auto.sh b/runit-2.1.2/src/warn-auto.sh
new file mode 100644
index 0000000..36d2313
--- /dev/null
+++ b/runit-2.1.2/src/warn-auto.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+# WARNING: This file was auto-generated. Do not edit!
diff --git a/runit-2.1.2/src/warn-shsgr b/runit-2.1.2/src/warn-shsgr
new file mode 100644
index 0000000..37c351e
--- /dev/null
+++ b/runit-2.1.2/src/warn-shsgr
@@ -0,0 +1,3 @@
+Oops. Your getgroups() returned 0, and setgroups() failed; this means
+that I can't reliably do my shsgr test. Please either ``make'' as root
+or ``make'' while you're in one or more supplementary groups.
diff --git a/runit-2.1.2/src/x86cpuid.c b/runit-2.1.2/src/x86cpuid.c
new file mode 100644
index 0000000..f81c593
--- /dev/null
+++ b/runit-2.1.2/src/x86cpuid.c
@@ -0,0 +1,40 @@
+/* Public domain. */
+
+#include <signal.h>
+
+void nope()
+{
+  exit(1);
+}
+
+int main()
+{
+  unsigned long x[4];
+  unsigned long y[4];
+  int i;
+  int j;
+  char c;
+
+  signal(SIGILL,nope);
+
+  x[0] = 0;
+  x[1] = 0;
+  x[2] = 0;
+  x[3] = 0;
+
+  asm volatile(".byte 15;.byte 162" : "=a"(x[0]),"=b"(x[1]),"=c"(x[3]),"=d"(x[2]) : "0"(0) );
+  if (!x[0]) return 0;
+  asm volatile(".byte 15;.byte 162" : "=a"(y[0]),"=b"(y[1]),"=c"(y[2]),"=d"(y[3]) : "0"(1) );
+
+  for (i = 1;i < 4;++i)
+    for (j = 0;j < 4;++j) {
+      c = x[i] >> (8 * j);
+      if (c < 32) c = 32;
+      if (c > 126) c = 126;
+      putchar(c);
+    }
+
+  printf("-%08x-%08x\n",y[0],y[3]);
+
+  return 0;
+}