mirror of
https://github.com/borgbackup/borg.git
synced 2025-12-18 15:46:20 -05:00
NetBSD: copy xattr implementation of FreeBSD, fixes #1332
This commit is contained in:
parent
9a0122995c
commit
0286fb6dc4
3 changed files with 108 additions and 2 deletions
9
setup.py
9
setup.py
|
|
@ -61,6 +61,7 @@ platform_linux_source = "src/borg/platform/linux.pyx"
|
|||
platform_syncfilerange_source = "src/borg/platform/syncfilerange.pyx"
|
||||
platform_darwin_source = "src/borg/platform/darwin.pyx"
|
||||
platform_freebsd_source = "src/borg/platform/freebsd.pyx"
|
||||
platform_netbsd_source = "src/borg/platform/netbsd.pyx"
|
||||
platform_windows_source = "src/borg/platform/windows.pyx"
|
||||
|
||||
cython_sources = [
|
||||
|
|
@ -76,6 +77,7 @@ cython_sources = [
|
|||
platform_linux_source,
|
||||
platform_syncfilerange_source,
|
||||
platform_freebsd_source,
|
||||
platform_netbsd_source,
|
||||
platform_darwin_source,
|
||||
platform_windows_source,
|
||||
]
|
||||
|
|
@ -197,6 +199,7 @@ if not on_rtd:
|
|||
"borg.platform.syncfilerange", [platform_syncfilerange_source], extra_compile_args=cflags
|
||||
)
|
||||
freebsd_ext = Extension("borg.platform.freebsd", [platform_freebsd_source], extra_compile_args=cflags)
|
||||
netbsd_ext = Extension("borg.platform.netbsd", [platform_netbsd_source], extra_compile_args=cflags)
|
||||
darwin_ext = Extension("borg.platform.darwin", [platform_darwin_source], extra_compile_args=cflags)
|
||||
windows_ext = Extension("borg.platform.windows", [platform_windows_source], extra_compile_args=cflags)
|
||||
|
||||
|
|
@ -209,6 +212,8 @@ if not on_rtd:
|
|||
ext_modules.append(syncfilerange_ext)
|
||||
elif sys.platform.startswith("freebsd"):
|
||||
ext_modules.append(freebsd_ext)
|
||||
elif sys.platform.startswith("netbsd"):
|
||||
ext_modules.append(netbsd_ext)
|
||||
elif sys.platform == "darwin":
|
||||
ext_modules.append(darwin_ext)
|
||||
|
||||
|
|
@ -230,7 +235,9 @@ if not on_rtd:
|
|||
|
||||
# generate C code from Cython for ALL supported platforms, so we have them in the sdist.
|
||||
# the sdist does not require Cython at install time, so we need all as C.
|
||||
cythonize([posix_ext, linux_ext, syncfilerange_ext, freebsd_ext, darwin_ext, windows_ext], **cython_opts)
|
||||
cythonize(
|
||||
[posix_ext, linux_ext, syncfilerange_ext, freebsd_ext, netbsd_ext, darwin_ext, windows_ext], **cython_opts
|
||||
)
|
||||
# generate C code from Cython for THIS platform (and for all platform-independent Cython parts).
|
||||
ext_modules = cythonize(ext_modules, **cython_opts)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ Platform-specific APIs.
|
|||
Public APIs are documented in platform.base.
|
||||
"""
|
||||
|
||||
from ..platformflags import is_win32, is_linux, is_freebsd, is_darwin, is_cygwin
|
||||
from ..platformflags import is_win32, is_linux, is_freebsd, is_netbsd, is_darwin, is_cygwin
|
||||
|
||||
from .base import ENOATTR, API_VERSION
|
||||
from .base import SaveFile, sync_dir, fdatasync, safe_fadvise
|
||||
|
|
@ -31,6 +31,16 @@ elif is_freebsd: # pragma: freebsd only
|
|||
from .posix import swidth
|
||||
from .posix import get_errno
|
||||
from .posix import uid2user, user2uid, gid2group, group2gid, getosusername
|
||||
elif is_netbsd: # pragma: netbsd only
|
||||
from .netbsd import API_VERSION as OS_API_VERSION
|
||||
from .netbsd import listxattr, getxattr, setxattr
|
||||
from .base import acl_get, acl_set
|
||||
from .base import set_flags, get_flags
|
||||
from .base import SyncFile
|
||||
from .posix import process_alive, local_pid_alive
|
||||
from .posix import swidth
|
||||
from .posix import get_errno
|
||||
from .posix import uid2user, user2uid, gid2group, group2gid, getosusername
|
||||
elif is_darwin: # pragma: darwin only
|
||||
from .darwin import API_VERSION as OS_API_VERSION
|
||||
from .darwin import listxattr, getxattr, setxattr
|
||||
|
|
|
|||
89
src/borg/platform/netbsd.pyx
Normal file
89
src/borg/platform/netbsd.pyx
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
from .xattr import _listxattr_inner, _getxattr_inner, _setxattr_inner, split_lstring
|
||||
|
||||
API_VERSION = '1.2_05'
|
||||
|
||||
cdef extern from "sys/extattr.h":
|
||||
ssize_t c_extattr_list_file "extattr_list_file" (const char *path, int attrnamespace, void *data, size_t nbytes)
|
||||
ssize_t c_extattr_list_link "extattr_list_link" (const char *path, int attrnamespace, void *data, size_t nbytes)
|
||||
ssize_t c_extattr_list_fd "extattr_list_fd" (int fd, int attrnamespace, void *data, size_t nbytes)
|
||||
|
||||
ssize_t c_extattr_get_file "extattr_get_file" (const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes)
|
||||
ssize_t c_extattr_get_link "extattr_get_link" (const char *path, int attrnamespace, const char *attrname, void *data, size_t nbytes)
|
||||
ssize_t c_extattr_get_fd "extattr_get_fd" (int fd, int attrnamespace, const char *attrname, void *data, size_t nbytes)
|
||||
|
||||
int c_extattr_set_file "extattr_set_file" (const char *path, int attrnamespace, const char *attrname, const void *data, size_t nbytes)
|
||||
int c_extattr_set_link "extattr_set_link" (const char *path, int attrnamespace, const char *attrname, const void *data, size_t nbytes)
|
||||
int c_extattr_set_fd "extattr_set_fd" (int fd, int attrnamespace, const char *attrname, const void *data, size_t nbytes)
|
||||
|
||||
int EXTATTR_NAMESPACE_USER
|
||||
|
||||
|
||||
# On NetBSD, Borg currently only deals with the USER namespace, as it is unclear
|
||||
# whether (and, if so, how exactly) it should deal with the SYSTEM namespace.
|
||||
NS_ID_MAP = {b"user": EXTATTR_NAMESPACE_USER, }
|
||||
|
||||
|
||||
def split_ns(ns_name, default_ns):
|
||||
# Split ns_name (which is in the form b"namespace.name") into namespace and name.
|
||||
# If there is no namespace given in ns_name, default to default_ns.
|
||||
# We also need to deal with "unexpected" namespaces here — they could come
|
||||
# from Borg archives made on other operating systems.
|
||||
ns_name_tuple = ns_name.split(b".", 1)
|
||||
if len(ns_name_tuple) == 2:
|
||||
# We have a namespace prefix in the given name.
|
||||
ns, name = ns_name_tuple
|
||||
else:
|
||||
# No namespace given in ns_name (no dot found); maybe data from an old Borg archive.
|
||||
ns, name = default_ns, ns_name
|
||||
return ns, name
|
||||
|
||||
|
||||
def listxattr(path, *, follow_symlinks=False):
|
||||
def func(path, buf, size):
|
||||
if isinstance(path, int):
|
||||
return c_extattr_list_fd(path, ns_id, <char *> buf, size)
|
||||
else:
|
||||
if follow_symlinks:
|
||||
return c_extattr_list_file(path, ns_id, <char *> buf, size)
|
||||
else:
|
||||
return c_extattr_list_link(path, ns_id, <char *> buf, size)
|
||||
|
||||
ns = b"user"
|
||||
ns_id = NS_ID_MAP[ns]
|
||||
n, buf = _listxattr_inner(func, path)
|
||||
return [ns + b"." + name for name in split_lstring(buf[:n]) if name]
|
||||
|
||||
|
||||
def getxattr(path, name, *, follow_symlinks=False):
|
||||
def func(path, name, buf, size):
|
||||
if isinstance(path, int):
|
||||
return c_extattr_get_fd(path, ns_id, name, <char *> buf, size)
|
||||
else:
|
||||
if follow_symlinks:
|
||||
return c_extattr_get_file(path, ns_id, name, <char *> buf, size)
|
||||
else:
|
||||
return c_extattr_get_link(path, ns_id, name, <char *> buf, size)
|
||||
|
||||
ns, name = split_ns(name, b"user")
|
||||
ns_id = NS_ID_MAP[ns] # this will raise a KeyError it the namespace is unsupported
|
||||
n, buf = _getxattr_inner(func, path, name)
|
||||
return bytes(buf[:n])
|
||||
|
||||
|
||||
def setxattr(path, name, value, *, follow_symlinks=False):
|
||||
def func(path, name, value, size):
|
||||
if isinstance(path, int):
|
||||
return c_extattr_set_fd(path, ns_id, name, <char *> value, size)
|
||||
else:
|
||||
if follow_symlinks:
|
||||
return c_extattr_set_file(path, ns_id, name, <char *> value, size)
|
||||
else:
|
||||
return c_extattr_set_link(path, ns_id, name, <char *> value, size)
|
||||
|
||||
ns, name = split_ns(name, b"user")
|
||||
try:
|
||||
ns_id = NS_ID_MAP[ns] # this will raise a KeyError it the namespace is unsupported
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
_setxattr_inner(func, path, name, value)
|
||||
Loading…
Reference in a new issue