Browse Source

acl: Added workaround for old Linux systems

Really old Linux systems do not have extended_file_no_follow()
Jonas Borgström 11 years ago
parent
commit
8f4e0f7506

+ 1 - 1
CHANGES

@@ -7,7 +7,7 @@ Version 0.14
 ------------
 
 (feature release, released on X)
-
+- Add workaround for old Linux systems without acl_extended_file_no_follow (#96)
 - Add MacPorts' path to the default openssl search path (#101)
 - HashIndex improvements, eliminates unnecessary IO on low memory systems.
 

+ 1 - 1
attic/archive.py

@@ -354,7 +354,7 @@ class Archive:
             item[b'xattrs'] = StableDict(xattrs)
         if has_lchflags and st.st_flags:
             item[b'bsdflags'] = st.st_flags
-        item[b'acl'] = acl_get(path, item, self.numeric_owner)
+        acl_get(path, item, st, self.numeric_owner)
         return item
 
     def process_item(self, path, st):

+ 1 - 1
attic/helpers.py

@@ -76,7 +76,7 @@ def check_extension_modules():
     if (attic.hashindex.API_VERSION != 2 or
         attic.chunker.API_VERSION != 1 or
         attic.crypto.API_VERSION != 2 or
-        attic.platform.API_VERSION != 1):
+        attic.platform.API_VERSION != 2):
         raise ExtensionModuleError
 
 

+ 2 - 2
attic/platform_darwin.pyx

@@ -1,7 +1,7 @@
 import os
 from attic.helpers import user2uid, group2gid
 
-API_VERSION = 1
+API_VERSION = 2
 
 cdef extern from "sys/acl.h":
     ctypedef struct _acl_t:
@@ -48,7 +48,7 @@ def _remove_non_numeric_identifier(acl):
     return b'\n'.join(entries)
 
 
-def acl_get(path, item, numeric_owner=False):
+def acl_get(path, item, st, numeric_owner=False):
     cdef acl_t acl = NULL
     cdef char *text = NULL
     try:

+ 2 - 2
attic/platform_freebsd.pyx

@@ -1,7 +1,7 @@
 import os
 from attic.helpers import posix_acl_use_stored_uid_gid
 
-API_VERSION = 1
+API_VERSION = 2
 
 cdef extern from "errno.h":
     int errno
@@ -42,7 +42,7 @@ cdef _get_acl(p, type, item, attribute, int flags):
         acl_free(acl)
 
 
-def acl_get(path, item, numeric_owner=False):
+def acl_get(path, item, st, numeric_owner=False):
     """Saves ACL Entries
 
     If `numeric_owner` is True the user/group field is not preserved only uid/gid

+ 5 - 4
attic/platform_linux.pyx

@@ -1,8 +1,9 @@
 import os
 import re
+from stat import S_ISLNK
 from attic.helpers import posix_acl_use_stored_uid_gid, user2uid, group2gid
 
-API_VERSION = 1
+API_VERSION = 2
 
 cdef extern from "sys/types.h":
     int ACL_TYPE_ACCESS
@@ -20,7 +21,7 @@ cdef extern from "sys/acl.h":
     char *acl_to_text(acl_t acl, ssize_t *len)
 
 cdef extern from "acl/libacl.h":
-    int acl_extended_file_nofollow(const char *path)
+    int acl_extended_file(const char *path)
 
 
 _comment_re = re.compile(' *#.*', re.M)
@@ -75,7 +76,7 @@ cdef acl_numeric_ids(acl):
     return ('\n'.join(entries)).encode('ascii')
 
 
-def acl_get(path, item, numeric_owner=False):
+def acl_get(path, item, st, numeric_owner=False):
     """Saves ACL Entries
 
     If `numeric_owner` is True the user/group field is not preserved only uid/gid
@@ -85,7 +86,7 @@ def acl_get(path, item, numeric_owner=False):
     cdef char *default_text = NULL
     cdef char *access_text = NULL
 
-    if acl_extended_file_nofollow(<bytes>os.fsencode(path)) <= 0:
+    if S_ISLNK(st.st_mode) or acl_extended_file(<bytes>os.fsencode(path)) <= 0:
         return
     if numeric_owner:
         converter = acl_numeric_ids

+ 2 - 2
attic/testsuite/platform.py

@@ -46,7 +46,7 @@ class PlatformLinuxTestCase(AtticTestCase):
 
     def get_acl(self, path, numeric_owner=False):
         item = {}
-        acl_get(path, item, numeric_owner=numeric_owner)
+        acl_get(path, item, os.stat(path), numeric_owner=numeric_owner)
         return item
 
     def set_acl(self, path, access=None, default=None, numeric_owner=False):
@@ -84,7 +84,7 @@ class PlatformDarwinTestCase(AtticTestCase):
 
     def get_acl(self, path, numeric_owner=False):
         item = {}
-        acl_get(path, item, numeric_owner=numeric_owner)
+        acl_get(path, item, os.stat(path), numeric_owner=numeric_owner)
         return item
 
     def set_acl(self, path, acl, numeric_owner=False):