/* 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. */
int64_t previous_number;
struct archive_string previous_pathname;
+ struct file_info *use_files;
struct heap_queue pending_files;
struct {
struct file_info *first;
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);
}
con = malloc(sizeof(struct content));
if (con == NULL) {
- release_file(iso9660, child);
archive_set_error(
&a->archive, ENOMEM,
"No memory for "
multi->size += child->size;
if (!child->multi_extent)
multi = NULL;
- release_file(iso9660, child);
}
} else
add_entry(iso9660, child);
/* 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);
/*
* 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
* 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
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;
/* 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. */
"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);
}
archive_entry_unset_size(entry);
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
- release_file(iso9660, file);
return (ARCHIVE_OK);
}
file->offset, iso9660->current_position);
iso9660->entry_bytes_remaining = 0;
iso9660->entry_sparse_offset = 0;
- release_file(iso9660, file);
return (ARCHIVE_WARN);
}
file->exposed = 1;
}
- release_file(iso9660, file);
-
if (rd_r != ARCHIVE_OK)
return (rd_r);
return (ARCHIVE_OK);
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);
}
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);
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);
}
fprintf(stderr, "\n");
}
#endif
+ register_file(iso9660, file);
return (file);
}
}
}
+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;
con = connext;
}
free(file);
- if (parent != NULL) {
- parent->refcount--;
- release_file(iso9660, parent);
- }
+ file = next;
}
}
* happen.
*/
file->next = NULL;
- file->refcount++;
*empty_files.last = file;
empty_files.last = &(file->next);
} else {
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);
}
{
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);
}
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);
}
}
file_key = file->key = key;
- file->refcount++;
/*
* Start with hole at end, walk it up tree to find insertion point.
* 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