summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranonymous <anonymous>2003-06-27 22:56:31 +0000
committeranonymous <anonymous>2003-06-27 22:56:31 +0000
commit8bd6fc0a98539e50d96fe4b499be40c06ca63f5e (patch)
treeb2d210d451f6cd8239fd60e2c7de620d40b65788
Initial revision
-rwxr-xr-xAUTHORS5
-rwxr-xr-xBUGS5
-rwxr-xr-xCOPYING14
-rwxr-xr-xChangeLog16
-rwxr-xr-xINSTALL33
-rwxr-xr-xMakefile.am4
-rwxr-xr-xNEWS1
-rwxr-xr-xREADME26
-rwxr-xr-xconfig.h.in146
-rwxr-xr-xconfigure.ac42
-rwxr-xr-xdoc/injail_man.html46
-rwxr-xr-xdoc/jailer_man.html109
-rwxr-xr-xpatches/jailer.patch179
-rwxr-xr-xscripts/Makefile.am15
-rwxr-xr-xscripts/halt44
-rwxr-xr-xscripts/reboot44
-rwxr-xr-xsrc/Makefile.am9
-rwxr-xr-xsrc/dmesg.c117
-rwxr-xr-xsrc/injail.836
-rwxr-xr-xsrc/injail.c67
-rwxr-xr-xsrc/injail_main.c51
-rwxr-xr-xsrc/jailer.8131
-rwxr-xr-xsrc/jailer.c494
23 files changed, 1634 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100755
index 0000000..6ac8ee9
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,5 @@
+nielsen@memberwebs.com
+stef0x77@yahoo.com
+
+Patches and Contributions:
+jimquick@mac.com
diff --git a/BUGS b/BUGS
new file mode 100755
index 0000000..8095082
--- /dev/null
+++ b/BUGS
@@ -0,0 +1,5 @@
+JAILER TODOS and BUGS
+
+- shutdown(8) doesn't work with the halt and reboot scripts
+- No console support on FreeBSD 5.0 due to devfs (will work on this shortly)
+- I'm sure there's more out there. LMK at nielsen@memberwebs.com
diff --git a/COPYING b/COPYING
new file mode 100755
index 0000000..cf2037b
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,14 @@
+LICENSE
+This software is in the public domain.
+
+The software is provided "as is", without warranty of any kind,
+express or implied, including but not limited to the warranties
+of merchantability, fitness for a particular purpose, and
+noninfringement. In no event shall the author(s) be liable for any
+claim, damages, or other liability, whether in an action of
+contract, tort, or otherwise, arising from, out of, or in connection
+with the software or the use or other dealings in the software.
+
+SUPPORT
+Send bug reports to: <nielsen@memberwebs.com>
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100755
index 0000000..108137e
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,16 @@
+Version 1.0
+ - Conditionally remove console support on FreeBSD 5.0
+
+Version 1.1.2
+ - Uses select when piping output from scripts
+
+Version 1.1.1
+ - Checks to make sure it's running in a jail.
+ - New utility 'injail' to check from scripts whether running in a jail
+ - Sets process title as state changes (for ps).
+
+Version 1.1
+ - Support the notion of a jail "console"
+ - Support stopping and restarting jail from inside
+ - jailer manages startup and shutdown and logs everything
+
diff --git a/INSTALL b/INSTALL
new file mode 100755
index 0000000..babb319
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,33 @@
+======================================================================
+ Jailer INSTALL
+
+
+This software only works with FreeBSD jails. It should be installed
+and run from within a full jail system.
+
+
+QUICK INSTALLATION:
+ # tar -zxvf jailer-1.1.2.tar.gz
+ # ./configure
+ # make && make install
+
+
+This installs the jailer on your system, probably in /usr/local/sbin.
+To use the jailer substitute 'sh /etc/rc' with it in your jail startup
+command:
+
+ # jail /usr/jails/myjail myjailhost 192.168.2.21 /usr/local/sbin/jailer
+
+See jail(8) for more information.
+
+
+
+REPLACING HALT AND REBOOT COMMANDS:
+
+To be able to reboot the jail from inside it, copy the provided
+halt and reboot scripts over your original halt and reboot commands.
+Note that you should only do this inside a jail!
+
+ # cp /usr/local/sbin/halt /usr/local/sbin/reboot /sbin
+
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100755
index 0000000..ce99b8d
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,4 @@
+EXTRA_DIST = BUGS
+SUBDIRS = src scripts
+
+
diff --git a/NEWS b/NEWS
new file mode 100755
index 0000000..c7ab92a
--- /dev/null
+++ b/NEWS
@@ -0,0 +1 @@
+See ChangeLog \ No newline at end of file
diff --git a/README b/README
new file mode 100755
index 0000000..5094f08
--- /dev/null
+++ b/README
@@ -0,0 +1,26 @@
+=================================================================
+ JAILER README
+
+This software is for those who have used jails and want a
+controlled way to manage and shut them down etc...
+
+
+It is to be installed inside a jail (NOT THE HOST SYSTEM)
+and will manage the processes. A jailer process runs inside
+each jail and manages the startup and shutdown.
+
+
+To shutdown or restart the jail, signal the jailer process
+running inside that jail. The signals are:
+
+
+ -QUIT Shutdown jail but leave jailer running
+ -HUP Restart the jail
+ -TERM Shutdown the jail and exit the jailer
+
+
+For further jail aids see:
+
+http://memberwebs.com/nielsen/freebsd/jails/
+
+
diff --git a/config.h.in b/config.h.in
new file mode 100755
index 0000000..433fc96
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,146 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `c' library (-lc). */
+#undef HAVE_LIBC
+
+/* Define to 1 if you have the `kvm' library (-lkvm). */
+#undef HAVE_LIBKVM
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the `setproctitle' function. */
+#undef HAVE_SETPROCTITLE
+
+/* Define to 1 if `stat' has the bug that it succeeds when given the
+ zero-length file name argument. */
+#undef HAVE_STAT_EMPTY_STRING_BUG
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+ slash. */
+#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
+
+/* Virtual jail console support disabled */
+#undef NO_CONSOLE
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Define to 1 if the `setvbuf' function takes the buffering type as its
+ second argument and the buffer pointer as the third, as on System V before
+ release 3. */
+#undef SETVBUF_REVERSED
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
diff --git a/configure.ac b/configure.ac
new file mode 100755
index 0000000..b6d3209
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,42 @@
+# Process this file with autoconf to produce a configure script.
+AC_INIT(jailer, 1.2, nielsen@memberwebs.com)
+AM_INIT_AUTOMAKE(jailer, 1.2)
+
+AC_CONFIG_SRCDIR([src/jailer.c])
+AM_CONFIG_HEADER([config.h])
+
+case `uname -r` in
+5.*)
+ echo "FreeBSD 5.x detected"
+ AC_DEFINE(NO_CONSOLE, 1, [Virtual jail console support disabled])
+ ;;
+esac
+
+# Checks for programs.
+AC_PROG_CC
+
+# Checks for libraries.
+AC_CHECK_LIB([kvm], [kvm_open], ,
+ ["ERROR: This software is applicable to FreeBSD only."] )
+AC_CHECK_LIB([c], [jail], ,
+ ["ERROR: This software requires the jail functionality of FreeBSD."] )
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([fcntl.h syslog.h unistd.h limits.h sys/file.h sys/param.h paths.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_STRUCT_TM
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_FUNC_SETVBUF_REVERSED
+AC_TYPE_SIGNAL
+AC_FUNC_STAT
+AC_CHECK_FUNCS([dup2 gethostname strerror atexit setproctitle select])
+
+AC_CONFIG_FILES([Makefile src/Makefile scripts/Makefile])
+AC_OUTPUT
diff --git a/doc/injail_man.html b/doc/injail_man.html
new file mode 100755
index 0000000..6854e73
--- /dev/null
+++ b/doc/injail_man.html
@@ -0,0 +1,46 @@
+<HTML>
+<BODY>
+<PRE>
+<!-- Manpage converted by man2html 3.0.1 -->
+
+
+</PRE>
+<H2>DESCRIPTION</H2><PRE>
+ The <B>injail</B> utility returns a result which indicates the jailed status of
+ the current process environment.
+
+
+</PRE>
+<H2>DIAGNOSTICS</H2><PRE>
+ The <B>injail</B> utility exits with one of the following values:
+ 0 the process is running in a jail.
+ 1 the process is not running in a jail.
+ 2 an error prevented determining if the process is running in a
+ jail.
+
+
+</PRE>
+<H2>BUGS</H2><PRE>
+ <B>injail</B> uses <B>kvm_getprocs(3)</B> to determine process status. Anything which
+ could cause a failure in either <B>kvm_open(3)</B> or <B>kvm_getprocs(3)</B> can cause
+ this to fail as well. There aught to be a cleaner way.
+
+
+</PRE>
+<H2>AUTHOR</H2><PRE>
+ James E. Quick &lt;jq@quick.com&gt;
+
+
+</PRE>
+<H2>SEE ALSO</H2><PRE>
+ <B>jailer(8)</B>, <B>jail(8)</B>, <B>kvm(3)</B>
+
+FreeBSD 4.6 May 28, 2002 FreeBSD 4.6
+</PRE>
+<HR>
+<ADDRESS>
+Man(1) output converted with
+<a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a>
+</ADDRESS>
+</BODY>
+</HTML>
diff --git a/doc/jailer_man.html b/doc/jailer_man.html
new file mode 100755
index 0000000..229d297
--- /dev/null
+++ b/doc/jailer_man.html
@@ -0,0 +1,109 @@
+<HTML>
+<BODY>
+<PRE>
+<!-- Manpage converted by man2html 3.0.1 -->
+
+</PRE>
+<H2>SYNOPSIS</H2><PRE>
+ <B>jailer</B> <B>[</B> <I>console-file</I> <B>]</B>
+
+
+</PRE>
+<H2>DESCRIPTION</H2><PRE>
+ <B>jailer</B> manages the startup and shutdown of a jail from
+ within the jail. It also manages the jails console by
+ linking /dev/console inside the jail to a log file.
+
+ To use, replace the '/bin/sh /etc/rc' portion of your jail
+ startup command with jailer. For example instead of:
+
+ <B>jail</B> <B>/jails/myjail</B> <B>host</B> <B>10.0.1.1</B> <B>/bin/sh</B> <B>/etc/rc</B>
+
+ use:
+
+ <B>jail</B> <B>/jails/myjail</B> <B>host</B> <B>10.0.1.1</B> <B>/usr/local/sbin/jailer</B>
+
+
+ <B>jailer</B> will start the jail by running <I>/etc/rc</I> and then
+ remain running as a daemon inside the jail waiting for
+ signals to perform shutdown or restarts.
+
+ A shutdown is performed by first running <I>/etc/rc.shutdown</I>,
+ and then killing all the processes still running. A
+ restart is a combination of the above.
+
+
+ The following signals have special meaning to the jailer:
+
+ HUP Causes <B>jailer</B> to restart the jail. If the jail is
+ not running at the time it is simply started.
+
+ QUIT Initiates a jail shutdown. <B>jailer</B> remains running
+ after processing the request.
+
+ TERM Same as <I>QUIT</I> but also quits jailer. No more pro-
+ cesses will be left running inside the jail.
+
+
+
+</PRE>
+<H2>JAIL CONSOLE MANAGEMENT</H2><PRE>
+ A normal jail has no console perse, and <B>dmesg(8)</B> reads
+ straight from the host kernel message buffer. <B>jailer</B>
+ changes this to provide a virtual console for the jail.
+
+ On jailer startup the file <I>/var/log/console</I> is created or
+ truncated. <I>/dev/console</I> is then hard linked to the con-
+ sole file.
+
+ Along with the jailer distribution you'll find a new
+ <B>dmesg(8)</B> which just reads from <I>/dev/console.</I> Replace
+ <B>/sbin/</B><B>dmesg(8)</B> with this new executable and you're set.
+
+
+
+</PRE>
+<H2>OPTIONS</H2><PRE>
+ console-file
+ Overrides the default location of the console log
+ file, usually <I>/var/log/console</I>
+
+
+
+</PRE>
+<H2>FILES</H2><PRE>
+ <I>/var/log/console</I>
+ Virtual console file.
+
+
+
+</PRE>
+<H2>BUGS</H2><PRE>
+ Virtual jail consoles don't work with FreeBSD 5.0 yet.
+ This is due to <B>devfs(8)</B>
+
+ <B>shutdown(8)</B> doesn't work with the <I>halt</I> and <I>reboot</I> scripts.
+
+
+
+</PRE>
+<H2>AUTHOR</H2><PRE>
+ Nate Nielsen &lt;nielsen@memberwebs.com&gt;
+
+
+
+</PRE>
+<H2>SEE ALSO</H2><PRE>
+ <B>jail(8)</B>, <B>halt(8)</B>, <B>reboot(8)</B>, <B>dmesg(8)</B>
+
+
+
+Version 1.2 May 2002 <B>JAILER(8)</B>
+</PRE>
+<HR>
+<ADDRESS>
+Man(1) output converted with
+<a href="http://www.oac.uci.edu/indiv/ehood/man2html.html">man2html</a>
+</ADDRESS>
+</BODY>
+</HTML>
diff --git a/patches/jailer.patch b/patches/jailer.patch
new file mode 100755
index 0000000..6df5594
--- /dev/null
+++ b/patches/jailer.patch
@@ -0,0 +1,179 @@
+diff -Naur jailer-1.1/src/Makefile.am jailer-1.1.1/src/Makefile.am
+--- jailer-1.1/src/Makefile.am Wed May 22 23:39:38 2002
++++ jailer-1.1.1/src/Makefile.am Tue May 28 15:44:41 2002
+@@ -1,6 +1,8 @@
+-sbin_PROGRAMS = jailer dmesg
+-jailer_SOURCES = jailer.c
++sbin_PROGRAMS = jailer dmesg injail
++jailer_SOURCES = jailer.c injail.c
++injail_SOURCES = injail.c injail_main.c
++LIBS = -lkvm
+ dmesg_SOURCES = dmesg.c
+-man_MANS = jailer.8
++man_MANS = jailer.8 injail.8
+ EXTRA_DIST = $(man_MANS)
+
+diff -Naur jailer-1.1/src/injail.8 jailer-1.1.1/src/injail.8
+--- jailer-1.1/src/injail.8 Wed Dec 31 19:00:00 1969
++++ jailer-1.1.1/src/injail.8 Tue May 28 16:09:55 2002
+@@ -0,0 +1,37 @@
++.Dd May 28, 2002
++.Dt INJAIL 8
++.Os
++.Sh NAME
++.Nm injail
++.Nd determine if a process is running in a jail
++.Sh SYNOPSIS
++.Nm
++.Sh DESCRIPTION
++The
++.Nm
++utility returns a result which indicates the jailed status of
++the current process environment.
++.Sh DIAGNOSTICS
++The
++.Nm
++utility exits with one of the following values:
++.Bl -tag -width indent -compact
++.It 0
++the process is running in a jail.
++.It 1
++the process is not running in a jail.
++.It 2
++an error prevented determining if the process is running in a jail.
++.El
++.Sh BUGS
++.Nm
++uses kvm_getprocs(3) to determine process status. Anything which
++could cause a failure in either kvm_open(3) or kvm_getprocs(3) can
++cause this to fail as well. There aught to be a cleaner way.
++.Sh AUTHOR
++ James E. Quick <jq@quick.com>
++
++.Sh SEE ALSO
++.Xr jailer 8 ,
++.Xr jail 8 ,
++.Xr kvm 3
+diff -Naur jailer-1.1/src/injail.c jailer-1.1.1/src/injail.c
+--- jailer-1.1/src/injail.c Wed Dec 31 19:00:00 1969
++++ jailer-1.1.1/src/injail.c Tue May 28 15:15:54 2002
+@@ -0,0 +1,52 @@
++/* injail
++* A utility function to determine if a process is running in a
++* FreeBSD jail.
++*
++* Compiled with _INJAIL_MAIN will produce an executable to allow
++* testing from within scripts.
++*
++* This code was written by James E. Quick mailto:jq@quick.com
++* The code may be freely re-used under the terms of the BSD copyright,
++* as long as this comment remains intact.
++*/
++
++#include <kvm.h>
++#include <sys/param.h>
++#include <paths.h>
++#include <limits.h>
++#include <sys/types.h>
++#include <sys/user.h>
++#include <sys/sysctl.h>
++#include <sys/file.h>
++#include <stdio.h>
++
++#if __FreeBSD_version > 500000
++#define P_FLAG ki_flag
++#else
++#define P_FLAG kp_proc.p_flag
++#endif
++
++/* int injail()
++* Return 1 if running in a jail, 0 if not, -1 on error
++* jq 05/28/2002
++*/
++int injail ()
++{
++ int count = 0;
++ kvm_t *kd = 0;
++ struct kinfo_proc *kp;
++ char *memf, *nlistf, *swapf, errbuf[_POSIX2_LINE_MAX];
++ int result = -1;
++
++ memf = nlistf = swapf = _PATH_DEVNULL;
++ kd = kvm_openfiles(nlistf, memf, swapf, O_RDONLY, errbuf);
++ if (kd) {
++ kp = kvm_getprocs(kd, KERN_PROC_PID, getpid(), &count);
++ if (kp) {
++ result = (kp->P_FLAG & P_JAILED) ? 0:1;
++ }
++ kvm_close(kd);
++ }
++
++ return result;
++}
+diff -Naur jailer-1.1/src/injail_main.c jailer-1.1.1/src/injail_main.c
+--- jailer-1.1/src/injail_main.c Wed Dec 31 19:00:00 1969
++++ jailer-1.1.1/src/injail_main.c Tue May 28 15:30:01 2002
+@@ -0,0 +1,36 @@
++/* injail
++* A utility function to determine if a process is running in a
++* FreeBSD jail.
++*
++* Compiled with _INJAIL_MAIN will produce an executable to allow
++* testing from within scripts.
++*
++* This code was written by James E. Quick mailto:jq@quick.com
++* The code may be freely re-used under the terms of the BSD copyright,
++* as long as this comment remains intact.
++*/
++
++#include <stdio.h>
++
++int injail();
++
++/* main for injail
++* return 0 if in a jail
++* return 1 if not in jail
++* return 2 if error prevented determining status
++* jq 05/28/2002
++*/
++main(int argc, char *argv[])
++{
++ int jailed;
++
++ jailed = injail();
++ if (jailed == -1) {
++ fprintf(stderr, "injail: Could not determine jailed status.\n");
++ return 2;
++ } else if (jailed) {
++ return 0;
++ }
++
++ return 1;
++}
+diff -Naur jailer-1.1/src/jailer.c jailer-1.1.1/src/jailer.c
+--- jailer-1.1/src/jailer.c Tue May 21 16:18:19 2002
++++ jailer-1.1.1/src/jailer.c Tue May 28 15:34:32 2002
+@@ -92,15 +92,23 @@
+ static void getJailName(char* buff, int buffLen);
+ static int createConsole();
+ static int runCommand(char* command, char* header);
++int injail();
+
+ int main(int argc, char* argv[])
+ {
++ int jailed;
+ char* consoleFile = CONSOLE_LOG;
+ FILE* console = NULL;
+
++ jailed = injail();
++ if (jailed == 0 || jailed == -1) {
++ fprintf(stderr, "jailer: Cannot determine if I am in jail.\n");
++ return 1;
++ }
+ /* Get the name of the current jail */
+ getJailName(g_jailName, MAX_JAIL_NAME);
+
++
+ if(argc > 1)
+ consoleFile = argv[1];
+
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
new file mode 100755
index 0000000..f901774
--- /dev/null
+++ b/scripts/Makefile.am
@@ -0,0 +1,15 @@
+sbin_SCRIPTS = halt reboot
+EXTRA_DIST = halt reboot
+
+POST_INSTALL = echo ' \
+===============================================\
+ To complete the installation execute the \
+ following as root: \
+ \
+ cp $(sbindir)halt /sbin/halt \
+ cp $(sbindir)reboot /sbin/reboot \
+ chmod 400 /sbin/halt /sbin/reboot \
+ \
+ Make sure you're in a jail! \
+ \
+==============================================='\ \ No newline at end of file
diff --git a/scripts/halt b/scripts/halt
new file mode 100755
index 0000000..f762495
--- /dev/null
+++ b/scripts/halt
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# AUTHOR
+# N. Nielsen
+#
+# LICENSE
+# This software is in the public domain.
+#
+# The software is provided "as is", without warranty of any kind,
+# express or implied, including but not limited to the warranties
+# of merchantability, fitness for a particular purpose, and
+# noninfringement. In no event shall the author(s) be liable for any
+# claim, damages, or other liability, whether in an action of
+# contract, tort, or otherwise, arising from, out of, or in connection
+# with the software or the use or other dealings in the software.
+#
+# SUPPORT
+# Send bug reports to: <nielsen@memberwebs.com>
+#
+
+#
+# 'halt' command from inside the jail
+
+killall=`which killall`
+ret=1
+
+if [ -n ${killall} ] && [ -x ${killall} ]; then
+ killall -QUIT jailer 2> /dev/null
+ ret=$?
+else
+ ps -xa | grep "[j]ailer" | while read pid dummy; do
+
+ kill -QUIT ${pid} 2> /dev/null
+
+ if [ $? -eq 0 ]; then
+ ret=0
+ fi
+
+ done
+fi
+
+if [ $ret -ne 0 ]; then
+ echo "halt: jailer not running or insufficient permissions. can't halt jail." >&2
+fi
diff --git a/scripts/reboot b/scripts/reboot
new file mode 100755
index 0000000..c07bd15
--- /dev/null
+++ b/scripts/reboot
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# AUTHOR
+# N. Nielsen
+#
+# LICENSE
+# This software is in the public domain.
+#
+# The software is provided "as is", without warranty of any kind,
+# express or implied, including but not limited to the warranties
+# of merchantability, fitness for a particular purpose, and
+# noninfringement. In no event shall the author(s) be liable for any
+# claim, damages, or other liability, whether in an action of
+# contract, tort, or otherwise, arising from, out of, or in connection
+# with the software or the use or other dealings in the software.
+#
+# SUPPORT
+# Send bug reports to: <nielsen@memberwebs.com>
+#
+
+#
+# 'reboot' command from inside the jail
+
+killall=`which killall`
+ret=1
+
+if [ -n ${killall} ] && [ -x ${killall} ]; then
+ killall -HUP jailer 2> /dev/null
+ ret=$?
+else
+ ps -xa | grep "[j]ailer" | while read pid; do
+
+ kill -HUP ${pid} 2> /dev/null
+
+ if [ $? -eq 0 ]; then
+ ret=0
+ fi
+
+ done
+fi
+
+if [ $ret -ne 0 ]; then
+ echo "reboot: jailer not running or insufficient permissions. can't reboot jail." >&2
+fi
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100755
index 0000000..5cf6ab4
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,9 @@
+sbin_PROGRAMS = jailer dmesg
+bin_PROGRAMS = injail
+jailer_SOURCES = jailer.c injail.c
+dmesg_SOURCES = dmesg.c
+injail_SOURCES = injail.c injail_main.c
+man_MANS = jailer.8 injail.8
+LIBS = -lkvm
+EXTRA_DIST = $(man_MANS)
+
diff --git a/src/dmesg.c b/src/dmesg.c
new file mode 100755
index 0000000..af6fbbd
--- /dev/null
+++ b/src/dmesg.c
@@ -0,0 +1,117 @@
+/*
+// AUTHOR
+// N. Nielsen
+//
+// LICENSE
+// This software is in the public domain.
+//
+// The software is provided "as is", without warranty of any kind,
+// express or implied, including but not limited to the warranties
+// of merchantability, fitness for a particular purpose, and
+// noninfringement. In no event shall the author(s) be liable for any
+// claim, damages, or other liability, whether in an action of
+// contract, tort, or otherwise, arising from, out of, or in connection
+// with the software or the use or other dealings in the software.
+//
+// SUPPORT
+// Send bug reports to: <nielsen@memberwebs.com>
+//
+// CHANGES
+// 1.1
+// Initial implementation
+*/
+
+#define SYSLOG_NAMES
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdarg.h>
+
+
+#define CONSOLE_DEV "/dev/console"
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+/* Error handlers */
+static void doWarn(const char* msg, ...);
+static void doQuit(const char* msg, ...);
+
+static int fcopy(FILE* dest, FILE* src);
+
+int main(int argc, char* argv[])
+{
+ FILE* console;
+ struct stat sb;
+
+ /*
+ * Check to see if /dev/console is a real console
+ */
+ if(stat(CONSOLE_DEV, &sb) == 0)
+ {
+ if(!(sb.st_mode & S_IFREG || sb.st_mode & S_IFLNK))
+ {
+ doWarn("%s is not a jail console.", CONSOLE_DEV);
+ return 1;
+ }
+ }
+
+ console = fopen(CONSOLE_DEV, "r");
+ if(!console)
+ {
+ doQuit("couldn't open jail console: %s", strerror(errno));
+ return 1;
+ }
+
+ fcopy(stdout, console);
+ return 0;
+}
+
+void doQuit(const char* msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+
+ vwarnx(msg, ap);
+
+ exit(2);
+
+ va_end(ap);
+}
+
+void doWarn(const char* msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+
+ /* Either to syslog or stderr */
+ vwarnx(msg, ap);
+
+ va_end(ap);
+}
+
+
+static int fcopy(FILE* dest, FILE* src)
+{
+ char buff[32];
+ size_t bytes = 0;
+
+ while(!feof(src) && !ferror(src) && !ferror(dest))
+ {
+ bytes = fread(buff, 1, 32, src);
+ fwrite(buff, 1, bytes, dest);
+ }
+
+ if(ferror(src) || ferror(dest))
+ return -1;
+
+ return 0;
+}
+
diff --git a/src/injail.8 b/src/injail.8
new file mode 100755
index 0000000..26345a6
--- /dev/null
+++ b/src/injail.8
@@ -0,0 +1,36 @@
+.Dd May 28, 2002
+.Dt INJAIL 8
+.Os
+.Sh NAME
+.Nm injail
+.Nd determine if a process is running in a jail
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+The
+.Nm
+utility returns a result which indicates the jailed status of
+the current process environment.
+.Sh DIAGNOSTICS
+The
+.Nm
+utility exits with one of the following values:
+.Bl -tag -width indent -compact
+.It 0
+the process is running in a jail.
+.It 1
+the process is not running in a jail.
+.It 2
+an error prevented determining if the process is running in a jail.
+.El
+.Sh BUGS
+.Nm
+uses kvm_getprocs(3) to determine process status. Anything which
+could cause a failure in either kvm_open(3) or kvm_getprocs(3) can
+cause this to fail as well. There aught to be a cleaner way.
+.Sh AUTHOR
+ James E. Quick <jq@quick.com>
+.Sh SEE ALSO
+.Xr jailer 8 ,
+.Xr jail 8 ,
+.Xr kvm 3 \ No newline at end of file
diff --git a/src/injail.c b/src/injail.c
new file mode 100755
index 0000000..7d653a6
--- /dev/null
+++ b/src/injail.c
@@ -0,0 +1,67 @@
+/*
+// AUTHOR
+// James Quick <jq@quick.com>
+// N. Nielsen
+//
+// LICENSE
+// This software is in the public domain.
+//
+// The software is provided "as is", without warranty of any kind,
+// express or implied, including but not limited to the warranties
+// of merchantability, fitness for a particular purpose, and
+// noninfringement. In no event shall the author(s) be liable for any
+// claim, damages, or other liability, whether in an action of
+// contract, tort, or otherwise, arising from, out of, or in connection
+// with the software or the use or other dealings in the software.
+//
+// SUPPORT
+// Send bug reports to: <nielsen@memberwebs.com>
+//
+// injail
+// A utility function to determine if a process is running in a FreeBSD jail.
+//
+// This code was written by James E. Quick mailto:jq@quick.com
+// The code may be freely re-used under the terms of the BSD copyright,
+// as long as this comment remains intact.
+*/
+
+#include <kvm.h>
+#include <sys/param.h>
+#include <paths.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <sys/file.h>
+#include <stdio.h>
+
+#if __FreeBSD_version > 500000
+#define P_FLAG ki_flag
+#else
+#define P_FLAG kp_proc.p_flag
+#endif
+
+/* int injail()
+* Return 1 if running in a jail, 0 if not, -1 on error
+* jq 05/28/2002
+*/
+int injail ()
+{
+ int count = 0;
+ kvm_t* kd = 0;
+ struct kinfo_proc* kp;
+ char *memf, *nlistf, *swapf, errbuf[_POSIX2_LINE_MAX];
+ int result = -1;
+
+ memf = nlistf = swapf = _PATH_DEVNULL;
+ kd = kvm_openfiles(nlistf, memf, swapf, O_RDONLY, errbuf);
+ if(kd)
+ {
+ kp = kvm_getprocs(kd, KERN_PROC_PID, getpid(), &count);
+ if(kp)
+ result = (kp->P_FLAG & P_JAILED) ? 1 : 0;
+ kvm_close(kd);
+ }
+
+ return result;
+}
diff --git a/src/injail_main.c b/src/injail_main.c
new file mode 100755
index 0000000..aaf8034
--- /dev/null
+++ b/src/injail_main.c
@@ -0,0 +1,51 @@
+/*
+// AUTHOR
+// N. Nielsen
+// James Quick <jq@quick.com>
+//
+// LICENSE
+// This software is in the public domain.
+//
+// The software is provided "as is", without warranty of any kind,
+// express or implied, including but not limited to the warranties
+// of merchantability, fitness for a particular purpose, and
+// noninfringement. In no event shall the author(s) be liable for any
+// claim, damages, or other liability, whether in an action of
+// contract, tort, or otherwise, arising from, out of, or in connection
+// with the software or the use or other dealings in the software.
+//
+// SUPPORT
+// Send bug reports to: <nielsen@memberwebs.com>
+//
+// CHANGES
+// 1.1
+// Initial implementation
+//
+// injail
+// A utility function to determine if a process is running in a
+// FreeBSD jail.
+//
+// This code was contributed by James E. Quick mailto:jq@quick.com
+// The code may be freely re-used under the terms of the BSD copyright,
+// as long as this comment remains intact.
+*/
+
+#include <stdio.h>
+
+int injail();
+
+/* main for injail
+ * return 0 if in a jail
+ * return 1 if not in jail
+ * return 2 if error prevented determining status
+ * jq 05/28/2002
+ */
+main(int argc, char *argv[])
+{
+ int jailed = injail();
+
+ if(jailed == -1)
+ errx(2, "Could not determine jailed status.\n");
+
+ return jailed ? 0 : 1;
+}
diff --git a/src/jailer.8 b/src/jailer.8
new file mode 100755
index 0000000..9c9b1f9
--- /dev/null
+++ b/src/jailer.8
@@ -0,0 +1,131 @@
+.\" Process this file with
+.\" groff -man -Tascii jailer.8
+.\"
+.TH JAILER 8 "May 2002" "Version 1.2" "User Manual"
+.SH NAME
+.B jailer
+\- manage a jail from inside
+.SH SYNOPSIS
+.B jailer [
+.I console-file
+.B ]
+.SH DESCRIPTION
+.B jailer
+manages the startup and shutdown of a jail from within
+the jail. It also manages the jails console by linking
+/dev/console inside the jail to a log file.
+
+To use, replace the '/bin/sh /etc/rc' portion
+of your jail startup command with jailer. For example
+instead of:
+
+.RS 1
+.B jail /jails/myjail host 10.0.1.1 /bin/sh /etc/rc
+.RE 1
+
+use:
+
+.RS 1
+.B jail /jails/myjail host 10.0.1.1 /usr/local/sbin/jailer
+.RE 1
+
+
+.B jailer
+will start the jail by running
+.I /etc/rc
+and then remain running as a daemon inside the jail waiting
+for signals to perform shutdown or restarts.
+
+A shutdown is performed by first running
+.IR /etc/rc.shutdown ,
+and then killing all the processes still running. A restart is
+a combination of the above.
+
+
+The following signals have special meaning to the jailer:
+.IP HUP
+Causes
+.B jailer
+to restart the jail. If the jail is not running at the time
+it is simply started.
+.IP QUIT
+Initiates a jail shutdown.
+.B jailer
+remains running after processing the request.
+.IP TERM
+Same as
+.I QUIT
+but also quits jailer. No more processes will be left running
+inside the jail.
+
+.SH JAIL CONSOLE MANAGEMENT
+A normal jail has no console perse, and
+.BR dmesg (8)
+reads straight from the host kernel message buffer.
+.B jailer
+changes this to provide a virtual console for the jail.
+
+On jailer startup the file
+.I /var/log/console
+is created or truncated.
+.I /dev/console
+is then hard linked to the console file.
+
+Along with the jailer distribution you'll find a new
+.BR dmesg (8)
+which just reads from
+.I /dev/console.
+Replace
+.BR /sbin/dmesg (8)
+with this new executable and you're set.
+
+The output of
+.B jailer
+startup and shutdown operations are also output to this
+virtual console.
+
+.SH SCRIPTS
+Along with the
+.B jailer
+distribution come several helper scripts:
+
+.IP halt
+This is a replacement for
+.BR /sbin/halt (8)
+inside the jail which signals the running
+.B jailer
+process.
+.IP reboot
+Same as above for
+.BR /sbin/reboot (8)
+
+.SH OPTIONS
+.IP console-file
+Overrides the default location of the console log file,
+usually
+.I /var/log/console
+
+.SH FILES
+.I /var/log/console
+.RS
+Virtual console file.
+
+.SH BUGS
+Virtual jail consoles don't work with FreeBSD 5.0 yet. This is due to
+.BR devfs (8)
+
+.BR shutdown (8)
+doesn't work with the
+.I halt
+and
+.I reboot
+scripts.
+
+.SH AUTHOR
+Nate Nielsen <nielsen@memberwebs.com>
+
+.SH "SEE ALSO"
+.BR jail (8),
+.BR halt (8),
+.BR reboot (8),
+.BR dmesg (8)
diff --git a/src/jailer.c b/src/jailer.c
new file mode 100755
index 0000000..8b49489
--- /dev/null
+++ b/src/jailer.c
@@ -0,0 +1,494 @@
+/*
+// AUTHOR
+// N. Nielsen
+//
+// LICENSE
+// This software is in the public domain.
+//
+// The software is provided "as is", without warranty of any kind,
+// express or implied, including but not limited to the warranties
+// of merchantability, fitness for a particular purpose, and
+// noninfringement. In no event shall the author(s) be liable for any
+// claim, damages, or other liability, whether in an action of
+// contract, tort, or otherwise, arising from, out of, or in connection
+// with the software or the use or other dealings in the software.
+//
+// SUPPORT
+// Send bug reports to: <nielsen@memberwebs.com>
+//
+// CHANGES
+// 1.1
+// console support
+// restart support
+// 1.1.1
+// checks if in jail (contributed by jimquick@mac.com)
+// changes process title with state
+// Uses path for /dev/console from paths.h
+// Doesn't fail stop if all processes in jail died during rc.shutdown
+// 1.1.2
+// use select when piping script output
+//
+// 1.2
+// conditionally remove console support for use on FBSD 5
+*/
+
+#define SYSLOG_NAMES
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <sys/file.h>
+
+#include <kvm.h>
+#include <paths.h>
+#include <signal.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+/* Length of buffer used for reading status file */
+#define FILE_BUFF_LEN 1024
+
+/* Maximum length of a jail name */
+#define MAX_JAIL_NAME 256
+
+/* Used when restarting before doing a SIGKILL */
+#define EXIT_TIMEOUT 5
+
+#ifndef NO_CONSOLE
+ /* The default file for the console messages to go to */
+ #define CONSOLE_LOG "/var/log/console"
+#endif
+
+/* Headers to go to the console for startup and shutdown */
+#define START_HEADER "\nJAIL BOOT -- %s -- %s\n"
+#define STOP_HEADER "\nJAIL HALT -- %s -- %s\n"
+
+/* The startup and shutdown commands */
+#define JAIL_START "exec 2>&1; . /etc/rc"
+#define JAIL_STOP "exec 2>&1; . /etc/rc.shutdown"
+
+#define TITLE_START "%s (running)"
+#define TITLE_STOP "%s (halted)"
+
+/* Set by signal handlers */
+int g_doShutdown = 0;
+int g_doRestart = 0;
+int g_doExit = 0;
+
+/* Other state */
+int g_isBackground = 0;
+int g_isJailRunning = 0;
+char g_jailName[MAX_JAIL_NAME];
+
+/* Signal handlers */
+static void onTERM(int);
+static void onHUP(int);
+static void onQUIT(int);
+
+
+/* Error handlers */
+static void doWarn(const char* msg, ...);
+static void doQuit(const char* msg, ...);
+
+/* Main functionality */
+static int stopJail();
+static int startJail();
+
+/* Helper functions */
+static void getJailName(char* buff, int buffLen);
+static int runCommand(char* command, char* header);
+int injail();
+
+#ifndef NO_CONSOLE
+static int createConsole();
+#endif
+
+int main(int argc, char* argv[])
+{
+#ifndef NO_CONSOLE
+ char* consoleFile = CONSOLE_LOG;
+#endif
+
+ /* Check if we're in a jail */
+ switch(injail())
+ {
+ case 0:
+ doQuit("must be run in a jail.");
+ break;
+
+ case -1:
+ doQuit("couldn't determine if running in a jail.");
+ break;
+ }
+
+ /* Get the name of the current jail */
+ getJailName(g_jailName, MAX_JAIL_NAME);
+
+#ifndef NO_CONSOLE
+ if(argc > 1)
+ consoleFile = argv[1];
+
+ /* Create the console device properly */
+ if(createConsole(consoleFile) != 0)
+ return 1;
+#endif
+
+ /* Start the jail */
+ if(startJail() != 0)
+ return 1;
+
+ /* Go into daemon mode */
+ daemon(0, 0);
+ g_isBackground = 1;
+
+
+
+ /* Catch appropriate signals */
+ siginterrupt(SIGTERM, 1);
+ siginterrupt(SIGHUP, 1);
+ siginterrupt(SIGQUIT, 1);
+
+ signal(SIGTERM, onTERM);
+ signal(SIGHUP, onHUP);
+ signal(SIGQUIT, onQUIT);
+
+
+ /* And wait! */
+ while(1)
+ {
+ sleep(1);
+
+ /* Got SIGQUIT Shutdown jail, but keep us running */
+ if(g_doShutdown)
+ {
+ if(g_isJailRunning)
+ {
+ doWarn("shutting down jail: %s", g_jailName);
+ stopJail();
+ }
+
+ g_doShutdown = 0;
+ }
+
+
+ /* Got SIGHUP Stop if necessary and start jail */
+ if(g_doRestart)
+ {
+ doWarn("restarting jail: %s", g_jailName);
+
+ if(g_isJailRunning)
+ stopJail();
+
+ /* TODO: Should we start the jail again if stop fails? */
+ startJail();
+
+ g_doRestart = 0;
+ }
+
+
+ /* Got SIGTERM Stop jail if necessary, then exit */
+ else if(g_doExit)
+ {
+ if(g_isJailRunning)
+ {
+ doWarn("shutting down jail: %s", g_jailName);
+ return stopJail();
+ }
+
+ return 0;
+ }
+ }
+}
+
+
+static int startJail()
+{
+ /* Just run the startup command */
+ int ret = runCommand(JAIL_START, START_HEADER);
+ if(ret < 0)
+ {
+ doWarn("couldn't run jail start script: %s\n", strerror(errno));
+ return -1;
+ }
+ else
+ {
+ g_isJailRunning = 1;
+ setproctitle(TITLE_START, g_jailName);
+ return 0;
+ }
+}
+
+static int stopJail()
+{
+ /* Run the rc.shutdown script */
+ int ret = runCommand(JAIL_STOP, STOP_HEADER);
+ if(ret < 0)
+ {
+ doWarn("couldn't run jail shutdown script: %s\n", strerror(errno));
+ return -1;
+ }
+
+
+ /* Kill all processes still running nicely */
+ if(kill(-1, SIGTERM) == -1 ||
+ sleep(EXIT_TIMEOUT) ||
+ kill(-1, SIGKILL) == -1)
+ {
+ if(errno != ESRCH)
+ {
+ doWarn("couldn't stop jail %s: %s", g_jailName, strerror(errno));
+ return -1;
+ }
+ }
+
+
+ setproctitle(TITLE_STOP, g_jailName);
+ g_isJailRunning = 0;
+ return 0;
+}
+
+
+/* Special function to duplicate output of a command to two
+ files.
+
+ NOTE: Yes, I know this may seem like overkill, but system,
+ popen and all those guys would hang with certain rc scripts.
+ Those which opened a daemon in the background ('&') but still
+ kept their output going to the same stdin/stdout handles.
+*/
+
+/* read & write ends of a pipe */
+#define READ_END 0
+#define WRITE_END 1
+
+/* pre-set file descriptors */
+#define STDIN 0
+#define STDOUT 1
+#define STDERR 2
+
+static int runCommand(char* command, char* header)
+{
+ int outpipe[2];
+ int pid;
+
+ /* Create a pipe for the child process */
+ if(pipe(outpipe) < 0)
+ return -1;
+
+ /* Now fork*/
+ switch(pid = fork())
+ {
+ case -1:
+ return -1;
+
+ /* This is the child here */
+ case 0:
+
+ {
+ int ret = 0;
+
+ /* Fix up our end of the pipe */
+ if(dup2(outpipe[WRITE_END], STDOUT) < 0)
+ return -1;
+
+ /* Okay, now run whatever command it was */
+ execl("/bin/sh", "sh", "-c", command, NULL);
+
+ /* In case it returns then have to do this to get
+ children to disconnect from stdout */
+ fflush(stdout);
+ fclose(stdout);
+ close(outpipe[WRITE_END]);
+
+ exit(errno);
+ }
+ break;
+
+
+ /* And this is the parent */
+ default:
+ {
+#ifndef NO_CONSOLE
+ FILE* console = NULL;
+#endif
+ time_t tm;
+ char buff[256];
+ int ret;
+ int status = 0;
+ fd_set readmask;
+ struct timeval timeout = { 0, 10000 };
+
+ FD_ZERO(&readmask);
+
+#ifndef NO_CONSOLE
+ /* Open the console file and write the header */
+ if(console = fopen(_PATH_CONSOLE, "a"))
+ {
+ setvbuf(console, NULL, _IONBF, 0);
+
+ /* Write this stuff to the console */
+ tm = time(NULL);
+ fprintf(console, header, g_jailName, asctime(localtime(&tm)));
+ }
+#endif
+
+ /* No blocking on the child processes pipe */
+ fcntl(outpipe[READ_END], F_SETFL, fcntl(outpipe[READ_END], F_GETFL, 0) | O_NONBLOCK);
+
+ /* Loop until the process dies or no more output */
+ while(1)
+ {
+ FD_SET(outpipe[READ_END], &readmask);
+
+ if(select(FD_SETSIZE, &readmask, NULL, NULL, &timeout) == -1)
+ doQuit("panic: select: %s", strerror(errno));
+
+ if(FD_ISSET(outpipe[READ_END], &readmask))
+ {
+ /* Read a character */
+ while((ret = read(outpipe[READ_END], buff, 256)) > 0)
+ {
+ /* Write it to our stdout */
+ write(STDOUT, buff, ret);
+
+#ifndef NO_CONSOLE
+ /* And to our console */
+ if(console)
+ write(fileno(console), buff, ret);
+#endif
+ }
+ }
+
+ /* If the processes exited then break out */
+ if(waitpid(pid, &status, WNOHANG) == pid)
+ break;
+
+ /* Or if there's an error or end of file */
+ if(ret == -1 && errno != EAGAIN || ret == 0)
+ break;
+ }
+
+ /* Return any status codes */
+ if(status != 0)
+ return -1;
+
+ /* Clean up */
+ close(outpipe[READ_END]);
+
+#ifndef NO_CONSOLE
+ if(console)
+ fclose(console);
+#endif
+ }
+ }
+
+ return 0;
+}
+
+
+void doQuit(const char* msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+
+ /* Either to syslog or stderr */
+ if(g_isBackground)
+ vsyslog(LOG_ALERT, msg, ap);
+ else
+ vwarnx(msg, ap);
+
+ exit(2);
+
+ va_end(ap);
+}
+
+void doWarn(const char* msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+
+ /* Either to syslog or stderr */
+ if(g_isBackground)
+ vsyslog(LOG_ALERT, msg, ap);
+ else
+ vwarnx(msg, ap);
+
+ va_end(ap);
+}
+
+
+RETSIGTYPE onTERM(int x)
+{
+ g_doExit = 1;
+}
+
+RETSIGTYPE onQUIT(int x)
+{
+ g_doShutdown = 1;
+}
+
+RETSIGTYPE onHUP(int x)
+{
+ g_doRestart = 1;
+}
+
+
+
+static void getJailName(char* buff, int buffLen)
+{
+ if(gethostname(buff, buffLen) == -1)
+ doQuit("couldn't get host name: %s", strerror(errno));
+}
+
+#ifndef NO_CONSOLE
+static int createConsole(char* consoleFile)
+{
+ FILE* file = NULL;
+ struct stat sb;
+
+ /*
+ * If we have a /dev/console already, only overwrite
+ * if it's not legit. ie: it's a link or a normal file.
+ */
+ if(stat(_PATH_CONSOLE, &sb) == 0)
+ {
+ if(!(sb.st_mode & S_IFREG || sb.st_mode & S_IFLNK))
+ {
+ doWarn("%s may be a valid console device.", _PATH_CONSOLE);
+ return 0;
+ }
+ }
+
+ unlink(_PATH_CONSOLE);
+
+
+ /*
+ * Create the log file and console link
+ * Note that we overwrite the old console log file.
+ * TODO: We may want to make this an option to jailer
+ */
+ if(!(file = fopen(consoleFile, "w")) ||
+ link(consoleFile, _PATH_CONSOLE) == -1)
+ doWarn("couldn't do console link (%s to %s): %s", consoleFile, _PATH_CONSOLE, strerror(errno));
+
+ if(file)
+ fclose(file);
+
+
+ return 0;
+}
+#endif