diff options
author | Clint Adams <clint@debian.org> | 2011-05-18 15:03:14 -0400 |
---|---|---|
committer | Clint Adams <clint@debian.org> | 2011-05-18 15:12:57 -0400 |
commit | 23aa3ababf5b35deb09145caa82ddfffe3228183 (patch) | |
tree | a2ef7fde1db93a6ff21fdedd30bd537b43182ede | |
parent | e8fae4623f2fc84c5d0c31315d54bc3a7f7fdf63 (diff) | |
download | debianutils-23aa3ababf5b35deb09145caa82ddfffe3228183.tar.gz |
ischroot utility by Aurelien Jarno. closes: #627205.
-rw-r--r-- | Makefile.am | 6 | ||||
-rwxr-xr-x | debian/rules | 7 | ||||
-rw-r--r-- | ischroot.1 | 37 | ||||
-rw-r--r-- | ischroot.c | 196 | ||||
-rw-r--r-- | po4a/po4a.conf | 4 |
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 \ |