(self, tarinfo, status=None, type=None)
| 1560 | |
| 1561 | @contextmanager |
| 1562 | def create_helper(self, tarinfo, status=None, type=None): |
| 1563 | ph = tarinfo.pax_headers |
| 1564 | if ph and "BORG.item.version" in ph: |
| 1565 | assert ph["BORG.item.version"] == "1" |
| 1566 | meta_bin = base64.b64decode(ph["BORG.item.meta"]) |
| 1567 | meta_dict = msgpack.unpackb(meta_bin, object_hook=StableDict) |
| 1568 | item = Item(internal_dict=meta_dict) |
| 1569 | else: |
| 1570 | |
| 1571 | def s_to_ns(s): |
| 1572 | return safe_ns(int(float(s) * 1e9)) |
| 1573 | |
| 1574 | # if the tar has names starting with "./", normalize them like borg create also does. |
| 1575 | # ./dir/file must become dir/file in the borg archive. |
| 1576 | normalized_path = posixpath.normpath(tarinfo.name) |
| 1577 | item = Item( |
| 1578 | path=make_path_safe(normalized_path), |
| 1579 | mode=tarinfo.mode | type, |
| 1580 | uid=tarinfo.uid, |
| 1581 | gid=tarinfo.gid, |
| 1582 | mtime=s_to_ns(tarinfo.mtime), |
| 1583 | ) |
| 1584 | if tarinfo.uname: |
| 1585 | item.user = tarinfo.uname |
| 1586 | if tarinfo.gname: |
| 1587 | item.group = tarinfo.gname |
| 1588 | if ph: |
| 1589 | # note: for mtime this is a bit redundant as it is already done by tarfile module, |
| 1590 | # but we just do it in our way to be consistent for sure. |
| 1591 | for name in "atime", "ctime", "mtime": |
| 1592 | if name in ph: |
| 1593 | ns = s_to_ns(ph[name]) |
| 1594 | setattr(item, name, ns) |
| 1595 | xattrs = StableDict() |
| 1596 | for key, value in ph.items(): |
| 1597 | if key.startswith(SCHILY_XATTR): |
| 1598 | key = key.removeprefix(SCHILY_XATTR) |
| 1599 | # the tarfile code gives us str keys and str values, |
| 1600 | # but we need bytes keys and bytes values. |
| 1601 | bkey = key.encode("utf-8", errors="surrogateescape") |
| 1602 | bvalue = value.encode("utf-8", errors="surrogateescape") |
| 1603 | xattrs[bkey] = bvalue |
| 1604 | elif key == SCHILY_ACL_ACCESS: |
| 1605 | # Process POSIX access ACL |
| 1606 | item.acl_access = value.encode("utf-8", errors="surrogateescape") |
| 1607 | elif key == SCHILY_ACL_DEFAULT: |
| 1608 | # Process POSIX default ACL |
| 1609 | item.acl_default = value.encode("utf-8", errors="surrogateescape") |
| 1610 | if xattrs: |
| 1611 | item.xattrs = xattrs |
| 1612 | yield item, status |
| 1613 | # if we get here, "with"-block worked ok without error/exception, the item was processed ok... |
| 1614 | self.add_item(item, stats=self.stats) |
| 1615 | |
| 1616 | def process_dir(self, *, tarinfo, status, type): |
| 1617 | with self.create_helper(tarinfo, status, type) as (item, status): |
no test coverage detected