diff options
author | kientzle <kientzle@FreeBSD.org> | 2005-08-02 03:17:57 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2005-08-02 03:17:57 +0000 |
commit | e937b9141e7547b529319477cd1d123aae205824 (patch) | |
tree | 99fc8157e4fc26fcbde7abbfd3a7d512d253a616 /lib/libarchive/archive_read_support_format_tar.c | |
parent | eda3e2bd3733063ba67e59dd8d3670614a834618 (diff) | |
download | FreeBSD-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/archive_read_support_format_tar.c')
-rw-r--r-- | lib/libarchive/archive_read_support_format_tar.c | 25 |
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; |