diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2012-02-27 02:46:31 +0100 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2012-02-27 03:52:05 +0100 |
commit | 8008228b940bd8c28a7ae8ee1c2568cb2127f1d1 (patch) | |
tree | 07aa4d397f5e1d398bd5355bbfe60dc13a6062d5 /source4/scripting/python/samba/xattr.py | |
parent | 2c9ff8a4d7d9217d69a7c4abdd4b776d138f9951 (diff) | |
download | samba-8008228b940bd8c28a7ae8ee1c2568cb2127f1d1.tar.gz samba-8008228b940bd8c28a7ae8ee1c2568cb2127f1d1.tar.xz samba-8008228b940bd8c28a7ae8ee1c2568cb2127f1d1.zip |
samba.xattr: Massively simplify copytree_with_xattrs.
Diffstat (limited to 'source4/scripting/python/samba/xattr.py')
-rw-r--r-- | source4/scripting/python/samba/xattr.py | 98 |
1 files changed, 34 insertions, 64 deletions
diff --git a/source4/scripting/python/samba/xattr.py b/source4/scripting/python/samba/xattr.py index 55ae041675..1c53ae810d 100644 --- a/source4/scripting/python/samba/xattr.py +++ b/source4/scripting/python/samba/xattr.py @@ -3,7 +3,6 @@ # # Utility code for dealing with POSIX extended attributes # -# Copyright (C) Matthieu Patou <mat@matws.net> 2009 - 2010 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2012 # # This program is free software; you can redistribute it and/or modify @@ -25,70 +24,41 @@ import samba.xattr_native import shutil -def copytree_with_xattrs(source, target): - """Copy a tree but preserve extended attributes. - - :param source: Source tree path - :param target: Target path - """ - shutil.copytree(source, target) - copyxattrs(target, source) +def copyattrs(frompath, topath): + """Copy ACL related attributes from a path to another path.""" + for attr_name in (xattr.XATTR_NTACL_NAME, "system.posix_acl_access"): + # Get the xattr attributes if any + try: + attribute = samba.xattr_native.wrap_getxattr(frompath, + xattr.XATTR_NTACL_NAME) + samba.xattr_native.wrap_setxattr(topath, + xattr.XATTR_NTACL_NAME, + attribute) + except Exception: + pass + # FIXME:Catch a specific exception -def copyxattrs(dir, refdir): - """Copy extended attributes from a reference dir to a destination dir +def copytree_with_xattrs(src, dst): + """Recursively copy a directory tree using shutil.copy2(), preserving xattrs. - Both dir are supposed to hold the same files - :param dir: Destination dir - :param refdir: Reference directory""" - - for root, dirs, files in os.walk(dir, topdown=True): - for name in files: - subdir = root[len(dir):] - ref = os.path.join(refdir, subdir, name) - statsinfo = os.stat(ref) - tgt = os.path.join(root, name) - try: - os.chown(tgt, statsinfo.st_uid, statsinfo.st_gid) - # Get the xattr attributes if any - try: - attribute = samba.xattr_native.wrap_getxattr(ref, - xattr.XATTR_NTACL_NAME) - samba.xattr_native.wrap_setxattr(tgt, - xattr.XATTR_NTACL_NAME, - attribute) - except Exception: - pass - # FIXME:Catch a specific exception - attribute = samba.xattr_native.wrap_getxattr(ref, - "system.posix_acl_access") - samba.xattr_native.wrap_setxattr(tgt, - "system.posix_acl_access", - attribute) - except Exception: - # FIXME: Catch a specific exception - continue - for name in dirs: - subdir = root[len(dir):] - ref = os.path.join(refdir, subdir, name) - statsinfo = os.stat(ref) - tgt = os.path.join(root, name) - try: - os.chown(os.path.join(root, name), statsinfo.st_uid, - statsinfo.st_gid) - try: - attribute = samba.xattr_native.wrap_getxattr(ref, - xattr.XATTR_NTACL_NAME) - samba.xattr_native.wrap_setxattr(tgt, - xattr.XATTR_NTACL_NAME, - attribute) - except Exception: - pass # FIXME: Catch a specific exception - attribute = samba.xattr_native.wrap_getxattr(ref, - "system.posix_acl_access") - samba.xattr_native.wrap_setxattr(tgt, - "system.posix_acl_access", - attribute) + The destination directory must not already exist. + If exception(s) occur, an Error is raised with a list of reasons. + """ + names = os.listdir(src) - except Exception: - continue + os.makedirs(dst) + errors = [] + for name in names: + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + if os.path.islink(srcname): + linkto = os.readlink(srcname) + os.symlink(linkto, dstname) + elif os.path.isdir(srcname): + copytree_with_xattrs(srcname, dstname) + else: + # Will raise a SpecialFileError for unsupported file types + shutil.copy2(srcname, dstname) + shutil.copystat(src, dst) + copyattrs(src, dst) |