From 5d5227539d7bfab73bd934f58666746209893ab4 Mon Sep 17 00:00:00 2001 From: kientzle Date: Thu, 1 Feb 2007 06:18:17 +0000 Subject: Add support for a new archive format "empty" that reads empty files. --- lib/libarchive/Makefile | 1 + lib/libarchive/archive.h.in | 2 + lib/libarchive/archive_read.3 | 16 +++- lib/libarchive/archive_read.c | 10 --- lib/libarchive/archive_read_support_format_all.c | 1 + lib/libarchive/archive_read_support_format_empty.c | 90 ++++++++++++++++++++++ 6 files changed, 109 insertions(+), 11 deletions(-) create mode 100644 lib/libarchive/archive_read_support_format_empty.c (limited to 'lib') diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile index 3a5651c..3c4170d 100644 --- a/lib/libarchive/Makefile +++ b/lib/libarchive/Makefile @@ -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 \ diff --git a/lib/libarchive/archive.h.in b/lib/libarchive/archive.h.in index 3ef335e..cdcc21f 100644 --- a/lib/libarchive/archive.h.in +++ b/lib/libarchive/archive.h.in @@ -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 *); diff --git a/lib/libarchive/archive_read.3 b/lib/libarchive/archive_read.3 index daa3c84..f968238 100644 --- a/lib/libarchive/archive_read.3 +++ b/lib/libarchive/archive_read.3 @@ -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. diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c index 9e5acab..c24f139 100644 --- a/lib/libarchive/archive_read.c +++ b/lib/libarchive/archive_read.c @@ -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; diff --git a/lib/libarchive/archive_read_support_format_all.c b/lib/libarchive/archive_read_support_format_all.c index 6a7b880..df3a03f 100644 --- a/lib/libarchive/archive_read_support_format_all.c +++ b/lib/libarchive/archive_read_support_format_all.c @@ -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); diff --git a/lib/libarchive/archive_read_support_format_empty.c b/lib/libarchive/archive_read_support_format_empty.c new file mode 100644 index 0000000..2df2194 --- /dev/null +++ b/lib/libarchive/archive_read_support_format_empty.c @@ -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); +} -- cgit v1.1