summaryrefslogtreecommitdiff
path: root/lib/libarchive
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@FreeBSD.org>2010-01-23 07:55:53 +0000
committerTim Kientzle <kientzle@FreeBSD.org>2010-01-23 07:55:53 +0000
commit54d2369731876af0f7a223d441036e4000bac18f (patch)
tree681b652c3348f927f7902061ad3e525b7349ed83 /lib/libarchive
parent58efb33976800e273e96f6e002775f85b487184e (diff)
Notes
Diffstat (limited to 'lib/libarchive')
-rw-r--r--lib/libarchive/archive_read_support_format_iso9660.c69
1 files changed, 23 insertions, 46 deletions
diff --git a/lib/libarchive/archive_read_support_format_iso9660.c b/lib/libarchive/archive_read_support_format_iso9660.c
index b1cdda0ee1d7..1f640037fadf 100644
--- a/lib/libarchive/archive_read_support_format_iso9660.c
+++ b/lib/libarchive/archive_read_support_format_iso9660.c
@@ -258,9 +258,9 @@ struct content {
/* In-memory storage for a directory record. */
struct file_info {
+ struct file_info *use_next;
struct file_info *parent;
struct file_info *next;
- int refcount;
int subdirs;
uint64_t key; /* Heap Key. */
uint64_t offset; /* Offset on disk. */
@@ -331,6 +331,7 @@ struct iso9660 {
int64_t previous_number;
struct archive_string previous_pathname;
+ struct file_info *use_files;
struct heap_queue pending_files;
struct {
struct file_info *first;
@@ -396,7 +397,8 @@ static void parse_rockridge_TF1(struct file_info *,
const unsigned char *, int);
static void parse_rockridge_ZF1(struct file_info *,
const unsigned char *, int);
-static void release_file(struct iso9660 *, struct file_info *);
+static void register_file(struct iso9660 *, struct file_info *);
+static void release_files(struct iso9660 *);
static unsigned toi(const void *p, int n);
static inline void cache_add_entry(struct iso9660 *iso9660,
struct file_info *file);
@@ -980,7 +982,6 @@ read_children(struct archive_read *a, struct file_info *parent)
}
con = malloc(sizeof(struct content));
if (con == NULL) {
- release_file(iso9660, child);
archive_set_error(
&a->archive, ENOMEM,
"No memory for "
@@ -998,7 +999,6 @@ read_children(struct archive_read *a, struct file_info *parent)
multi->size += child->size;
if (!child->multi_extent)
multi = NULL;
- release_file(iso9660, child);
}
} else
add_entry(iso9660, child);
@@ -1029,10 +1029,8 @@ relocate_dir(struct iso9660 *iso9660, struct file_info *file)
/* This case is wrong pattern. */
return (0);
if (re->offset == file->cl_offset) {
- re->parent->refcount--;
re->parent->subdirs--;
re->parent = file->parent;
- re->parent->refcount++;
re->parent->subdirs++;
cache_add_to_next_of_parent(iso9660, re);
return (1);
@@ -1077,10 +1075,8 @@ read_entries(struct archive_read *a)
/*
* Relocate directory which rr_moved has.
*/
- while ((file = heap_get_entry(&(iso9660->cl_files))) != NULL) {
+ while ((file = heap_get_entry(&(iso9660->cl_files))) != NULL)
relocate_dir(iso9660, file);
- release_file(iso9660, file);
- }
/* If rr_moved directory still has children,
* Add rr_moved into pending_files to show
@@ -1092,10 +1088,8 @@ read_entries(struct archive_read *a)
* is broken), the entries won't be exposed. */
while ((file = heap_get_entry(&(iso9660->re_dirs))) != NULL)
cache_add_entry(iso9660, file);
- } else {
+ } else
iso9660->rr_moved->parent->subdirs--;
- release_file(iso9660, iso9660->rr_moved);
- }
} else {
/*
* In case ISO image is broken. If the name of rr_moved
@@ -1174,7 +1168,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
if (vd == &(iso9660->primary) && !iso9660->seenRockridge
&& iso9660->seenJoliet) {
/* Switch reading data from primary to joliet. */
- release_file(iso9660, file);
vd = &(iso9660->joliet);
skipsize = LOGICAL_BLOCK_SIZE * vd->location;
skipsize -= iso9660->current_position;
@@ -1214,10 +1207,8 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
/* Get the next entry that appears after the current offset. */
r = next_entry_seek(a, iso9660, &file);
- if (r != ARCHIVE_OK) {
- release_file(iso9660, file);
+ if (r != ARCHIVE_OK)
return (r);
- }
iso9660->entry_bytes_remaining = file->size;
iso9660->entry_sparse_offset = 0; /* Offset for sparse-file-aware clients. */
@@ -1227,7 +1218,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
"File is beyond end-of-media: %s", file->name);
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
- release_file(iso9660, file);
return (ARCHIVE_WARN);
}
@@ -1263,7 +1253,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
archive_entry_unset_size(entry);
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
- release_file(iso9660, file);
return (ARCHIVE_OK);
}
@@ -1291,7 +1280,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
file->offset, iso9660->current_position);
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
- release_file(iso9660, file);
return (ARCHIVE_WARN);
}
@@ -1331,8 +1319,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
file->exposed = 1;
}
- release_file(iso9660, file);
-
if (rd_r != ARCHIVE_OK)
return (rd_r);
return (ARCHIVE_OK);
@@ -1648,14 +1634,10 @@ static int
archive_read_format_iso9660_cleanup(struct archive_read *a)
{
struct iso9660 *iso9660;
- struct file_info *file;
int r = ARCHIVE_OK;
iso9660 = (struct iso9660 *)(a->format->data);
- while ((file = cache_get_entry(iso9660)) != NULL)
- release_file(iso9660, file);
- while ((file = next_entry(iso9660)) != NULL)
- release_file(iso9660, file);
+ release_files(iso9660);
free(iso9660->read_ce_req.reqs);
archive_string_free(&iso9660->pathname);
archive_string_free(&iso9660->previous_pathname);
@@ -1736,8 +1718,6 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
}
memset(file, 0, sizeof(*file));
file->parent = parent;
- if (parent != NULL)
- parent->refcount++;
file->offset = iso9660->logical_block_size * (uint64_t)location;
file->size = toi(isodirrec + DR_size_offset, DR_size_size);
file->mtime = isodate7(isodirrec + DR_date_offset);
@@ -1869,8 +1849,6 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
rr_start += iso9660->suspOffset;
r = parse_rockridge(a, file, rr_start, rr_end);
if (r != ARCHIVE_OK) {
- if (parent != NULL)
- parent->refcount--;
free(file);
return (NULL);
}
@@ -1880,6 +1858,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
iso9660->opt_support_rockridge = 0;
}
+ file->nlinks = 1;/* Reset nlink. we'll calculate it later. */
/* Tell file's parent how many children that parent has. */
if (parent != NULL && (flags & 0x02) && file->cl_offset == 0)
parent->subdirs++;
@@ -1908,6 +1887,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
fprintf(stderr, "\n");
}
#endif
+ register_file(iso9660, file);
return (file);
}
@@ -2460,18 +2440,24 @@ parse_rockridge_ZF1(struct file_info *file, const unsigned char *data,
}
}
+static void
+register_file(struct iso9660 *iso9660, struct file_info *file)
+{
+
+ file->use_next = iso9660->use_files;
+ iso9660->use_files = file;
+}
static void
-release_file(struct iso9660 *iso9660, struct file_info *file)
+release_files(struct iso9660 *iso9660)
{
- struct file_info *parent;
struct content *con, *connext;
+ struct file_info *file;
- if (file == NULL)
- return;
+ file = iso9660->use_files;
+ while (file != NULL) {
+ struct file_info *next = file->use_next;
- if (file->refcount == 0) {
- parent = file->parent;
archive_string_free(&file->name);
archive_string_free(&file->symlink);
con = file->contents.first;
@@ -2481,10 +2467,7 @@ release_file(struct iso9660 *iso9660, struct file_info *file)
con = connext;
}
free(file);
- if (parent != NULL) {
- parent->refcount--;
- release_file(iso9660, parent);
- }
+ file = next;
}
}
@@ -2568,7 +2551,6 @@ next_cache_entry(struct iso9660 *iso9660)
* happen.
*/
file->next = NULL;
- file->refcount++;
*empty_files.last = file;
empty_files.last = &(file->next);
} else {
@@ -2611,7 +2593,6 @@ static inline void
cache_add_entry(struct iso9660 *iso9660, struct file_info *file)
{
file->next = NULL;
- file->refcount++;
*iso9660->cache_files.last = file;
iso9660->cache_files.last = &(file->next);
}
@@ -2621,7 +2602,6 @@ cache_add_to_next_of_parent(struct iso9660 *iso9660, struct file_info *file)
{
file->next = file->parent->next;
file->parent->next = file;
- file->refcount++;
if (iso9660->cache_files.last == &(file->parent->next))
iso9660->cache_files.last = &(file->next);
}
@@ -2633,7 +2613,6 @@ cache_get_entry(struct iso9660 *iso9660)
if ((file = iso9660->cache_files.first) != NULL) {
iso9660->cache_files.first = file->next;
- file->refcount--;
if (iso9660->cache_files.first == NULL)
iso9660->cache_files.last = &(iso9660->cache_files.first);
}
@@ -2669,7 +2648,6 @@ heap_add_entry(struct heap_queue *heap, struct file_info *file, uint64_t key)
}
file_key = file->key = key;
- file->refcount++;
/*
* Start with hole at end, walk it up tree to find insertion point.
@@ -2703,7 +2681,6 @@ heap_get_entry(struct heap_queue *heap)
* The first file in the list is the earliest; we'll return this.
*/
r = heap->files[0];
- r->refcount--;
/*
* Move the last item in the heap to the root of the tree