More work on ACLs: fix error in archive_entry's ACL parsing code,
try to set ACLs even if fflag restore fails, first cut at reading Solaris tar ACLs Code improvement: merge gnu tar read support into main tar reader; this eliminates a lot of duplicate code and generalizes the tar reader to handle formats with GNU-like extensions. Style: Makefile cleanup, eliminate 'dmalloc' references, remove 'tartype' from archive_entry (this makes archive_entry more format-agnostic) Thanks to: David Magda for providing Solaris tar test files
This commit is contained in:
parent
4cbbc3a35e
commit
aee47dd7c8
@ -1,14 +1,16 @@
|
||||
# Makefile for libarchive.
|
||||
#
|
||||
# $FreeBSD$
|
||||
DEBUG_FLAGS=-g
|
||||
|
||||
LIB= archive
|
||||
SHLIB_MAJOR= 1
|
||||
|
||||
WARNS?= 6
|
||||
|
||||
# I'm not yet ready for a shared version of this library, as
|
||||
# there are a couple of API changes still in the works.
|
||||
NOPIC= 1
|
||||
|
||||
INCS= archive.h archive_entry.h
|
||||
|
||||
SRCS= archive_check_magic.c \
|
||||
archive_entry.c \
|
||||
archive_read.c \
|
||||
@ -23,7 +25,6 @@ SRCS= archive_check_magic.c \
|
||||
archive_read_support_compression_none.c \
|
||||
archive_read_support_format_all.c \
|
||||
archive_read_support_format_cpio.c \
|
||||
archive_read_support_format_gnutar.c \
|
||||
archive_read_support_format_tar.c \
|
||||
archive_string.c \
|
||||
archive_string_sprintf.c \
|
||||
@ -41,90 +42,78 @@ SRCS= archive_check_magic.c \
|
||||
archive_write_set_format_shar.c \
|
||||
archive_write_set_format_ustar.c
|
||||
|
||||
MAN = archive_entry.3 \
|
||||
MAN= archive_entry.3 \
|
||||
archive_read.3 \
|
||||
archive_util.3 \
|
||||
archive_write.3 \
|
||||
libarchive.3 \
|
||||
tar.5
|
||||
|
||||
MLINKS += archive_entry.3 archive_entry_clear.3
|
||||
MLINKS += archive_entry.3 archive_entry_clone.3
|
||||
MLINKS += archive_entry.3 archive_entry_copy_stat.3
|
||||
MLINKS += archive_entry.3 archive_entry_dup.3
|
||||
MLINKS += archive_entry.3 archive_entry_free.3
|
||||
MLINKS += archive_entry.3 archive_entry_gname.3
|
||||
MLINKS += archive_entry.3 archive_entry_hardlink.3
|
||||
MLINKS += archive_entry.3 archive_entry_new.3
|
||||
MLINKS += archive_entry.3 archive_entry_pathname.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_devmajor.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_devminor.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_gid.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_gname.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_hardlink.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_mode.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_pathname.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_symlink.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_tartype.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_uid.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_uname.3
|
||||
MLINKS += archive_entry.3 archive_entry_size.3
|
||||
MLINKS += archive_entry.3 archive_entry_stat.3
|
||||
MLINKS += archive_entry.3 archive_entry_symlink.3
|
||||
MLINKS += archive_entry.3 archive_entry_tartype.3
|
||||
MLINKS += archive_entry.3 archive_entry_uname.3
|
||||
MLINKS += archive_read.3 archive_read_data.3
|
||||
MLINKS += archive_read.3 archive_read_data_into_buffer.3
|
||||
MLINKS += archive_read.3 archive_read_data_into_file.3
|
||||
MLINKS += archive_read.3 archive_read_data_skip.3
|
||||
MLINKS += archive_read.3 archive_read_extract.3
|
||||
MLINKS += archive_read.3 archive_read_finish.3
|
||||
MLINKS += archive_read.3 archive_read_new.3
|
||||
MLINKS += archive_read.3 archive_read_next_header.3
|
||||
MLINKS += archive_read.3 archive_read_open.3
|
||||
MLINKS += archive_read.3 archive_read_open_fd.3
|
||||
MLINKS += archive_read.3 archive_read_open_file.3
|
||||
MLINKS += archive_read.3 archive_read_set_bytes_per_block.3
|
||||
MLINKS += archive_read.3 archive_read_support_compression_all.3
|
||||
MLINKS += archive_read.3 archive_read_support_compression_bzip2.3
|
||||
MLINKS += archive_read.3 archive_read_support_compression_gzip.3
|
||||
MLINKS += archive_read.3 archive_read_support_compression_none.3
|
||||
MLINKS += archive_read.3 archive_read_support_format_all.3
|
||||
MLINKS += archive_read.3 archive_read_support_format_cpio.3
|
||||
MLINKS += archive_read.3 archive_read_support_format_gnutar.3
|
||||
MLINKS += archive_read.3 archive_read_support_format_tar.3
|
||||
MLINKS += archive_util.3 archive_compression.3
|
||||
MLINKS += archive_util.3 archive_compression_name.3
|
||||
MLINKS += archive_util.3 archive_errno.3
|
||||
MLINKS += archive_util.3 archive_error_string.3
|
||||
MLINKS += archive_util.3 archive_format.3
|
||||
MLINKS += archive_util.3 archive_format_name.3
|
||||
MLINKS += archive_write.3 archive_write_data.3
|
||||
MLINKS += archive_write.3 archive_write_finish.3
|
||||
MLINKS += archive_write.3 archive_write_header.3
|
||||
MLINKS += archive_write.3 archive_write_new.3
|
||||
MLINKS += archive_write.3 archive_write_open.3
|
||||
MLINKS += archive_write.3 archive_write_open_fd.3
|
||||
MLINKS += archive_write.3 archive_write_open_file.3
|
||||
MLINKS += archive_write.3 archive_write_prepare.3
|
||||
MLINKS += archive_write.3 archive_write_set_bytes_per_block.3
|
||||
MLINKS += archive_write.3 archive_write_set_bytes_in_last_block.3
|
||||
MLINKS += archive_write.3 archive_write_set_callbacks.3
|
||||
MLINKS += archive_write.3 archive_write_set_compression_bzip2.3
|
||||
MLINKS += archive_write.3 archive_write_set_compression_gzip.3
|
||||
MLINKS += archive_write.3 archive_write_set_format_pax.3
|
||||
MLINKS += archive_write.3 archive_write_set_format_ustar.3
|
||||
MLINKS += libarchive.3 archive.3
|
||||
|
||||
INCS = archive.h archive_entry.h
|
||||
|
||||
.if defined(DMALLOC)
|
||||
DEBUG_FLAGS+= -DDEBUG -g
|
||||
CFLAGS+= -DHAVE_DMALLOC -I/usr/local/include
|
||||
LDFLAGS+= -L/usr/local/lib -ldmalloc
|
||||
.endif
|
||||
#CFLAGS+= -O3
|
||||
|
||||
WARNS?= 6
|
||||
MLINKS+= archive_entry.3 archive_entry_clear.3
|
||||
MLINKS+= archive_entry.3 archive_entry_clone.3
|
||||
MLINKS+= archive_entry.3 archive_entry_copy_stat.3
|
||||
MLINKS+= archive_entry.3 archive_entry_dup.3
|
||||
MLINKS+= archive_entry.3 archive_entry_free.3
|
||||
MLINKS+= archive_entry.3 archive_entry_gname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_hardlink.3
|
||||
MLINKS+= archive_entry.3 archive_entry_new.3
|
||||
MLINKS+= archive_entry.3 archive_entry_pathname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_devmajor.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_devminor.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_gid.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_gname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_hardlink.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_link.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_mode.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_pathname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_symlink.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_uid.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_uname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_size.3
|
||||
MLINKS+= archive_entry.3 archive_entry_stat.3
|
||||
MLINKS+= archive_entry.3 archive_entry_symlink.3
|
||||
MLINKS+= archive_entry.3 archive_entry_uname.3
|
||||
MLINKS+= archive_read.3 archive_read_data.3
|
||||
MLINKS+= archive_read.3 archive_read_data_into_buffer.3
|
||||
MLINKS+= archive_read.3 archive_read_data_into_file.3
|
||||
MLINKS+= archive_read.3 archive_read_data_skip.3
|
||||
MLINKS+= archive_read.3 archive_read_extract.3
|
||||
MLINKS+= archive_read.3 archive_read_finish.3
|
||||
MLINKS+= archive_read.3 archive_read_new.3
|
||||
MLINKS+= archive_read.3 archive_read_next_header.3
|
||||
MLINKS+= archive_read.3 archive_read_open.3
|
||||
MLINKS+= archive_read.3 archive_read_open_fd.3
|
||||
MLINKS+= archive_read.3 archive_read_open_file.3
|
||||
MLINKS+= archive_read.3 archive_read_set_bytes_per_block.3
|
||||
MLINKS+= archive_read.3 archive_read_support_compression_all.3
|
||||
MLINKS+= archive_read.3 archive_read_support_compression_bzip2.3
|
||||
MLINKS+= archive_read.3 archive_read_support_compression_gzip.3
|
||||
MLINKS+= archive_read.3 archive_read_support_compression_none.3
|
||||
MLINKS+= archive_read.3 archive_read_support_format_all.3
|
||||
MLINKS+= archive_read.3 archive_read_support_format_cpio.3
|
||||
MLINKS+= archive_read.3 archive_read_support_format_gnutar.3
|
||||
MLINKS+= archive_read.3 archive_read_support_format_tar.3
|
||||
MLINKS+= archive_util.3 archive_compression.3
|
||||
MLINKS+= archive_util.3 archive_compression_name.3
|
||||
MLINKS+= archive_util.3 archive_errno.3
|
||||
MLINKS+= archive_util.3 archive_error_string.3
|
||||
MLINKS+= archive_util.3 archive_format.3
|
||||
MLINKS+= archive_util.3 archive_format_name.3
|
||||
MLINKS+= archive_write.3 archive_write_data.3
|
||||
MLINKS+= archive_write.3 archive_write_finish.3
|
||||
MLINKS+= archive_write.3 archive_write_header.3
|
||||
MLINKS+= archive_write.3 archive_write_new.3
|
||||
MLINKS+= archive_write.3 archive_write_open.3
|
||||
MLINKS+= archive_write.3 archive_write_open_fd.3
|
||||
MLINKS+= archive_write.3 archive_write_open_file.3
|
||||
MLINKS+= archive_write.3 archive_write_prepare.3
|
||||
MLINKS+= archive_write.3 archive_write_set_bytes_per_block.3
|
||||
MLINKS+= archive_write.3 archive_write_set_bytes_in_last_block.3
|
||||
MLINKS+= archive_write.3 archive_write_set_callbacks.3
|
||||
MLINKS+= archive_write.3 archive_write_set_compression_bzip2.3
|
||||
MLINKS+= archive_write.3 archive_write_set_compression_gzip.3
|
||||
MLINKS+= archive_write.3 archive_write_set_format_pax.3
|
||||
MLINKS+= archive_write.3 archive_write_set_format_ustar.3
|
||||
MLINKS+= libarchive.3 archive.3
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -1,14 +1,16 @@
|
||||
# Makefile for libarchive.
|
||||
#
|
||||
# $FreeBSD$
|
||||
DEBUG_FLAGS=-g
|
||||
|
||||
LIB= archive
|
||||
SHLIB_MAJOR= 1
|
||||
|
||||
WARNS?= 6
|
||||
|
||||
# I'm not yet ready for a shared version of this library, as
|
||||
# there are a couple of API changes still in the works.
|
||||
NOPIC= 1
|
||||
|
||||
INCS= archive.h archive_entry.h
|
||||
|
||||
SRCS= archive_check_magic.c \
|
||||
archive_entry.c \
|
||||
archive_read.c \
|
||||
@ -23,7 +25,6 @@ SRCS= archive_check_magic.c \
|
||||
archive_read_support_compression_none.c \
|
||||
archive_read_support_format_all.c \
|
||||
archive_read_support_format_cpio.c \
|
||||
archive_read_support_format_gnutar.c \
|
||||
archive_read_support_format_tar.c \
|
||||
archive_string.c \
|
||||
archive_string_sprintf.c \
|
||||
@ -41,90 +42,78 @@ SRCS= archive_check_magic.c \
|
||||
archive_write_set_format_shar.c \
|
||||
archive_write_set_format_ustar.c
|
||||
|
||||
MAN = archive_entry.3 \
|
||||
MAN= archive_entry.3 \
|
||||
archive_read.3 \
|
||||
archive_util.3 \
|
||||
archive_write.3 \
|
||||
libarchive.3 \
|
||||
tar.5
|
||||
|
||||
MLINKS += archive_entry.3 archive_entry_clear.3
|
||||
MLINKS += archive_entry.3 archive_entry_clone.3
|
||||
MLINKS += archive_entry.3 archive_entry_copy_stat.3
|
||||
MLINKS += archive_entry.3 archive_entry_dup.3
|
||||
MLINKS += archive_entry.3 archive_entry_free.3
|
||||
MLINKS += archive_entry.3 archive_entry_gname.3
|
||||
MLINKS += archive_entry.3 archive_entry_hardlink.3
|
||||
MLINKS += archive_entry.3 archive_entry_new.3
|
||||
MLINKS += archive_entry.3 archive_entry_pathname.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_devmajor.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_devminor.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_gid.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_gname.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_hardlink.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_mode.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_pathname.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_symlink.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_tartype.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_uid.3
|
||||
MLINKS += archive_entry.3 archive_entry_set_uname.3
|
||||
MLINKS += archive_entry.3 archive_entry_size.3
|
||||
MLINKS += archive_entry.3 archive_entry_stat.3
|
||||
MLINKS += archive_entry.3 archive_entry_symlink.3
|
||||
MLINKS += archive_entry.3 archive_entry_tartype.3
|
||||
MLINKS += archive_entry.3 archive_entry_uname.3
|
||||
MLINKS += archive_read.3 archive_read_data.3
|
||||
MLINKS += archive_read.3 archive_read_data_into_buffer.3
|
||||
MLINKS += archive_read.3 archive_read_data_into_file.3
|
||||
MLINKS += archive_read.3 archive_read_data_skip.3
|
||||
MLINKS += archive_read.3 archive_read_extract.3
|
||||
MLINKS += archive_read.3 archive_read_finish.3
|
||||
MLINKS += archive_read.3 archive_read_new.3
|
||||
MLINKS += archive_read.3 archive_read_next_header.3
|
||||
MLINKS += archive_read.3 archive_read_open.3
|
||||
MLINKS += archive_read.3 archive_read_open_fd.3
|
||||
MLINKS += archive_read.3 archive_read_open_file.3
|
||||
MLINKS += archive_read.3 archive_read_set_bytes_per_block.3
|
||||
MLINKS += archive_read.3 archive_read_support_compression_all.3
|
||||
MLINKS += archive_read.3 archive_read_support_compression_bzip2.3
|
||||
MLINKS += archive_read.3 archive_read_support_compression_gzip.3
|
||||
MLINKS += archive_read.3 archive_read_support_compression_none.3
|
||||
MLINKS += archive_read.3 archive_read_support_format_all.3
|
||||
MLINKS += archive_read.3 archive_read_support_format_cpio.3
|
||||
MLINKS += archive_read.3 archive_read_support_format_gnutar.3
|
||||
MLINKS += archive_read.3 archive_read_support_format_tar.3
|
||||
MLINKS += archive_util.3 archive_compression.3
|
||||
MLINKS += archive_util.3 archive_compression_name.3
|
||||
MLINKS += archive_util.3 archive_errno.3
|
||||
MLINKS += archive_util.3 archive_error_string.3
|
||||
MLINKS += archive_util.3 archive_format.3
|
||||
MLINKS += archive_util.3 archive_format_name.3
|
||||
MLINKS += archive_write.3 archive_write_data.3
|
||||
MLINKS += archive_write.3 archive_write_finish.3
|
||||
MLINKS += archive_write.3 archive_write_header.3
|
||||
MLINKS += archive_write.3 archive_write_new.3
|
||||
MLINKS += archive_write.3 archive_write_open.3
|
||||
MLINKS += archive_write.3 archive_write_open_fd.3
|
||||
MLINKS += archive_write.3 archive_write_open_file.3
|
||||
MLINKS += archive_write.3 archive_write_prepare.3
|
||||
MLINKS += archive_write.3 archive_write_set_bytes_per_block.3
|
||||
MLINKS += archive_write.3 archive_write_set_bytes_in_last_block.3
|
||||
MLINKS += archive_write.3 archive_write_set_callbacks.3
|
||||
MLINKS += archive_write.3 archive_write_set_compression_bzip2.3
|
||||
MLINKS += archive_write.3 archive_write_set_compression_gzip.3
|
||||
MLINKS += archive_write.3 archive_write_set_format_pax.3
|
||||
MLINKS += archive_write.3 archive_write_set_format_ustar.3
|
||||
MLINKS += libarchive.3 archive.3
|
||||
|
||||
INCS = archive.h archive_entry.h
|
||||
|
||||
.if defined(DMALLOC)
|
||||
DEBUG_FLAGS+= -DDEBUG -g
|
||||
CFLAGS+= -DHAVE_DMALLOC -I/usr/local/include
|
||||
LDFLAGS+= -L/usr/local/lib -ldmalloc
|
||||
.endif
|
||||
#CFLAGS+= -O3
|
||||
|
||||
WARNS?= 6
|
||||
MLINKS+= archive_entry.3 archive_entry_clear.3
|
||||
MLINKS+= archive_entry.3 archive_entry_clone.3
|
||||
MLINKS+= archive_entry.3 archive_entry_copy_stat.3
|
||||
MLINKS+= archive_entry.3 archive_entry_dup.3
|
||||
MLINKS+= archive_entry.3 archive_entry_free.3
|
||||
MLINKS+= archive_entry.3 archive_entry_gname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_hardlink.3
|
||||
MLINKS+= archive_entry.3 archive_entry_new.3
|
||||
MLINKS+= archive_entry.3 archive_entry_pathname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_devmajor.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_devminor.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_gid.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_gname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_hardlink.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_link.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_mode.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_pathname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_symlink.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_uid.3
|
||||
MLINKS+= archive_entry.3 archive_entry_set_uname.3
|
||||
MLINKS+= archive_entry.3 archive_entry_size.3
|
||||
MLINKS+= archive_entry.3 archive_entry_stat.3
|
||||
MLINKS+= archive_entry.3 archive_entry_symlink.3
|
||||
MLINKS+= archive_entry.3 archive_entry_uname.3
|
||||
MLINKS+= archive_read.3 archive_read_data.3
|
||||
MLINKS+= archive_read.3 archive_read_data_into_buffer.3
|
||||
MLINKS+= archive_read.3 archive_read_data_into_file.3
|
||||
MLINKS+= archive_read.3 archive_read_data_skip.3
|
||||
MLINKS+= archive_read.3 archive_read_extract.3
|
||||
MLINKS+= archive_read.3 archive_read_finish.3
|
||||
MLINKS+= archive_read.3 archive_read_new.3
|
||||
MLINKS+= archive_read.3 archive_read_next_header.3
|
||||
MLINKS+= archive_read.3 archive_read_open.3
|
||||
MLINKS+= archive_read.3 archive_read_open_fd.3
|
||||
MLINKS+= archive_read.3 archive_read_open_file.3
|
||||
MLINKS+= archive_read.3 archive_read_set_bytes_per_block.3
|
||||
MLINKS+= archive_read.3 archive_read_support_compression_all.3
|
||||
MLINKS+= archive_read.3 archive_read_support_compression_bzip2.3
|
||||
MLINKS+= archive_read.3 archive_read_support_compression_gzip.3
|
||||
MLINKS+= archive_read.3 archive_read_support_compression_none.3
|
||||
MLINKS+= archive_read.3 archive_read_support_format_all.3
|
||||
MLINKS+= archive_read.3 archive_read_support_format_cpio.3
|
||||
MLINKS+= archive_read.3 archive_read_support_format_gnutar.3
|
||||
MLINKS+= archive_read.3 archive_read_support_format_tar.3
|
||||
MLINKS+= archive_util.3 archive_compression.3
|
||||
MLINKS+= archive_util.3 archive_compression_name.3
|
||||
MLINKS+= archive_util.3 archive_errno.3
|
||||
MLINKS+= archive_util.3 archive_error_string.3
|
||||
MLINKS+= archive_util.3 archive_format.3
|
||||
MLINKS+= archive_util.3 archive_format_name.3
|
||||
MLINKS+= archive_write.3 archive_write_data.3
|
||||
MLINKS+= archive_write.3 archive_write_finish.3
|
||||
MLINKS+= archive_write.3 archive_write_header.3
|
||||
MLINKS+= archive_write.3 archive_write_new.3
|
||||
MLINKS+= archive_write.3 archive_write_open.3
|
||||
MLINKS+= archive_write.3 archive_write_open_fd.3
|
||||
MLINKS+= archive_write.3 archive_write_open_file.3
|
||||
MLINKS+= archive_write.3 archive_write_prepare.3
|
||||
MLINKS+= archive_write.3 archive_write_set_bytes_per_block.3
|
||||
MLINKS+= archive_write.3 archive_write_set_bytes_in_last_block.3
|
||||
MLINKS+= archive_write.3 archive_write_set_callbacks.3
|
||||
MLINKS+= archive_write.3 archive_write_set_compression_bzip2.3
|
||||
MLINKS+= archive_write.3 archive_write_set_compression_gzip.3
|
||||
MLINKS+= archive_write.3 archive_write_set_format_pax.3
|
||||
MLINKS+= archive_write.3 archive_write_set_format_ustar.3
|
||||
MLINKS+= libarchive.3 archive.3
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
@ -29,9 +29,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
@ -52,14 +52,12 @@
|
||||
.Nm archive_entry_set_mode
|
||||
.Nm archive_entry_set_pathname
|
||||
.Nm archive_entry_set_symlink
|
||||
.Nm archive_entry_set_tartype
|
||||
.Nm archive_entry_set_uid
|
||||
.Nm archive_entry_set_uname
|
||||
.Nm archive_entry_size
|
||||
.Nm archive_entry_stat
|
||||
.Nm archive_entry_symlink
|
||||
.Nm archive_entry_symlink_w
|
||||
.Nm archive_entry_tartype
|
||||
.Nm archive_entry_uname
|
||||
.Nm archive_entry_uname_w
|
||||
.Nd functions for manipulating archive entry descriptions
|
||||
@ -114,8 +112,6 @@
|
||||
.Ft void
|
||||
.Fn archive_entry_set_symlink "struct archive_entry *" "const char *"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_tartype "struct archive_entry *" "int"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_uid "struct archive_entry *" "uid_t"
|
||||
.Ft void
|
||||
.Fn archive_entry_set_uname "struct archive_entry *" "const char *"
|
||||
@ -127,8 +123,6 @@
|
||||
.Fn archive_entry_symlink "struct archive_entry *"
|
||||
.Ft const wchar_t *
|
||||
.Fn archive_entry_symlink_w "struct archive_entry *"
|
||||
.Ft int
|
||||
.Fn archive_entry_tartype "struct archive_entry *"
|
||||
.Ft const char *
|
||||
.Fn archive_entry_uname "struct archive_entry *"
|
||||
.Ft const wchar_t *
|
||||
@ -199,12 +193,6 @@ object.
|
||||
Allocate and return a blank
|
||||
.Tn struct archive_entry
|
||||
object.
|
||||
.It Fn archive_entry_set_tartype
|
||||
Sets the value to be used in a tar-format header
|
||||
for this entry.
|
||||
Client code should generally not set this; if it
|
||||
is left unset, the library will automatically determine
|
||||
an appropriate value.
|
||||
.El
|
||||
.\" .Sh EXAMPLE
|
||||
.\" .Sh RETURN VALUES
|
||||
|
@ -29,9 +29,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -119,9 +116,6 @@ struct archive_entry {
|
||||
*/
|
||||
struct stat ae_stat;
|
||||
|
||||
/* I'm not happy with having this format-particular data here. */
|
||||
int ae_tartype;
|
||||
|
||||
/*
|
||||
* Use aes here so that we get transparent mbs<->wcs conversions.
|
||||
*/
|
||||
@ -283,7 +277,6 @@ archive_entry_clear(struct archive_entry *entry)
|
||||
aes_clean(&entry->ae_uname);
|
||||
archive_entry_acl_clear(entry);
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
entry->ae_tartype = -1;
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -298,7 +291,6 @@ archive_entry_clone(struct archive_entry *entry)
|
||||
return (NULL);
|
||||
memset(entry2, 0, sizeof(*entry2));
|
||||
entry2->ae_stat = entry->ae_stat;
|
||||
entry2->ae_tartype = entry->ae_tartype;
|
||||
|
||||
aes_copy(&entry2->ae_fflags ,&entry->ae_fflags);
|
||||
aes_copy(&entry2->ae_gname ,&entry->ae_gname);
|
||||
@ -326,7 +318,6 @@ archive_entry_new(void)
|
||||
if(entry == NULL)
|
||||
return (NULL);
|
||||
memset(entry, 0, sizeof(*entry));
|
||||
entry->ae_tartype = -1;
|
||||
return (entry);
|
||||
}
|
||||
|
||||
@ -415,12 +406,6 @@ archive_entry_symlink(struct archive_entry *entry)
|
||||
return (aes_get_mbs(&entry->ae_symlink));
|
||||
}
|
||||
|
||||
int
|
||||
archive_entry_tartype(struct archive_entry *entry)
|
||||
{
|
||||
return (entry->ae_tartype);
|
||||
}
|
||||
|
||||
const char *
|
||||
archive_entry_uname(struct archive_entry *entry)
|
||||
{
|
||||
@ -501,6 +486,16 @@ archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target
|
||||
aes_copy_wcs(&entry->ae_hardlink, target);
|
||||
}
|
||||
|
||||
/* Set symlink if symlink is already set, else set hardlink. */
|
||||
void
|
||||
archive_entry_set_link(struct archive_entry *entry, const char *target)
|
||||
{
|
||||
if (entry->ae_symlink.aes_mbs != NULL ||
|
||||
entry->ae_symlink.aes_wcs != NULL)
|
||||
aes_set_mbs(&entry->ae_symlink, target);
|
||||
aes_set_mbs(&entry->ae_hardlink, target);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_mode(struct archive_entry *entry, mode_t m)
|
||||
{
|
||||
@ -537,12 +532,6 @@ archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linknam
|
||||
aes_copy_wcs(&entry->ae_symlink, linkname);
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_tartype(struct archive_entry *entry, char t)
|
||||
{
|
||||
entry->ae_tartype = t;
|
||||
}
|
||||
|
||||
void
|
||||
archive_entry_set_uid(struct archive_entry *entry, uid_t u)
|
||||
{
|
||||
@ -1121,15 +1110,16 @@ __archive_entry_acl_parse_w(struct archive_entry *entry,
|
||||
namebuff =
|
||||
malloc(namebuff_length * sizeof(wchar_t));
|
||||
}
|
||||
wmemcpy(namebuff, start, end-start);
|
||||
wmemcpy(namebuff, name_start, name_end - name_start);
|
||||
archive_entry_acl_add_entry_w(entry, type,
|
||||
permset, tag, id, namebuff);
|
||||
}
|
||||
}
|
||||
if (namebuff != NULL)
|
||||
free(namebuff);
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
fail:
|
||||
fprintf(stderr, "ACL error\n");
|
||||
if (namebuff != NULL)
|
||||
free(namebuff);
|
||||
return (ARCHIVE_WARN);
|
||||
|
@ -79,7 +79,6 @@ const wchar_t *archive_entry_pathname_w(struct archive_entry *);
|
||||
int64_t archive_entry_size(struct archive_entry *);
|
||||
const struct stat *archive_entry_stat(struct archive_entry *);
|
||||
const char *archive_entry_symlink(struct archive_entry *);
|
||||
int archive_entry_tartype(struct archive_entry *);
|
||||
const char *archive_entry_uname(struct archive_entry *);
|
||||
|
||||
/*
|
||||
@ -99,23 +98,24 @@ void archive_entry_set_gname(struct archive_entry *, const char *);
|
||||
void archive_entry_copy_gname_w(struct archive_entry *, const wchar_t *);
|
||||
void archive_entry_set_hardlink(struct archive_entry *, const char *);
|
||||
void archive_entry_copy_hardlink_w(struct archive_entry *, const wchar_t *);
|
||||
void archive_entry_set_link(struct archive_entry *, const char *);
|
||||
void archive_entry_set_mode(struct archive_entry *, mode_t);
|
||||
void archive_entry_set_pathname(struct archive_entry *, const char *);
|
||||
void archive_entry_copy_pathname_w(struct archive_entry *, const wchar_t *);
|
||||
void archive_entry_set_size(struct archive_entry *, int64_t);
|
||||
void archive_entry_set_symlink(struct archive_entry *, const char *);
|
||||
void archive_entry_copy_symlink_w(struct archive_entry *, const wchar_t *);
|
||||
void archive_entry_set_tartype(struct archive_entry *, char);
|
||||
void archive_entry_set_uid(struct archive_entry *, uid_t);
|
||||
void archive_entry_set_uname(struct archive_entry *, const char *);
|
||||
void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
|
||||
|
||||
/*
|
||||
* ACL routines. This used to simply store and return text-format ACL
|
||||
* strings, but that proved insufficient. The intent here is to allow
|
||||
* libarchive internals to fetch/store text-format strings, but
|
||||
* clients use the more involved interface that allows them control
|
||||
* over uid/uname/gid/gname lookups.
|
||||
* strings, but that proved insufficient for a number of reasons:
|
||||
* = clients need control over uname/uid and gname/gid mappings
|
||||
* = there are many different ACL text formats
|
||||
* = would like to be able to read/convert archives containing ACLs
|
||||
* on platforms that lack ACL libraries
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -139,7 +139,6 @@ void archive_entry_copy_uname_w(struct archive_entry *, const wchar_t *);
|
||||
#define ARCHIVE_ENTRY_ACL_MASK 10005 /* Modify group access. */
|
||||
#define ARCHIVE_ENTRY_ACL_OTHER 10006 /* Public. */
|
||||
|
||||
|
||||
/*
|
||||
* Set the ACL by clearing it and adding entries one at a time.
|
||||
* Unlike the POSIX.1e ACL routines, you must specify the type
|
||||
@ -185,6 +184,17 @@ const wchar_t *archive_entry_acl_text_w(struct archive_entry *, int flags);
|
||||
/* Return a count of entries matching 'want_type' */
|
||||
int archive_entry_acl_count(struct archive_entry *, int want_type);
|
||||
|
||||
|
||||
/*
|
||||
* Private ACL parser. This is private because it handles some
|
||||
* very weird formats that clients should not be messing with.
|
||||
* Clients should only deal with their platform-native formats.
|
||||
* Because of the need to support many formats cleanly, new arguments
|
||||
* are likely to get added on a regular basis. Clients who try to use
|
||||
* this interface are likely to be surprised when it changes.
|
||||
*
|
||||
* You were warned!
|
||||
*/
|
||||
int __archive_entry_acl_parse_w(struct archive_entry *,
|
||||
const wchar_t *, int type);
|
||||
|
||||
#endif /* !ARCHIVE_ENTRY_H_INCLUDED */
|
||||
|
@ -201,7 +201,7 @@ struct archive {
|
||||
/* Utility function to format a USTAR header into a buffer. */
|
||||
int
|
||||
__archive_write_format_header_ustar(struct archive *, char buff[512],
|
||||
struct archive_entry *);
|
||||
struct archive_entry *, int tartype);
|
||||
|
||||
#define ARCHIVE_STATE_ANY 0xFFFFU
|
||||
#define ARCHIVE_STATE_NEW 1U
|
||||
@ -231,17 +231,4 @@ int __archive_read_register_compression(struct archive *a,
|
||||
|
||||
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
||||
|
||||
/*
|
||||
* Private ACL handling: parse and generate ACL strings.
|
||||
* These are private because they handle a lot of very weird formats
|
||||
* that clients should not be messing with. Clients should only
|
||||
* deal with their platform-native formats. Because of the need to
|
||||
* support many formats cleanly, new arguments are likely to get added
|
||||
* on a regular basis. Clients who try to use this interface are
|
||||
* likely to be surprised when it changes.
|
||||
*/
|
||||
int __archive_entry_acl_parse_w(struct archive_entry *,
|
||||
const wchar_t *, int type);
|
||||
|
||||
#endif
|
||||
|
@ -35,9 +35,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "archive.h"
|
||||
|
@ -28,10 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
|
||||
#include "archive.h"
|
||||
|
@ -34,9 +34,6 @@ __FBSDID("$FreeBSD$");
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
@ -773,15 +770,15 @@ set_perm(struct archive *a, struct archive_entry *entry, int mode, int flags)
|
||||
static int
|
||||
set_extended_perm(struct archive *a, struct archive_entry *entry, int flags)
|
||||
{
|
||||
int ret;
|
||||
int ret, ret2;
|
||||
|
||||
if ((flags & ARCHIVE_EXTRACT_PERM) == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
ret = set_fflags(a, entry);
|
||||
if (ret == ARCHIVE_OK)
|
||||
ret = set_acls(a, entry);
|
||||
return (ret);
|
||||
ret2 = set_acls(a, entry);
|
||||
|
||||
return (err_combine(ret,ret2));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -831,6 +828,7 @@ set_acls(struct archive *a, struct archive_entry *entry)
|
||||
{
|
||||
(void)a;
|
||||
(void)entry;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
@ -878,22 +876,33 @@ set_acl(struct archive *a, struct archive_entry *entry, acl_type_t acl_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
acl_create_entry(&acl, &acl_entry);
|
||||
|
||||
if (ae_tag == ARCHIVE_ENTRY_ACL_USER) {
|
||||
switch (ae_tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
acl_set_tag_type(acl_entry, ACL_USER);
|
||||
ae_uid = lookup_uid(a, ae_name, ae_id);
|
||||
acl_set_qualifier(acl_entry, &ae_uid);
|
||||
} else if (ae_tag == ARCHIVE_ENTRY_ACL_GROUP) {
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP);
|
||||
ae_gid = lookup_gid(a, ae_name, ae_id);
|
||||
acl_set_qualifier(acl_entry, &ae_gid);
|
||||
} else if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_USER_OBJ);
|
||||
else if (ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
|
||||
else if (ae_tag == ARCHIVE_ENTRY_ACL_MASK)
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
acl_set_tag_type(acl_entry, ACL_MASK);
|
||||
else if (ae_tag == ARCHIVE_ENTRY_ACL_OTHER)
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
acl_set_tag_type(acl_entry, ACL_OTHER);
|
||||
break;
|
||||
default:
|
||||
/* XXX */
|
||||
break;
|
||||
}
|
||||
|
||||
acl_get_permset(acl_entry, &acl_permset);
|
||||
acl_clear_perms(acl_permset);
|
||||
@ -906,6 +915,7 @@ set_acl(struct archive *a, struct archive_entry *entry, acl_type_t acl_type,
|
||||
}
|
||||
|
||||
name = archive_entry_pathname(entry);
|
||||
|
||||
if (acl_set_file(name, acl_type, acl) != 0) {
|
||||
archive_set_error(a, errno, "Failed to set %s acl", typename);
|
||||
ret = ARCHIVE_WARN;
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -27,10 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
|
||||
int
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -27,10 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
|
||||
#include "archive.h"
|
||||
|
||||
int
|
||||
|
@ -29,9 +29,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
/* #include <stdint.h> */ /* See archive_platform.h */
|
||||
|
@ -1,574 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2004 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
|
||||
* in this position and unchanged.
|
||||
* 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 <sys/stat.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
/* #include <stdint.h> */ /* See archive_platform.h */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "archive.h"
|
||||
#include "archive_entry.h"
|
||||
#include "archive_private.h"
|
||||
|
||||
/*
|
||||
* Structure of GNU tar header
|
||||
*/
|
||||
struct archive_entry_header_gnutar {
|
||||
char name[100];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char checksum[8];
|
||||
char typeflag[1];
|
||||
char linkname[100];
|
||||
char magic[8]; /* "ustar \0" (note blank/blank/null at end) */
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char atime[12];
|
||||
char ctime[12];
|
||||
char offset[12];
|
||||
char longnames[4];
|
||||
char unused[1];
|
||||
struct {
|
||||
char offset[12];
|
||||
char numbytes[12];
|
||||
} sparse[4];
|
||||
char isextended[1];
|
||||
char realsize[12];
|
||||
/*
|
||||
* GNU doesn't use POSIX 'prefix' field; they use the 'L' (longname)
|
||||
* entry instead.
|
||||
*/
|
||||
};
|
||||
|
||||
struct gnutar {
|
||||
struct archive_string entry_name;
|
||||
struct archive_string entry_linkname;
|
||||
struct archive_string entry_uname;
|
||||
struct archive_string entry_gname;
|
||||
struct archive_string gnu_name;
|
||||
struct archive_string gnu_linkname;
|
||||
int gnu_header_recursion_depth;
|
||||
};
|
||||
|
||||
static int archive_block_is_null(const unsigned char *p);
|
||||
static int archive_header_gnu(struct archive *, struct archive_entry *,
|
||||
const void *);
|
||||
static int archive_read_format_gnutar_bid(struct archive *a);
|
||||
static int archive_read_format_gnutar_cleanup(struct archive *);
|
||||
static int archive_read_format_gnutar_read_header(struct archive *a,
|
||||
struct archive_entry *);
|
||||
static int checksum(struct archive *a, const void *h);
|
||||
static int64_t tar_atol(const char *, unsigned);
|
||||
static int64_t tar_atol8(const char *, unsigned);
|
||||
static int64_t tar_atol256(const char *, unsigned);
|
||||
|
||||
/*
|
||||
* The ONLY publicly visible function in this file.
|
||||
*/
|
||||
int
|
||||
archive_read_support_format_gnutar(struct archive *a)
|
||||
{
|
||||
struct gnutar *gnutar;
|
||||
|
||||
gnutar = malloc(sizeof(*gnutar));
|
||||
memset(gnutar, 0, sizeof(*gnutar));
|
||||
|
||||
return (__archive_read_register_format(a,
|
||||
gnutar,
|
||||
archive_read_format_gnutar_bid,
|
||||
archive_read_format_gnutar_read_header,
|
||||
archive_read_format_gnutar_cleanup));
|
||||
}
|
||||
|
||||
static int
|
||||
archive_read_format_gnutar_cleanup(struct archive *a)
|
||||
{
|
||||
struct gnutar *gnutar;
|
||||
|
||||
gnutar = *(a->pformat_data);
|
||||
if (gnutar->entry_name.s != NULL)
|
||||
free(gnutar->entry_name.s);
|
||||
if (gnutar->entry_linkname.s != NULL)
|
||||
free(gnutar->entry_linkname.s);
|
||||
if (gnutar->entry_uname.s != NULL)
|
||||
free(gnutar->entry_uname.s);
|
||||
if (gnutar->entry_gname.s != NULL)
|
||||
free(gnutar->entry_gname.s);
|
||||
if (gnutar->gnu_name.s != NULL)
|
||||
free(gnutar->gnu_name.s);
|
||||
if (gnutar->gnu_linkname.s != NULL)
|
||||
free(gnutar->gnu_linkname.s);
|
||||
|
||||
free(gnutar);
|
||||
*(a->pformat_data) = NULL;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_read_format_gnutar_bid(struct archive *a)
|
||||
{
|
||||
int bid;
|
||||
size_t bytes_read;
|
||||
const void *h;
|
||||
const struct archive_entry_header_gnutar *header;
|
||||
|
||||
/*
|
||||
* If we're already reading a non-tar file, don't
|
||||
* bother to bid.
|
||||
*/
|
||||
if (a->archive_format != 0 &&
|
||||
(a->archive_format & ARCHIVE_FORMAT_BASE_MASK) !=
|
||||
ARCHIVE_FORMAT_TAR)
|
||||
return (0);
|
||||
|
||||
bid = 0;
|
||||
|
||||
/* If last header was my preferred format, bid a bit more. */
|
||||
if (a->archive_format == ARCHIVE_FORMAT_TAR_GNUTAR)
|
||||
bid += 10;
|
||||
|
||||
bytes_read = (a->compression_read_ahead)(a, &h, 512);
|
||||
if (bytes_read < 512)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* TODO: if checksum or header fail, scan ahead for
|
||||
* next valid header.
|
||||
*/
|
||||
|
||||
/* Checksum field is eight 8-bit values: 64 bits of validation. */
|
||||
if (!checksum(a, h))
|
||||
return (0);
|
||||
bid += 64;
|
||||
|
||||
header = (const struct archive_entry_header_gnutar *)h;
|
||||
|
||||
/* This distinguishes GNU tar formats from POSIX formats */
|
||||
if (memcmp(header->magic, "ustar \0", 8) != 0)
|
||||
return (0);
|
||||
bid += 64;
|
||||
|
||||
return (bid);
|
||||
}
|
||||
|
||||
static int
|
||||
archive_read_format_gnutar_read_header(struct archive *a,
|
||||
struct archive_entry *entry)
|
||||
{
|
||||
const void *h;
|
||||
ssize_t bytes;
|
||||
int oldstate;
|
||||
struct gnutar *gnutar;
|
||||
|
||||
gnutar = *(a->pformat_data);
|
||||
a->archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
|
||||
a->archive_format_name = "GNU tar";
|
||||
|
||||
/* Skip remains of previous entry. */
|
||||
oldstate = a->state;
|
||||
a->state = ARCHIVE_STATE_DATA;
|
||||
archive_read_data_skip(a);
|
||||
a->state = oldstate;
|
||||
|
||||
/* Read 512-byte header record */
|
||||
bytes = (a->compression_read_ahead)(a, &h, 512);
|
||||
if (bytes < 512)
|
||||
return (ARCHIVE_FATAL);
|
||||
(a->compression_read_consume)(a, 512);
|
||||
|
||||
/*
|
||||
* If this is a block of nulls, return 0 (no more entries).
|
||||
* Note the initial (*h)==0 test short-circuits the function call
|
||||
* in the most common case.
|
||||
*/
|
||||
if (((*(const char *)h)==0) && archive_block_is_null(h)) {
|
||||
/* TODO: Store file location of start of block in public area */
|
||||
archive_set_error(a, 0, NULL);
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
|
||||
/* TODO: add support for scanning for next valid header */
|
||||
if (!checksum(a, h)) {
|
||||
archive_set_error(a, EINVAL, "Damaged GNU tar archive");
|
||||
return (ARCHIVE_FATAL); /* Not a valid header. */
|
||||
}
|
||||
|
||||
/* This function gets called recursively for long name headers, etc. */
|
||||
if (++gnutar->gnu_header_recursion_depth > 32)
|
||||
errx(EINVAL,
|
||||
"*** Too many special headers for one entry; giving up. "
|
||||
"(%s:%s@%d)\n",
|
||||
__FUNCTION__, __FILE__, __LINE__);
|
||||
|
||||
archive_header_gnu(a, entry, h);
|
||||
gnutar->gnu_header_recursion_depth--;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if block checksum is correct.
|
||||
*/
|
||||
static int
|
||||
checksum(struct archive *a, const void *h)
|
||||
{
|
||||
const unsigned char *bytes;
|
||||
const struct archive_entry_header_gnutar *header;
|
||||
int i, sum, signed_sum, unsigned_sum;
|
||||
|
||||
(void)a; /* UNUSED */
|
||||
bytes = h;
|
||||
header = h;
|
||||
|
||||
/* Test checksum: POSIX specifies UNSIGNED for this calculation. */
|
||||
sum = tar_atol(header->checksum, sizeof(header->checksum));
|
||||
unsigned_sum = 0;
|
||||
for (i = 0; i < 148; i++)
|
||||
unsigned_sum += (unsigned char)bytes[i];
|
||||
for (; i < 156; i++)
|
||||
unsigned_sum += 32;
|
||||
for (; i < 512; i++)
|
||||
unsigned_sum += (unsigned char)bytes[i];
|
||||
if (sum == unsigned_sum)
|
||||
return (1);
|
||||
|
||||
/*
|
||||
* Repeat test with SIGNED bytes, just in case this archive
|
||||
* was created by an old BSD, Solaris, or HP-UX tar with a broken
|
||||
* checksum calculation.
|
||||
*/
|
||||
signed_sum = 0;
|
||||
for (i = 0; i < 148; i++)
|
||||
signed_sum += (signed char)bytes[i];
|
||||
for (; i < 156; i++)
|
||||
signed_sum += 32;
|
||||
for (; i < 512; i++)
|
||||
signed_sum += (signed char)bytes[i];
|
||||
if (sum == signed_sum)
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if this block contains only nulls.
|
||||
*/
|
||||
static int
|
||||
archive_block_is_null(const unsigned char *p)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < ARCHIVE_BYTES_PER_RECORD / sizeof(*p); i++) {
|
||||
if (*p++)
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse GNU tar header
|
||||
*/
|
||||
static int
|
||||
archive_header_gnu(struct archive *a, struct archive_entry *entry,
|
||||
const void *h)
|
||||
{
|
||||
struct stat st;
|
||||
const struct archive_entry_header_gnutar *header;
|
||||
struct gnutar *gnutar;
|
||||
char tartype;
|
||||
unsigned oldstate;
|
||||
|
||||
/* Clear out entry structure */
|
||||
memset(&st, 0, sizeof(st));
|
||||
gnutar = *(a->pformat_data);
|
||||
|
||||
/*
|
||||
* GNU header is like POSIX, except 'prefix' is
|
||||
* replaced with some other fields. This also means the
|
||||
* filename is stored as in old-style archives.
|
||||
*/
|
||||
|
||||
/* Copy filename over (to ensure null termination). */
|
||||
header = h;
|
||||
archive_strncpy(&(gnutar->entry_name), header->name,
|
||||
sizeof(header->name));
|
||||
archive_entry_set_pathname(entry, gnutar->entry_name.s);
|
||||
|
||||
/* Copy linkname over */
|
||||
if (header->linkname[0])
|
||||
archive_strncpy(&(gnutar->entry_linkname), header->linkname,
|
||||
sizeof(header->linkname));
|
||||
|
||||
/* Parse out the numeric fields (all are octal) */
|
||||
st.st_mode = tar_atol(header->mode, sizeof(header->mode));
|
||||
st.st_uid = tar_atol(header->uid, sizeof(header->uid));
|
||||
st.st_gid = tar_atol(header->gid, sizeof(header->gid));
|
||||
st.st_size = tar_atol(header->size, sizeof(header->size));
|
||||
st.st_mtime = tar_atol(header->mtime, sizeof(header->mtime));
|
||||
|
||||
/* Handle the tar type flag appropriately. */
|
||||
tartype = header->typeflag[0];
|
||||
archive_entry_set_tartype(entry, tartype);
|
||||
st.st_mode &= ~S_IFMT;
|
||||
|
||||
/* Fields common to ustar and GNU */
|
||||
archive_strncpy(&(gnutar->entry_uname),
|
||||
header->uname, sizeof(header->uname));
|
||||
archive_entry_set_uname(entry, gnutar->entry_uname.s);
|
||||
|
||||
archive_strncpy(&(gnutar->entry_gname),
|
||||
header->gname, sizeof(header->gname));
|
||||
archive_entry_set_gname(entry, gnutar->entry_gname.s);
|
||||
|
||||
/* Parse out device numbers only for char and block specials */
|
||||
if (header->typeflag[0] == '3' || header->typeflag[0] == '4')
|
||||
st.st_rdev = makedev (
|
||||
tar_atol(header->devmajor, sizeof(header->devmajor)),
|
||||
tar_atol(header->devminor, sizeof(header->devminor)));
|
||||
else
|
||||
st.st_rdev = 0;
|
||||
|
||||
/* Grab additional GNU fields. */
|
||||
/* TODO: FILL THIS IN!!! */
|
||||
st.st_atime = tar_atol(header->atime, sizeof(header->atime));
|
||||
st.st_ctime = tar_atol(header->atime, sizeof(header->ctime));
|
||||
|
||||
/* Set internal counter for locating next header */
|
||||
a->entry_bytes_remaining = st.st_size;
|
||||
a->entry_padding = 0x1ff & (-a->entry_bytes_remaining);
|
||||
|
||||
/* Interpret entry type */
|
||||
switch (tartype) {
|
||||
case '1': /* Hard link */
|
||||
archive_entry_set_hardlink(entry, gnutar->entry_linkname.s);
|
||||
/*
|
||||
* Note: Technically, tar does not store the file type
|
||||
* for a "hard link" entry, only the fact that it is a
|
||||
* hard link. So, I leave the file type in st_mode
|
||||
* zero here.
|
||||
*/
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
break;
|
||||
case '2': /* Symlink */
|
||||
st.st_mode |= S_IFLNK;
|
||||
st.st_size = 0;
|
||||
archive_entry_set_symlink(entry, gnutar->entry_linkname.s);
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
break;
|
||||
case '3': /* Character device */
|
||||
st.st_mode |= S_IFCHR;
|
||||
st.st_size = 0;
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
break;
|
||||
case '4': /* Block device */
|
||||
st.st_mode |= S_IFBLK;
|
||||
st.st_size = 0;
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
break;
|
||||
case '5': /* POSIX Dir */
|
||||
st.st_mode |= S_IFDIR;
|
||||
st.st_size = 0;
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
break;
|
||||
case '6': /* FIFO device */
|
||||
st.st_mode |= S_IFIFO;
|
||||
st.st_size = 0;
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
break;
|
||||
case 'D': /* GNU incremental directory type */
|
||||
/*
|
||||
* No special handling is actually required here.
|
||||
* It might be nice someday to preprocess the file list and
|
||||
* provide it to the client, though.
|
||||
*/
|
||||
st.st_mode &= ~ S_IFMT;
|
||||
st.st_mode |= S_IFDIR;
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
break;
|
||||
case 'K': /* GNU long linkname */
|
||||
/* Entry body is full name of link for next header. */
|
||||
archive_string_ensure(&(gnutar->gnu_linkname), st.st_size+1);
|
||||
/* Temporarily fudge internal state for read_data call. */
|
||||
oldstate = a->state;
|
||||
a->state = ARCHIVE_STATE_DATA;
|
||||
archive_read_data_into_buffer(a, gnutar->gnu_linkname.s,
|
||||
st.st_size);
|
||||
a->state = oldstate;
|
||||
gnutar->gnu_linkname.s[st.st_size] = 0; /* Null term name! */
|
||||
/*
|
||||
* This next call will usually overwrite
|
||||
* gnutar->entry_linkname, which is why we _must_ have
|
||||
* a separate gnu_linkname field.
|
||||
*/
|
||||
archive_read_format_gnutar_read_header(a, entry);
|
||||
if (archive_entry_tartype(entry) == '1')
|
||||
archive_entry_set_hardlink(entry, gnutar->gnu_linkname.s);
|
||||
else if (archive_entry_tartype(entry) == '2')
|
||||
archive_entry_set_symlink(entry, gnutar->gnu_linkname.s);
|
||||
/* TODO: else { ... } */
|
||||
break;
|
||||
case 'L': /* GNU long filename */
|
||||
/* Entry body is full pathname for next header. */
|
||||
archive_string_ensure(&(gnutar->gnu_name), st.st_size+1);
|
||||
/* Temporarily fudge internal state for read_data call. */
|
||||
oldstate = a->state;
|
||||
a->state = ARCHIVE_STATE_DATA;
|
||||
archive_read_data_into_buffer(a, gnutar->gnu_name.s,
|
||||
st.st_size);
|
||||
a->state = oldstate;
|
||||
gnutar->gnu_name.s[st.st_size] = 0; /* Null terminate name! */
|
||||
/*
|
||||
* This next call will typically overwrite
|
||||
* gnutar->entry_name, which is why we _must_ have a
|
||||
* separate gnu_name field.
|
||||
*/
|
||||
archive_read_format_gnutar_read_header(a, entry);
|
||||
archive_entry_set_pathname(entry, gnutar->gnu_name.s);
|
||||
break;
|
||||
case 'M': /* GNU Multi-volume (remainder of file from last archive) */
|
||||
/*
|
||||
* As far as I can tell, this is just like a regular file
|
||||
* entry, except that the contents should be _appended_ to
|
||||
* the indicated file at the indicated offset. This may
|
||||
* require some API work to fully support.
|
||||
*/
|
||||
break;
|
||||
case 'N': /* Old GNU long filename; this will never be supported */
|
||||
/* Essentially, body of this entry is a script for
|
||||
* renaming previously-extracted entries. Ugh. */
|
||||
break;
|
||||
case 'S': /* GNU Sparse files: These are really ugly, and unlikely
|
||||
* to be supported anytime soon. */
|
||||
break;
|
||||
case 'V': /* GNU volume header */
|
||||
/* Just skip it */
|
||||
return (archive_read_format_gnutar_read_header(a, entry));
|
||||
default: /* Regular file and non-standard types */
|
||||
/* Per POSIX: non-recognized types should always be
|
||||
* treated as regular files. Of course, GNU
|
||||
* extensions aren't compatible with this dictum.
|
||||
* <sigh> */
|
||||
st.st_mode |= S_IFREG;
|
||||
archive_entry_copy_stat(entry, &st);
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert text->integer.
|
||||
*
|
||||
* Traditional tar formats (including POSIX) specify base-8 for
|
||||
* all of the standard numeric fields. GNU tar supports base-256
|
||||
* as well in many of the numeric fields. There is also an old
|
||||
* and short-lived base-64 format, but I doubt I'll ever see
|
||||
* an archive that uses it. (According to the changelog for GNU tar,
|
||||
* that format was only implemented for a couple of weeks!)
|
||||
*/
|
||||
static int64_t
|
||||
tar_atol(const char *p, unsigned char_cnt)
|
||||
{
|
||||
if (*p & 0x80)
|
||||
return (tar_atol256(p, char_cnt));
|
||||
return (tar_atol8(p, char_cnt));
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that this implementation does not (and should not!) obey
|
||||
* locale settings; you cannot simply substitute strtol here, since
|
||||
* it does obey locale.
|
||||
*/
|
||||
static int64_t
|
||||
tar_atol8(const char *p, unsigned char_cnt)
|
||||
{
|
||||
int64_t l;
|
||||
int digit, sign;
|
||||
|
||||
static const int64_t limit = INT64_MAX / 8;
|
||||
static const int base = 8;
|
||||
static const char last_digit_limit = INT64_MAX % 8;
|
||||
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
if (*p == '-') {
|
||||
sign = -1;
|
||||
p++;
|
||||
} else
|
||||
sign = 1;
|
||||
|
||||
l = 0;
|
||||
digit = *p - '0';
|
||||
while (digit >= 0 && digit < base && char_cnt-- > 0) {
|
||||
if (l>limit || (l == limit && digit > last_digit_limit)) {
|
||||
l = INT64_MAX; /* Truncate on overflow */
|
||||
break;
|
||||
}
|
||||
l = ( l * base ) + digit;
|
||||
digit = *++p - '0';
|
||||
}
|
||||
return (sign < 0) ? -l : l;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a base-256 integer.
|
||||
*
|
||||
* TODO: This overflows very quickly for negative values; fix this.
|
||||
*/
|
||||
static int64_t
|
||||
tar_atol256(const char *p, unsigned char_cnt)
|
||||
{
|
||||
int64_t l;
|
||||
int digit;
|
||||
|
||||
const int64_t limit = INT64_MAX / 256;
|
||||
|
||||
/* Ignore high bit of first byte (that's the base-256 flag). */
|
||||
l = 0;
|
||||
digit = 0x7f & *(const unsigned char *)p;
|
||||
while (char_cnt-- > 0) {
|
||||
if (l > limit) {
|
||||
l = INT64_MAX; /* Truncate on overflow */
|
||||
break;
|
||||
}
|
||||
l = (l << 8) + digit;
|
||||
digit = *(const unsigned char *)++p;
|
||||
}
|
||||
return (l);
|
||||
}
|
@ -28,9 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
/* #include <stdint.h> */ /* See archive_platform.h */
|
||||
#include <stdlib.h>
|
||||
@ -97,8 +94,12 @@ static int header_longlink(struct archive *, struct tar *,
|
||||
struct archive_entry *, struct stat *, const void *h);
|
||||
static int header_longname(struct archive *, struct tar *,
|
||||
struct archive_entry *, struct stat *, const void *h);
|
||||
static int header_volume(struct archive *, struct tar *,
|
||||
struct archive_entry *, struct stat *, const void *h);
|
||||
static int header_ustar(struct archive *, struct tar *,
|
||||
struct archive_entry *, struct stat *, const void *h);
|
||||
static int header_gnutar(struct archive *, struct tar *,
|
||||
struct archive_entry *, struct stat *, const void *h);
|
||||
static int archive_read_format_tar_bid(struct archive *);
|
||||
static int archive_read_format_tar_cleanup(struct archive *);
|
||||
static int archive_read_format_tar_read_header(struct archive *,
|
||||
@ -119,6 +120,13 @@ static int tar_read_header(struct archive *, struct tar *,
|
||||
struct archive_entry *, struct stat *);
|
||||
static int utf8_decode(wchar_t *, const char *, size_t length);
|
||||
|
||||
int
|
||||
archive_read_support_format_gnutar(struct archive *a)
|
||||
{
|
||||
return (archive_read_support_format_tar(a));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
archive_read_support_format_tar(struct archive *a)
|
||||
{
|
||||
@ -185,11 +193,6 @@ archive_read_format_tar_bid(struct archive *a)
|
||||
ARCHIVE_FORMAT_TAR)
|
||||
bid++;
|
||||
|
||||
/* If last header was my preferred format, bid a bit more. */
|
||||
if (a->archive_format == ARCHIVE_FORMAT_TAR_USTAR ||
|
||||
a->archive_format == ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE)
|
||||
bid++;
|
||||
|
||||
/* Now let's look at the actual header and see if it matches. */
|
||||
bytes_read = (a->compression_read_ahead)(a, &h, 512);
|
||||
if (bytes_read < 512)
|
||||
@ -211,6 +214,11 @@ archive_read_format_tar_bid(struct archive *a)
|
||||
&&(memcmp(header->version, "00", 2)==0))
|
||||
bid += 56;
|
||||
|
||||
/* Recognize GNU tar format as well. */
|
||||
if ((memcmp(header->magic, "ustar ", 6) == 0)
|
||||
&&(memcmp(header->version, " \0", 2)==0))
|
||||
bid += 56;
|
||||
|
||||
/* Type flag must be null, digit or A-Z, a-z. */
|
||||
if (header->typeflag[0] != 0 &&
|
||||
!( header->typeflag[0] >= '0' && header->typeflag[0] <= '9') &&
|
||||
@ -280,7 +288,6 @@ tar_read_header(struct archive *a, struct tar *tar,
|
||||
|
||||
/* Check for end-of-archive mark. */
|
||||
if (((*(const char *)h)==0) && archive_block_is_null(h)) {
|
||||
/* TODO: Store file location of start of block */
|
||||
archive_set_error(a, 0, NULL);
|
||||
return (ARCHIVE_EOF);
|
||||
}
|
||||
@ -304,11 +311,7 @@ tar_read_header(struct archive *a, struct tar *tar,
|
||||
|
||||
/* Determine the format variant. */
|
||||
header = h;
|
||||
if (memcmp(header->magic, "ustar", 5) != 0) {
|
||||
a->archive_format = ARCHIVE_FORMAT_TAR;
|
||||
a->archive_format_name = "tar (non-POSIX)";
|
||||
err = header_old_tar(a, tar, entry, st, h);
|
||||
} else switch(header->typeflag[0]) {
|
||||
switch(header->typeflag[0]) {
|
||||
case 'A': /* Solaris tar ACL */
|
||||
a->archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
||||
a->archive_format_name = "Solaris tar";
|
||||
@ -319,12 +322,15 @@ tar_read_header(struct archive *a, struct tar *tar,
|
||||
a->archive_format_name = "POSIX pax interchange format";
|
||||
err = header_pax_global(a, tar, entry, st, h);
|
||||
break;
|
||||
case 'K': /* Long link name (non-POSIX, but fairly common). */
|
||||
case 'K': /* Long link name (GNU tar, others) */
|
||||
err = header_longlink(a, tar, entry, st, h);
|
||||
break;
|
||||
case 'L': /* Long filename (non-POSIX, but fairly common). */
|
||||
case 'L': /* Long filename (GNU tar, others) */
|
||||
err = header_longname(a, tar, entry, st, h);
|
||||
break;
|
||||
case 'V': /* GNU volume header */
|
||||
err = header_volume(a, tar, entry, st, h);
|
||||
break;
|
||||
case 'X': /* Used by SUN tar; same as 'x'. */
|
||||
a->archive_format = ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE;
|
||||
a->archive_format_name =
|
||||
@ -337,12 +343,21 @@ tar_read_header(struct archive *a, struct tar *tar,
|
||||
err = header_pax_extensions(a, tar, entry, st, h);
|
||||
break;
|
||||
default:
|
||||
if (a->archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE
|
||||
&& a->archive_format != ARCHIVE_FORMAT_TAR_USTAR) {
|
||||
a->archive_format = ARCHIVE_FORMAT_TAR_USTAR;
|
||||
a->archive_format_name = "POSIX ustar format";
|
||||
if (memcmp(header->magic, "ustar \0", 8) == 0) {
|
||||
a->archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
|
||||
a->archive_format_name = "GNU tar format";
|
||||
err = header_gnutar(a, tar, entry, st, h);
|
||||
} else if (memcmp(header->magic, "ustar", 5) == 0) {
|
||||
if (a->archive_format != ARCHIVE_FORMAT_TAR_PAX_INTERCHANGE) {
|
||||
a->archive_format = ARCHIVE_FORMAT_TAR_USTAR;
|
||||
a->archive_format_name = "POSIX ustar format";
|
||||
}
|
||||
err = header_ustar(a, tar, entry, st, h);
|
||||
} else {
|
||||
a->archive_format = ARCHIVE_FORMAT_TAR;
|
||||
a->archive_format_name = "tar (non-POSIX)";
|
||||
err = header_old_tar(a, tar, entry, st, h);
|
||||
}
|
||||
err = header_ustar(a, tar, entry, st, h);
|
||||
}
|
||||
archive_entry_copy_stat(entry, st);
|
||||
--tar->header_recursion_depth;
|
||||
@ -418,17 +433,32 @@ header_Solaris_ACL(struct archive *a, struct tar *tar,
|
||||
struct archive_entry *entry, struct stat *st, const void *h)
|
||||
{
|
||||
int err, err2;
|
||||
char *p;
|
||||
wchar_t *wp;
|
||||
|
||||
err = read_body_to_string(a, &(tar->acl_text), h);
|
||||
err2 = tar_read_header(a, tar, entry, st);
|
||||
err = err_combine(err, err2);
|
||||
|
||||
/* XXX DO SOMETHING WITH THE ACL!!! XXX */
|
||||
{
|
||||
const char *msg = "\nXXX Solaris ACL entries recognized but not yet handled!!\n";
|
||||
write(2, msg, strlen(msg));
|
||||
/* XXX Ensure p doesn't overrun acl_text */
|
||||
|
||||
/* Skip leading octal number. */
|
||||
/* XXX TODO: Parse the octal number and sanity-check it. */
|
||||
p = tar->acl_text.s;
|
||||
while (*p != '\0')
|
||||
p++;
|
||||
p++;
|
||||
|
||||
wp = malloc((strlen(p) + 1) * sizeof(wchar_t));
|
||||
if (wp != NULL) {
|
||||
utf8_decode(wp, p, strlen(p));
|
||||
err2 = __archive_entry_acl_parse_w(entry, wp,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
err = err_combine(err, err2);
|
||||
free(wp);
|
||||
}
|
||||
|
||||
return (err_combine(err, err2));
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -443,10 +473,8 @@ header_longlink(struct archive *a, struct tar *tar,
|
||||
err = read_body_to_string(a, &(tar->longlink), h);
|
||||
err2 = tar_read_header(a, tar, entry, st);
|
||||
if (err == ARCHIVE_OK && err2 == ARCHIVE_OK) {
|
||||
if (archive_entry_tartype(entry) == '1')
|
||||
archive_entry_set_hardlink(entry, tar->longlink.s);
|
||||
else if (archive_entry_tartype(entry) == '2')
|
||||
archive_entry_set_symlink(entry, tar->longlink.s);
|
||||
/* Set symlink if symlink already set, else hardlink. */
|
||||
archive_entry_set_link(entry, tar->longlink.s);
|
||||
}
|
||||
return (err_combine(err, err2));
|
||||
}
|
||||
@ -468,6 +496,20 @@ header_longname(struct archive *a, struct tar *tar,
|
||||
return (err_combine(err, err2));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Interpret 'V' GNU tar volume header.
|
||||
*/
|
||||
static int
|
||||
header_volume(struct archive *a, struct tar *tar,
|
||||
struct archive_entry *entry, struct stat *st, const void *h)
|
||||
{
|
||||
(void)h;
|
||||
|
||||
/* Just skip this and read the next header. */
|
||||
return (tar_read_header(a, tar, entry, st));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read body of an archive entry into an archive_string object.
|
||||
*/
|
||||
@ -535,7 +577,6 @@ header_common(struct archive *a, struct tar *tar, struct archive_entry *entry,
|
||||
|
||||
/* Handle the tar type flag appropriately. */
|
||||
tartype = header->typeflag[0];
|
||||
archive_entry_set_tartype(entry, tartype);
|
||||
st->st_mode &= ~S_IFMT;
|
||||
|
||||
switch (tartype) {
|
||||
@ -574,6 +615,31 @@ header_common(struct archive *a, struct tar *tar, struct archive_entry *entry,
|
||||
st->st_mode |= S_IFIFO;
|
||||
st->st_size = 0;
|
||||
break;
|
||||
case 'D': /* GNU incremental directory type */
|
||||
/*
|
||||
* No special handling is actually required here.
|
||||
* It might be nice someday to preprocess the file list and
|
||||
* provide it to the client, though.
|
||||
*/
|
||||
st->st_mode |= S_IFDIR;
|
||||
break;
|
||||
case 'M': /* GNU "Multi-volume" (remainder of file from last archive)*/
|
||||
/*
|
||||
* As far as I can tell, this is just like a regular file
|
||||
* entry, except that the contents should be _appended_ to
|
||||
* the indicated file at the indicated offset. This may
|
||||
* require some API work to fully support.
|
||||
*/
|
||||
break;
|
||||
case 'N': /* Old GNU "long filename" entry. */
|
||||
/* The body of this entry is a script for renaming
|
||||
* previously-extracted entries. Ugh. It will never
|
||||
* be supported by libarchive. */
|
||||
st->st_mode |= S_IFREG;
|
||||
break;
|
||||
case 'S': /* GNU sparse files */
|
||||
/* I would like to support these someday... */
|
||||
break;
|
||||
default: /* Regular file and non-standard types */
|
||||
/*
|
||||
* Per POSIX: non-recognized types should always be
|
||||
@ -612,7 +678,6 @@ header_old_tar(struct archive *a, struct tar *tar, struct archive_entry *entry,
|
||||
'/' == tar->entry_name.s[strlen(tar->entry_name.s) - 1]) {
|
||||
st->st_mode &= ~S_IFMT;
|
||||
st->st_mode |= S_IFDIR;
|
||||
archive_entry_set_tartype(entry, '5');
|
||||
}
|
||||
|
||||
a->entry_bytes_remaining = st->st_size;
|
||||
@ -953,6 +1018,100 @@ pax_time(const wchar_t *p, struct timespec *t)
|
||||
} while (l /= 10);
|
||||
}
|
||||
|
||||
/*
|
||||
* Structure of GNU tar header
|
||||
*/
|
||||
struct archive_entry_header_gnutar {
|
||||
char name[100];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char checksum[8];
|
||||
char typeflag[1];
|
||||
char linkname[100];
|
||||
char magic[8]; /* "ustar \0" (note blank/blank/null at end) */
|
||||
char uname[32];
|
||||
char gname[32];
|
||||
char devmajor[8];
|
||||
char devminor[8];
|
||||
char atime[12];
|
||||
char ctime[12];
|
||||
char offset[12];
|
||||
char longnames[4];
|
||||
char unused[1];
|
||||
struct {
|
||||
char offset[12];
|
||||
char numbytes[12];
|
||||
} sparse[4];
|
||||
char isextended[1];
|
||||
char realsize[12];
|
||||
/*
|
||||
* GNU doesn't use POSIX 'prefix' field; they use the 'L' (longname)
|
||||
* entry instead.
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
* Parse GNU tar header
|
||||
*/
|
||||
static int
|
||||
header_gnutar(struct archive *a, struct tar *tar, struct archive_entry *entry,
|
||||
struct stat *st, const void *h)
|
||||
{
|
||||
const struct archive_entry_header_gnutar *header;
|
||||
|
||||
(void)a;
|
||||
|
||||
/*
|
||||
* GNU header is like POSIX ustar, except 'prefix' is
|
||||
* replaced with some other fields. This also means the
|
||||
* filename is stored as in old-style archives.
|
||||
*/
|
||||
|
||||
/* Grab fields common to all tar variants. */
|
||||
header_common(a, tar, entry, st, h);
|
||||
|
||||
/* Copy filename over (to ensure null termination). */
|
||||
header = h;
|
||||
archive_strncpy(&(tar->entry_name), header->name,
|
||||
sizeof(header->name));
|
||||
archive_entry_set_pathname(entry, tar->entry_name.s);
|
||||
|
||||
/* Fields common to ustar and GNU */
|
||||
/* XXX Can the following be factored out since it's common
|
||||
* to ustar and gnu tar? Is it okay to move it down into
|
||||
* header_common, perhaps? */
|
||||
archive_strncpy(&(tar->entry_uname),
|
||||
header->uname, sizeof(header->uname));
|
||||
archive_entry_set_uname(entry, tar->entry_uname.s);
|
||||
|
||||
archive_strncpy(&(tar->entry_gname),
|
||||
header->gname, sizeof(header->gname));
|
||||
archive_entry_set_gname(entry, tar->entry_gname.s);
|
||||
|
||||
/* Parse out device numbers only for char and block specials */
|
||||
if (header->typeflag[0] == '3' || header->typeflag[0] == '4')
|
||||
st->st_rdev = makedev (
|
||||
tar_atol(header->devmajor, sizeof(header->devmajor)),
|
||||
tar_atol(header->devminor, sizeof(header->devminor)));
|
||||
else
|
||||
st->st_rdev = 0;
|
||||
|
||||
/* Grab GNU-specific fields. */
|
||||
/* TODO: FILL THIS IN!!! */
|
||||
st->st_atime = tar_atol(header->atime, sizeof(header->atime));
|
||||
st->st_ctime = tar_atol(header->atime, sizeof(header->ctime));
|
||||
|
||||
/* XXX TODO: Recognize and skip extra GNU header blocks. */
|
||||
|
||||
a->entry_bytes_remaining = st->st_size;
|
||||
a->entry_padding = 0x1ff & (-a->entry_bytes_remaining);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Convert text->integer.
|
||||
*
|
||||
|
@ -32,9 +32,6 @@ __FBSDID("$FreeBSD$");
|
||||
* strings while minimizing heap activity.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -34,9 +34,6 @@ __FBSDID("$FreeBSD$");
|
||||
* the core code, so it cannot easily be omitted.)
|
||||
*/
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -29,9 +29,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
#include "archive.h"
|
||||
|
@ -36,9 +36,6 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
|
||||
#include <sys/wait.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
|
@ -28,9 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -28,9 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -28,9 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -27,9 +27,6 @@
|
||||
#include "archive_platform.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -28,9 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -29,9 +29,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -584,7 +581,7 @@ archive_write_pax_header(struct archive *a,
|
||||
|
||||
/* Format 'ustar' header for main entry. */
|
||||
/* We don't care if this returns an error. */
|
||||
__archive_write_format_header_ustar(a, ustarbuff, entry_main);
|
||||
__archive_write_format_header_ustar(a, ustarbuff, entry_main, -1);
|
||||
|
||||
/* If we built any extended attributes, write that entry first. */
|
||||
ret = 0;
|
||||
@ -598,7 +595,6 @@ archive_write_pax_header(struct archive *a,
|
||||
p = archive_entry_pathname(entry_main);
|
||||
pax_attr_name = build_pax_attribute_name(p, &pax_entry_name);
|
||||
|
||||
archive_entry_set_tartype(pax_attr_entry, 'x');
|
||||
archive_entry_set_pathname(pax_attr_entry, pax_attr_name);
|
||||
st.st_size = archive_strlen(&(pax->pax_header));
|
||||
st.st_uid = st_main->st_uid;
|
||||
@ -612,7 +608,7 @@ archive_write_pax_header(struct archive *a,
|
||||
archive_entry_gname(entry_main));
|
||||
|
||||
ret = __archive_write_format_header_ustar(a, paxbuff,
|
||||
pax_attr_entry);
|
||||
pax_attr_entry, 'x');
|
||||
|
||||
archive_entry_free(pax_attr_entry);
|
||||
free(pax_entry_name.s);
|
||||
|
@ -28,9 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
@ -28,9 +28,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_DMALLOC
|
||||
#include <dmalloc.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -132,7 +129,7 @@ archive_write_ustar_header(struct archive *a, struct archive_entry *entry)
|
||||
!S_ISREG(archive_entry_mode(entry)))
|
||||
archive_entry_set_size(entry, 0);
|
||||
|
||||
ret = __archive_write_format_header_ustar(a, buff, entry);
|
||||
ret = __archive_write_format_header_ustar(a, buff, entry, -1);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
ret = (a->compression_write)(a, buff, 512);
|
||||
@ -154,7 +151,7 @@ archive_write_ustar_header(struct archive *a, struct archive_entry *entry)
|
||||
*/
|
||||
int
|
||||
__archive_write_format_header_ustar(struct archive *a, char buff[512],
|
||||
struct archive_entry *entry)
|
||||
struct archive_entry *entry, int tartype)
|
||||
{
|
||||
unsigned int checksum;
|
||||
struct archive_entry_header_ustar *h;
|
||||
@ -283,8 +280,8 @@ __archive_write_format_header_ustar(struct archive *a, char buff[512],
|
||||
OCTAL_TERM_SPACE_NULL);
|
||||
}
|
||||
|
||||
if (archive_entry_tartype(entry) >= 0) {
|
||||
h->typeflag[0] = archive_entry_tartype(entry);
|
||||
if (tartype >= 0) {
|
||||
h->typeflag[0] = tartype;
|
||||
} else if (archive_entry_hardlink(entry) != NULL) {
|
||||
h->typeflag[0] = '1';
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user