diff --git a/darc/testsuite/xattr.py b/darc/testsuite/xattr.py index 37c10f277..febe3559d 100644 --- a/darc/testsuite/xattr.py +++ b/darc/testsuite/xattr.py @@ -17,16 +17,16 @@ class XattrTestCase(DarcTestCase): def test_low_level(self): self.assert_equal(llistxattr(self.tmpfile.name), []) self.assert_equal(llistxattr(self.symlink), []) - lsetxattr(self.tmpfile.name, b'user.foo', b'bar') - self.assert_equal(llistxattr(self.tmpfile.name), [b'user.foo']) - self.assert_equal(lgetxattr(self.tmpfile.name, b'user.foo'), b'bar') + lsetxattr(self.tmpfile.name, b'foo', b'bar') + self.assert_equal(llistxattr(self.tmpfile.name), [b'foo']) + self.assert_equal(lgetxattr(self.tmpfile.name, b'foo'), b'bar') self.assert_equal(llistxattr(self.symlink), []) def test_low_level_fileno(self): self.assert_equal(flistxattr(self.tmpfile.fileno()), []) - fsetxattr(self.tmpfile.fileno(), b'user.foo', b'bar') - self.assert_equal(flistxattr(self.tmpfile.fileno()), [b'user.foo']) - self.assert_equal(fgetxattr(self.tmpfile.fileno(), b'user.foo'), b'bar') + fsetxattr(self.tmpfile.fileno(), b'foo', b'bar') + self.assert_equal(flistxattr(self.tmpfile.fileno()), [b'foo']) + self.assert_equal(fgetxattr(self.tmpfile.fileno(), b'foo'), b'bar') def test_high_level(self): self.assert_equal(get_all(self.tmpfile.name), {}) diff --git a/darc/xattr.py b/darc/xattr.py index 50a89a5cb..e94ebfca8 100644 --- a/darc/xattr.py +++ b/darc/xattr.py @@ -1,4 +1,6 @@ -"""A basic extended attributes (xattr) implementation for Linux +"""A basic extended attributes (xattr) implementation for Linux and MacOS X + +On Linux only the "user." namespace is accessed """ import os import sys @@ -8,6 +10,24 @@ from ctypes.util import find_library libc = CDLL(find_library('c'), use_errno=True) +def set(path_or_fd, name, value): + if isinstance(path_or_fd, int): + fsetxattr(path_or_fd, name, value) + else: + lsetxattr(path_or_fd, name, value) + + +def get_all(path_or_fd): + """Return a dictionary with all (user) xattrs for "path_or_fd" + + Symbolic links are not followed + """ + if isinstance(path_or_fd, int): + return dict((name, fgetxattr(path_or_fd, name)) for name in flistxattr(path_or_fd)) + else: + return dict((name, lgetxattr(path_or_fd, name)) for name in llistxattr(path_or_fd)) + + def _check(rv, path=None): if rv < 0: raise OSError(get_errno(), path) @@ -28,22 +48,6 @@ if sys.platform.startswith('linux'): libc.fgetxattr.argtypes = (c_int, c_char_p, c_char_p, c_size_t) libc.fgetxattr.restype = c_ssize_t - def set(path_or_fd, name, value): - if isinstance(path_or_fd, int): - fsetxattr(path_or_fd, b'user.' + name, value) - else: - lsetxattr(path_or_fd, b'user.' + name, value) - - def get_all(path_or_fd): - """Return a dictionary with all (user) xattrs for "path_or_fd" - - Symbolic links are not followed - """ - if isinstance(path_or_fd, int): - return dict((name[5:], fgetxattr(path_or_fd, name)) for name in flistxattr(path_or_fd) if name.startswith(b'user.')) - else: - return dict((name[5:], lgetxattr(path_or_fd, name)) for name in llistxattr(path_or_fd) if name.startswith(b'user.')) - def llistxattr(path): path = os.fsencode(path) n = _check(libc.llistxattr(path, None, 0), path) @@ -53,7 +57,7 @@ if sys.platform.startswith('linux'): n2 = _check(libc.llistxattr(path, namebuf, n)) if n2 != n: raise Exception('llistxattr failed') - return namebuf.raw.split(b'\0')[:-1] + return [name[5:] for name in namebuf.raw.split(b'\0')[:-1] if name.startswith(b'user.')] def flistxattr(fd): n = _check(libc.flistxattr(fd, None, 0)) @@ -63,16 +67,17 @@ if sys.platform.startswith('linux'): n2 = _check(libc.flistxattr(fd, namebuf, n)) if n2 != n: raise Exception('flistxattr failed') - return namebuf.raw.split(b'\0')[:-1] + return [name[5:] for name in namebuf.raw.split(b'\0')[:-1] if name.startswith(b'user.')] def lsetxattr(path, name, value, flags=0): - _check(libc.lsetxattr(os.fsencode(path), name, value, len(value), flags), path) + _check(libc.lsetxattr(os.fsencode(path), b'user.' + name, value, len(value), flags), path) def fsetxattr(fd, name, value, flags=0): - _check(libc.fsetxattr(fd, name, value, len(value), flags)) + _check(libc.fsetxattr(fd, b'user.' + name, value, len(value), flags)) def lgetxattr(path, name): path = os.fsencode(path) + name = b'user.' + name n = _check(libc.lgetxattr(path, name, None, 0)) if n == 0: return None @@ -83,6 +88,7 @@ if sys.platform.startswith('linux'): return valuebuf.raw def fgetxattr(fd, name): + name = b'user.' + name n = _check(libc.fgetxattr(fd, name, None, 0)) if n == 0: return None @@ -108,22 +114,6 @@ elif sys.platform == 'darwin': XATTR_NOFOLLOW = 0x0001 - def set(path_or_fd, name, value): - if isinstance(path_or_fd, int): - fsetxattr(path_or_fd, name, value) - else: - lsetxattr(path_or_fd, name, value) - - def get_all(path_or_fd): - """Return a dictionary with all (user) xattrs for "path_or_fd" - - Symbolic links are not followed - """ - if isinstance(path_or_fd, int): - return dict((name, fgetxattr(path_or_fd, name)) for name in flistxattr(path_or_fd)) - else: - return dict((name, lgetxattr(path_or_fd, name)) for name in llistxattr(path_or_fd)) - def llistxattr(path): path = os.fsencode(path) n = _check(libc.listxattr(path, None, 0, XATTR_NOFOLLOW), path) diff --git a/setup.py b/setup.py index c80066704..de6f2a65c 100644 --- a/setup.py +++ b/setup.py @@ -55,12 +55,14 @@ setup( url='http://github.com/jborg/darc/', description='Deduplicating ARChiver written in Python', license='BSD', + platforms=['Linux', 'MacOS X'], classifiers=[ 'Development Status :: 4 - Beta', 'Environment :: Console', 'Intended Audience :: System Administrators', 'License :: OSI Approved :: BSD License', - 'Operating System :: POSIX', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: POSIX :: Linux', 'Programming Language :: Python', 'Topic :: Security :: Cryptography', 'Topic :: System :: Archiving :: Backup', diff --git a/tox.ini b/tox.ini index c8b60d7a1..e8b04d198 100644 --- a/tox.ini +++ b/tox.ini @@ -3,4 +3,4 @@ envlist = py32, py33 [testenv] changedir = docs # Change dir to avoid import problem -commands = fakeroot {envpython} -m darc.testsuite.run -bv [] +commands = {envpython} -m darc.testsuite.run -bv []