install.py: add bash wrapper for python script
authorZac Medico <zmedico@gentoo.org>
Sat, 22 Jun 2013 00:29:42 +0000 (17:29 -0700)
committerZac Medico <zmedico@gentoo.org>
Sat, 22 Jun 2013 00:29:42 +0000 (17:29 -0700)
The wrapper is needed in order to support the PORTAGE_PYTHON variable,
and also safe python imports (see bug #469338).

bin/ebuild-helpers/xattr/install [new file with mode: 0755]
bin/install.py

diff --git a/bin/ebuild-helpers/xattr/install b/bin/ebuild-helpers/xattr/install
new file mode 100755 (executable)
index 0000000..51a4774
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Copyright 2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
+PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
+# Use safe cwd, avoiding unsafe import for bug #469338.
+export __PORTAGE_HELPER_CWD=${PWD}
+cd "${PORTAGE_PYM_PATH}"
+export __PORTAGE_HELPER_PATH=${BASH_SOURCE[0]}
+PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}$PYTHONPATH \
+       exec "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/install.py" "$@"
index f7118a683a6b1820c2398883d84336a8eb1b88dd..4925564c34cf128fb0968018ff2ec2ca1a8111d1 100755 (executable)
@@ -3,6 +3,7 @@
 # Distributed under the terms of the GNU General Public License v2
 
 import os
+import stat
 import sys
 import subprocess
 import traceback
@@ -25,6 +26,9 @@ except ImportError:
                        self.add_argument = parser.add_option
                        self.parse_known_args = parser.parse_args
 
+# Change back to original cwd _after_ all imports (bug #469338).
+os.chdir(os.environ["__PORTAGE_HELPER_CWD"])
+
 def parse_args(args):
        """
        Parse the command line arguments using optparse for python 2.6 compatibility
@@ -194,34 +198,45 @@ def copy_xattrs(opts, files):
                return os.EX_OSERR
 
 
-def Which(filename, path=None, all=False):
+def Which(filename, path=None, exclude=None):
        """
        Find the absolute path of 'filename' in a given search 'path'
        Args:
          filename: basename of the file
          path: colon delimited search path
-         all: return a list of all intances if true, else return just the first
+         exclude: path of file to exclude
        """
        if path is None:
                path = os.environ.get('PATH', '')
-       ret = []
+
+       if exclude is not None:
+               st = os.stat(exclude)
+               exclude = (st.st_ino, st.st_dev)
+
        for p in path.split(':'):
                p = os.path.join(p, filename)
                if os.access(p, os.X_OK):
-                       if all:
-                               ret.append(p)
+                       try:
+                               st = os.stat(p)
+                       except OSError:
+                               # file disappeared?
+                               pass
                        else:
-                               return p
-       if all:
-               return ret
-       else:
-               return None
+                               if stat.S_ISREG(st.st_mode) and \
+                                       (exclude is None or exclude != (st.st_ino, st.st_dev)):
+                                       return p
+
+       return None
 
 
 def main(args):
        opts, files = parse_args(args)
-       path_installs = Which('install', all=True)
-       cmdline = path_installs[0:1]
+       install_binary = Which('install', exclude=os.environ["__PORTAGE_HELPER_PATH"])
+       if install_binary is None:
+               sys.stderr.write("install: command not found\n")
+               return 127
+
+       cmdline = [install_binary]
        cmdline += args
 
        if sys.hexversion >= 0x3020000: