aboutsummaryrefslogtreecommitdiffstats
path: root/src/3rdparty/python/lib/python3.9/site-packages/mac_alias/osx.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/python/lib/python3.9/site-packages/mac_alias/osx.py')
-rw-r--r--src/3rdparty/python/lib/python3.9/site-packages/mac_alias/osx.py1074
1 files changed, 1074 insertions, 0 deletions
diff --git a/src/3rdparty/python/lib/python3.9/site-packages/mac_alias/osx.py b/src/3rdparty/python/lib/python3.9/site-packages/mac_alias/osx.py
new file mode 100644
index 000000000..1b2feabaa
--- /dev/null
+++ b/src/3rdparty/python/lib/python3.9/site-packages/mac_alias/osx.py
@@ -0,0 +1,1074 @@
+import datetime
+import os
+import uuid
+from ctypes import (
+ POINTER,
+ Structure,
+ Union,
+ byref,
+ c_byte,
+ c_char,
+ c_char_p,
+ c_int,
+ c_long,
+ c_longlong,
+ c_short,
+ c_uint,
+ c_ulong,
+ c_ulonglong,
+ c_ushort,
+ c_void_p,
+ cdll,
+ create_string_buffer,
+ sizeof,
+)
+
+from .utils import unix_epoch
+
+libc = cdll.LoadLibrary("/usr/lib/libc.dylib")
+
+# Constants
+FSOPT_NOFOLLOW = 0x00000001
+FSOPT_NOINMEMUPDATE = 0x00000002
+FSOPT_REPORT_FULLSIZE = 0x00000004
+FSOPT_PACK_INVAL_ATTRS = 0x00000008
+FSOPT_ATTR_CMN_EXTENDED = 0x00000020
+FSOPT_RETURN_REALDEV = 0x00000200
+
+VOL_CAPABILITIES_FORMAT = 0
+VOL_CAPABILITIES_INTERFACES = 1
+
+VOL_CAP_FMT_PERSISTENTOBJECTIDS = 0x00000001
+VOL_CAP_FMT_SYMBOLICLINKS = 0x00000002
+VOL_CAP_FMT_HARDLINKS = 0x00000004
+VOL_CAP_FMT_JOURNAL = 0x00000008
+VOL_CAP_FMT_JOURNAL_ACTIVE = 0x00000010
+VOL_CAP_FMT_NO_ROOT_TIMES = 0x00000020
+VOL_CAP_FMT_SPARSE_FILES = 0x00000040
+VOL_CAP_FMT_ZERO_RUNS = 0x00000080
+VOL_CAP_FMT_CASE_SENSITIVE = 0x00000100
+VOL_CAP_FMT_CASE_PRESERVING = 0x00000200
+VOL_CAP_FMT_FAST_STATFS = 0x00000400
+VOL_CAP_FMT_2TB_FILESIZE = 0x00000800
+VOL_CAP_FMT_OPENDENYMODES = 0x00001000
+VOL_CAP_FMT_HIDDEN_FILES = 0x00002000
+VOL_CAP_FMT_PATH_FROM_ID = 0x00004000
+VOL_CAP_FMT_NO_VOLUME_SIZES = 0x00008000
+VOL_CAP_FMT_DECMPFS_COMPRESSION = 0x00010000
+VOL_CAP_FMT_64BIT_OBJECT_IDS = 0x00020000
+
+VOL_CAP_INT_SEARCHFS = 0x00000001
+VOL_CAP_INT_ATTRLIST = 0x00000002
+VOL_CAP_INT_NFSEXPORT = 0x00000004
+VOL_CAP_INT_READDIRATTR = 0x00000008
+VOL_CAP_INT_EXCHANGEDATA = 0x00000010
+VOL_CAP_INT_COPYFILE = 0x00000020
+VOL_CAP_INT_ALLOCATE = 0x00000040
+VOL_CAP_INT_VOL_RENAME = 0x00000080
+VOL_CAP_INT_ADVLOCK = 0x00000100
+VOL_CAP_INT_FLOCK = 0x00000200
+VOL_CAP_INT_EXTENDED_SECURITY = 0x00000400
+VOL_CAP_INT_USERACCESS = 0x00000800
+VOL_CAP_INT_MANLOCK = 0x00001000
+VOL_CAP_INT_NAMEDSTREAMS = 0x00002000
+VOL_CAP_INT_EXTENDED_ATTR = 0x00004000
+VOL_CAP_INT_CLONE = 0x00010000
+VOL_CAP_INT_SNAPSHOT = 0x00020000
+VOL_CAP_INT_RENAME_SWAP = 0x00040000
+VOL_CAP_INT_RENAME_EXCL = 0x00080000
+VOL_CAP_INT_RENAME_OPENFAIL = 0x00100000
+
+ATTR_CMN_NAME = 0x00000001
+ATTR_CMN_DEVID = 0x00000002
+ATTR_CMN_FSID = 0x00000004
+ATTR_CMN_OBJTYPE = 0x00000008
+ATTR_CMN_OBJTAG = 0x00000010
+ATTR_CMN_OBJID = 0x00000020
+ATTR_CMN_OBJPERMANENTID = 0x00000040
+ATTR_CMN_PAROBJID = 0x00000080
+ATTR_CMN_SCRIPT = 0x00000100
+ATTR_CMN_CRTIME = 0x00000200
+ATTR_CMN_MODTIME = 0x00000400
+ATTR_CMN_CHGTIME = 0x00000800
+ATTR_CMN_ACCTIME = 0x00001000
+ATTR_CMN_BKUPTIME = 0x00002000
+ATTR_CMN_FNDRINFO = 0x00004000
+ATTR_CMN_OWNERID = 0x00008000
+ATTR_CMN_GRPID = 0x00010000
+ATTR_CMN_ACCESSMASK = 0x00020000
+ATTR_CMN_FLAGS = 0x00040000
+ATTR_CMN_GEN_COUNT = 0x00080000
+ATTR_CMN_DOCUMENT_ID = 0x00100000
+ATTR_CMN_USERACCESS = 0x00200000
+ATTR_CMN_EXTENDED_SECURITY = 0x00400000
+ATTR_CMN_UUID = 0x00800000
+ATTR_CMN_GRPUUID = 0x01000000
+ATTR_CMN_FILEID = 0x02000000
+ATTR_CMN_PARENTID = 0x04000000
+ATTR_CMN_FULLPATH = 0x08000000
+ATTR_CMN_ADDEDTIME = 0x10000000
+ATTR_CMN_ERROR = 0x20000000
+ATTR_CMN_DATA_PROTECT_FLAGS = 0x40000000
+ATTR_CMN_RETURNED_ATTRS = 0x80000000
+ATTR_CMN_ALL_ATTRS = 0xFFFFFFFF
+
+ATTR_CMN_VALIDMASK = 0xFFFFFFFF
+ATTR_CMN_SETMASK = 0x51C7FF00
+ATTR_CMN_VOLSETMASK = 0x00006700
+
+ATTR_VOL_FSTYPE = 0x00000001
+ATTR_VOL_SIGNATURE = 0x00000002
+ATTR_VOL_SIZE = 0x00000004
+ATTR_VOL_SPACEFREE = 0x00000008
+ATTR_VOL_SPACEAVAIL = 0x00000010
+ATTR_VOL_MINALLOCATION = 0x00000020
+ATTR_VOL_ALLOCATIONCLUMP = 0x00000040
+ATTR_VOL_IOBLOCKSIZE = 0x00000080
+ATTR_VOL_OBJCOUNT = 0x00000100
+ATTR_VOL_FILECOUNT = 0x00000200
+ATTR_VOL_DIRCOUNT = 0x00000400
+ATTR_VOL_MAXOBJCOUNT = 0x00000800
+ATTR_VOL_MOUNTPOINT = 0x00001000
+ATTR_VOL_NAME = 0x00002000
+ATTR_VOL_MOUNTFLAGS = 0x00004000
+ATTR_VOL_MOUNTEDDEVICE = 0x00008000
+ATTR_VOL_ENCODINGSUSED = 0x00010000
+ATTR_VOL_CAPABILITIES = 0x00020000
+ATTR_VOL_UUID = 0x00040000
+ATTR_VOL_QUOTA_SIZE = 0x10000000
+ATTR_VOL_RESERVED_SIZE = 0x20000000
+ATTR_VOL_ATTRIBUTES = 0x40000000
+ATTR_VOL_INFO = 0x80000000
+ATTR_VOL_ALL_ATTRS = 0xF007FFFF
+
+ATTR_DIR_LINKCOUNT = 0x00000001
+ATTR_DIR_ENTRYCOUNT = 0x00000002
+ATTR_DIR_MOUNTSTATUS = 0x00000004
+DIR_MNTSTATUS_MNTPOINT = 0x00000001
+DIR_MNTSTATUS_TRIGGER = 0x00000002
+ATTR_DIR_ALLOCSIZE = 0x00000008
+ATTR_DIR_IOBLOCKSIZE = 0x00000010
+ATTR_DIR_DATALENGTH = 0x00000020
+ATTR_DIR_ALL_ATTRS = 0x0000003F
+
+ATTR_DIR_VALIDMASK = 0x0000003F
+ATTR_DIR_SETMASK = 0x00000000
+
+ATTR_FILE_LINKCOUNT = 0x00000001
+ATTR_FILE_TOTALSIZE = 0x00000002
+ATTR_FILE_ALLOCSIZE = 0x00000004
+ATTR_FILE_IOBLOCKSIZE = 0x00000008
+ATTR_FILE_DEVTYPE = 0x00000020
+ATTR_FILE_FORKCOUNT = 0x00000080
+ATTR_FILE_FORKLIST = 0x00000100
+ATTR_FILE_DATALENGTH = 0x00000200
+ATTR_FILE_DATAALLOCSIZE = 0x00000400
+ATTR_FILE_RSRCLENGTH = 0x00001000
+ATTR_FILE_RSRCALLOCSIZE = 0x00002000
+ATTR_FILE_ALL_ATTRS = 0x000037FF
+
+ATTR_FILE_VALIDMASK = 0x000037FF
+ATTR_FILE_SETMASK = 0x00000020
+
+# These are deprecated
+ATTR_FORK_TOTALSIZE = 0x00000001
+ATTR_FORK_ALLOCSIZE = 0x00000002
+ATTR_FORK_ALL_ATTRS = 0x00000003
+
+# These go in the fork attribute field
+ATTR_CMNEXT_RELPATH = 0x00000004
+ATTR_CMNEXT_PRIVATESIZE = 0x00000008
+ATTR_CMNEXT_LINKID = 0x0000010
+ATTR_CMNEXT_NOFIRMLINKPATH = 0x00000020
+ATTR_CMNEXT_REALDEVID = 0x00000040
+ATTR_CMNEXT_REALFSID = 0x00000080
+ATTR_CMNEXT_CLONEID = 0x00000100
+ATTR_CMNEXT_EXT_FLAGS = 0x00000200
+ATTR_CMNEXT_RECURSIVE_GENCOUNT = 0x00000400
+ATTR_CMNEXT_ALL_ATTRS = 0x000007FC
+
+ATTR_CMNEXT_VALIDMASK = 0x000007FC
+ATTR_CMNEXT_SETMASK = 0x00000000
+
+ATTR_FORK_VALIDMASK = 0x00000003
+ATTR_FORK_SETMASK = 0x00000000
+
+# These can't be used
+ATTR_CMN_NAMEDATTRCOUNT = 0x00080000
+ATTR_CMN_NAMEDATTRLIST = 0x00100000
+ATTR_FILE_CLUMPSIZE = 0x00000010
+ATTR_FILE_FILETYPE = 0x00000040
+ATTR_FILE_DATAEXTENTS = 0x00000800
+ATTR_FILE_RSRCEXTENTS = 0x00004000
+
+
+class attrlist(Structure):
+ _fields_ = [
+ ("bitmapcount", c_ushort),
+ ("reserved", c_ushort),
+ ("commonattr", c_uint),
+ ("volattr", c_uint),
+ ("dirattr", c_uint),
+ ("fileattr", c_uint),
+ ("forkattr", c_uint),
+ ]
+
+
+class attribute_set_t(Structure):
+ _fields_ = [
+ ("commonattr", c_uint),
+ ("volattr", c_uint),
+ ("dirattr", c_uint),
+ ("fileattr", c_uint),
+ ("forkattr", c_uint),
+ ]
+
+
+class fsobj_id_t(Structure):
+ _fields_ = [
+ ("fid_objno", c_uint),
+ ("fid_generation", c_uint),
+ ]
+
+
+class timespec(Structure):
+ _fields_ = [
+ ("tv_sec", c_long),
+ ("tv_nsec", c_long),
+ ]
+
+
+class attrreference_t(Structure):
+ _fields_ = [
+ ("attr_dataoffset", c_int),
+ ("attr_length", c_uint),
+ ]
+
+
+class fsid_t(Structure):
+ _fields_ = [
+ ("val", c_uint * 2),
+ ]
+
+
+class guid_t(Structure):
+ _fields_ = [
+ ("g_guid", c_byte * 16),
+ ]
+
+
+class kauth_ace(Structure):
+ _fields_ = [
+ ("ace_applicable", guid_t),
+ ("ace_flags", c_uint),
+ ]
+
+
+class kauth_acl(Structure):
+ _fields_ = [
+ ("acl_entrycount", c_uint),
+ ("acl_flags", c_uint),
+ ("acl_ace", kauth_ace * 128),
+ ]
+
+
+class kauth_filesec(Structure):
+ _fields_ = [
+ ("fsec_magic", c_uint),
+ ("fsec_owner", guid_t),
+ ("fsec_group", guid_t),
+ ("fsec_acl", kauth_acl),
+ ]
+
+
+class diskextent(Structure):
+ _fields_ = [
+ ("startblock", c_uint),
+ ("blockcount", c_uint),
+ ]
+
+
+OSType = c_uint
+UInt16 = c_ushort
+SInt16 = c_short
+SInt32 = c_int
+
+
+class Point(Structure):
+ _fields_ = [
+ ("x", SInt16),
+ ("y", SInt16),
+ ]
+
+
+class Rect(Structure):
+ _fields_ = [
+ ("x", SInt16),
+ ("y", SInt16),
+ ("w", SInt16),
+ ("h", SInt16),
+ ]
+
+
+class FileInfo(Structure):
+ _fields_ = [
+ ("fileType", OSType),
+ ("fileCreator", OSType),
+ ("finderFlags", UInt16),
+ ("location", Point),
+ ("reservedField", UInt16),
+ ("reserved1", SInt16 * 4),
+ ("extendedFinderFlags", UInt16),
+ ("reserved2", SInt16),
+ ("putAwayFolderID", SInt32),
+ ]
+
+
+class FolderInfo(Structure):
+ _fields_ = [
+ ("windowBounds", Rect),
+ ("finderFlags", UInt16),
+ ("location", Point),
+ ("reservedField", UInt16),
+ ("scrollPosition", Point),
+ ("reserved1", SInt32),
+ ("extendedFinderFlags", UInt16),
+ ("reserved2", SInt16),
+ ("putAwayFolderID", SInt32),
+ ]
+
+
+class FinderInfo(Union):
+ _fields_ = [
+ ("fileInfo", FileInfo),
+ ("folderInfo", FolderInfo),
+ ]
+
+
+extentrecord = diskextent * 8
+vol_capabilities_set_t = c_uint * 4
+
+
+class vol_capabilities_attr_t(Structure):
+ _fields_ = [
+ ("capabilities", vol_capabilities_set_t),
+ ("valid", vol_capabilities_set_t),
+ ]
+
+
+class vol_attributes_attr_t(Structure):
+ _fields_ = [
+ ("validattr", attribute_set_t),
+ ("nativeattr", attribute_set_t),
+ ]
+
+
+dev_t = c_uint
+
+fsobj_type_t = c_uint
+
+VNON = 0
+VREG = 1
+VDIR = 2
+VBLK = 3
+VCHR = 4
+VLNK = 5
+VSOCK = 6
+VFIFO = 7
+VBAD = 8
+VSTR = 9
+VCPLX = 10
+
+fsobj_tag_t = c_uint
+
+VT_NON = 0
+VT_UFS = 1
+VT_NFS = 2
+VT_MFS = 3
+VT_MSDOSFS = 4
+VT_LFS = 5
+VT_LOFS = 6
+VT_FDESC = 7
+VT_PORTAL = 8
+VT_NULL = 9
+VT_UMAP = 10
+VT_KERNFS = 11
+VT_PROCFS = 12
+VT_AFS = 13
+VT_ISOFS = 14
+VT_UNION = 15
+VT_HFS = 16
+VT_ZFS = 17
+VT_DEVFS = 18
+VT_WEBDAV = 19
+VT_UDF = 20
+VT_AFP = 21
+VT_CDDA = 22
+VT_CIFS = 23
+VT_OTHER = 24
+
+fsfile_type_t = c_uint
+fsvolid_t = c_uint
+text_encoding_t = c_uint
+uid_t = c_uint
+gid_t = c_uint
+int32_t = c_int
+uint32_t = c_uint
+int64_t = c_longlong
+uint64_t = c_ulonglong
+off_t = c_long
+size_t = c_ulong
+uuid_t = c_byte * 16
+
+NAME_MAX = 255
+PATH_MAX = 1024
+FSTYPE_MAX = 16
+
+
+class struct_statfs(Structure):
+ _fields_ = [
+ ("f_bsize", uint32_t),
+ ("f_iosize", int32_t),
+ ("f_blocks", uint64_t),
+ ("f_bfree", uint64_t),
+ ("f_bavail", uint64_t),
+ ("f_files", uint64_t),
+ ("f_ffree", uint64_t),
+ ("f_fsid", fsid_t),
+ ("f_owner", uid_t),
+ ("f_type", uint32_t),
+ ("f_flags", uint32_t),
+ ("f_fssubtype", uint32_t),
+ ("f_fstypename", c_char * FSTYPE_MAX),
+ ("f_mntonname", c_char * PATH_MAX),
+ ("f_mntfromname", c_char * PATH_MAX),
+ ("f_flags_ext", uint32_t),
+ ("f_reserved", uint32_t * 7),
+ ]
+
+
+# Calculate the maximum number of bytes required for the attribute buffer
+_attr_info = (
+ # Common attributes
+ (0, ATTR_CMN_RETURNED_ATTRS, sizeof(attribute_set_t)),
+ (0, ATTR_CMN_NAME, sizeof(attrreference_t) + NAME_MAX * 3 + 1),
+ (0, ATTR_CMN_DEVID, sizeof(dev_t)),
+ (0, ATTR_CMN_FSID, sizeof(fsid_t)),
+ (0, ATTR_CMN_OBJTYPE, sizeof(fsobj_type_t)),
+ (0, ATTR_CMN_OBJTAG, sizeof(fsobj_tag_t)),
+ (0, ATTR_CMN_OBJID, sizeof(fsobj_id_t)),
+ (0, ATTR_CMN_OBJPERMANENTID, sizeof(fsobj_id_t)),
+ (0, ATTR_CMN_PAROBJID, sizeof(fsobj_id_t)),
+ (0, ATTR_CMN_SCRIPT, sizeof(text_encoding_t)),
+ (0, ATTR_CMN_CRTIME, sizeof(timespec)),
+ (0, ATTR_CMN_MODTIME, sizeof(timespec)),
+ (0, ATTR_CMN_CHGTIME, sizeof(timespec)),
+ (0, ATTR_CMN_ACCTIME, sizeof(timespec)),
+ (0, ATTR_CMN_BKUPTIME, sizeof(timespec)),
+ (0, ATTR_CMN_FNDRINFO, sizeof(FinderInfo)),
+ (0, ATTR_CMN_OWNERID, sizeof(uid_t)),
+ (0, ATTR_CMN_GRPID, sizeof(gid_t)),
+ (0, ATTR_CMN_ACCESSMASK, sizeof(uint32_t)),
+ (0, ATTR_CMN_NAMEDATTRCOUNT, None),
+ (0, ATTR_CMN_NAMEDATTRLIST, None),
+ (0, ATTR_CMN_FLAGS, sizeof(uint32_t)),
+ (0, ATTR_CMN_GEN_COUNT, sizeof(uint32_t)),
+ (0, ATTR_CMN_DOCUMENT_ID, sizeof(uint32_t)),
+ (0, ATTR_CMN_USERACCESS, sizeof(uint32_t)),
+ (0, ATTR_CMN_EXTENDED_SECURITY, sizeof(attrreference_t) + sizeof(kauth_filesec)),
+ (0, ATTR_CMN_UUID, sizeof(guid_t)),
+ (0, ATTR_CMN_GRPUUID, sizeof(guid_t)),
+ (0, ATTR_CMN_FILEID, sizeof(uint64_t)),
+ (0, ATTR_CMN_PARENTID, sizeof(uint64_t)),
+ (0, ATTR_CMN_FULLPATH, sizeof(attrreference_t) + PATH_MAX),
+ (0, ATTR_CMN_ADDEDTIME, sizeof(timespec)),
+ (0, ATTR_CMN_DATA_PROTECT_FLAGS, sizeof(uint32_t)),
+ # Volume attributes
+ (1, ATTR_VOL_FSTYPE, sizeof(uint32_t)),
+ (1, ATTR_VOL_SIGNATURE, sizeof(uint32_t)),
+ (1, ATTR_VOL_SIZE, sizeof(off_t)),
+ (1, ATTR_VOL_SPACEFREE, sizeof(off_t)),
+ (1, ATTR_VOL_SPACEAVAIL, sizeof(off_t)),
+ (1, ATTR_VOL_MINALLOCATION, sizeof(off_t)),
+ (1, ATTR_VOL_ALLOCATIONCLUMP, sizeof(off_t)),
+ (1, ATTR_VOL_IOBLOCKSIZE, sizeof(uint32_t)),
+ (1, ATTR_VOL_OBJCOUNT, sizeof(uint32_t)),
+ (1, ATTR_VOL_FILECOUNT, sizeof(uint32_t)),
+ (1, ATTR_VOL_DIRCOUNT, sizeof(uint32_t)),
+ (1, ATTR_VOL_MAXOBJCOUNT, sizeof(uint32_t)),
+ (1, ATTR_VOL_MOUNTPOINT, sizeof(attrreference_t) + PATH_MAX),
+ (1, ATTR_VOL_NAME, sizeof(attrreference_t) + NAME_MAX + 1),
+ (1, ATTR_VOL_MOUNTFLAGS, sizeof(uint32_t)),
+ (1, ATTR_VOL_MOUNTEDDEVICE, sizeof(attrreference_t) + PATH_MAX),
+ (1, ATTR_VOL_ENCODINGSUSED, sizeof(c_ulonglong)),
+ (1, ATTR_VOL_CAPABILITIES, sizeof(vol_capabilities_attr_t)),
+ (1, ATTR_VOL_UUID, sizeof(uuid_t)),
+ (1, ATTR_VOL_QUOTA_SIZE, sizeof(off_t)),
+ (1, ATTR_VOL_RESERVED_SIZE, sizeof(off_t)),
+ (1, ATTR_VOL_ATTRIBUTES, sizeof(vol_attributes_attr_t)),
+ # Directory attributes
+ (2, ATTR_DIR_LINKCOUNT, sizeof(uint32_t)),
+ (2, ATTR_DIR_ENTRYCOUNT, sizeof(uint32_t)),
+ (2, ATTR_DIR_MOUNTSTATUS, sizeof(uint32_t)),
+ (2, ATTR_DIR_ALLOCSIZE, sizeof(off_t)),
+ (2, ATTR_DIR_IOBLOCKSIZE, sizeof(uint32_t)),
+ (2, ATTR_DIR_DATALENGTH, sizeof(off_t)),
+ # File attributes
+ (3, ATTR_FILE_LINKCOUNT, sizeof(uint32_t)),
+ (3, ATTR_FILE_TOTALSIZE, sizeof(off_t)),
+ (3, ATTR_FILE_ALLOCSIZE, sizeof(off_t)),
+ (3, ATTR_FILE_IOBLOCKSIZE, sizeof(uint32_t)),
+ (3, ATTR_FILE_CLUMPSIZE, sizeof(uint32_t)),
+ (3, ATTR_FILE_DEVTYPE, sizeof(uint32_t)),
+ (3, ATTR_FILE_FILETYPE, sizeof(uint32_t)),
+ (3, ATTR_FILE_FORKCOUNT, sizeof(uint32_t)),
+ (3, ATTR_FILE_FORKLIST, None),
+ (3, ATTR_FILE_DATALENGTH, sizeof(off_t)),
+ (3, ATTR_FILE_DATAALLOCSIZE, sizeof(off_t)),
+ (3, ATTR_FILE_DATAEXTENTS, sizeof(extentrecord)),
+ (3, ATTR_FILE_RSRCLENGTH, sizeof(off_t)),
+ (3, ATTR_FILE_RSRCALLOCSIZE, sizeof(off_t)),
+ (3, ATTR_FILE_RSRCEXTENTS, sizeof(extentrecord)),
+ # Fork attributes
+ (4, ATTR_FORK_TOTALSIZE, sizeof(off_t)),
+ (4, ATTR_FORK_ALLOCSIZE, sizeof(off_t)),
+ # Extended common attributes
+ (4, ATTR_CMNEXT_RELPATH, sizeof(attrreference_t) + PATH_MAX),
+ (4, ATTR_CMNEXT_PRIVATESIZE, sizeof(off_t)),
+ (4, ATTR_CMNEXT_LINKID, sizeof(uint64_t)),
+ (4, ATTR_CMNEXT_NOFIRMLINKPATH, sizeof(attrreference_t) + PATH_MAX),
+ (4, ATTR_CMNEXT_REALDEVID, sizeof(dev_t)),
+ (4, ATTR_CMNEXT_REALFSID, sizeof(fsid_t)),
+ (4, ATTR_CMNEXT_CLONEID, sizeof(uint64_t)),
+ (4, ATTR_CMNEXT_EXT_FLAGS, sizeof(uint64_t)),
+)
+
+
+def _attrbuf_size(attrs):
+ size = 4
+ for entry in _attr_info:
+ if attrs[entry[0]] & entry[1]:
+ if entry[2] is None:
+ raise ValueError(
+ "Unsupported attribute (%u, %x)" % (entry[0], entry[1])
+ )
+ size += entry[2]
+ return size
+
+
+_getattrlist = libc.getattrlist
+_getattrlist.argtypes = [c_char_p, POINTER(attrlist), c_void_p, c_ulong, c_ulong]
+_getattrlist.restype = c_int
+
+_fgetattrlist = libc.fgetattrlist
+_fgetattrlist.argtypes = [c_int, POINTER(attrlist), c_void_p, c_ulong, c_ulong]
+_fgetattrlist.restype = c_int
+
+try:
+ _statfs = libc["statfs$INODE64"]
+except (KeyError, AttributeError):
+ _statfs = libc["statfs"]
+
+_statfs.argtypes = [
+ c_char_p,
+ POINTER(struct_statfs),
+]
+_statfs.restype = c_int
+
+try:
+ _fstatfs = libc["fstatfs$INODE64"]
+except (KeyError, AttributeError):
+ _fstatfs = libc["fstatfs"]
+
+_fstatfs.argtypes = [
+ c_int,
+ POINTER(struct_statfs),
+]
+_fstatfs.restype = c_int
+
+
+def _datetime_from_timespec(ts):
+ td = datetime.timedelta(seconds=ts.tv_sec + 1.0e-9 * ts.tv_nsec)
+ return unix_epoch + td
+
+
+def _decode_utf8_nul(sz):
+ nul = sz.find(b"\0")
+ if nul > -1:
+ sz = sz[:nul]
+ return sz.decode("utf-8")
+
+
+def _decode_attrlist_result(buf, attrs, options):
+ result = []
+
+ assert len(buf) >= 4
+ total_size = uint32_t.from_buffer(buf, 0).value
+ assert total_size <= len(buf)
+
+ offset = 4
+
+ # Common attributes
+ if attrs[0] & ATTR_CMN_RETURNED_ATTRS:
+ a = attribute_set_t.from_buffer(buf, offset)
+ result.append(a)
+ offset += sizeof(attribute_set_t)
+ if not (options & FSOPT_PACK_INVAL_ATTRS):
+ attrs = [a.commonattr, a.volattr, a.dirattr, a.fileattr, a.forkattr]
+ if attrs[0] & ATTR_CMN_NAME:
+ a = attrreference_t.from_buffer(buf, offset)
+ ofs = offset + a.attr_dataoffset
+ name = _decode_utf8_nul(buf[ofs : ofs + a.attr_length])
+ offset += sizeof(attrreference_t)
+ result.append(name)
+ if attrs[0] & ATTR_CMN_DEVID:
+ a = dev_t.from_buffer(buf, offset)
+ offset += sizeof(dev_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_FSID:
+ a = fsid_t.from_buffer(buf, offset)
+ offset += sizeof(fsid_t)
+ result.append(a)
+ if attrs[0] & ATTR_CMN_OBJTYPE:
+ a = fsobj_type_t.from_buffer(buf, offset)
+ offset += sizeof(fsobj_type_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_OBJTAG:
+ a = fsobj_tag_t.from_buffer(buf, offset)
+ offset += sizeof(fsobj_tag_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_OBJID:
+ a = fsobj_id_t.from_buffer(buf, offset)
+ offset += sizeof(fsobj_id_t)
+ result.append(a)
+ if attrs[0] & ATTR_CMN_OBJPERMANENTID:
+ a = fsobj_id_t.from_buffer(buf, offset)
+ offset += sizeof(fsobj_id_t)
+ result.append(a)
+ if attrs[0] & ATTR_CMN_PAROBJID:
+ a = fsobj_id_t.from_buffer(buf, offset)
+ offset += sizeof(fsobj_id_t)
+ result.append(a)
+ if attrs[0] & ATTR_CMN_SCRIPT:
+ a = text_encoding_t.from_buffer(buf, offset)
+ offset += sizeof(text_encoding_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_CRTIME:
+ a = timespec.from_buffer(buf, offset)
+ offset += sizeof(timespec)
+ result.append(_datetime_from_timespec(a))
+ if attrs[0] & ATTR_CMN_MODTIME:
+ a = timespec.from_buffer(buf, offset)
+ offset += sizeof(timespec)
+ result.append(_datetime_from_timespec(a))
+ if attrs[0] & ATTR_CMN_CHGTIME:
+ a = timespec.from_buffer(buf, offset)
+ offset += sizeof(timespec)
+ result.append(_datetime_from_timespec(a))
+ if attrs[0] & ATTR_CMN_ACCTIME:
+ a = timespec.from_buffer(buf, offset)
+ offset += sizeof(timespec)
+ result.append(_datetime_from_timespec(a))
+ if attrs[0] & ATTR_CMN_BKUPTIME:
+ a = timespec.from_buffer(buf, offset)
+ offset += sizeof(timespec)
+ result.append(_datetime_from_timespec(a))
+ if attrs[0] & ATTR_CMN_FNDRINFO:
+ a = FinderInfo.from_buffer(buf, offset)
+ offset += sizeof(FinderInfo)
+ result.append(a)
+ if attrs[0] & ATTR_CMN_OWNERID:
+ a = uid_t.from_buffer(buf, offset)
+ offset += sizeof(uid_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_GRPID:
+ a = gid_t.from_buffer(buf, offset)
+ offset += sizeof(gid_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_ACCESSMASK:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_FLAGS:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_GEN_COUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_DOCUMENT_ID:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_USERACCESS:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_EXTENDED_SECURITY:
+ a = attrreference_t.from_buffer(buf, offset)
+ ofs = offset + a.attr_dataoffset
+ offset += sizeof(attrreference_t)
+ ec = uint32_t.from_buffer(buf, ofs + 36).value
+
+ class kauth_acl(Structure):
+ _fields_ = [
+ ("acl_entrycount", c_uint),
+ ("acl_flags", c_uint),
+ ("acl_ace", kauth_ace * ec),
+ ]
+
+ class kauth_filesec(Structure):
+ _fields_ = [
+ ("fsec_magic", c_uint),
+ ("fsec_owner", guid_t),
+ ("fsec_group", guid_t),
+ ("fsec_acl", kauth_acl),
+ ]
+
+ a = kauth_filesec.from_buffer(buf, ofs)
+ result.append(a)
+ if attrs[0] & ATTR_CMN_UUID:
+ result.append(uuid.UUID(bytes=buf[offset : offset + 16]))
+ offset += sizeof(guid_t)
+ if attrs[0] & ATTR_CMN_GRPUUID:
+ result.append(uuid.UUID(bytes=buf[offset : offset + 16]))
+ offset += sizeof(guid_t)
+ if attrs[0] & ATTR_CMN_FILEID:
+ a = uint64_t.from_buffer(buf, offset)
+ offset += sizeof(uint64_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_PARENTID:
+ a = uint64_t.from_buffer(buf, offset)
+ offset += sizeof(uint64_t)
+ result.append(a.value)
+ if attrs[0] & ATTR_CMN_FULLPATH:
+ a = attrreference_t.from_buffer(buf, offset)
+ ofs = offset + a.attr_dataoffset
+ path = _decode_utf8_nul(buf[ofs : ofs + a.attr_length])
+ offset += sizeof(attrreference_t)
+ result.append(path)
+ if attrs[0] & ATTR_CMN_ADDEDTIME:
+ a = timespec.from_buffer(buf, offset)
+ offset += sizeof(timespec)
+ result.append(_datetime_from_timespec(a))
+ if attrs[0] & ATTR_CMN_DATA_PROTECT_FLAGS:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+
+ # Volume attributes
+ if attrs[1] & ATTR_VOL_FSTYPE:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_SIGNATURE:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_SIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_SPACEFREE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_SPACEAVAIL:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_MINALLOCATION:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_ALLOCATIONCLUMP:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_IOBLOCKSIZE:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_OBJCOUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_FILECOUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_DIRCOUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_MAXOBJCOUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_MOUNTPOINT:
+ a = attrreference_t.from_buffer(buf, offset)
+ ofs = offset + a.attr_dataoffset
+ path = _decode_utf8_nul(buf[ofs : ofs + a.attr_length])
+ offset += sizeof(attrreference_t)
+ result.append(path)
+ if attrs[1] & ATTR_VOL_NAME:
+ a = attrreference_t.from_buffer(buf, offset)
+ ofs = offset + a.attr_dataoffset
+ name = _decode_utf8_nul(buf[ofs : ofs + a.attr_length])
+ offset += sizeof(attrreference_t)
+ result.append(name)
+ if attrs[1] & ATTR_VOL_MOUNTFLAGS:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_MOUNTEDDEVICE:
+ a = attrreference_t.from_buffer(buf, offset)
+ ofs = offset + a.attr_dataoffset
+ path = _decode_utf8_nul(buf[ofs : ofs + a.attr_length])
+ offset += sizeof(attrreference_t)
+ result.append(path)
+ if attrs[1] & ATTR_VOL_ENCODINGSUSED:
+ a = c_ulonglong.from_buffer(buf, offset)
+ offset += sizeof(c_ulonglong)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_CAPABILITIES:
+ a = vol_capabilities_attr_t.from_buffer(buf, offset)
+ offset += sizeof(vol_capabilities_attr_t)
+ result.append(a)
+ if attrs[1] & ATTR_VOL_UUID:
+ result.append(uuid.UUID(bytes=buf[offset : offset + 16]))
+ offset += sizeof(uuid_t)
+ if attrs[1] & ATTR_VOL_QUOTA_SIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_RESERVED_SIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[1] & ATTR_VOL_ATTRIBUTES:
+ a = vol_attributes_attr_t.from_buffer(buf, offset)
+ offset += sizeof(vol_attributes_attr_t)
+ result.append(a)
+
+ # Directory attributes
+ if attrs[2] & ATTR_DIR_LINKCOUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[2] & ATTR_DIR_ENTRYCOUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[2] & ATTR_DIR_MOUNTSTATUS:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[2] & ATTR_DIR_ALLOCSIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[2] & ATTR_DIR_IOBLOCKSIZE:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[2] & ATTR_DIR_DATALENGTH:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+
+ # File attributes
+ if attrs[3] & ATTR_FILE_LINKCOUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_TOTALSIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_ALLOCSIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_IOBLOCKSIZE:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_CLUMPSIZE:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_DEVTYPE:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_FILETYPE:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_FORKCOUNT:
+ a = uint32_t.from_buffer(buf, offset)
+ offset += sizeof(uint32_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_DATALENGTH:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_DATAALLOCSIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_DATAEXTENTS:
+ a = extentrecord.from_buffer(buf, offset)
+ offset += sizeof(extentrecord)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_RSRCLENGTH:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_RSRCALLOCSIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[3] & ATTR_FILE_RSRCEXTENTS:
+ a = extentrecord.from_buffer(buf, offset)
+ offset += sizeof(extentrecord)
+ result.append(a.value)
+
+ # Fork attributes
+ if attrs[4] & ATTR_FORK_TOTALSIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[4] & ATTR_FORK_ALLOCSIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+
+ # Extended common attributes
+ if attrs[4] & ATTR_CMNEXT_RELPATH:
+ a = attrreference_t.from_buffer(buf, offset)
+ ofs = offset + a.attr_dataoffset
+ path = _decode_utf8_nul(buf[ofs : ofs + a.attr_length])
+ offset += sizeof(attrreference_t)
+ result.append(path)
+ if attrs[4] & ATTR_CMNEXT_PRIVATESIZE:
+ a = off_t.from_buffer(buf, offset)
+ offset += sizeof(off_t)
+ result.append(a.value)
+ if attrs[4] & ATTR_CMNEXT_LINKID:
+ a = uint64_t.from_buffer(buf, offset)
+ offset += sizeof(uint64_t)
+ result.append(a.value)
+ if attrs[4] & ATTR_CMNEXT_NOFIRMLINKPATH:
+ a = attrreference_t.from_buffer(buf, offset)
+ ofs = offset + a.attr_dataoffset
+ path = _decode_utf8_nul(buf[ofs : ofs + a.attr_length])
+ offset += sizeof(attrreference_t)
+ result.append(path)
+ if attrs[4] & ATTR_CMNEXT_REALDEVID:
+ a = dev_t.from_buffer(buf, offset)
+ offset += sizeof(dev_t)
+ result.append(a.value)
+ if attrs[4] & ATTR_CMNEXT_REALFSID:
+ a = fsid_t.from_buffer(buf, offset)
+ offset += sizeof(fsid_t)
+ result.append(a.value)
+ if attrs[4] & ATTR_CMNEXT_CLONEID:
+ a = uint64_t.from_buffer(buf, offset)
+ offset += sizeof(uint64_t)
+ result.append(a.value)
+ if attrs[4] & ATTR_CMNEXT_EXT_FLAGS:
+ a = uint64_t.from_buffer(buf, offset)
+ offset += sizeof(uint64_t)
+ result.append(a.value)
+
+ return result
+
+
+# Sadly, ctypes.get_errno() seems not to work
+__error = libc.__error
+__error.restype = POINTER(c_int)
+
+
+def _get_errno():
+ return __error().contents.value
+
+
+def getattrlist(path, attrs, options):
+ if not isinstance(path, bytes):
+ path = path.encode("utf-8")
+ attrs = list(attrs)
+ if attrs[1]:
+ attrs[1] |= ATTR_VOL_INFO
+ alist = attrlist(
+ bitmapcount=5,
+ commonattr=attrs[0],
+ volattr=attrs[1],
+ dirattr=attrs[2],
+ fileattr=attrs[3],
+ forkattr=attrs[4],
+ )
+
+ bufsize = _attrbuf_size(attrs)
+ buf = create_string_buffer(bufsize)
+
+ ret = _getattrlist(
+ path, byref(alist), buf, bufsize, options | FSOPT_REPORT_FULLSIZE
+ )
+
+ if ret < 0:
+ err = _get_errno()
+ raise OSError(err, os.strerror(err), path)
+
+ return _decode_attrlist_result(buf, attrs, options)
+
+
+def fgetattrlist(fd, attrs, options):
+ if hasattr(fd, "fileno"):
+ fd = fd.fileno()
+ attrs = list(attrs)
+ if attrs[1]:
+ attrs[1] |= ATTR_VOL_INFO
+ alist = attrlist(
+ bitmapcount=5,
+ commonattr=attrs[0],
+ volattr=attrs[1],
+ dirattr=attrs[2],
+ fileattr=attrs[3],
+ forkattr=attrs[4],
+ )
+
+ bufsize = _attrbuf_size(attrs)
+ buf = create_string_buffer(bufsize)
+
+ ret = _fgetattrlist(fd, byref(alist), buf, bufsize, options | FSOPT_REPORT_FULLSIZE)
+
+ if ret < 0:
+ err = _get_errno()
+ raise OSError(err, os.strerror(err))
+
+ return _decode_attrlist_result(buf, attrs, options)
+
+
+def statfs(path):
+ if not isinstance(path, bytes):
+ path = path.encode("utf-8")
+ result = struct_statfs()
+ ret = _statfs(path, byref(result))
+ if ret < 0:
+ err = _get_errno()
+ raise OSError(err, os.strerror(err), path)
+ return result
+
+
+def fstatfs(fd):
+ if hasattr(fd, "fileno"):
+ fd = fd.fileno()
+ result = struct_statfs()
+ ret = _fstatfs(fd, byref(result))
+ if ret < 0:
+ err = _get_errno()
+ raise OSError(err, os.strerror(err))
+ return result