summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_read_support_format_cpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libarchive/archive_read_support_format_cpio.c')
-rw-r--r--lib/libarchive/archive_read_support_format_cpio.c215
1 files changed, 98 insertions, 117 deletions
diff --git a/lib/libarchive/archive_read_support_format_cpio.c b/lib/libarchive/archive_read_support_format_cpio.c
index 0fe4051..7eccc87 100644
--- a/lib/libarchive/archive_read_support_format_cpio.c
+++ b/lib/libarchive/archive_read_support_format_cpio.c
@@ -26,15 +26,6 @@
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#ifdef MAJOR_IN_MKDEV
-#include <sys/mkdev.h>
-#elif defined(MAJOR_IN_SYSMACROS)
-#include <sys/sysmacros.h>
-#endif
-
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@@ -45,9 +36,6 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_STRING_H
#include <string.h>
#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
#include "archive.h"
#include "archive_entry.h"
@@ -112,7 +100,7 @@ struct links_entry {
struct cpio {
int magic;
int (*read_header)(struct archive_read *, struct cpio *,
- struct stat *, size_t *, size_t *);
+ struct archive_entry *, size_t *, size_t *);
struct links_entry *links_head;
struct archive_string entry_name;
struct archive_string entry_linkname;
@@ -130,17 +118,16 @@ static int archive_read_format_cpio_read_data(struct archive_read *,
static int archive_read_format_cpio_read_header(struct archive_read *,
struct archive_entry *);
static int be4(const unsigned char *);
-static int header_bin_be(struct archive_read *, struct cpio *, struct stat *,
- size_t *, size_t *);
-static int header_bin_le(struct archive_read *, struct cpio *, struct stat *,
- size_t *, size_t *);
-static int header_newc(struct archive_read *, struct cpio *, struct stat *,
- size_t *, size_t *);
-static int header_odc(struct archive_read *, struct cpio *, struct stat *,
- size_t *, size_t *);
+static int header_bin_be(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
+static int header_bin_le(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
+static int header_newc(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
+static int header_odc(struct archive_read *, struct cpio *,
+ struct archive_entry *, size_t *, size_t *);
static int le4(const unsigned char *);
-static void record_hardlink(struct cpio *cpio, struct archive_entry *entry,
- const struct stat *st);
+static void record_hardlink(struct cpio *cpio, struct archive_entry *entry);
int
archive_read_support_format_cpio(struct archive *_a)
@@ -179,9 +166,9 @@ archive_read_format_cpio_bid(struct archive_read *a)
const unsigned char *p;
struct cpio *cpio;
- cpio = (struct cpio *)*(a->pformat_data);
+ cpio = (struct cpio *)(a->format->data);
bid = 0;
- bytes_read = (a->compression_read_ahead)(a, &h, 6);
+ bytes_read = (a->decompressor->read_ahead)(a, &h, 6);
/* Convert error code into error return. */
if (bytes_read < 0)
return ((int)bytes_read);
@@ -234,7 +221,6 @@ static int
archive_read_format_cpio_read_header(struct archive_read *a,
struct archive_entry *entry)
{
- struct stat st;
struct cpio *cpio;
size_t bytes;
const void *h;
@@ -242,33 +228,28 @@ archive_read_format_cpio_read_header(struct archive_read *a,
size_t name_pad;
int r;
- memset(&st, 0, sizeof(st));
-
- cpio = (struct cpio *)*(a->pformat_data);
- r = (cpio->read_header(a, cpio, &st, &namelength, &name_pad));
+ cpio = (struct cpio *)(a->format->data);
+ r = (cpio->read_header(a, cpio, entry, &namelength, &name_pad));
if (r != ARCHIVE_OK)
return (r);
- /* Assign all of the 'stat' fields at once. */
- archive_entry_copy_stat(entry, &st);
-
/* Read name from buffer. */
- bytes = (a->compression_read_ahead)(a, &h, namelength + name_pad);
+ bytes = (a->decompressor->read_ahead)(a, &h, namelength + name_pad);
if (bytes < namelength + name_pad)
return (ARCHIVE_FATAL);
- (a->compression_read_consume)(a, namelength + name_pad);
+ (a->decompressor->consume)(a, namelength + name_pad);
archive_strncpy(&cpio->entry_name, (const char *)h, namelength);
archive_entry_set_pathname(entry, cpio->entry_name.s);
cpio->entry_offset = 0;
/* If this is a symlink, read the link contents. */
- if (S_ISLNK(st.st_mode)) {
- bytes = (a->compression_read_ahead)(a, &h,
+ if (archive_entry_filetype(entry) == AE_IFLNK) {
+ bytes = (a->decompressor->read_ahead)(a, &h,
cpio->entry_bytes_remaining);
if ((off_t)bytes < cpio->entry_bytes_remaining)
return (ARCHIVE_FATAL);
- (a->compression_read_consume)(a, cpio->entry_bytes_remaining);
+ (a->decompressor->consume)(a, cpio->entry_bytes_remaining);
archive_strncpy(&cpio->entry_linkname, (const char *)h,
cpio->entry_bytes_remaining);
archive_entry_set_symlink(entry, cpio->entry_linkname.s);
@@ -283,7 +264,7 @@ archive_read_format_cpio_read_header(struct archive_read *a,
}
/* Detect and record hardlinks to previously-extracted entries. */
- record_hardlink(cpio, entry, &st);
+ record_hardlink(cpio, entry);
return (ARCHIVE_OK);
}
@@ -295,9 +276,9 @@ archive_read_format_cpio_read_data(struct archive_read *a,
ssize_t bytes_read;
struct cpio *cpio;
- cpio = (struct cpio *)*(a->pformat_data);
+ cpio = (struct cpio *)(a->format->data);
if (cpio->entry_bytes_remaining > 0) {
- bytes_read = (a->compression_read_ahead)(a, buff, 1);
+ bytes_read = (a->decompressor->read_ahead)(a, buff, 1);
if (bytes_read <= 0)
return (ARCHIVE_FATAL);
if (bytes_read > cpio->entry_bytes_remaining)
@@ -306,16 +287,16 @@ archive_read_format_cpio_read_data(struct archive_read *a,
*offset = cpio->entry_offset;
cpio->entry_offset += bytes_read;
cpio->entry_bytes_remaining -= bytes_read;
- (a->compression_read_consume)(a, bytes_read);
+ (a->decompressor->consume)(a, bytes_read);
return (ARCHIVE_OK);
} else {
while (cpio->entry_padding > 0) {
- bytes_read = (a->compression_read_ahead)(a, buff, 1);
+ bytes_read = (a->decompressor->read_ahead)(a, buff, 1);
if (bytes_read <= 0)
return (ARCHIVE_FATAL);
if (bytes_read > cpio->entry_padding)
bytes_read = cpio->entry_padding;
- (a->compression_read_consume)(a, bytes_read);
+ (a->decompressor->consume)(a, bytes_read);
cpio->entry_padding -= bytes_read;
}
*buff = NULL;
@@ -326,20 +307,20 @@ archive_read_format_cpio_read_data(struct archive_read *a,
}
static int
-header_newc(struct archive_read *a, struct cpio *cpio, struct stat *st,
- size_t *namelength, size_t *name_pad)
+header_newc(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
const void *h;
const struct cpio_newc_header *header;
size_t bytes;
/* Read fixed-size portion of header. */
- bytes = (a->compression_read_ahead)(a, &h, sizeof(struct cpio_newc_header));
+ bytes = (a->decompressor->read_ahead)(a, &h, sizeof(struct cpio_newc_header));
if (bytes < sizeof(struct cpio_newc_header))
return (ARCHIVE_FATAL);
- (a->compression_read_consume)(a, sizeof(struct cpio_newc_header));
+ (a->decompressor->consume)(a, sizeof(struct cpio_newc_header));
- /* Parse out hex fields into struct stat. */
+ /* Parse out hex fields. */
header = (const struct cpio_newc_header *)h;
if (memcmp(header->c_magic, "070701", 6) == 0) {
@@ -352,18 +333,16 @@ header_newc(struct archive_read *a, struct cpio *cpio, struct stat *st,
/* TODO: Abort here? */
}
- st->st_dev = makedev(
- atol16(header->c_devmajor, sizeof(header->c_devmajor)),
- atol16(header->c_devminor, sizeof(header->c_devminor)));
- st->st_ino = atol16(header->c_ino, sizeof(header->c_ino));
- st->st_mode = atol16(header->c_mode, sizeof(header->c_mode));
- st->st_uid = atol16(header->c_uid, sizeof(header->c_uid));
- st->st_gid = atol16(header->c_gid, sizeof(header->c_gid));
- st->st_nlink = atol16(header->c_nlink, sizeof(header->c_nlink));
- st->st_rdev = makedev(
- atol16(header->c_rdevmajor, sizeof(header->c_rdevmajor)),
- atol16(header->c_rdevminor, sizeof(header->c_rdevminor)));
- st->st_mtime = atol16(header->c_mtime, sizeof(header->c_mtime));
+ archive_entry_set_devmajor(entry, atol16(header->c_devmajor, sizeof(header->c_devmajor)));
+ archive_entry_set_devminor(entry, atol16(header->c_devminor, sizeof(header->c_devminor)));
+ archive_entry_set_ino(entry, atol16(header->c_ino, sizeof(header->c_ino)));
+ archive_entry_set_mode(entry, atol16(header->c_mode, sizeof(header->c_mode)));
+ archive_entry_set_uid(entry, atol16(header->c_uid, sizeof(header->c_uid)));
+ archive_entry_set_gid(entry, atol16(header->c_gid, sizeof(header->c_gid)));
+ archive_entry_set_nlink(entry, atol16(header->c_nlink, sizeof(header->c_nlink)));
+ archive_entry_set_rdevmajor(entry, atol16(header->c_rdevmajor, sizeof(header->c_rdevmajor)));
+ archive_entry_set_rdevminor(entry, atol16(header->c_rdevminor, sizeof(header->c_rdevminor)));
+ archive_entry_set_mtime(entry, atol16(header->c_mtime, sizeof(header->c_mtime)), 0);
*namelength = atol16(header->c_namesize, sizeof(header->c_namesize));
/* Pad name to 2 more than a multiple of 4. */
*name_pad = (2 - *namelength) & 3;
@@ -371,20 +350,19 @@ header_newc(struct archive_read *a, struct cpio *cpio, struct stat *st,
/*
* Note: entry_bytes_remaining is at least 64 bits and
* therefore guaranteed to be big enough for a 33-bit file
- * size. struct stat.st_size may only be 32 bits, so
- * assigning there first could lose information.
+ * size.
*/
cpio->entry_bytes_remaining =
atol16(header->c_filesize, sizeof(header->c_filesize));
- st->st_size = cpio->entry_bytes_remaining;
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
/* Pad file contents to a multiple of 4. */
cpio->entry_padding = 3 & -cpio->entry_bytes_remaining;
return (ARCHIVE_OK);
}
static int
-header_odc(struct archive_read *a, struct cpio *cpio, struct stat *st,
- size_t *namelength, size_t *name_pad)
+header_odc(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
const void *h;
const struct cpio_odc_header *header;
@@ -394,41 +372,40 @@ header_odc(struct archive_read *a, struct cpio *cpio, struct stat *st,
a->archive.archive_format_name = "POSIX octet-oriented cpio";
/* Read fixed-size portion of header. */
- bytes = (a->compression_read_ahead)(a, &h, sizeof(struct cpio_odc_header));
+ bytes = (a->decompressor->read_ahead)(a, &h, sizeof(struct cpio_odc_header));
if (bytes < sizeof(struct cpio_odc_header))
return (ARCHIVE_FATAL);
- (a->compression_read_consume)(a, sizeof(struct cpio_odc_header));
+ (a->decompressor->consume)(a, sizeof(struct cpio_odc_header));
- /* Parse out octal fields into struct stat. */
+ /* Parse out octal fields. */
header = (const struct cpio_odc_header *)h;
- st->st_dev = atol8(header->c_dev, sizeof(header->c_dev));
- st->st_ino = atol8(header->c_ino, sizeof(header->c_ino));
- st->st_mode = atol8(header->c_mode, sizeof(header->c_mode));
- st->st_uid = atol8(header->c_uid, sizeof(header->c_uid));
- st->st_gid = atol8(header->c_gid, sizeof(header->c_gid));
- st->st_nlink = atol8(header->c_nlink, sizeof(header->c_nlink));
- st->st_rdev = atol8(header->c_rdev, sizeof(header->c_rdev));
- st->st_mtime = atol8(header->c_mtime, sizeof(header->c_mtime));
+ archive_entry_set_dev(entry, atol8(header->c_dev, sizeof(header->c_dev)));
+ archive_entry_set_ino(entry, atol8(header->c_ino, sizeof(header->c_ino)));
+ archive_entry_set_mode(entry, atol8(header->c_mode, sizeof(header->c_mode)));
+ archive_entry_set_uid(entry, atol8(header->c_uid, sizeof(header->c_uid)));
+ archive_entry_set_gid(entry, atol8(header->c_gid, sizeof(header->c_gid)));
+ archive_entry_set_nlink(entry, atol8(header->c_nlink, sizeof(header->c_nlink)));
+ archive_entry_set_rdev(entry, atol8(header->c_rdev, sizeof(header->c_rdev)));
+ archive_entry_set_mtime(entry, atol8(header->c_mtime, sizeof(header->c_mtime)), 0);
*namelength = atol8(header->c_namesize, sizeof(header->c_namesize));
*name_pad = 0; /* No padding of filename. */
/*
* Note: entry_bytes_remaining is at least 64 bits and
* therefore guaranteed to be big enough for a 33-bit file
- * size. struct stat.st_size may only be 32 bits, so
- * assigning there first could lose information.
+ * size.
*/
cpio->entry_bytes_remaining =
atol8(header->c_filesize, sizeof(header->c_filesize));
- st->st_size = cpio->entry_bytes_remaining;
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
cpio->entry_padding = 0;
return (ARCHIVE_OK);
}
static int
-header_bin_le(struct archive_read *a, struct cpio *cpio, struct stat *st,
- size_t *namelength, size_t *name_pad)
+header_bin_le(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
const void *h;
const struct cpio_bin_header *header;
@@ -438,34 +415,34 @@ header_bin_le(struct archive_read *a, struct cpio *cpio, struct stat *st,
a->archive.archive_format_name = "cpio (little-endian binary)";
/* Read fixed-size portion of header. */
- bytes = (a->compression_read_ahead)(a, &h, sizeof(struct cpio_bin_header));
+ bytes = (a->decompressor->read_ahead)(a, &h, sizeof(struct cpio_bin_header));
if (bytes < sizeof(struct cpio_bin_header))
return (ARCHIVE_FATAL);
- (a->compression_read_consume)(a, sizeof(struct cpio_bin_header));
+ (a->decompressor->consume)(a, sizeof(struct cpio_bin_header));
- /* Parse out binary fields into struct stat. */
+ /* Parse out binary fields. */
header = (const struct cpio_bin_header *)h;
- st->st_dev = header->c_dev[0] + header->c_dev[1] * 256;
- st->st_ino = header->c_ino[0] + header->c_ino[1] * 256;
- st->st_mode = header->c_mode[0] + header->c_mode[1] * 256;
- st->st_uid = header->c_uid[0] + header->c_uid[1] * 256;
- st->st_gid = header->c_gid[0] + header->c_gid[1] * 256;
- st->st_nlink = header->c_nlink[0] + header->c_nlink[1] * 256;
- st->st_rdev = header->c_rdev[0] + header->c_rdev[1] * 256;
- st->st_mtime = le4(header->c_mtime);
+ archive_entry_set_dev(entry, header->c_dev[0] + header->c_dev[1] * 256);
+ archive_entry_set_ino(entry, header->c_ino[0] + header->c_ino[1] * 256);
+ archive_entry_set_mode(entry, header->c_mode[0] + header->c_mode[1] * 256);
+ archive_entry_set_uid(entry, header->c_uid[0] + header->c_uid[1] * 256);
+ archive_entry_set_gid(entry, header->c_gid[0] + header->c_gid[1] * 256);
+ archive_entry_set_nlink(entry, header->c_nlink[0] + header->c_nlink[1] * 256);
+ archive_entry_set_rdev(entry, header->c_rdev[0] + header->c_rdev[1] * 256);
+ archive_entry_set_mtime(entry, le4(header->c_mtime), 0);
*namelength = header->c_namesize[0] + header->c_namesize[1] * 256;
*name_pad = *namelength & 1; /* Pad to even. */
cpio->entry_bytes_remaining = le4(header->c_filesize);
- st->st_size = cpio->entry_bytes_remaining;
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
return (ARCHIVE_OK);
}
static int
-header_bin_be(struct archive_read *a, struct cpio *cpio, struct stat *st,
- size_t *namelength, size_t *name_pad)
+header_bin_be(struct archive_read *a, struct cpio *cpio,
+ struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
const void *h;
const struct cpio_bin_header *header;
@@ -475,27 +452,27 @@ header_bin_be(struct archive_read *a, struct cpio *cpio, struct stat *st,
a->archive.archive_format_name = "cpio (big-endian binary)";
/* Read fixed-size portion of header. */
- bytes = (a->compression_read_ahead)(a, &h,
+ bytes = (a->decompressor->read_ahead)(a, &h,
sizeof(struct cpio_bin_header));
if (bytes < sizeof(struct cpio_bin_header))
return (ARCHIVE_FATAL);
- (a->compression_read_consume)(a, sizeof(struct cpio_bin_header));
+ (a->decompressor->consume)(a, sizeof(struct cpio_bin_header));
- /* Parse out binary fields into struct stat. */
+ /* Parse out binary fields. */
header = (const struct cpio_bin_header *)h;
- st->st_dev = header->c_dev[0] * 256 + header->c_dev[1];
- st->st_ino = header->c_ino[0] * 256 + header->c_ino[1];
- st->st_mode = header->c_mode[0] * 256 + header->c_mode[1];
- st->st_uid = header->c_uid[0] * 256 + header->c_uid[1];
- st->st_gid = header->c_gid[0] * 256 + header->c_gid[1];
- st->st_nlink = header->c_nlink[0] * 256 + header->c_nlink[1];
- st->st_rdev = header->c_rdev[0] * 256 + header->c_rdev[1];
- st->st_mtime = be4(header->c_mtime);
+ archive_entry_set_dev(entry, header->c_dev[0] * 256 + header->c_dev[1]);
+ archive_entry_set_ino(entry, header->c_ino[0] * 256 + header->c_ino[1]);
+ archive_entry_set_mode(entry, header->c_mode[0] * 256 + header->c_mode[1]);
+ archive_entry_set_uid(entry, header->c_uid[0] * 256 + header->c_uid[1]);
+ archive_entry_set_gid(entry, header->c_gid[0] * 256 + header->c_gid[1]);
+ archive_entry_set_nlink(entry, header->c_nlink[0] * 256 + header->c_nlink[1]);
+ archive_entry_set_rdev(entry, header->c_rdev[0] * 256 + header->c_rdev[1]);
+ archive_entry_set_mtime(entry, be4(header->c_mtime), 0);
*namelength = header->c_namesize[0] * 256 + header->c_namesize[1];
*name_pad = *namelength & 1; /* Pad to even. */
cpio->entry_bytes_remaining = be4(header->c_filesize);
- st->st_size = cpio->entry_bytes_remaining;
+ archive_entry_set_size(entry, cpio->entry_bytes_remaining);
cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
return (ARCHIVE_OK);
}
@@ -505,7 +482,7 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
{
struct cpio *cpio;
- cpio = (struct cpio *)*(a->pformat_data);
+ cpio = (struct cpio *)(a->format->data);
/* Free inode->name map */
while (cpio->links_head != NULL) {
struct links_entry *lp = cpio->links_head->next;
@@ -515,9 +492,9 @@ archive_read_format_cpio_cleanup(struct archive_read *a)
free(cpio->links_head);
cpio->links_head = lp;
}
-
+ archive_string_free(&cpio->entry_name);
free(cpio);
- *(a->pformat_data) = NULL;
+ (a->format->data) = NULL;
return (ARCHIVE_OK);
}
@@ -582,17 +559,21 @@ atol16(const char *p, unsigned char_cnt)
}
static void
-record_hardlink(struct cpio *cpio, struct archive_entry *entry,
- const struct stat *st)
+record_hardlink(struct cpio *cpio, struct archive_entry *entry)
{
struct links_entry *le;
+ dev_t dev;
+ ino_t ino;
+
+ dev = archive_entry_dev(entry);
+ ino = archive_entry_ino(entry);
/*
* First look in the list of multiply-linked files. If we've
* already dumped it, convert this entry to a hard link entry.
*/
for (le = cpio->links_head; le; le = le->next) {
- if (le->dev == st->st_dev && le->ino == st->st_ino) {
+ if (le->dev == dev && le->ino == ino) {
archive_entry_set_hardlink(entry, le->name);
if (--le->links <= 0) {
@@ -617,9 +598,9 @@ record_hardlink(struct cpio *cpio, struct archive_entry *entry,
le->next = cpio->links_head;
le->previous = NULL;
cpio->links_head = le;
- le->dev = st->st_dev;
- le->ino = st->st_ino;
- le->links = st->st_nlink - 1;
+ le->dev = dev;
+ le->ino = ino;
+ le->links = archive_entry_nlink(entry) - 1;
le->name = strdup(archive_entry_pathname(entry));
if (le->name == NULL)
__archive_errx(1, "Out of memory adding file to list");
OpenPOWER on IntegriCloud