summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2012-05-23 12:15:56 +0200
committerLars Wirzenius <liw@liw.fi>2012-05-23 12:15:56 +0200
commita750aa29c29ba60b3d848c56482059c556374fa6 (patch)
tree3515c26502591d00ef4a2d5a59575c80aad32ad5
parentdcd33d3089bec1de05a96839d49e3bb586b918ad (diff)
downloadsummain-a750aa29c29ba60b3d848c56482059c556374fa6.tar.gz
Add xattrs support
-rwxr-xr-xsummain2
-rw-r--r--summainlib.py23
-rw-r--r--summainlib_tests.py6
-rwxr-xr-xtests/xattrs.script10
-rw-r--r--tests/xattrs.stdout8
5 files changed, 45 insertions, 4 deletions
diff --git a/summain b/summain
index 55bb855..278eca8 100755
--- a/summain
+++ b/summain
@@ -27,7 +27,7 @@ import summainlib
class OutputFormat(object):
keys = ['Mtime', 'Mode', 'Ino', 'Dev', 'Nlink', 'Size',
- 'Uid', 'Username', 'Gid', 'Group', 'Target']
+ 'Uid', 'Username', 'Gid', 'Group', 'Target', 'Xattrs']
def __init__(self, output, checksums, objects):
self.output = output
diff --git a/summainlib.py b/summainlib.py
index 784efe5..93d3737 100644
--- a/summainlib.py
+++ b/summainlib.py
@@ -136,7 +136,8 @@ class FilesystemObject(object):
def __init__(self, filename, nn, pn, exclude,
stat_result=None, sha1=None, sha224=None,
sha256=None, sha384=None, sha512=None,
- md5=None, open_file=None, readlink=None):
+ md5=None, open_file=None, readlink=None,
+ xattrs=None):
self.filename = filename
self.relative = None
self._exclude = set(self._normalize_key(k) for k in exclude)
@@ -149,6 +150,8 @@ class FilesystemObject(object):
self._sha384 = sha384 or hashlib.sha384()
self._sha512 = sha512 or hashlib.sha512()
self._stat_result = stat_result or _summain.lstat(filename)
+ self._xattrs = (xattrs if xattrs is not None
+ else self.get_xattrs(filename))
self.open_file = open_file or file
self.readlink = readlink or os.readlink
self.values = dict()
@@ -214,6 +217,12 @@ class FilesystemObject(object):
if stat.S_ISLNK(self._stat_result[RESULT_MODE]):
return self.readlink(self.filename)
+ def _compute_xattrs(self): # pragma: no cover
+ if len(self._xattrs) == 0:
+ return ''
+ parts = [' %s=%s' % (k, self._xattrs[k]) for k in self._xattrs]
+ return '\n' + '\n'.join(parts)
+
def format_time(self, secs, nsecs):
s = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(secs))
s += '.%09d' % nsecs
@@ -261,3 +270,15 @@ class FilesystemObject(object):
'''Is this a directory?'''
return stat.S_ISDIR(int(self['Mode'], 8))
+ def get_xattrs(self, filename): # pragma: no cover
+ ret = _summain.llistxattr(filename)
+ if type(ret) is int:
+ raise OSError((ret, os.strerror(ret), filename))
+
+ names = [s for s in ret.split('\0') if s]
+
+ xattrs = {}
+ for name in names:
+ xattrs[name] = _summain.lgetxattr(filename, name)
+ return xattrs
+
diff --git a/summainlib_tests.py b/summainlib_tests.py
index f8bcc27..e2a3c0f 100644
--- a/summainlib_tests.py
+++ b/summainlib_tests.py
@@ -95,7 +95,8 @@ class FilesystemObjectTests(unittest.TestCase):
sha512=FakeChecksummer(),
md5=FakeChecksummer(),
open_file=FakeOpenFile(),
- readlink=FakeReadlink(self))
+ readlink=FakeReadlink(self),
+ xattrs={})
def test_raises_keyerror_for_unknown_field(self):
self.assertRaises(KeyError, self.new('foo').__getitem__,
@@ -207,7 +208,8 @@ class FilesystemObjectNormalizedNumbersTests(unittest.TestCase):
sha512=FakeChecksummer(),
md5=FakeChecksummer(),
open_file=FakeOpenFile(),
- readlink=FakeReadlink(self))
+ readlink=FakeReadlink(self),
+ xattrs={})
def test_inode_numbers_are_repeatable(self):
a1 = self.new('foo')
diff --git a/tests/xattrs.script b/tests/xattrs.script
new file mode 100755
index 0000000..383cf6e
--- /dev/null
+++ b/tests/xattrs.script
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+set -e
+
+mkdir -m 0775 "$DATADIR/xattrs"
+touch "$DATADIR/xattrs/file"
+setfattr -n user.foo -v bar "$DATADIR/xattrs/file"
+./summain --exclude=mtime --exclude=uid --exclude=username \
+ --exclude=gid --exclude=group --exclude=ino --exclude=dev \
+ --exclude=nlink --exclude=size --exclude=sha1 --relative "$DATADIR/xattrs"
diff --git a/tests/xattrs.stdout b/tests/xattrs.stdout
new file mode 100644
index 0000000..60984f8
--- /dev/null
+++ b/tests/xattrs.stdout
@@ -0,0 +1,8 @@
+Name: .
+Mode: 40775
+
+Name: file
+Mode: 100664
+Xattrs:
+ user.foo=bar
+