summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClint Adams <clint@debian.org>2011-05-18 15:03:14 -0400
committerClint Adams <clint@debian.org>2011-05-18 15:12:57 -0400
commit23aa3ababf5b35deb09145caa82ddfffe3228183 (patch)
treea2ef7fde1db93a6ff21fdedd30bd537b43182ede
parente8fae4623f2fc84c5d0c31315d54bc3a7f7fdf63 (diff)
downloaddebianutils-23aa3ababf5b35deb09145caa82ddfffe3228183.tar.gz
ischroot utility by Aurelien Jarno. closes: #627205.
-rw-r--r--Makefile.am6
-rwxr-xr-xdebian/rules7
-rw-r--r--ischroot.137
-rw-r--r--ischroot.c196
-rw-r--r--po4a/po4a.conf4
5 files changed, 246 insertions, 4 deletions
diff --git a/Makefile.am b/Makefile.am
index 789d641..2ad3d26 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,9 +2,10 @@ AUTOMAKE_OPTIONS = foreign
SUBDIRS = po4a
-bin_PROGRAMS = run-parts tempfile
+bin_PROGRAMS = run-parts tempfile ischroot
run_parts_SOURCES = run-parts.c
tempfile_SOURCES = tempfile.c
+ischroot_SOURCES = ischroot.c
bin_SCRIPTS = which savelog
@@ -12,4 +13,5 @@ sbin_SCRIPTS = installkernel add-shell remove-shell
man_MANS = run-parts.8 \
installkernel.8 savelog.8 \
- tempfile.1 which.1 add-shell.8 remove-shell.8
+ tempfile.1 which.1 add-shell.8 \
+ remove-shell.8 ischroot.1
diff --git a/debian/rules b/debian/rules
index dd44f41..e1d4e49 100755
--- a/debian/rules
+++ b/debian/rules
@@ -64,7 +64,8 @@ binary-arch: checkroot build
ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
strip --remove-section=.comment --remove-section=.note \
debian/tmp/bin/run-parts \
- debian/tmp/bin/tempfile
+ debian/tmp/bin/tempfile \
+ debian/tmp/usr/bin/ischroot
endif
ifneq ($(DEB_HOST_ARCH_OS),hurd)
@@ -91,7 +92,9 @@ endif
cd debian/tmp && find * -type f ! -regex '^DEBIAN/.*' -print0 | xargs -r0 md5sum > DEBIAN/md5sums
- dpkg-shlibdeps debian/tmp/bin/run-parts debian/tmp/bin/tempfile
+ dpkg-shlibdeps debian/tmp/bin/run-parts \
+ debian/tmp/bin/tempfile \
+ debian/tmp/usr/bin/ischroot
dpkg-gencontrol -isp
dpkg --build debian/tmp ..
diff --git a/ischroot.1 b/ischroot.1
new file mode 100644
index 0000000..7a84c09
--- /dev/null
+++ b/ischroot.1
@@ -0,0 +1,37 @@
+.\" -*- nroff -*-
+.TH ISCHROOT 1 "17 May 2011" "Debian"
+.SH NAME
+ischroot \- detect if running in a chroot
+.SH SYNOPSIS
+.B ischroot
+[\-\-default\-false] [\-\-default\-true] [\-\-help] [\-\-version]
+.SH DESCRIPTION
+.PP
+.B ischroot
+detects if it is currently running in a chroot. The exit status is:
+.TP
+0
+if currently running in a chroot
+.TP
+1
+if currently not running in a chroot
+.TP
+2
+if the detection is not possible (On GNU/Linux in happens if the script
+is not run as root).
+.SH OPTIONS
+.TP
+.B "-f, --default-false "
+Exit with status 1 if the detection is not possible.
+.TP
+.B "-t, --default-true "
+Exit with status 0 if the detection is not possible.
+.TP
+.B "--help"
+Print a usage message on standard output and exit successfully.
+.TP
+.B "--version"
+Print version information on standard output and exit successfully.
+.SH BUGS
+On GNU/Linux, chroot detection is not possible as root. This works correctly
+on GNU/Hurd and GNU/kFreeBSD.
diff --git a/ischroot.c b/ischroot.c
new file mode 100644
index 0000000..f280602
--- /dev/null
+++ b/ischroot.c
@@ -0,0 +1,196 @@
+/* ischroot: detect if running in a chroot
+ *
+ * Debian ischroot program
+ * Copyright (C) 2011 Aurelien Jarno <aurel32@debian.org>
+ *
+ * This is free software; see the GNU General Public License version 2
+ * or later for copying conditions. There is NO warranty.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif /* HAVE_GETOPT_H */
+
+void version()
+{
+ fprintf(stderr, "Debian ischroot, version " PACKAGE_VERSION
+ "Copyright (C) 2011 Aurelien Jarno\n"
+ "This is free software; see the GNU General Public License version 2\n"
+ "or later for copying conditions. There is NO warranty.\n");
+ exit(0);
+}
+
+void usage()
+{
+ fprintf(stderr, "Usage: ischroot [OPTION]\n"
+ " -f, --default-false return false if detection fails\n"
+ " -t, --default-true return true if detection fails\n"
+ " -V, --version output version information and exit.\n"
+ " -h, --help display this help and exit.\n");
+ exit(0);
+}
+
+#if defined (__linux__)
+
+/* On Linux we can detect chroots by checking if the
+ * devicenumber/inode pair of / are the same as that of
+ * /sbin/init's. This may fail if not running as root or if
+ * /proc is not mounted, in which case 2 is returned.
+ */
+
+static int ischroot()
+{
+ struct stat st1, st2;
+
+ if (stat("/", &st1) || stat("/proc/1/root", &st2))
+ return 2;
+ else if ((st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino))
+ return 1;
+ else
+ return 0;
+}
+
+#elif defined (__FreeBSD_kernel__) || defined (__FreeBSD__)
+
+#include <sys/sysctl.h>
+#include <sys/user.h>
+
+/* On FreeBSD we can detect chroot by looking for a specific
+ * file descriptor pointing to the location of the chroot. There
+ * is not need to be root, so it is unlikely to fail in normal
+ * cases, but return 2 if a memory failure or the like happens. */
+
+static int ischroot()
+{
+ int mib[4];
+ size_t kf_len = 0;
+ char *kf_buf, *kf_bufp;
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_FILEDESC;
+ mib[3] = getpid ();
+
+ if (sysctl (mib, 4, NULL, &kf_len, NULL, 0) != 0)
+ return 2;
+
+ kf_buf = kf_bufp = malloc (kf_len);
+ if (kf_buf == NULL)
+ return 2;
+
+ if (sysctl (mib, 4, kf_buf, &kf_len, NULL, 0) != 0)
+ {
+ free(kf_buf);
+ return 2;
+ }
+
+ while (kf_bufp < kf_buf + kf_len)
+ {
+ struct kinfo_file *kf = (struct kinfo_file *) (uintptr_t) kf_bufp;
+
+ if (kf->kf_fd == KF_FD_TYPE_JAIL)
+ {
+ free(kf_buf);
+ return 0;
+ }
+ kf_bufp += kf->kf_structsize;
+ }
+
+ free(kf_buf);
+ return 1;
+}
+
+#elif defined (__GNU__)
+
+/* On Hurd we can detect chroot by looking at the device number
+ * containing /. The device number of the first mounted filesystem
+ * equals 3, and due to bug http://savannah.gnu.org/bugs/?23213
+ * chroots have to be created on a different filesystem. Return 2
+ * if it is not possible to probe this device. */
+
+static int ischroot()
+{
+ struct stat st;
+
+ if (stat("/", &st))
+ return 2;
+ else if (st.st_dev == 3)
+ return 1;
+ else
+ return 0;
+}
+
+#else
+
+static int ischroot()
+{
+ return 2;
+}
+
+#warning unknown system, chroot detection will always fail
+
+#endif
+
+/* Process options */
+int main(int argc, char *argv[])
+{
+ int default_false = 0;
+ int default_true = 0;
+ int exit_status;
+
+ for (;;) {
+ int c;
+ int option_index = 0;
+
+ static struct option long_options[] = {
+ {"default-false", 0, 0, 'f'},
+ {"default-true", 0, 0, 't'},
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'V'},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "fthV", long_options, &option_index);
+ if (c == EOF)
+ break;
+ switch (c) {
+ case 'f':
+ default_false = 1;
+ break;
+ case 't':
+ default_true = 1;
+ break;
+ case 'h':
+ usage();
+ break;
+ case 'V':
+ version();
+ break;
+ default:
+ fprintf(stderr, "Try `ischroot --help' for more information.\n");
+ exit(1);
+ }
+ }
+
+ if (default_false && default_true) {
+ fprintf(stderr, "Can't default to both true and false!\n");
+ fprintf(stderr, "Try `ischroot --help' for more information.\n");
+ exit(1);
+ }
+
+ exit_status = ischroot();
+
+ if (exit_status == 2) {
+ if (default_true)
+ exit_status = 0;
+ if (default_false)
+ exit_status = 1;
+ }
+
+ return exit_status;
+}
diff --git a/po4a/po4a.conf b/po4a/po4a.conf
index e6d0626..97d8437 100644
--- a/po4a/po4a.conf
+++ b/po4a/po4a.conf
@@ -11,6 +11,10 @@
sl:sl/installkernel.8 add_sl:sl/translator_slovene.add \
de:de/installkernel.8 add_de:de/translator_german.add \
es:es/installkernel.8
+[type:man] ../ischroot.1 fr:fr/ischroot.1 add_fr:fr/ischroot.1.fr.add \
+ sl:sl/ischroot.1 add_sl:sl/translator_slovene.add \
+ de:de/ischroot.1 add_de:de/translator_german.add \
+ es:es/ischroot.1
# There is no mdoc module in po4a. This one is still translated manually
[type:man] ../remove-shell.8 fr:fr/remove-shell.8 add_fr:fr/translator_french.add \
sl:sl/remove-shell.8 add_sl:sl/translator_slovene.add \