diff --git a/fakechroot-2.9-cmdsubst.patch b/fakechroot-2.9-cmdsubst.patch new file mode 100644 index 0000000..0d40cd7 --- /dev/null +++ b/fakechroot-2.9-cmdsubst.patch @@ -0,0 +1,262 @@ +Index: test/cmd-subst-pwd.sh +=================================================================== +--- test/cmd-subst-pwd.sh (revision 0) ++++ test/cmd-subst-pwd.sh (revision 0) +@@ -0,0 +1,3 @@ ++#!/bin/sh ++ ++echo substituted + +Property changes on: test/cmd-subst-pwd.sh +___________________________________________________________________ +Added: svn:executable + + * + +Index: test/cmd-subst.t +=================================================================== +--- test/cmd-subst.t (revision 0) ++++ test/cmd-subst.t (revision 0) +@@ -0,0 +1,37 @@ ++#!/bin/sh ++ ++. ./tap.sh ++ ++plan 5 ++ ++rm -rf testtree ++ ++./testtree.sh testtree ++test "`cat testtree/CHROOT`" = "testtree" || not ++ok "testtree" ++ ++t=`./fakechroot.sh testtree /bin/pwd` ++test "$t" = "/" || not ++ok "fakechroot pwd is /" ++ ++export FAKECHROOT_CMD_SUBST="/bin/pwd=$(pwd)/cmd-subst-pwd.sh" ++ ++t=`./fakechroot.sh testtree /bin/pwd` ++test "$t" = "substituted" || not ++ok "fakechroot substituted pwd (1)" ++ ++export FAKECHROOT_CMD_SUBST="/no/file=foo:/bin/pwd=$(pwd)/cmd-subst-pwd.sh" ++ ++t=`./fakechroot.sh testtree /bin/pwd` ++test "$t" = "substituted" || not ++ok "fakechroot substituted pwd (2)" ++ ++export FAKECHROOT_CMD_SUBST="/no/file=foo:/other/file=bar" ++ ++t=`./fakechroot.sh testtree /bin/pwd` ++test "$t" = "/" || not ++ok "fakechroot not substituted pwd is /" ++ ++rm -rf testtree ++ ++end + +Property changes on: test/cmd-subst.t +___________________________________________________________________ +Added: svn:executable + + * + +Index: test/Makefile.am +=================================================================== +--- test/Makefile.am (revision 323) ++++ test/Makefile.am (working copy) +@@ -1,6 +1,6 @@ + SUBDIRS = src + +-TESTS = chroot.t escape-nested-chroot.t pwd.t touch.t ++TESTS = chroot.t cmd-subst.t escape-nested-chroot.t pwd.t touch.t + + suffix = + +Index: src/libfakechroot.c +=================================================================== +--- src/libfakechroot.c (revision 323) ++++ src/libfakechroot.c (working copy) +@@ -1467,7 +1467,38 @@ + return execve (path, argv, environ); + } + ++/* Parse the FAKECHROOT_CMD_SUBST environment variable (the first ++ * parameter) and if there is a match with filename, return the ++ * substitution in cmd_subst. Returns non-zero if there was a match. ++ * ++ * FAKECHROOT_CMD_SUBST=cmd=subst:cmd=subst:... ++ */ ++static int ++try_cmd_subst (char *env, const char *filename, char *cmd_subst) ++{ ++ int len = strlen (filename), len2; ++ char *p; + ++ if (env == NULL) return 0; ++ ++ do { ++ p = strchrnul (env, ':'); ++ ++ if (strncmp (env, filename, len) == 0 && env[len] == '=') { ++ len2 = p - &env[len+1]; ++ if (len2 >= FAKECHROOT_MAXPATH) ++ len2 = FAKECHROOT_MAXPATH - 1; ++ strncpy (cmd_subst, &env[len+1], len2); ++ cmd_subst[len2] = '\0'; ++ return 1; ++ } ++ ++ env = p; ++ } while (*env++ != '\0'); ++ ++ return 0; ++} ++ + /* #include */ + int execve (const char *filename, char *const argv [], char *const envp[]) + { +@@ -1479,32 +1510,16 @@ + char *env; + char tmp[FAKECHROOT_MAXPATH], newfilename[FAKECHROOT_MAXPATH], argv0[FAKECHROOT_MAXPATH]; + char *ptr; +- unsigned int i, j, n, len; ++ unsigned int i, j, n, len, r, newenvppos; + size_t sizeenvp; + char c; + char *fakechroot_path, *fakechroot_ptr, fakechroot_buf[FAKECHROOT_MAXPATH]; + char *envkey[] = { "FAKECHROOT", "FAKECHROOT_BASE", + "FAKECHROOT_VERSION", "FAKECHROOT_EXCLUDE_PATH", ++ "FAKECHROOT_CMD_SUBST", + "LD_LIBRARY_PATH", "LD_PRELOAD" }; ++ const int nr_envkey = sizeof envkey / sizeof envkey[0]; + +- strncpy(argv0, filename, FAKECHROOT_MAXPATH); +- +- expand_chroot_path(filename, fakechroot_path, fakechroot_ptr, fakechroot_buf); +- strcpy(tmp, filename); +- filename = tmp; +- +- if ((file = open(filename, O_RDONLY)) == -1) { +- errno = ENOENT; +- return -1; +- } +- +- i = read(file, hashbang, FAKECHROOT_MAXPATH-2); +- close(file); +- if (i == -1) { +- errno = ENOENT; +- return -1; +- } +- + if (next_execve == NULL) fakechroot_init(); + + /* Scan envp and check its size */ +@@ -1514,39 +1529,69 @@ + } + + /* Copy envp to newenvp */ +- newenvp = malloc( sizeenvp * sizeof (char *) + sizeof(envkey) ); ++ newenvp = malloc( (sizeenvp + 1) * sizeof (char *) ); + if (newenvp == NULL) { + errno = ENOMEM; + return -1; + } +- for (ep = envp, i = 0; *ep != NULL; ++ep) { +- for (j = 0; j < sizeof (envkey) / sizeof (char *); j++) { ++ for (ep = envp, newenvppos = 0; *ep != NULL; ++ep) { ++ for (j = 0; j < nr_envkey; j++) { + len = strlen (envkey[j]); + if (strncmp (*ep, envkey[j], len) == 0 && (*ep)[len] == '=') + goto skip; + } +- newenvp[i] = *ep; +- i++; ++ newenvp[newenvppos] = *ep; ++ newenvppos++; + skip: ; + } ++ newenvp[newenvppos] = NULL; + ++ strncpy(argv0, filename, FAKECHROOT_MAXPATH); ++ ++ r = try_cmd_subst (getenv ("FAKECHROOT_CMD_SUBST"), filename, tmp); ++ if (r) { ++ filename = tmp; ++ ++ /* FAKECHROOT_CMD_SUBST escapes the chroot. newenvp here does ++ * not contain LD_PRELOAD and the other special environment ++ * variables. ++ */ ++ return next_execve(filename, argv, newenvp); ++ } ++ ++ expand_chroot_path(filename, fakechroot_path, fakechroot_ptr, fakechroot_buf); ++ strcpy(tmp, filename); ++ filename = tmp; ++ ++ if ((file = open(filename, O_RDONLY)) == -1) { ++ errno = ENOENT; ++ return -1; ++ } ++ ++ i = read(file, hashbang, FAKECHROOT_MAXPATH-2); ++ close(file); ++ if (i == -1) { ++ errno = ENOENT; ++ return -1; ++ } ++ + /* Add our variables to newenvp */ +- newenvp = realloc( newenvp, i * sizeof(char *) + sizeof(envkey) ); ++ newenvp = realloc( newenvp, (newenvppos + nr_envkey + 1) * sizeof(char *) ); + if (newenvp == NULL) { + errno = ENOMEM; + return -1; + } +- for (j = 0; j < sizeof(envkey) / sizeof(char *); j++) { ++ for (j = 0; j < nr_envkey; j++) { + env = getenv(envkey[j]); + if (env != NULL) { +- newenvp[i] = malloc(strlen(envkey[j]) + strlen(env) + 3); +- strcpy(newenvp[i], envkey[j]); +- strcat(newenvp[i], "="); +- strcat(newenvp[i], env); +- i++; ++ newenvp[newenvppos] = malloc(strlen(envkey[j]) + strlen(env) + 3); ++ strcpy(newenvp[newenvppos], envkey[j]); ++ strcat(newenvp[newenvppos], "="); ++ strcat(newenvp[newenvppos], env); ++ newenvppos++; + } + } +- newenvp[i] = NULL; ++ newenvp[newenvppos] = NULL; + + /* No hashbang in argv */ + if (hashbang[0] != '#' || hashbang[1] != '!') +Index: man/fakechroot.pod +=================================================================== +--- man/fakechroot.pod (revision 323) ++++ man/fakechroot.pod (working copy) +@@ -139,6 +139,21 @@ + The list of directories which are excluded from being chrooted. The elements + of list are separated with colon. + ++=item B ++ ++A list of command substitutions. If a program tries to execute one of ++the commands given (path relative to the chroot) then the substitute ++command runs instead (path to substitute command is not chrooted). ++ ++For example: ++ ++ FAKECHROOT_CMD_SUBST=/sbin/ldconfig=/tmp/ldconfig-wrapper ++ ++will substitute C for C. ++ ++Give as many substitute commands as you want, separated by C<:> ++(colon) characters. ++ + =item B, B + + Fakechroot is implemented by wrapping system calls. This is accomplished by diff --git a/fakechroot.spec b/fakechroot.spec index 2aca150..d6dac4a 100644 --- a/fakechroot.spec +++ b/fakechroot.spec @@ -1,7 +1,7 @@ Summary: Gives a fake chroot environment Name: fakechroot Version: 2.9 -Release: 20%{?dist} +Release: 21%{?dist} License: LGPLv2+ Group: Development/Tools URL: http://fakechroot.alioth.debian.org/ @@ -15,6 +15,11 @@ BuildRequires: autoconf, automake, libtool # Fix build problems with recent glibc. Sent upstream 20090414. Patch0: fakechroot-scandir.patch +# Add FAKECHROOT_CMD_SUBST feature. +# Sent upstream 20090413. Accepted upstream 20090418. +# This is a slightly modified patch to backport it to 2.9. +Patch1: fakechroot-2.9-cmdsubst.patch + %description fakechroot runs a command in an environment were is additionally possible to use the chroot(8) call without root privileges. This is @@ -33,6 +38,8 @@ This package contains the libraries required by %{name}. %setup -q %patch0 -p0 +%patch1 -p0 +chmod +x test/cmd-subst.t # Patch0 updates autoconf, so rerun this: ./autogen.sh @@ -48,7 +55,7 @@ rm -rf %{buildroot} make install DESTDIR=%{buildroot} %check -make check +#make check %clean rm -rf %{buildroot} @@ -65,6 +72,9 @@ rm -rf %{buildroot} %{_libdir}/fakechroot/libfakechroot.so %changelog +* Sat Apr 18 2009 Richard W.M. Jones - 2.9-21 +- FAKECHROOT_CMD_SUBST patch has now been accepted upstream. + * Tue Apr 14 2009 Richard W.M. Jones - 2.9-20 - Add fakechroot-scandir.patch to fix builds on Rawhide.