* Change __archive_check_magic to return a status code.
* Change callers to use the archive_check_magic() wrapper macro,
which calls __archive_check_magic and returns immediately
if there's an ARCHIVE_FATAL status.
* Update a bunch of API calls to actually do magic state checks.
I've also changed __archive_check_magic around a little bit:
* Magic number checks still call abort().
* State failures still call abort()
* Starting with libarchive 3.0, state failures will return ARCHIVE_FATAL.
SVN-Revision: 2003
* (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000)
* #endif
*/
-#define ARCHIVE_VERSION_NUMBER 3000000
+/* Note: Compiler will complain if this does not match archive_entry.h! */
+#define ARCHIVE_VERSION_NUMBER 2008900
__LA_DECL int archive_version_number(void);
/*
* Textual name/version of the library, useful for version displays.
*/
-#define ARCHIVE_VERSION_STRING "libarchive 3.0.0a"
+#define ARCHIVE_VERSION_STRING "libarchive 2.8.900a"
__LA_DECL const char * archive_version_string(void);
#if ARCHIVE_VERSION_NUMBER < 3000000
/*-
- * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2003-2010 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
}
-static void
-write_all_states(unsigned int states)
+static char *
+write_all_states(char *buff, unsigned int states)
{
unsigned int lowbit;
+ buff[0] = '\0';
+
/* A trick for computing the lowest set bit. */
while ((lowbit = states & (1 + ~states)) != 0) {
states &= ~lowbit; /* Clear the low bit. */
- errmsg(state_name(lowbit));
+ strcat(buff, state_name(lowbit));
if (states != 0)
- errmsg("/");
+ strcat(buff, "/");
}
+ return buff;
}
/*
- * Check magic value and current state; bail if it isn't valid.
+ * Check magic value and current state.
+ * Magic value mismatches are fatal and result in calls to abort().
+ * State mismatches return ARCHIVE_FATAL.
+ * Otherwise, returns ARCHIVE_OK.
*
* This is designed to catch serious programming errors that violate
* the libarchive API.
*/
-void
+int
__archive_check_magic(struct archive *a, unsigned int magic,
unsigned int state, const char *function)
{
+ char states1[64];
+ char states2[64];
+
if (a->magic != magic) {
- errmsg("INTERNAL ERROR: Function ");
+ errmsg("PROGRAMMER ERROR: Function ");
errmsg(function);
- errmsg(" invoked with invalid struct archive structure.\n");
+ errmsg(" invoked with invalid archive handle.\n");
diediedie();
}
- if (state == ARCHIVE_STATE_ANY)
- return;
-
if ((a->state & state) == 0) {
- errmsg("INTERNAL ERROR: Function '");
- errmsg(function);
- errmsg("' invoked with archive structure in state '");
- write_all_states(a->state);
- errmsg("', should be in state '");
- write_all_states(state);
- errmsg("'\n");
+ /* If we're already FATAL, don't overwrite the error. */
+ if (a->state != ARCHIVE_STATE_FATAL)
+ archive_set_error(a, -1,
+ "INTERNAL ERROR: Function '%s' invoked with"
+ " archive structure in state '%s',"
+ " should be in state '%s'",
+ function,
+ write_all_states(states1, a->state),
+ write_all_states(states2, a->state));
+ a->state = ARCHIVE_STATE_FATAL;
+#if ARCHIVE_VERSION_NUMBER < 3000000
+ // XXXX This should be identical to the old behavior.
+ errmsg(archive_error_string(a));
diediedie();
+#else
+ // XXXX This is the proposed new behavior.
+ return (ARCHIVE_FATAL);
+#endif
}
+ return ARCHIVE_OK;
}
#ifndef ARCHIVE_ENTRY_H_INCLUDED
#define ARCHIVE_ENTRY_H_INCLUDED
-/* Needed if archive_entry.h is used without archive.h */
-#ifndef ARCHIVE_VERSION_NUMBER
-#define ARCHIVE_VERSION_NUMBER 3000000
-#endif
+/* Note: Compiler will complain if this does not match archive.h! */
+#define ARCHIVE_VERSION_NUMBER 2008900
/*
* Note: archive_entry.h is for use outside of libarchive; the
#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U)
#define ARCHIVE_READ_DISK_MAGIC (0xbadb0c5U)
-#define ARCHIVE_STATE_ANY 0xFFFFU
#define ARCHIVE_STATE_NEW 1U
#define ARCHIVE_STATE_HEADER 2U
#define ARCHIVE_STATE_DATA 4U
#define ARCHIVE_STATE_EOF 0x10U
#define ARCHIVE_STATE_CLOSED 0x20U
#define ARCHIVE_STATE_FATAL 0x8000U
+#define ARCHIVE_STATE_ANY (0xFFFFU & ~ARCHIVE_STATE_FATAL)
struct archive_vtable {
int (*archive_close)(struct archive *);
struct archive_string error_string;
};
-/* Check magic value and state; exit if it isn't valid. */
-void __archive_check_magic(struct archive *, unsigned int magic,
+/* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
+int __archive_check_magic(struct archive *, unsigned int magic,
unsigned int state, const char *func);
+#define archive_check_magic(a, expected_magic, allowed_states, function_name) \
+ do { \
+ int magic_test = __archive_check_magic((a), (expected_magic), \
+ (allowed_states), (function_name)); \
+ if (magic_test == ARCHIVE_FATAL) \
+ return ARCHIVE_FATAL; \
+ } while (0)
void __archive_errx(int retvalue, const char *msg) __LA_DEAD;
#endif
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_extract_set_skip_file");
+
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_extract_set_skip_file"))
+ return;
+
a->skip_file_dev = d;
a->skip_file_ino = i;
}
size_t i;
int len, r;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_set_format_options");
if (s == NULL || *s == '\0')
return (ARCHIVE_OK);
a = (struct archive_read *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_set_format_options");
len = 0;
for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
format = &a->formats[i];
char key[64], val[64];
int len, r;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_set_filter_options");
if (s == NULL || *s == '\0')
return (ARCHIVE_OK);
a = (struct archive_read *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_NEW, "archive_read_set_filter_options");
len = 0;
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
bidder = filter->bidder;
{
int r;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_set_options");
archive_clear_error(_a);
struct archive_read_filter *filter;
int e;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"archive_read_open");
archive_clear_error(&a->archive);
struct archive_read *a = (struct archive_read *)_a;
int slot, ret;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_read_next_header");
archive_read_header_position(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_header_position");
return (a->header_position);
}
int64_t offset;
#endif
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
"archive_read_data_skip");
if (a->format->read_data_skip != NULL)
#endif
{
struct archive_read *a = (struct archive_read *)_a;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
"archive_read_data_block");
if (a->format->read_data == NULL) {
struct archive_read *a = (struct archive_read *)_a;
int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
- ARCHIVE_STATE_ANY, "archive_read_close");
+ archive_check_magic(&a->archive, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
archive_clear_error(&a->archive);
- a->archive.state = ARCHIVE_STATE_CLOSED;
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
/* TODO: Clean up the formatters. */
int slots;
int r = ARCHIVE_OK;
- __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_ANY,
- "archive_read_free");
- if (a->archive.state != ARCHIVE_STATE_CLOSED)
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
+ if (a->archive.state != ARCHIVE_STATE_CLOSED
+ && a->archive.state != ARCHIVE_STATE_FATAL)
r = archive_read_close(&a->archive);
/* Call cleanup functions registered by optional components. */
{
int i, number_slots;
- __archive_check_magic(&a->archive,
+ archive_check_magic(&a->archive,
ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
"__archive_read_register_format");
{
int i, number_slots;
- __archive_check_magic(&a->archive,
- ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
- "__archive_read_get_bidder");
-
number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
for (i = 0; i < number_slots; i++) {
#endif
off_t output_offset;
- __archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA, "archive_read_data_into_fd");
+ archive_check_magic(a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_DATA,
+ "archive_read_data_into_fd");
total_written = 0;
output_offset = 0;
#endif
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (a->lookup_gname != NULL)
- return ((*a->lookup_gname)(a->lookup_gname_data, gid));
- return (NULL);
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_gname"))
+ return (NULL);
+ if (a->lookup_gname == NULL)
+ return (NULL);
+ return ((*a->lookup_gname)(a->lookup_gname_data, gid));
}
#if ARCHIVE_VERSION_NUMBER < 3000000
#endif
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
- if (a->lookup_uname != NULL)
- return ((*a->lookup_uname)(a->lookup_uname_data, uid));
- return (NULL);
+ if (ARCHIVE_OK != __archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_uname"))
+ return (NULL);
+ if (a->lookup_uname == NULL)
+ return (NULL);
+ return ((*a->lookup_uname)(a->lookup_uname_data, uid));
}
#if ARCHIVE_VERSION_NUMBER < 3000000
#endif
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_set_gname_lookup");
if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
#endif
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_READ_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_read_disk_set_uname_lookup");
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
if (a->cleanup_gname != NULL && a->lookup_gname_data != NULL)
(a->cleanup_gname)(a->lookup_gname_data);
if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
(a->cleanup_uname)(a->lookup_uname_data);
archive_string_free(&a->archive.error_string);
+ a->archive.magic = 0;
free(a);
return (ARCHIVE_OK);
}
static int
_archive_read_close(struct archive *_a)
{
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_close");
(void)_a; /* UNUSED */
return (ARCHIVE_OK);
}
archive_read_disk_set_symlink_logical(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_logical");
a->symlink_mode = 'L';
a->follow_symlinks = 1;
return (ARCHIVE_OK);
archive_read_disk_set_symlink_physical(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_physical");
a->symlink_mode = 'P';
a->follow_symlinks = 0;
return (ARCHIVE_OK);
archive_read_disk_set_symlink_hybrid(struct archive *_a)
{
struct archive_read_disk *a = (struct archive_read_disk *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC,
+ ARCHIVE_STATE_ANY, "archive_read_disk_set_symlink_hybrid");
a->symlink_mode = 'H';
a->follow_symlinks = 1; /* Follow symlinks initially. */
return (ARCHIVE_OK);
struct ar *ar;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_ar");
+
ar = (struct ar *)malloc(sizeof(*ar));
if (ar == NULL) {
archive_set_error(&a->archive, ENOMEM,
struct cpio *cpio;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_cpio");
+
cpio = (struct cpio *)malloc(sizeof(*cpio));
if (cpio == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_empty");
+
r = __archive_read_register_format(a,
NULL,
NULL,
struct iso9660 *iso9660;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_iso9660");
+
iso9660 = (struct iso9660 *)malloc(sizeof(*iso9660));
if (iso9660 == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't allocate iso9660 data");
struct mtree *mtree;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_mtree");
+
mtree = (struct mtree *)malloc(sizeof(*mtree));
if (mtree == NULL) {
archive_set_error(&a->archive, ENOMEM,
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_raw");
+
info = (struct raw_info *)calloc(1, sizeof(*info));
if (info == NULL) {
archive_set_error(&a->archive, ENOMEM,
int
archive_read_support_format_gnutar(struct archive *a)
{
+ archive_check_magic(a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_gnutar");
return (archive_read_support_format_tar(a));
}
struct tar *tar;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_tar");
+
tar = (struct tar *)malloc(sizeof(*tar));
if (tar == NULL) {
archive_set_error(&a->archive, ENOMEM,
archive_read_support_format_xar(struct archive *_a)
{
struct archive_read *a = (struct archive_read *)_a;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Xar not supported on this platform");
struct archive_read *a = (struct archive_read *)_a;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_xar");
+
xar = (struct xar *)calloc(1, sizeof(*xar));
if (xar == NULL) {
archive_set_error(&a->archive, ENOMEM,
struct zip *zip;
int r;
+ archive_check_magic(_a, ARCHIVE_READ_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_read_support_format_zip");
+
zip = (struct zip *)malloc(sizeof(*zip));
if (zip == NULL) {
archive_set_error(&a->archive, ENOMEM, "Can't allocate zip data");
char key[64], val[64];
int len, r, ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_format_options");
archive_clear_error(&a->archive);
int len, r;
int ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_compressor_options");
archive_clear_error(&a->archive);
archive_write_set_bytes_per_block(struct archive *_a, int bytes_per_block)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_set_bytes_per_block");
a->bytes_per_block = bytes_per_block;
return (ARCHIVE_OK);
archive_write_get_bytes_per_block(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_per_block");
return (a->bytes_per_block);
}
archive_write_set_bytes_in_last_block(struct archive *_a, int bytes)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_set_bytes_in_last_block");
a->bytes_in_last_block = bytes;
return (ARCHIVE_OK);
archive_write_get_bytes_in_last_block(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_get_bytes_in_last_block");
return (a->bytes_in_last_block);
}
#endif
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_set_skip_file");
a->skip_file_dev = d;
a->skip_file_ino = i;
{
struct archive_write *a = (struct archive_write *)_a;
struct archive_write_filter *f;
- __archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_allocate_filter");
+
f = calloc(1, sizeof(*f));
f->archive = _a;
if (a->filter_first == NULL)
const void *buff, size_t length)
{
int r;
+ if (length == 0)
+ return(ARCHIVE_OK);
r = (f->write)(f, buff, length);
f->bytes_written += length;
return (r);
struct archive_write_filter *client_filter;
int ret;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_NEW, "archive_write_open");
archive_clear_error(&a->archive);
struct archive_write *a = (struct archive_write *)_a;
int r = ARCHIVE_OK, r1 = ARCHIVE_OK;
- /*
- * It's perfectly reasonable to call close() as part of
- * routine cleanup, even after an error, so we're a little
- * tolerant of being called in odd states.
- */
- if (a->archive.state & ARCHIVE_STATE_FATAL)
- return (ARCHIVE_FATAL);
- archive_clear_error(&a->archive);
- if (a->archive.state & (ARCHIVE_STATE_NEW | ARCHIVE_STATE_CLOSED))
- return (ARCHIVE_OK);
-
- __archive_check_magic(&a->archive,
- ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL,
"archive_write_close");
+ if (a->archive.state == ARCHIVE_STATE_NEW
+ || a->archive.state == ARCHIVE_STATE_CLOSED)
+ return (ARCHIVE_OK); // Okay to close() when not open.
+
+ archive_clear_error(&a->archive);
/* Finish the last entry. */
- if (a->archive.state & ARCHIVE_STATE_DATA)
+ if (a->archive.state == ARCHIVE_STATE_DATA)
r = ((a->format_finish_entry)(a));
/* Finish off the archive. */
if (r1 < r)
r = r1;
- a->archive.state = ARCHIVE_STATE_CLOSED;
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
+ a->archive.state = ARCHIVE_STATE_CLOSED;
return (r);
}
struct archive_write *a = (struct archive_write *)_a;
int r = ARCHIVE_OK, r1;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_ANY, "archive_write_free");
- if (a->archive.state != ARCHIVE_STATE_CLOSED
- && a->archive.state != ARCHIVE_STATE_FATAL)
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ /* It is okay to call free() in state FATAL. */
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_free");
+ if (a->archive.state != ARCHIVE_STATE_FATAL)
r = archive_write_close(&a->archive);
/* Release format resources. */
struct archive_write *a = (struct archive_write *)_a;
int ret, r2;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA | ARCHIVE_STATE_HEADER, "archive_write_header");
archive_clear_error(&a->archive);
struct archive_write *a = (struct archive_write *)_a;
int ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_finish_entry");
if (a->archive.state & ARCHIVE_STATE_DATA)
_archive_write_data(struct archive *_a, const void *buff, size_t s)
{
struct archive_write *a = (struct archive_write *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
archive_clear_error(&a->archive);
return ((a->format_write_data)(a, buff, s));
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_data *data;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_bzip2");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_bzip2");
data = calloc(1, sizeof(*data));
if (data == NULL) {
struct archive_write *a = (struct archive_write *)_a;
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_compress");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_compress");
f->open = &archive_compressor_compress_open;
f->code = ARCHIVE_COMPRESSION_COMPRESS;
f->name = "compress";
struct archive_write *a = (struct archive_write *)_a;
struct archive_write_filter *f = __archive_write_allocate_filter(_a);
struct private_data *data;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_gzip");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_gzip");
data = calloc(1, sizeof(*data));
if (data == NULL) {
struct archive_write *a = (struct archive_write *)_a;
struct private_data *data;
static const char *prefix = "Program: ";
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_set_compression_program");
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_program");
data = calloc(1, sizeof(*data));
if (data == NULL) {
archive_set_error(&a->archive, ENOMEM, "Out of memory");
{
struct private_data *data;
struct archive_write *a = (struct archive_write *)f->archive;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
- ARCHIVE_STATE_NEW, "archive_write_add_filter_xz");
data = calloc(1, sizeof(*data));
if (data == NULL) {
archive_set_error(&a->archive, ENOMEM, "Out of memory");
int
archive_write_add_filter_xz(struct archive *_a)
{
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- int r = common_setup(f);
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_xz");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
if (r == ARCHIVE_OK) {
f->code = ARCHIVE_COMPRESSION_XZ;
f->name = "xz";
int
archive_write_add_filter_lzma(struct archive *_a)
{
- struct archive_write_filter *f = __archive_write_allocate_filter(_a);
- int r = common_setup(f);
+ struct archive_write_filter *f;
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_add_filter_lzma");
+ f = __archive_write_allocate_filter(_a);
+ r = common_setup(f);
if (r == ARCHIVE_OK) {
f->code = ARCHIVE_COMPRESSION_LZMA;
f->name = "lzma";
struct fixup_entry *fe;
int ret, r;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_disk_header");
archive_clear_error(&a->archive);
#endif
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
a->skip_file_dev = d;
a->skip_file_ino = i;
struct archive_write_disk *a = (struct archive_write_disk *)_a;
ssize_t r;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data_block");
a->offset = offset;
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_DATA, "archive_write_data");
return (write_data_block(a, buff, size));
struct archive_write_disk *a = (struct archive_write_disk *)_a;
int ret = ARCHIVE_OK;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_finish_entry");
if (a->archive.state & ARCHIVE_STATE_HEADER)
#endif
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
a->lookup_gid = lookup_gid;
#endif
{
struct archive_write_disk *a = (struct archive_write_disk *)_a;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
a->lookup_uid = lookup_uid;
struct fixup_entry *next, *p;
int ret;
- __archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
+ archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
"archive_write_disk_close");
ret = _archive_write_disk_finish_entry(&a->archive);
static int
_archive_write_disk_free(struct archive *_a)
{
- struct archive_write_disk *a = (struct archive_write_disk *)_a;
+ struct archive_write_disk *a;
int ret;
+ if (_a == NULL)
+ return (ARCHIVE_OK);
+ archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
+ ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
+ a = (struct archive_write_disk *)_a;
ret = _archive_write_disk_close(&a->archive);
if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
(a->cleanup_gid)(a->lookup_gid_data);
archive_string_free(&a->_name_data);
archive_string_free(&a->archive.error_string);
archive_string_free(&a->path_safe);
+ a->archive.magic = 0;
free(a);
return (ret);
}
archive_write_set_format_ar_bsd(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- int r = archive_write_set_format_ar(a);
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ar_bsd");
+ r = archive_write_set_format_ar(a);
if (r == ARCHIVE_OK) {
a->archive.archive_format = ARCHIVE_FORMAT_AR_BSD;
a->archive.archive_format_name = "ar (BSD)";
archive_write_set_format_ar_svr4(struct archive *_a)
{
struct archive_write *a = (struct archive_write *)_a;
- int r = archive_write_set_format_ar(a);
+ int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ar_svr4");
+ r = archive_write_set_format_ar(a);
if (r == ARCHIVE_OK) {
a->archive.archive_format = ARCHIVE_FORMAT_AR_GNU;
a->archive.archive_format_name = "ar (GNU/SVR4)";
}
archive_set_error(a, EINVAL, "No such format '%s'", name);
+ a->state = ARCHIVE_STATE_FATAL;
return (ARCHIVE_FATAL);
}
struct archive_write *a = (struct archive_write *)_a;
struct cpio *cpio;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio");
+
/* If someone else was already registered, unregister them. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
struct archive_write *a = (struct archive_write *)_a;
struct cpio *cpio;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_newc");
+
/* If someone else was already registered, unregister them. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
struct archive_write *a = (struct archive_write *)_a;
struct iso9660 *iso9660;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_iso9660");
+
/* If another format was already registered, unregister it. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
struct archive_write *a = (struct archive_write *)_a;
struct mtree_writer *mtree;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_mtree");
+
if (a->format_destroy != NULL)
(a->format_destroy)(a);
{
struct archive_write *a = (struct archive_write *)_a;
int r;
+
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_pax_restricted");
+
r = archive_write_set_format_pax(&a->archive);
a->archive.archive_format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
a->archive.archive_format_name = "restricted POSIX pax interchange";
struct archive_write *a = (struct archive_write *)_a;
struct pax *pax;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_pax");
+
if (a->format_destroy != NULL)
(a->format_destroy)(a);
struct archive_write *a = (struct archive_write *)_a;
struct shar *shar;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_shar");
+
/* If someone else was already registered, unregister them. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
struct archive_write *a = (struct archive_write *)_a;
struct ustar *ustar;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_ustar");
+
/* If someone else was already registered, unregister them. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);
struct archive_write *a = (struct archive_write *)_a;
struct zip *zip;
+ archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
+ ARCHIVE_STATE_NEW, "archive_write_set_format_zip");
+
/* If another format was already registered, unregister it. */
if (a->format_destroy != NULL)
(a->format_destroy)(a);