summaryrefslogtreecommitdiff
path: root/libarchive/archive_read_support_format_ar.c
diff options
context:
space:
mode:
authorBrian Harring <ferringb@gmail.com>2010-09-23 07:26:11 -0400
committerBrian Harring <ferringb@gmail.com>2010-09-23 07:26:11 -0400
commit3d4481a39ae351c0e523dcedd123d8bd7074c540 (patch)
tree3e96062fd1fcf7195f15f2ea6a955b5707a2d25c /libarchive/archive_read_support_format_ar.c
parent9cc344aa6103866190fa4f1263d1bcf2aef207fc (diff)
downloadlibarchive-3d4481a39ae351c0e523dcedd123d8bd7074c540.tar.gz
not hugely happy with the implementation (specifically unconsumed passing), but rework the header reading to properly pair it's read_ahead/consume usage
SVN-Revision: 2689
Diffstat (limited to 'libarchive/archive_read_support_format_ar.c')
-rw-r--r--libarchive/archive_read_support_format_ar.c74
1 files changed, 49 insertions, 25 deletions
diff --git a/libarchive/archive_read_support_format_ar.c b/libarchive/archive_read_support_format_ar.c
index a78db96a..5a381da8 100644
--- a/libarchive/archive_read_support_format_ar.c
+++ b/libarchive/archive_read_support_format_ar.c
@@ -161,39 +161,16 @@ archive_read_format_ar_bid(struct archive_read *a)
}
static int
-archive_read_format_ar_read_header(struct archive_read *a,
- struct archive_entry *entry)
+_ar_read_header(struct archive_read *a, struct archive_entry *entry,
+ struct ar *ar, const char *h, size_t *unconsumed)
{
char filename[AR_name_size + 1];
- struct ar *ar;
uint64_t number; /* Used to hold parsed numbers before validation. */
- ssize_t bytes_read;
size_t bsd_name_length, entry_size;
char *p, *st;
const void *b;
- const char *h;
int r;
- ar = (struct ar*)(a->format->data);
-
- if (!ar->read_global_header) {
- /*
- * We are now at the beginning of the archive,
- * so we need first consume the ar global header.
- */
- __archive_read_consume(a, 8);
- ar->read_global_header = 1;
- /* Set a default format code for now. */
- a->archive.archive_format = ARCHIVE_FORMAT_AR;
- }
-
- /* Read the header for the next file entry. */
- if ((b = __archive_read_ahead(a, 60, &bytes_read)) == NULL)
- /* Broken header. */
- return (ARCHIVE_EOF);
- __archive_read_consume(a, 60);
- h = (const char *)b;
-
/* Verify the magic signature on the file header. */
if (strncmp(h + AR_fmag_offset, "`\n", 2) != 0) {
archive_set_error(&a->archive, EINVAL,
@@ -297,6 +274,12 @@ archive_read_format_ar_read_header(struct archive_read *a,
}
ar->strtab = st;
ar->strtab_size = entry_size;
+
+ if (*unconsumed) {
+ __archive_read_consume(a, *unconsumed);
+ *unconsumed = 0;
+ }
+
if ((b = __archive_read_ahead(a, entry_size, NULL)) == NULL)
return (ARCHIVE_FATAL);
memcpy(st, b, entry_size);
@@ -361,6 +344,11 @@ archive_read_format_ar_read_header(struct archive_read *a,
/* Adjust file size reported to client. */
archive_entry_set_size(entry, ar->entry_bytes_remaining);
+ if (*unconsumed) {
+ __archive_read_consume(a, *unconsumed);
+ *unconsumed = 0;
+ }
+
/* Read the long name into memory. */
if ((b = __archive_read_ahead(a, bsd_name_length, NULL)) == NULL) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
@@ -415,6 +403,42 @@ archive_read_format_ar_read_header(struct archive_read *a,
}
static int
+archive_read_format_ar_read_header(struct archive_read *a,
+ struct archive_entry *entry)
+{
+ struct ar *ar = (struct ar*)(a->format->data);
+ size_t unconsumed;
+ const void *header_data;
+ int ret;
+
+ if (!ar->read_global_header) {
+ /*
+ * We are now at the beginning of the archive,
+ * so we need first consume the ar global header.
+ */
+ __archive_read_consume(a, 8);
+ ar->read_global_header = 1;
+ /* Set a default format code for now. */
+ a->archive.archive_format = ARCHIVE_FORMAT_AR;
+ }
+
+ /* Read the header for the next file entry. */
+ if ((header_data = __archive_read_ahead(a, 60, NULL)) == NULL)
+ /* Broken header. */
+ return (ARCHIVE_EOF);
+
+ unconsumed = 60;
+
+ ret = _ar_read_header(a, entry, ar, (const char *)header_data, &unconsumed);
+
+ if (unconsumed)
+ __archive_read_consume(a, 60);
+
+ return ret;
+}
+
+
+static int
ar_parse_common_header(struct ar *ar, struct archive_entry *entry,
const char *h)
{