summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2005-08-02 03:17:57 +0000
committerkientzle <kientzle@FreeBSD.org>2005-08-02 03:17:57 +0000
commite937b9141e7547b529319477cd1d123aae205824 (patch)
tree99fc8157e4fc26fcbde7abbfd3a7d512d253a616 /lib/libarchive
parenteda3e2bd3733063ba67e59dd8d3670614a834618 (diff)
downloadFreeBSD-src-e937b9141e7547b529319477cd1d123aae205824.zip
FreeBSD-src-e937b9141e7547b529319477cd1d123aae205824.tar.gz
Generate default fake "device" and "inode" numbers for entries
extracted from tar archives. Otherwise, converting tar archives to cpio format (with "bsdtar -cf out.cpio @in.tar") convert every entry into a hard link to a single file. This simple logic breaks hard links, but that's better than the alternative. MFC after: 7 days
Diffstat (limited to 'lib/libarchive')
-rw-r--r--lib/libarchive/archive_read_support_format_tar.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/lib/libarchive/archive_read_support_format_tar.c b/lib/libarchive/archive_read_support_format_tar.c
index 81f08b1..882d2df 100644
--- a/lib/libarchive/archive_read_support_format_tar.c
+++ b/lib/libarchive/archive_read_support_format_tar.c
@@ -361,6 +361,22 @@ static int
archive_read_format_tar_read_header(struct archive *a,
struct archive_entry *entry)
{
+ /*
+ * When converting tar archives to cpio archives, it is
+ * essential that each distinct file have a distinct inode
+ * number. To simplify this, we keep a static count here to
+ * assign fake dev/inode numbers to each tar entry. Note that
+ * pax format archives may overwrite this with something more
+ * useful.
+ *
+ * Ideally, we would track every file read from the archive so
+ * that we could assign the same dev/ino pair to hardlinks,
+ * but the memory required to store a complete lookup table is
+ * probably not worthwhile just to support the relatively
+ * obscure tar->cpio conversion case.
+ */
+ static int default_inode;
+ static int default_dev;
struct stat st;
struct tar *tar;
const char *p;
@@ -368,6 +384,15 @@ archive_read_format_tar_read_header(struct archive *a,
size_t l;
memset(&st, 0, sizeof(st));
+ /* Assign default device/inode values. */
+ st.st_dev = 1 + default_dev; /* Don't use zero. */
+ st.st_ino = ++default_inode; /* Don't use zero. */
+ /* Limit generated st_ino number to 16 bits. */
+ if (default_inode >= 0xffff) {
+ ++default_dev;
+ default_inode = 0;
+ }
+
tar = *(a->pformat_data);
tar->entry_offset = 0;
OpenPOWER on IntegriCloud