diff options
author | kientzle <kientzle@FreeBSD.org> | 2007-03-03 07:37:37 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2007-03-03 07:37:37 +0000 |
commit | 1a60578adb6be1f7da9ed95f38cf52c20be13591 (patch) | |
tree | 1b026213a337089af577dee3ed6d194ee1b87d88 /lib/libarchive/archive_private.h | |
parent | 56746aa8e0ffff51b371e72446368d6dbbe6b4ba (diff) | |
download | FreeBSD-src-1a60578adb6be1f7da9ed95f38cf52c20be13591.zip FreeBSD-src-1a60578adb6be1f7da9ed95f38cf52c20be13591.tar.gz |
libarchive 2.0
* libarchive_test program exercises many of the core features
* Refactored old "read_extract" into new "archive_write_disk", which
uses archive_write methods to put entries onto disk. In particular,
you can now use archive_write_disk to create objects on disk
without having an archive available.
* Pushed some security checks from bsdtar down into libarchive, where
they can be better optimized.
* Rearchitected the logic for creating objects on disk to reduce
the number of system calls. Several common cases now use a
minimum number of system calls.
* Virtualized some internal interfaces to provide a clearer separation
of read and write handling and make it simpler to override key
methods.
* New "empty" format reader.
* Corrected return types (this ABI breakage required the "2.0" version bump)
* Many bug fixes.
Diffstat (limited to 'lib/libarchive/archive_private.h')
-rw-r--r-- | lib/libarchive/archive_private.h | 204 |
1 files changed, 29 insertions, 175 deletions
diff --git a/lib/libarchive/archive_private.h b/lib/libarchive/archive_private.h index 6e6867a..a6b7fd6 100644 --- a/lib/libarchive/archive_private.h +++ b/lib/libarchive/archive_private.h @@ -33,6 +33,28 @@ #define ARCHIVE_WRITE_MAGIC (0xb0c5c0deU) #define ARCHIVE_READ_MAGIC (0xdeb0c5U) +#define ARCHIVE_WRITE_DISK_MAGIC (0xc001b0c5U) + +#define ARCHIVE_STATE_ANY 0xFFFFU +#define ARCHIVE_STATE_NEW 1U +#define ARCHIVE_STATE_HEADER 2U +#define ARCHIVE_STATE_DATA 4U +#define ARCHIVE_STATE_DATA_END 8U +#define ARCHIVE_STATE_EOF 0x10U +#define ARCHIVE_STATE_CLOSED 0x20U +#define ARCHIVE_STATE_FATAL 0x8000U + +struct archive_vtable { + int (*archive_write_close)(struct archive *); + int (*archive_write_finish)(struct archive *); + int (*archive_write_header)(struct archive *, + struct archive_entry *); + int (*archive_write_finish_entry)(struct archive *); + ssize_t (*archive_write_data)(struct archive *, + const void *, size_t); + ssize_t (*archive_write_data_block)(struct archive *, + const void *, size_t, off_t); +}; struct archive { /* @@ -44,202 +66,34 @@ struct archive { unsigned magic; unsigned state; - struct archive_entry *entry; - uid_t user_uid; /* UID of current user. */ - - /* Dev/ino of the archive being read/written. */ - dev_t skip_file_dev; - ino_t skip_file_ino; - - /* Utility: Pointer to a block of nulls. */ - const unsigned char *nulls; - size_t null_length; - /* - * Used by archive_read_data() to track blocks and copy - * data to client buffers, filling gaps with zero bytes. + * Some public API functions depend on the "real" type of the + * archive object. */ - const char *read_data_block; - off_t read_data_offset; - off_t read_data_output_offset; - size_t read_data_remaining; + struct archive_vtable *vtable; - /* Callbacks to open/read/write/close archive stream. */ - archive_open_callback *client_opener; - archive_read_callback *client_reader; - archive_skip_callback *client_skipper; - archive_write_callback *client_writer; - archive_close_callback *client_closer; - void *client_data; - - /* - * Blocking information. Note that bytes_in_last_block is - * misleadingly named; I should find a better name. These - * control the final output from all compressors, including - * compression_none. - */ - int bytes_per_block; - int bytes_in_last_block; + int archive_format; + const char *archive_format_name; - /* - * These control whether data within a gzip/bzip2 compressed - * stream gets padded or not. If pad_uncompressed is set, - * the data will be padded to a full block before being - * compressed. The pad_uncompressed_byte determines the value - * that will be used for padding. Note that these have no - * effect on compression "none." - */ - int pad_uncompressed; - int pad_uncompressed_byte; /* TODO: Support this. */ + int compression_code; /* Currently active compression. */ + const char *compression_name; /* Position in UNCOMPRESSED data stream. */ off_t file_position; /* Position in COMPRESSED data stream. */ off_t raw_position; - /* File offset of beginning of most recently-read header. */ - off_t header_position; - - /* - * Detection functions for decompression: bid functions are - * given a block of data from the beginning of the stream and - * can bid on whether or not they support the data stream. - * General guideline: bid the number of bits that you actually - * test, e.g., 16 if you test a 2-byte magic value. The - * highest bidder will have their init function invoked, which - * can set up pointers to specific handlers. - * - * On write, the client just invokes an archive_write_set function - * which sets up the data here directly. - */ - int compression_code; /* Currently active compression. */ - const char *compression_name; - struct { - int (*bid)(const void *buff, size_t); - int (*init)(struct archive *, const void *buff, size_t); - } decompressors[4]; - /* Read/write data stream (with compression). */ - void *compression_data; /* Data for (de)compressor. */ - int (*compression_init)(struct archive *); /* Initialize. */ - int (*compression_finish)(struct archive *); - int (*compression_write)(struct archive *, const void *, size_t); - /* - * Read uses a peek/consume I/O model: the decompression code - * returns a pointer to the requested block and advances the - * file position only when requested by a consume call. This - * reduces copying and also simplifies look-ahead for format - * detection. - */ - ssize_t (*compression_read_ahead)(struct archive *, - const void **, size_t request); - ssize_t (*compression_read_consume)(struct archive *, size_t); - off_t (*compression_skip)(struct archive *, off_t); - - /* - * Format detection is mostly the same as compression - * detection, with two significant differences: The bidders - * use the read_ahead calls above to examine the stream rather - * than having the supervisor hand them a block of data to - * examine, and the auction is repeated for every header. - * Winning bidders should set the archive_format and - * archive_format_name appropriately. Bid routines should - * check archive_format and decline to bid if the format of - * the last header was incompatible. - * - * Again, write support is considerably simpler because there's - * no need for an auction. - */ - int archive_format; - const char *archive_format_name; - - struct archive_format_descriptor { - int (*bid)(struct archive *); - int (*read_header)(struct archive *, struct archive_entry *); - int (*read_data)(struct archive *, const void **, size_t *, off_t *); - int (*read_data_skip)(struct archive *); - int (*cleanup)(struct archive *); - void *format_data; /* Format-specific data for readers. */ - } formats[8]; - struct archive_format_descriptor *format; /* Active format. */ - - /* - * Storage for format-specific data. Note that there can be - * multiple format readers active at one time, so we need to - * allow for multiple format readers to have their data - * available. The pformat_data slot here is the solution: on - * read, it is guaranteed to always point to a void* variable - * that the format can use. - */ - void **pformat_data; /* Pointer to current format_data. */ - void *format_data; /* Used by writers. */ - - /* - * Pointers to format-specific functions for writing. They're - * initialized by archive_write_set_format_XXX() calls. - */ - int (*format_init)(struct archive *); /* Only used on write. */ - int (*format_finish)(struct archive *); - int (*format_finish_entry)(struct archive *); - int (*format_write_header)(struct archive *, - struct archive_entry *); - ssize_t (*format_write_data)(struct archive *, - const void *buff, size_t); - - /* - * Various information needed by archive_extract. - */ - struct extract *extract; - void (*extract_progress)(void *); - void *extract_progress_user_data; - int (*cleanup_archive_extract)(struct archive *); int archive_error_number; const char *error; struct archive_string error_string; }; - -#define ARCHIVE_STATE_ANY 0xFFFFU -#define ARCHIVE_STATE_NEW 1U -#define ARCHIVE_STATE_HEADER 2U -#define ARCHIVE_STATE_DATA 4U -#define ARCHIVE_STATE_EOF 8U -#define ARCHIVE_STATE_CLOSED 0x10U -#define ARCHIVE_STATE_FATAL 0x8000U - /* Check magic value and state; exit if it isn't valid. */ void __archive_check_magic(struct archive *, unsigned magic, unsigned state, const char *func); - -int __archive_read_register_format(struct archive *a, - void *format_data, - int (*bid)(struct archive *), - int (*read_header)(struct archive *, struct archive_entry *), - int (*read_data)(struct archive *, const void **, size_t *, off_t *), - int (*read_data_skip)(struct archive *), - int (*cleanup)(struct archive *)); - -int __archive_read_register_compression(struct archive *a, - int (*bid)(const void *, size_t), - int (*init)(struct archive *, const void *, size_t)); - void __archive_errx(int retvalue, const char *msg); #define err_combine(a,b) ((a) < (b) ? (a) : (b)) - -/* - * Utility function to format a USTAR header into a buffer. If - * "strict" is set, this tries to create the absolutely most portable - * version of a ustar header. If "strict" is set to 0, then it will - * relax certain requirements. - * - * Generally, format-specific declarations don't belong in this - * header; this is a rare example of a function that is shared by - * two very similar formats (ustar and pax). - */ -int -__archive_write_format_header_ustar(struct archive *, char buff[512], - struct archive_entry *, int tartype, int strict); - #endif |