diff --git a/lib/python2.7/rexec.py b/lib/python2.7/rexec.py
new file mode 100644
index 0000000..7446151
--- /dev/null
+++ b/lib/python2.7/rexec.py
@@ -0,0 +1,588 @@
+"""Restricted execution facilities.
+
+The class RExec exports methods r_exec(), r_eval(), r_execfile(), and
+r_import(), which correspond roughly to the built-in operations
+exec, eval(), execfile() and import, but executing the code in an
+environment that only exposes those built-in operations that are
+deemed safe.  To this end, a modest collection of 'fake' modules is
+created which mimics the standard modules by the same names.  It is a
+policy decision which built-in modules and operations are made
+available; this module provides a reasonable default, but derived
+classes can change the policies e.g. by overriding or extending class
+variables like ok_builtin_modules or methods like make_sys().
+
+XXX To do:
+- r_open should allow writing tmp dir
+- r_exec etc. with explicit globals/locals? (Use rexec("exec ... in ...")?)
+
+"""
+from warnings import warnpy3k
+warnpy3k("the rexec module has been removed in Python 3.0", stacklevel=2)
+del warnpy3k
+
+
+import sys
+import __builtin__
+import os
+import ihooks
+import imp
+
+__all__ = ["RExec"]
+
+class FileBase:
+
+    ok_file_methods = ('fileno', 'flush', 'isatty', 'read', 'readline',
+            'readlines', 'seek', 'tell', 'write', 'writelines', 'xreadlines',
+            '__iter__')
+
+
+class FileWrapper(FileBase):
+
+    # XXX This is just like a Bastion -- should use that!
+
+    def __init__(self, f):
+        for m in self.ok_file_methods:
+            if not hasattr(self, m) and hasattr(f, m):
+                setattr(self, m, getattr(f, m))
+
+    def close(self):
+        self.flush()
+
+
+TEMPLATE = """
+def %s(self, *args):
+        return getattr(self.mod, self.name).%s(*args)
+"""
+
+class FileDelegate(FileBase):
+
+    def __init__(self, mod, name):
+        self.mod = mod
+        self.name = name
+
+    for m in FileBase.ok_file_methods + ('close',):
+        exec TEMPLATE % (m, m)
+
+
+class RHooks(ihooks.Hooks):
+
+    def __init__(self, *args):
+        # Hacks to support both old and new interfaces:
+        # old interface was RHooks(rexec[, verbose])
+        # new interface is RHooks([verbose])
+        verbose = 0
+        rexec = None
+        if args and type(args[-1]) == type(0):
+            verbose = args[-1]
+            args = args[:-1]
+        if args and hasattr(args[0], '__class__'):
+            rexec = args[0]
+            args = args[1:]
+        if args:
+            raise TypeError, "too many arguments"
+        ihooks.Hooks.__init__(self, verbose)
+        self.rexec = rexec
+
+    def set_rexec(self, rexec):
+        # Called by RExec instance to complete initialization
+        self.rexec = rexec
+
+    def get_suffixes(self):
+        return self.rexec.get_suffixes()
+
+    def is_builtin(self, name):
+        return self.rexec.is_builtin(name)
+
+    def init_builtin(self, name):
+        m = __import__(name)
+        return self.rexec.copy_except(m, ())
+
+    def init_frozen(self, name): raise SystemError, "don't use this"
+    def load_source(self, *args): raise SystemError, "don't use this"
+    def load_compiled(self, *args): raise SystemError, "don't use this"
+    def load_package(self, *args): raise SystemError, "don't use this"
+
+    def load_dynamic(self, name, filename, file):
+        return self.rexec.load_dynamic(name, filename, file)
+
+    def add_module(self, name):
+        return self.rexec.add_module(name)
+
+    def modules_dict(self):
+        return self.rexec.modules
+
+    def default_path(self):
+        return self.rexec.modules['sys'].path
+
+
+# XXX Backwards compatibility
+RModuleLoader = ihooks.FancyModuleLoader
+RModuleImporter = ihooks.ModuleImporter
+
+
+class RExec(ihooks._Verbose):
+    """Basic restricted execution framework.
+
+    Code executed in this restricted environment will only have access to
+    modules and functions that are deemed safe; you can subclass RExec to
+    add or remove capabilities as desired.
+
+    The RExec class can prevent code from performing unsafe operations like
+    reading or writing disk files, or using TCP/IP sockets.  However, it does
+    not protect against code using extremely large amounts of memory or
+    processor time.
+
+    """
+
+    ok_path = tuple(sys.path)           # That's a policy decision
+
+    ok_builtin_modules = ('audioop', 'array', 'binascii',
+                          'cmath', 'errno', 'imageop',
+                          'marshal', 'math', 'md5', 'operator',
+                          'parser', 'select',
+                          'sha', '_sre', 'strop', 'struct', 'time',
+                          '_weakref')
+
+    ok_posix_names = ('error', 'fstat', 'listdir', 'lstat', 'readlink',
+                      'stat', 'times', 'uname', 'getpid', 'getppid',
+                      'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')
+
+    ok_sys_names = ('byteorder', 'copyright', 'exit', 'getdefaultencoding',
+                    'getrefcount', 'hexversion', 'maxint', 'maxunicode',
+                    'platform', 'ps1', 'ps2', 'version', 'version_info')
+
+    nok_builtin_names = ('open', 'file', 'reload', '__import__')
+
+    ok_file_types = (imp.C_EXTENSION, imp.PY_SOURCE)
+
+    def __init__(self, hooks = None, verbose = 0):
+        """Returns an instance of the RExec class.
+
+        The hooks parameter is an instance of the RHooks class or a subclass
+        of it.  If it is omitted or None, the default RHooks class is
+        instantiated.
+
+        Whenever the RExec module searches for a module (even a built-in one)
+        or reads a module's code, it doesn't actually go out to the file
+        system itself.  Rather, it calls methods of an RHooks instance that
+        was passed to or created by its constructor.  (Actually, the RExec
+        object doesn't make these calls --- they are made by a module loader
+        object that's part of the RExec object.  This allows another level of
+        flexibility, which can be useful when changing the mechanics of
+        import within the restricted environment.)
+
+        By providing an alternate RHooks object, we can control the file
+        system accesses made to import a module, without changing the
+        actual algorithm that controls the order in which those accesses are
+        made.  For instance, we could substitute an RHooks object that
+        passes all filesystem requests to a file server elsewhere, via some
+        RPC mechanism such as ILU.  Grail's applet loader uses this to support
+        importing applets from a URL for a directory.
+
+        If the verbose parameter is true, additional debugging output may be
+        sent to standard output.
+
+        """
+
+        raise RuntimeError, "This code is not secure in Python 2.2 and later"
+
+        ihooks._Verbose.__init__(self, verbose)
+        # XXX There's a circular reference here:
+        self.hooks = hooks or RHooks(verbose)
+        self.hooks.set_rexec(self)
+        self.modules = {}
+        self.ok_dynamic_modules = self.ok_builtin_modules
+        list = []
+        for mname in self.ok_builtin_modules:
+            if mname in sys.builtin_module_names:
+                list.append(mname)
+        self.ok_builtin_modules = tuple(list)
+        self.set_trusted_path()
+        self.make_builtin()
+        self.make_initial_modules()
+        # make_sys must be last because it adds the already created
+        # modules to its builtin_module_names
+        self.make_sys()
+        self.loader = RModuleLoader(self.hooks, verbose)
+        self.importer = RModuleImporter(self.loader, verbose)
+
+    def set_trusted_path(self):
+        # Set the path from which dynamic modules may be loaded.
+        # Those dynamic modules must also occur in ok_builtin_modules
+        self.trusted_path = filter(os.path.isabs, sys.path)
+
+    def load_dynamic(self, name, filename, file):
+        if name not in self.ok_dynamic_modules:
+            raise ImportError, "untrusted dynamic module: %s" % name
+        if name in sys.modules:
+            src = sys.modules[name]
+        else:
+            src = imp.load_dynamic(name, filename, file)
+        dst = self.copy_except(src, [])
+        return dst
+
+    def make_initial_modules(self):
+        self.make_main()
+        self.make_osname()
+
+    # Helpers for RHooks
+
+    def get_suffixes(self):
+        return [item   # (suff, mode, type)
+                for item in imp.get_suffixes()
+                if item[2] in self.ok_file_types]
+
+    def is_builtin(self, mname):
+        return mname in self.ok_builtin_modules
+
+    # The make_* methods create specific built-in modules
+
+    def make_builtin(self):
+        m = self.copy_except(__builtin__, self.nok_builtin_names)
+        m.__import__ = self.r_import
+        m.reload = self.r_reload
+        m.open = m.file = self.r_open
+
+    def make_main(self):
+        self.add_module('__main__')
+
+    def make_osname(self):
+        osname = os.name
+        src = __import__(osname)
+        dst = self.copy_only(src, self.ok_posix_names)
+        dst.environ = e = {}
+        for key, value in os.environ.items():
+            e[key] = value
+
+    def make_sys(self):
+        m = self.copy_only(sys, self.ok_sys_names)
+        m.modules = self.modules
+        m.argv = ['RESTRICTED']
+        m.path = map(None, self.ok_path)
+        m.exc_info = self.r_exc_info
+        m = self.modules['sys']
+        l = self.modules.keys() + list(self.ok_builtin_modules)
+        l.sort()
+        m.builtin_module_names = tuple(l)
+
+    # The copy_* methods copy existing modules with some changes
+
+    def copy_except(self, src, exceptions):
+        dst = self.copy_none(src)
+        for name in dir(src):
+            setattr(dst, name, getattr(src, name))
+        for name in exceptions:
+            try:
+                delattr(dst, name)
+            except AttributeError:
+                pass
+        return dst
+
+    def copy_only(self, src, names):
+        dst = self.copy_none(src)
+        for name in names:
+            try:
+                value = getattr(src, name)
+            except AttributeError:
+                continue
+            setattr(dst, name, value)
+        return dst
+
+    def copy_none(self, src):
+        m = self.add_module(src.__name__)
+        m.__doc__ = src.__doc__
+        return m
+
+    # Add a module -- return an existing module or create one
+
+    def add_module(self, mname):
+        m = self.modules.get(mname)
+        if m is None:
+            self.modules[mname] = m = self.hooks.new_module(mname)
+        m.__builtins__ = self.modules['__builtin__']
+        return m
+
+    # The r* methods are public interfaces
+
+    def r_exec(self, code):
+        """Execute code within a restricted environment.
+
+        The code parameter must either be a string containing one or more
+        lines of Python code, or a compiled code object, which will be
+        executed in the restricted environment's __main__ module.
+
+        """
+        m = self.add_module('__main__')
+        exec code in m.__dict__
+
+    def r_eval(self, code):
+        """Evaluate code within a restricted environment.
+
+        The code parameter must either be a string containing a Python
+        expression, or a compiled code object, which will be evaluated in
+        the restricted environment's __main__ module.  The value of the
+        expression or code object will be returned.
+
+        """
+        m = self.add_module('__main__')
+        return eval(code, m.__dict__)
+
+    def r_execfile(self, file):
+        """Execute the Python code in the file in the restricted
+        environment's __main__ module.
+
+        """
+        m = self.add_module('__main__')
+        execfile(file, m.__dict__)
+
+    def r_import(self, mname, globals={}, locals={}, fromlist=[]):
+        """Import a module, raising an ImportError exception if the module
+        is considered unsafe.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        """
+        return self.importer.import_module(mname, globals, locals, fromlist)
+
+    def r_reload(self, m):
+        """Reload the module object, re-parsing and re-initializing it.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        """
+        return self.importer.reload(m)
+
+    def r_unload(self, m):
+        """Unload the module.
+
+        Removes it from the restricted environment's sys.modules dictionary.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        """
+        return self.importer.unload(m)
+
+    # The s_* methods are similar but also swap std{in,out,err}
+
+    def make_delegate_files(self):
+        s = self.modules['sys']
+        self.delegate_stdin = FileDelegate(s, 'stdin')
+        self.delegate_stdout = FileDelegate(s, 'stdout')
+        self.delegate_stderr = FileDelegate(s, 'stderr')
+        self.restricted_stdin = FileWrapper(sys.stdin)
+        self.restricted_stdout = FileWrapper(sys.stdout)
+        self.restricted_stderr = FileWrapper(sys.stderr)
+
+    def set_files(self):
+        if not hasattr(self, 'save_stdin'):
+            self.save_files()
+        if not hasattr(self, 'delegate_stdin'):
+            self.make_delegate_files()
+        s = self.modules['sys']
+        s.stdin = self.restricted_stdin
+        s.stdout = self.restricted_stdout
+        s.stderr = self.restricted_stderr
+        sys.stdin = self.delegate_stdin
+        sys.stdout = self.delegate_stdout
+        sys.stderr = self.delegate_stderr
+
+    def reset_files(self):
+        self.restore_files()
+        s = self.modules['sys']
+        self.restricted_stdin = s.stdin
+        self.restricted_stdout = s.stdout
+        self.restricted_stderr = s.stderr
+
+
+    def save_files(self):
+        self.save_stdin = sys.stdin
+        self.save_stdout = sys.stdout
+        self.save_stderr = sys.stderr
+
+    def restore_files(self):
+        sys.stdin = self.save_stdin
+        sys.stdout = self.save_stdout
+        sys.stderr = self.save_stderr
+
+    def s_apply(self, func, args=(), kw={}):
+        self.save_files()
+        try:
+            self.set_files()
+            r = func(*args, **kw)
+        finally:
+            self.restore_files()
+        return r
+
+    def s_exec(self, *args):
+        """Execute code within a restricted environment.
+
+        Similar to the r_exec() method, but the code will be granted access
+        to restricted versions of the standard I/O streams sys.stdin,
+        sys.stderr, and sys.stdout.
+
+        The code parameter must either be a string containing one or more
+        lines of Python code, or a compiled code object, which will be
+        executed in the restricted environment's __main__ module.
+
+        """
+        return self.s_apply(self.r_exec, args)
+
+    def s_eval(self, *args):
+        """Evaluate code within a restricted environment.
+
+        Similar to the r_eval() method, but the code will be granted access
+        to restricted versions of the standard I/O streams sys.stdin,
+        sys.stderr, and sys.stdout.
+
+        The code parameter must either be a string containing a Python
+        expression, or a compiled code object, which will be evaluated in
+        the restricted environment's __main__ module.  The value of the
+        expression or code object will be returned.
+
+        """
+        return self.s_apply(self.r_eval, args)
+
+    def s_execfile(self, *args):
+        """Execute the Python code in the file in the restricted
+        environment's __main__ module.
+
+        Similar to the r_execfile() method, but the code will be granted
+        access to restricted versions of the standard I/O streams sys.stdin,
+        sys.stderr, and sys.stdout.
+
+        """
+        return self.s_apply(self.r_execfile, args)
+
+    def s_import(self, *args):
+        """Import a module, raising an ImportError exception if the module
+        is considered unsafe.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        Similar to the r_import() method, but has access to restricted
+        versions of the standard I/O streams sys.stdin, sys.stderr, and
+        sys.stdout.
+
+        """
+        return self.s_apply(self.r_import, args)
+
+    def s_reload(self, *args):
+        """Reload the module object, re-parsing and re-initializing it.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        Similar to the r_reload() method, but has access to restricted
+        versions of the standard I/O streams sys.stdin, sys.stderr, and
+        sys.stdout.
+
+        """
+        return self.s_apply(self.r_reload, args)
+
+    def s_unload(self, *args):
+        """Unload the module.
+
+        Removes it from the restricted environment's sys.modules dictionary.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        Similar to the r_unload() method, but has access to restricted
+        versions of the standard I/O streams sys.stdin, sys.stderr, and
+        sys.stdout.
+
+        """
+        return self.s_apply(self.r_unload, args)
+
+    # Restricted open(...)
+
+    def r_open(self, file, mode='r', buf=-1):
+        """Method called when open() is called in the restricted environment.
+
+        The arguments are identical to those of the open() function, and a
+        file object (or a class instance compatible with file objects)
+        should be returned.  RExec's default behaviour is allow opening
+        any file for reading, but forbidding any attempt to write a file.
+
+        This method is implicitly called by code executing in the
+        restricted environment.  Overriding this method in a subclass is
+        used to change the policies enforced by a restricted environment.
+
+        """
+        mode = str(mode)
+        if mode not in ('r', 'rb'):
+            raise IOError, "can't open files for writing in restricted mode"
+        return open(file, mode, buf)
+
+    # Restricted version of sys.exc_info()
+
+    def r_exc_info(self):
+        ty, va, tr = sys.exc_info()
+        tr = None
+        return ty, va, tr
+
+
+def test():
+    import getopt, traceback
+    opts, args = getopt.getopt(sys.argv[1:], 'vt:')
+    verbose = 0
+    trusted = []
+    for o, a in opts:
+        if o == '-v':
+            verbose = verbose+1
+        if o == '-t':
+            trusted.append(a)
+    r = RExec(verbose=verbose)
+    if trusted:
+        r.ok_builtin_modules = r.ok_builtin_modules + tuple(trusted)
+    if args:
+        r.modules['sys'].argv = args
+        r.modules['sys'].path.insert(0, os.path.dirname(args[0]))
+    else:
+        r.modules['sys'].path.insert(0, "")
+    fp = sys.stdin
+    if args and args[0] != '-':
+        try:
+            fp = open(args[0])
+        except IOError, msg:
+            print "%s: can't open file %r" % (sys.argv[0], args[0])
+            return 1
+    if fp.isatty():
+        try:
+            import readline
+        except ImportError:
+            pass
+        import code
+        class RestrictedConsole(code.InteractiveConsole):
+            def runcode(self, co):
+                self.locals['__builtins__'] = r.modules['__builtin__']
+                r.s_apply(code.InteractiveConsole.runcode, (self, co))
+        try:
+            RestrictedConsole(r.modules['__main__'].__dict__).interact()
+        except SystemExit, n:
+            return n
+    else:
+        text = fp.read()
+        fp.close()
+        c = compile(text, fp.name, 'exec')
+        try:
+            r.s_exec(c)
+        except SystemExit, n:
+            return n
+        except:
+            traceback.print_exc()
+            return 1
+
+
+if __name__ == '__main__':
+    sys.exit(test())
