|
@@ -13,6 +13,7 @@ from io import BytesIO
|
|
|
from itertools import groupby, zip_longest
|
|
|
from shutil import get_terminal_size
|
|
|
|
|
|
+from .platformflags import is_win32, is_linux, is_freebsd, is_darwin
|
|
|
from .logger import create_logger
|
|
|
|
|
|
logger = create_logger()
|
|
@@ -29,7 +30,7 @@ from .helpers import Manifest
|
|
|
from .helpers import hardlinkable
|
|
|
from .helpers import ChunkIteratorFileWrapper, open_item
|
|
|
from .helpers import Error, IntegrityError, set_ec
|
|
|
-from .helpers import uid2user, user2uid, gid2group, group2gid
|
|
|
+from .platform import uid2user, user2uid, gid2group, group2gid
|
|
|
from .helpers import parse_timestamp, to_localtime
|
|
|
from .helpers import OutputTimestamp, format_timedelta, format_file_size, file_status, FileSize
|
|
|
from .helpers import safe_encode, safe_decode, make_path_safe, remove_surrogates
|
|
@@ -679,57 +680,58 @@ Utilization of max. archive size: {csize_max:.0%}
|
|
|
uid = item.uid if uid is None else uid
|
|
|
gid = item.gid if gid is None else gid
|
|
|
# This code is a bit of a mess due to os specific differences
|
|
|
- try:
|
|
|
- if fd:
|
|
|
- os.fchown(fd, uid, gid)
|
|
|
- else:
|
|
|
- os.chown(path, uid, gid, follow_symlinks=False)
|
|
|
- except OSError:
|
|
|
- pass
|
|
|
- if fd:
|
|
|
- os.fchmod(fd, item.mode)
|
|
|
- elif not symlink:
|
|
|
- os.chmod(path, item.mode)
|
|
|
- elif has_lchmod: # Not available on Linux
|
|
|
- os.lchmod(path, item.mode)
|
|
|
- mtime = item.mtime
|
|
|
- if 'atime' in item:
|
|
|
- atime = item.atime
|
|
|
- else:
|
|
|
- # old archives only had mtime in item metadata
|
|
|
- atime = mtime
|
|
|
- if 'birthtime' in item:
|
|
|
- birthtime = item.birthtime
|
|
|
+ if not is_win32:
|
|
|
try:
|
|
|
- # This should work on FreeBSD, NetBSD, and Darwin and be harmless on other platforms.
|
|
|
- # See utimes(2) on either of the BSDs for details.
|
|
|
if fd:
|
|
|
- os.utime(fd, None, ns=(atime, birthtime))
|
|
|
+ os.fchown(fd, uid, gid)
|
|
|
else:
|
|
|
- os.utime(path, None, ns=(atime, birthtime), follow_symlinks=False)
|
|
|
+ os.chown(path, uid, gid, follow_symlinks=False)
|
|
|
except OSError:
|
|
|
- # some systems don't support calling utime on a symlink
|
|
|
pass
|
|
|
- try:
|
|
|
if fd:
|
|
|
- os.utime(fd, None, ns=(atime, mtime))
|
|
|
+ os.fchmod(fd, item.mode)
|
|
|
+ elif not symlink:
|
|
|
+ os.chmod(path, item.mode)
|
|
|
+ elif has_lchmod: # Not available on Linux
|
|
|
+ os.lchmod(path, item.mode)
|
|
|
+ mtime = item.mtime
|
|
|
+ if 'atime' in item:
|
|
|
+ atime = item.atime
|
|
|
else:
|
|
|
- os.utime(path, None, ns=(atime, mtime), follow_symlinks=False)
|
|
|
- except OSError:
|
|
|
- # some systems don't support calling utime on a symlink
|
|
|
- pass
|
|
|
- acl_set(path, item, self.numeric_owner, fd=fd)
|
|
|
- # chown removes Linux capabilities, so set the extended attributes at the end, after chown, since they include
|
|
|
- # the Linux capabilities in the "security.capability" attribute.
|
|
|
- warning = xattr.set_all(fd or path, item.get('xattrs', {}), follow_symlinks=False)
|
|
|
- if warning:
|
|
|
- set_ec(EXIT_WARNING)
|
|
|
- # bsdflags include the immutable flag and need to be set last:
|
|
|
- if not self.nobsdflags and 'bsdflags' in item:
|
|
|
+ # old archives only had mtime in item metadata
|
|
|
+ atime = mtime
|
|
|
+ if 'birthtime' in item:
|
|
|
+ birthtime = item.birthtime
|
|
|
+ try:
|
|
|
+ # This should work on FreeBSD, NetBSD, and Darwin and be harmless on other platforms.
|
|
|
+ # See utimes(2) on either of the BSDs for details.
|
|
|
+ if fd:
|
|
|
+ os.utime(fd, None, ns=(atime, birthtime))
|
|
|
+ else:
|
|
|
+ os.utime(path, None, ns=(atime, birthtime), follow_symlinks=False)
|
|
|
+ except OSError:
|
|
|
+ # some systems don't support calling utime on a symlink
|
|
|
+ pass
|
|
|
try:
|
|
|
- set_flags(path, item.bsdflags, fd=fd)
|
|
|
+ if fd:
|
|
|
+ os.utime(fd, None, ns=(atime, mtime))
|
|
|
+ else:
|
|
|
+ os.utime(path, None, ns=(atime, mtime), follow_symlinks=False)
|
|
|
except OSError:
|
|
|
+ # some systems don't support calling utime on a symlink
|
|
|
pass
|
|
|
+ acl_set(path, item, self.numeric_owner, fd=fd)
|
|
|
+ # chown removes Linux capabilities, so set the extended attributes at the end, after chown, since they include
|
|
|
+ # the Linux capabilities in the "security.capability" attribute.
|
|
|
+ warning = xattr.set_all(fd or path, item.get('xattrs', {}), follow_symlinks=False)
|
|
|
+ if warning:
|
|
|
+ set_ec(EXIT_WARNING)
|
|
|
+ # bsdflags include the immutable flag and need to be set last:
|
|
|
+ if not self.nobsdflags and 'bsdflags' in item:
|
|
|
+ try:
|
|
|
+ set_flags(path, item.bsdflags, fd=fd)
|
|
|
+ except OSError:
|
|
|
+ pass
|
|
|
|
|
|
def set_meta(self, key, value):
|
|
|
metadata = self._load_meta(self.id)
|