Add support for a new archive format "empty" that reads empty files.

This commit is contained in:
Tim Kientzle 2007-02-01 06:18:17 +00:00
parent c69e1d83f5
commit a9490c597b
6 changed files with 109 additions and 11 deletions

View File

@ -60,6 +60,7 @@ SRCS= archive.h \
archive_read_support_compression_none.c \
archive_read_support_format_all.c \
archive_read_support_format_cpio.c \
archive_read_support_format_empty.c \
archive_read_support_format_iso9660.c \
archive_read_support_format_tar.c \
archive_read_support_format_zip.c \

View File

@ -157,6 +157,7 @@ typedef int archive_close_callback(struct archive *, void *_client_data);
#define ARCHIVE_FORMAT_ISO9660 0x40000
#define ARCHIVE_FORMAT_ISO9660_ROCKRIDGE (ARCHIVE_FORMAT_ISO9660 | 1)
#define ARCHIVE_FORMAT_ZIP 0x50000
#define ARCHIVE_FORMAT_EMPTY 0x60000
/*-
* Basic outline for reading an archive:
@ -187,6 +188,7 @@ int archive_read_support_compression_none(struct archive *);
int archive_read_support_format_all(struct archive *);
int archive_read_support_format_cpio(struct archive *);
int archive_read_support_format_empty(struct archive *);
int archive_read_support_format_gnutar(struct archive *);
int archive_read_support_format_iso9660(struct archive *);
int archive_read_support_format_tar(struct archive *);

View File

@ -36,6 +36,7 @@
.Nm archive_read_support_compression_none ,
.Nm archive_read_support_format_all ,
.Nm archive_read_support_format_cpio ,
.Nm archive_read_support_format_empty ,
.Nm archive_read_support_format_iso9660 ,
.Nm archive_read_support_format_tar ,
.Nm archive_read_support_format_zip ,
@ -75,6 +76,8 @@
.Ft int
.Fn archive_read_support_format_cpio "struct archive *"
.Ft int
.Fn archive_read_support_format_empty "struct archive *"
.Ft int
.Fn archive_read_support_format_iso9660 "struct archive *"
.Ft int
.Fn archive_read_support_format_tar "struct archive *"
@ -135,7 +138,7 @@ is always enabled by default.
For convenience,
.Fn archive_read_support_compression_all
enables all available decompression code.
.It Fn archive_read_support_format_all , Fn archive_read_support_format_cpio , Fn archive_read_support_format_iso9660 , Fn archive_read_support_format_tar, Fn archive_read_support_format_zip
.It Fn archive_read_support_format_all , Fn archive_read_support_format_cpio , Fn archive_read_support_format_empty , Fn archive_read_support_format_iso9660 , Fn archive_read_support_format_tar, Fn archive_read_support_format_zip
Enables support---including auto-detection code---for the
specified archive format.
For example,
@ -539,3 +542,14 @@ or before calling
you may confuse the permission-setting logic with
the result that directory permissions are restored
incorrectly.
.Pp
Many traditional archiver programs treat
empty files as valid empty archives.
For example, many implementations of
.Xr tar 1
allow you to append entries to an empty file.
Of course, it is impossible to determine the format of an empty file
by inspecting the contents, so this library treats empty files as
having a special
.Dq empty
format.

View File

@ -172,16 +172,6 @@ archive_read_open2(struct archive *a, void *client_data,
return (ARCHIVE_FATAL);
}
/* An empty archive is a serious error. */
if (bytes_read == 0) {
archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
"Empty input file");
/* Close the empty file. */
if (client_closer)
(client_closer)(a, client_data);
return (ARCHIVE_FATAL);
}
/* Now that the client callbacks have worked, remember them. */
a->client_opener = client_opener; /* Do we need to remember this? */
a->client_reader = client_reader;

View File

@ -32,6 +32,7 @@ int
archive_read_support_format_all(struct archive *a)
{
archive_read_support_format_cpio(a);
archive_read_support_format_empty(a);
archive_read_support_format_iso9660(a);
archive_read_support_format_tar(a);
archive_read_support_format_zip(a);

View File

@ -0,0 +1,90 @@
/*-
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "archive_platform.h"
__FBSDID("$FreeBSD$");
#include "archive.h"
#include "archive_entry.h"
#include "archive_private.h"
static int archive_read_format_empty_bid(struct archive *);
static int archive_read_format_empty_read_data(struct archive *,
const void **, size_t *, off_t *);
static int archive_read_format_empty_read_header(struct archive *,
struct archive_entry *);
int
archive_read_support_format_empty(struct archive *a)
{
int r;
r = __archive_read_register_format(a,
NULL,
archive_read_format_empty_bid,
archive_read_format_empty_read_header,
archive_read_format_empty_read_data,
NULL,
NULL);
return (r);
}
static int
archive_read_format_empty_bid(struct archive *a)
{
int bytes_read;
const void *h;
bytes_read = (a->compression_read_ahead)(a, &h, 1);
if (bytes_read > 0)
return (-1);
return (1);
}
static int
archive_read_format_empty_read_header(struct archive *a,
struct archive_entry *entry)
{
(void)a; /* UNUSED */
(void)entry; /* UNUSED */
a->archive_format = ARCHIVE_FORMAT_EMPTY;
a->archive_format_name = "Empty file";
return (ARCHIVE_EOF);
}
static int
archive_read_format_empty_read_data(struct archive *a,
const void **buff, size_t *size, off_t *offset)
{
(void)a; /* UNUSED */
(void)buff; /* UNUSED */
(void)size; /* UNUSED */
(void)offset; /* UNUSED */
return (ARCHIVE_EOF);
}