MFhead@r313243

This commit is contained in:
Enji Cooper 2017-02-04 18:06:09 +00:00
commit 9b3ece1c2e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/netbsd-tests-upstream-01-2017/; revision=313244
2435 changed files with 54667 additions and 75326 deletions

View file

@ -236,7 +236,7 @@ _MAKE+= MK_META_MODE=no
# Guess machine architecture from machine type, and vice versa.
.if !defined(TARGET_ARCH) && defined(TARGET)
_TARGET_ARCH= ${TARGET:S/pc98/i386/:S/arm64/aarch64/}
_TARGET_ARCH= ${TARGET:S/arm64/aarch64/}
.elif !defined(TARGET) && defined(TARGET_ARCH) && \
${TARGET_ARCH} != ${MACHINE_ARCH}
_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/powerpcspe/powerpc/:C/riscv64(sf)?/riscv/}
@ -417,13 +417,12 @@ worlds: .PHONY
# existing system is.
#
.if make(universe) || make(universe_kernels) || make(tinderbox) || make(targets)
TARGETS?=amd64 arm arm64 i386 mips pc98 powerpc sparc64
TARGETS?=amd64 arm arm64 i386 mips powerpc sparc64
_UNIVERSE_TARGETS= ${TARGETS}
TARGET_ARCHES_arm?= arm armeb armv6
TARGET_ARCHES_arm64?= aarch64
TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipselhf mipshf mips64elhf mips64hf
TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe
TARGET_ARCHES_pc98?= i386
.for target in ${TARGETS}
TARGET_ARCHES_${target}?= ${target}
.endfor

View file

@ -242,13 +242,11 @@ SUBDIR+= ${_DIR}
# of a LOCAL_DIRS directory. This allows LOCAL_DIRS=foo and
# LOCAL_LIB_DIRS=foo/lib to behave as expected.
.for _DIR in ${LOCAL_DIRS:M*/} ${LOCAL_DIRS:N*/:S|$|/|}
_REDUNDENT_LIB_DIRS+= ${LOCAL_LIB_DIRS:M${_DIR}*}
_REDUNDANT_LIB_DIRS+= ${LOCAL_LIB_DIRS:M${_DIR}*}
.endfor
.for _DIR in ${LOCAL_LIB_DIRS}
.if empty(_REDUNDENT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile)
.if empty(_REDUNDANT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile)
SUBDIR+= ${_DIR}
.else
.warning ${_DIR} not added to SUBDIR list. See UPDATING 20141121.
.endif
.endfor
@ -349,7 +347,6 @@ KNOWN_ARCHES?= aarch64/arm64 \
armeb/arm \
armv6/arm \
i386 \
i386/pc98 \
mips \
mipsel/mips \
mips64el/mips \
@ -516,7 +513,7 @@ TMAKE= MAKEOBJDIRPREFIX=${OBJTREE} \
# cross-tools stage
XMAKE= TOOLS_PREFIX=${WORLDTMP} ${BMAKE} \
TARGET=${TARGET} TARGET_ARCH=${TARGET_ARCH} \
MK_GDB=no MK_TESTS=no MK_LLD_AS_LD=no
MK_GDB=no MK_TESTS=no MK_LLD_IS_LD=no
# kernel-tools stage
KTMAKEENV= INSTALL="sh ${.CURDIR}/tools/install.sh" \
@ -1694,11 +1691,10 @@ _kerberos5_bootstrap_tools= \
.endif
# r283777 makewhatis(1) replaced with mandoc version which builds a database.
.if ${MK_MANDOCDB} != "no" && ${BOOTSTRAPPING} < 1100075
.if ${MK_MANDOCDB} != "no"
_libopenbsd?= lib/libopenbsd
_makewhatis= lib/libsqlite3 \
usr.bin/mandoc
${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd ${_bt}-lib/libsqlite3
_makewhatis= usr.bin/mandoc
${_bt}-usr.bin/mandoc: ${_bt}-lib/libopenbsd
.endif
bootstrap-tools: .PHONY
@ -1952,6 +1948,7 @@ native-xtools: .PHONY
usr.bin/mktemp \
usr.bin/mt \
usr.bin/patch \
usr.bin/readelf \
usr.bin/sed \
usr.bin/sort \
usr.bin/tar \

View file

@ -50,6 +50,8 @@ LIB32WMAKEFLAGS= LD="${XLD} -m elf32btsmip_fbsd"
LIB32WMAKEFLAGS+= OBJCOPY="${XOBJCOPY}"
.endif
LIB32WMAKEFLAGS+= NM="${XNM}"
LIB32CFLAGS= -DCOMPAT_32BIT
LIB32DTRACE= ${DTRACE} -32

View file

@ -38,6 +38,19 @@
# xargs -n1 | sort | uniq -d;
# done
# 20170128: remove pc98 support
OLD_FILES+=usr/include/dev/ic/i8251.h
OLD_FILES+=usr/include/dev/ic/i8255.h
OLD_FILES+=usr/include/dev/ic/rsa.h
OLD_FILES+=usr/include/dev/ic/wd33c93reg.h
OLD_FILES+=usr/include/sys/disk/pc98.h
OLD_FILES+=usr/include/sys/diskpc98.h
OLD_FILES+=usr/share/man/man4/i386/ct.4.gz
OLD_FILES+=usr/share/man/man4/i386/snc.4.gz
OLD_FILES+=usr/share/syscons/keymaps/jp.pc98.iso.kbd
OLD_FILES+=usr/share/syscons/keymaps/jp.pc98.kbd
OLD_FILES+=usr/share/vt/keymaps/jp.pc98.iso.kbd
OLD_FILES+=usr/share/vt/keymaps/jp.pc98.kbd
# 20170110: Four files from ggate tests consolidated into one
OLD_FILES+=usr/tests/sys/geom/class/gate/1_test
OLD_FILES+=usr/tests/sys/geom/class/gate/2_test

View file

@ -51,6 +51,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
****************************** SPECIAL WARNING: ******************************
20170127:
The WITH_LLD_AS_LD / WITHOUT_LLD_AS_LD build knobs have been renamed
WITH_LLD_IS_LD / WITHOUT_LLD_IS_LD, for consistency with CLANG_IS_CC.
20170112:
The EM_MULTIQUEUE kernel configuration option is deprecated now that
the em(4) driver conforms to iflib specifications.

View file

@ -238,6 +238,24 @@ translator ipinfo_t < uint8_t *p > {
inet_ntoa6(&((struct ip6_hdr *)p)->ip6_dst);
};
#pragma D binding "1.13" translator
translator ipinfo_t < struct mbuf *m > {
ip_ver = m == NULL ? 0 : ((struct ip *)m->m_data)->ip_v;
ip_plength = m == NULL ? 0 :
((struct ip *)m->m_data)->ip_v == 4 ?
ntohs(((struct ip *)m->m_data)->ip_len) -
(((struct ip *)m->m_data)->ip_hl << 2):
ntohs(((struct ip6_hdr *)m->m_data)->ip6_ctlun.ip6_un1.ip6_un1_plen);
ip_saddr = m == NULL ? 0 :
((struct ip *)m->m_data)->ip_v == 4 ?
inet_ntoa(&((struct ip *)m->m_data)->ip_src.s_addr) :
inet_ntoa6(&((struct ip6_hdr *)m->m_data)->ip6_src);
ip_daddr = m == NULL ? 0 :
((struct ip *)m->m_data)->ip_v == 4 ?
inet_ntoa(&((struct ip *)m->m_data)->ip_dst.s_addr) :
inet_ntoa6(&((struct ip6_hdr *)m->m_data)->ip6_dst);
};
#pragma D binding "1.5" IFF_LOOPBACK
inline int IFF_LOOPBACK = 0x8;

View file

@ -656,8 +656,11 @@ CaseFile::DeSerializeFile(const char *fileName)
uint64_t vdevGUID;
nvlist_t *vdevConf;
sscanf(fileName, "pool_%" PRIu64 "_vdev_%" PRIu64 ".case",
&poolGUID, &vdevGUID);
if (sscanf(fileName, "pool_%" PRIu64 "_vdev_%" PRIu64 ".case",
&poolGUID, &vdevGUID) != 2) {
throw ZfsdException("CaseFile::DeSerialize: "
"Unintelligible CaseFile filename %s.\n", fileName);
}
existingCaseFile = Find(Guid(poolGUID), Guid(vdevGUID));
if (existingCaseFile != NULL) {
/*

View file

@ -15156,6 +15156,7 @@ static const struct mips_cpu_info mips_cpu_info_table[] =
/* Cavium Networks Octeon CPU core */
{ "octeon", 0, ISA_MIPS64R2, CPU_OCTEON },
{ "octeon+", 0, ISA_MIPS64R2, CPU_OCTEON },
/* End marker */
{ NULL, 0, 0, 0 }

View file

@ -2789,6 +2789,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
{ "crnor", XL(19,33), XL_MASK, COM, { BT, BA, BB } },
{ "rfmci", X(19,38), 0xffffffff, PPCRFMCI, { 0 } },
{ "rfdi", XL(19,39), 0xffffffff, BOOKE, { 0 } },
{ "rfi", XL(19,50), 0xffffffff, COM, { 0 } },
{ "rfci", XL(19,51), 0xffffffff, PPC403 | BOOKE, { 0 } },

View file

@ -34,6 +34,7 @@
#include <sys/queue.h>
#include <sys/ucred.h>
#include <stdbool.h>
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
@ -119,13 +120,15 @@ udp_init_port(struct tport *tp)
addr.sin_port = htons(p->port);
addr.sin_family = AF_INET;
addr.sin_len = sizeof(addr);
if (addr.sin_addr.s_addr == INADDR_ANY &&
setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on,
sizeof(on)) == -1) {
syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m");
close(p->input.fd);
p->input.fd = -1;
return (SNMP_ERR_GENERR);
if (addr.sin_addr.s_addr == INADDR_ANY) {
if (setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on,
sizeof(on)) == -1) {
syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m");
close(p->input.fd);
p->input.fd = -1;
return (SNMP_ERR_GENERR);
}
p->recvdstaddr = true;
}
if (bind(p->input.fd, (struct sockaddr *)&addr, sizeof(addr))) {
if (errno == EADDRNOTAVAIL) {
@ -218,7 +221,6 @@ udp_send(struct tport *tp, const u_char *buf, size_t len,
{
struct udp_port *p = (struct udp_port *)tp;
struct cmsghdr *cmsg;
struct in_addr *src_addr;
struct msghdr msg;
char cbuf[CMSG_SPACE(sizeof(struct in_addr))];
struct iovec iov;
@ -231,15 +233,20 @@ udp_send(struct tport *tp, const u_char *buf, size_t len,
msg.msg_iovlen = 1;
msg.msg_name = __DECONST(void *, addr);
msg.msg_namelen = addrlen;
msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_SENDSRCADDR;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
src_addr = (struct in_addr *)(void*)CMSG_DATA(cmsg);
memcpy(src_addr, &p->recv_addr, sizeof(struct in_addr));
if (p->recvdstaddr) {
msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = IPPROTO_IP;
cmsg->cmsg_type = IP_SENDSRCADDR;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
memcpy(CMSG_DATA(cmsg), &p->dstaddr, sizeof(struct in_addr));
} else {
msg.msg_control = NULL;
msg.msg_controllen = 0;
}
return (sendmsg(p->input.fd, &msg, 0));
}
@ -260,11 +267,12 @@ check_priv_dgram(struct port_input *pi, struct sockcred *cred)
* Each receive should return one datagram.
*/
static ssize_t
recv_dgram(struct port_input *pi, struct in_addr *laddr)
udp_recv(struct tport *tp, struct port_input *pi)
{
u_char embuf[1000];
char cbuf[CMSG_SPACE(SOCKCREDSIZE(CMGROUP_MAX)) +
CMSG_SPACE(sizeof(struct in_addr))];
struct udp_port *p = (struct udp_port *)tp;
struct msghdr msg;
struct iovec iov[1];
ssize_t len;
@ -316,7 +324,8 @@ recv_dgram(struct port_input *pi, struct in_addr *laddr)
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level == IPPROTO_IP &&
cmsg->cmsg_type == IP_RECVDSTADDR)
memcpy(laddr, CMSG_DATA(cmsg), sizeof(struct in_addr));
memcpy(&p->dstaddr, CMSG_DATA(cmsg),
sizeof(struct in_addr));
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDS)
cred = (struct sockcred *)CMSG_DATA(cmsg);
@ -328,42 +337,6 @@ recv_dgram(struct port_input *pi, struct in_addr *laddr)
return (0);
}
/*
* Receive something
*/
static ssize_t
udp_recv(struct tport *tp, struct port_input *pi)
{
struct udp_port *p = (struct udp_port *)tp;
struct cmsghdr *cmsgp;
struct in_addr *laddr;
struct msghdr msg;
char cbuf[CMSG_SPACE(sizeof(struct in_addr))];
ssize_t ret;
memset(cbuf, 0, sizeof(cbuf));
msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);
cmsgp = CMSG_FIRSTHDR(&msg);
cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
cmsgp->cmsg_level = IPPROTO_IP;
cmsgp->cmsg_type = IP_SENDSRCADDR;
laddr = (struct in_addr *)CMSG_DATA(cmsgp);
ret = recv_dgram(pi, laddr);
memcpy(&p->recv_addr, laddr, sizeof(struct in_addr));
if (laddr->s_addr == INADDR_ANY) {
msg.msg_control = NULL;
msg.msg_controllen = 0;
}
return (ret);
}
/*
* Port table
*/

View file

@ -39,7 +39,9 @@ struct udp_port {
struct port_input input; /* common input stuff */
struct sockaddr_in ret; /* the return address */
struct in_addr recv_addr; /* the address the request was sent to */
bool recvdstaddr; /* IP_RECVDSTADDR is on */
struct in_addr dstaddr; /* address the request was sent to */
};
/* argument for open call */

View file

@ -1,3 +1,33 @@
2017-02-01 Thomas E. Dickey <dickey@invisible-island.net>
* test/btyacc/expr.oxout.error, test/btyacc/expr.oxout.output, test/btyacc/expr.oxout.tab.c, test/btyacc/expr.oxout.tab.h, test/yacc/expr.oxout.error, test/yacc/expr.oxout.output, test/yacc/expr.oxout.tab.c, test/yacc/expr.oxout.tab.h:
RCS_BASE
* package/debian/copyright: update copyright
* reader.c, defs.h, main.c:
avoid using regex.h since some low-end platforms do not have this
* test/expr.oxout.y: RCS_BASE
* configure: regen
* aclocal.m4: quiet a strict gcc warning in CF_MKSTEMP
2017-02-01 Tom.Shields
* main.c, reader.c, defs.h:
process #line directives, like bison and flex
2017-02-01 Thomas E. Dickey <dickey@invisible-island.net>
* VERSION, package/byacc.spec, package/debian/changelog, package/mingw-byacc.spec, package/pkgsrc/Makefile:
bump
2016-12-31 Thomas E. Dickey <dickey@invisible-island.net>
* config.guess, config.sub: 2017-01-01
2016-12-02 Thomas E. Dickey <dickey@invisible-island.net>
* test/btyacc/quote_calc4-s.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/ok_syntax1.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/rename_debug.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/btyacc_destroy1.tab.c, test/btyacc/btyacc_destroy2.tab.c, test/btyacc/btyacc_destroy3.tab.c, btyaccpar.c:

View file

@ -1,4 +1,4 @@
MANIFEST for byacc-20161202, version t20161202
MANIFEST for byacc-20170201, version t20170201
--------------------------------------------------------------------------------
MANIFEST this file
ACKNOWLEDGEMENTS original version of byacc - 1993
@ -77,6 +77,22 @@ test/btyacc/btyacc_demo.error reference output for testing
test/btyacc/btyacc_demo.output reference output for testing
test/btyacc/btyacc_demo.tab.c reference output for testing
test/btyacc/btyacc_demo.tab.h reference output for testing
test/btyacc/btyacc_demo2.error reference output for testing
test/btyacc/btyacc_demo2.output reference output for testing
test/btyacc/btyacc_demo2.tab.c reference output for testing
test/btyacc/btyacc_demo2.tab.h reference output for testing
test/btyacc/btyacc_destroy1.error reference output for testing
test/btyacc/btyacc_destroy1.output reference output for testing
test/btyacc/btyacc_destroy1.tab.c reference output for testing
test/btyacc/btyacc_destroy1.tab.h reference output for testing
test/btyacc/btyacc_destroy2.error reference output for testing
test/btyacc/btyacc_destroy2.output reference output for testing
test/btyacc/btyacc_destroy2.tab.c reference output for testing
test/btyacc/btyacc_destroy2.tab.h reference output for testing
test/btyacc/btyacc_destroy3.error reference output for testing
test/btyacc/btyacc_destroy3.output reference output for testing
test/btyacc/btyacc_destroy3.tab.c reference output for testing
test/btyacc/btyacc_destroy3.tab.h reference output for testing
test/btyacc/calc.error reference output for testing
test/btyacc/calc.output reference output for testing
test/btyacc/calc.tab.c reference output for testing
@ -256,6 +272,10 @@ test/btyacc/error.error reference output for testing
test/btyacc/error.output reference output for testing
test/btyacc/error.tab.c reference output for testing
test/btyacc/error.tab.h reference output for testing
test/btyacc/expr.oxout.error reference output for testing
test/btyacc/expr.oxout.output reference output for testing
test/btyacc/expr.oxout.tab.c reference output for testing
test/btyacc/expr.oxout.tab.h reference output for testing
test/btyacc/grammar.dot reference output for testing
test/btyacc/grammar.error reference output for testing
test/btyacc/grammar.output reference output for testing
@ -359,6 +379,9 @@ test/btyacc/varsyntax_calc1.tab.h reference output for testing
test subdirectory
test/btyacc_calc1.y testcase for btyacc
test/btyacc_demo.y testcase for btyacc
test/btyacc_destroy1.y btyacc test-case for %parse-param
test/btyacc_destroy2.y btyacc test-case for %parse-param
test/btyacc_destroy3.y btyacc test-case for %parse-param
test/calc.y example from VMS freeware version of byacc
test/calc1.y advanced example from Steve Johnson's paper.
test/calc2.y test-cases and reference files for %lex-param / %parse-param
@ -403,6 +426,7 @@ test/err_syntax8.y testcase for used_reserved()
test/err_syntax8a.y testcase for used_reserved()
test/err_syntax9.y testcase for tokenized_start()
test/error.y original version of byacc - 1993
test/expr.oxout.y test-case for "#line" feature
test/grammar.y grammar from cproto
test/inherit0.y testcase for btyacc
test/inherit1.y testcase for btyacc
@ -577,6 +601,10 @@ test/yacc/error.error reference output for testing
test/yacc/error.output reference output for testing
test/yacc/error.tab.c reference output for testing
test/yacc/error.tab.h reference output for testing
test/yacc/expr.oxout.error reference output for testing
test/yacc/expr.oxout.output reference output for testing
test/yacc/expr.oxout.tab.c reference output for testing
test/yacc/expr.oxout.tab.h reference output for testing
test/yacc/grammar.dot reference output for testing
test/yacc/grammar.error reference output for testing
test/yacc/grammar.output reference output for testing

View file

@ -1 +1 @@
20161202
20170201

View file

@ -1,7 +1,7 @@
dnl $Id: aclocal.m4,v 1.41 2016/12/02 13:03:06 tom Exp $
dnl $Id: aclocal.m4,v 1.42 2017/02/01 10:12:21 tom Exp $
dnl Macros for byacc configure script (Thomas E. Dickey)
dnl ---------------------------------------------------------------------------
dnl Copyright 2004-2015,2016 Thomas E. Dickey
dnl Copyright 2004-2016,2017 Thomas E. Dickey
dnl
dnl Permission is hereby granted, free of charge, to any person obtaining a
dnl copy of this software and associated documentation files (the
@ -803,20 +803,26 @@ fi
test "$cf_cv_mixedcase" = yes && AC_DEFINE(MIXEDCASE_FILENAMES,1,[Define to 1 if filesystem supports mixed-case filenames.])
])dnl
dnl ---------------------------------------------------------------------------
dnl CF_MKSTEMP version: 9 updated: 2012/10/03 04:34:49
dnl CF_MKSTEMP version: 10 updated: 2017/01/21 11:12:16
dnl ----------
dnl Check for a working mkstemp. This creates two files, checks that they are
dnl successfully created and distinct (AmigaOS apparently fails on the last).
AC_DEFUN([CF_MKSTEMP],[
AC_CHECK_HEADERS( \
unistd.h \
)
AC_CACHE_CHECK(for working mkstemp, cf_cv_func_mkstemp,[
rm -rf conftest*
AC_TRY_RUN([
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
int main()
int main(void)
{
char *tmpl = "conftestXXXXXX";
char name[2][80];

View file

@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright 1992-2016 Free Software Foundation, Inc.
# Copyright 1992-2017 Free Software Foundation, Inc.
timestamp='2016-10-02'
timestamp='2017-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright 1992-2016 Free Software Foundation, Inc.
Copyright 1992-2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."

View file

@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2016 Free Software Foundation, Inc.
# Copyright 1992-2017 Free Software Foundation, Inc.
timestamp='2016-11-19'
timestamp='2017-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2016 Free Software Foundation, Inc.
Copyright 1992-2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -1409,7 +1409,7 @@ case $os in
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
| -onefs* | -tirtos* | -phoenix* | -fuchsia*)
| -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@ -1638,6 +1638,9 @@ case $basic_machine in
sparc-* | *-sun)
os=-sunos4.1.1
;;
pru-*)
os=-elf
;;
*-be)
os=-beos
;;

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
/* $Id: defs.h,v 1.54 2016/12/02 19:27:56 tom Exp $ */
/* $Id: defs.h,v 1.56 2017/02/02 00:44:38 tom Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
@ -313,6 +313,7 @@ extern const char *const trailer[];
extern char *code_file_name;
extern char *input_file_name;
extern size_t input_file_name_len;
extern char *defines_file_name;
extern char *externs_file_name;

View file

@ -1,4 +1,4 @@
/* $Id: main.c,v 1.57 2016/12/02 18:44:44 tom Exp $ */
/* $Id: main.c,v 1.59 2017/02/02 00:44:38 tom Exp $ */
#include <signal.h>
#ifndef _WIN32
@ -48,13 +48,13 @@ const char *myname = "yacc";
int lineno;
int outline;
static char empty_string[] = "";
static char default_file_prefix[] = "y";
static char *file_prefix = default_file_prefix;
char *code_file_name;
char *input_file_name = empty_string;
char *input_file_name;
size_t input_file_name_len = 0;
char *defines_file_name;
char *externs_file_name;
@ -381,7 +381,10 @@ getargs(int argc, char *argv[])
no_more_options:;
if (i + 1 != argc)
usage();
input_file_name = argv[i];
input_file_name_len = strlen(argv[i]);
input_file_name = TMALLOC(char, input_file_name_len + 1);
NO_SPACE(input_file_name);
strcpy(input_file_name, argv[i]);
}
void *

View file

@ -1,8 +1,8 @@
Summary: byacc - public domain Berkeley LALR Yacc parser generator
%define AppProgram byacc
%define AppVersion 20161202
%define AppVersion 20170201
%define UseProgram yacc
# $XTermId: byacc.spec,v 1.32 2016/12/02 12:58:46 tom Exp $
# $XTermId: byacc.spec,v 1.33 2017/02/01 09:55:04 tom Exp $
Name: %{AppProgram}
Version: %{AppVersion}
Release: 1

View file

@ -1,3 +1,9 @@
byacc (20170201) unstable; urgency=low
* maintenance updates
-- Thomas E. Dickey <dickey@invisible-island.net> Wed, 01 Feb 2017 04:55:04 -0500
byacc (20161202) unstable; urgency=low
* maintenance updates

View file

@ -36,7 +36,7 @@ skeleton.c with the bug report. Do not expect rapid responses.
Files: aclocal.m4
Licence: other-BSD
Copyright: 2004-2015,2016 by Thomas E. Dickey
Copyright: 2004-2016,2017 by Thomas E. Dickey
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including

View file

@ -1,8 +1,8 @@
Summary: byacc - public domain Berkeley LALR Yacc parser generator
%define AppProgram byacc
%define AppVersion 20161202
%define AppVersion 20170201
%define UseProgram yacc
# $XTermId: mingw-byacc.spec,v 1.14 2016/12/02 12:58:46 tom Exp $
# $XTermId: mingw-byacc.spec,v 1.15 2017/02/01 09:55:04 tom Exp $
Name: %{AppProgram}
Version: %{AppVersion}
Release: 1

View file

@ -1,7 +1,7 @@
# $NetBSD: Makefile,v 1.9 2008/07/24 17:13:00 tonnerre Exp $
#
DISTNAME= byacc-20161202
DISTNAME= byacc-20170201
PKGREVISION= 1
CATEGORIES= devel
MASTER_SITES= ftp://invisible-island.net/byacc/

View file

@ -1,4 +1,4 @@
/* $Id: reader.c,v 1.66 2016/12/02 20:14:34 tom Exp $ */
/* $Id: reader.c,v 1.68 2017/02/02 01:05:36 tom Exp $ */
#include "defs.h"
@ -108,6 +108,134 @@ cachec(int c)
++cinc;
}
typedef enum
{
ldSPC1,
ldSPC2,
ldNAME,
ldSPC3,
ldNUM,
ldSPC4,
ldFILE,
ldOK,
ldERR
}
LINE_DIR;
/*
* Expect this pattern:
* /^[[:space:]]*#[[:space:]]*
* line[[:space:]]+
* [[:digit:]]+
* ([[:space:]]*|[[:space:]]+"[^"]+")/
*/
static int
line_directive(void)
{
#define UNLESS(what) if (what) { ld = ldERR; break; }
int n;
int line_1st = -1;
int name_1st = -1;
int name_end = -1;
LINE_DIR ld = ldSPC1;
for (n = 0; (ld <= ldOK) && (line[n] != '\0'); ++n)
{
int ch = UCH(line[n]);
switch (ld)
{
case ldSPC1:
if (isspace(ch))
{
break;
}
else
UNLESS(ch != '#');
ld = ldSPC2;
break;
case ldSPC2:
if (isspace(ch))
{
break;
}
/* FALLTHRU */
case ldNAME:
UNLESS(strncmp(line + n, "line", 4));
n += 4;
if (line[n] == '\0')
{
ld = ldOK;
break;
}
else
UNLESS(!isspace(UCH(line[n])));
ld = ldSPC3;
break;
case ldSPC3:
if (isspace(ch))
{
break;
}
else
UNLESS(!isdigit(ch));
line_1st = n;
ld = ldNUM;
/* FALLTHRU */
case ldNUM:
if (isdigit(ch))
{
break;
}
else
UNLESS(!isspace(ch));
ld = ldSPC4;
break;
case ldSPC4:
if (isspace(ch))
{
break;
}
else
UNLESS(ch != '"');
UNLESS(line[n + 1] == '"');
ld = ldFILE;
name_1st = n;
break;
case ldFILE:
if (ch != '"')
{
break;
}
ld = ldOK;
name_end = n;
/* FALLTHRU */
case ldERR:
case ldOK:
break;
}
}
if (ld == ldOK)
{
size_t need = (size_t) (name_end - name_1st);
if (need > input_file_name_len)
{
input_file_name_len = need;
input_file_name = TREALLOC(char, input_file_name, need + 1);
NO_SPACE(input_file_name);
}
memcpy(input_file_name, line + name_1st + 1, need - 1);
input_file_name[need - 1] = '\0';
}
if (ld >= ldNUM && ld < ldERR)
{
lineno = (int)strtol(line + line_1st, NULL, 10) - 1;
}
return (ld == ldOK);
#undef UNLESS
}
static void
get_line(void)
{
@ -115,49 +243,53 @@ get_line(void)
int c;
int i;
if (saw_eof || (c = getc(f)) == EOF)
do
{
if (line)
if (saw_eof || (c = getc(f)) == EOF)
{
FREE(line);
line = 0;
if (line)
{
FREE(line);
line = 0;
}
cptr = 0;
saw_eof = 1;
return;
}
cptr = 0;
saw_eof = 1;
return;
}
if (line == NULL || linesize != (LINESIZE + 1))
{
if (line)
FREE(line);
linesize = LINESIZE + 1;
line = TMALLOC(char, linesize);
NO_SPACE(line);
}
i = 0;
++lineno;
for (;;)
{
line[i++] = (char)c;
if (c == '\n')
break;
if ((i + 3) >= linesize)
if (line == NULL || linesize != (LINESIZE + 1))
{
linesize += LINESIZE;
line = TREALLOC(char, line, linesize);
if (line)
FREE(line);
linesize = LINESIZE + 1;
line = TMALLOC(char, linesize);
NO_SPACE(line);
}
c = getc(f);
if (c == EOF)
i = 0;
++lineno;
for (;;)
{
line[i++] = '\n';
saw_eof = 1;
break;
line[i++] = (char)c;
if (c == '\n')
break;
if ((i + 3) >= linesize)
{
linesize += LINESIZE;
line = TREALLOC(char, line, linesize);
NO_SPACE(line);
}
c = getc(f);
if (c == EOF)
{
line[i++] = '\n';
saw_eof = 1;
break;
}
}
line[i] = '\0';
}
line[i] = '\0';
while (line_directive());
cptr = line;
return;
}

View file

@ -0,0 +1 @@
YACC: w - line 6 of "expr.Y", the precedence of '*' has been redeclared

View file

@ -0,0 +1,227 @@
0 $accept : yyyAugNonterm $end
1 $$1 :
2 yyyAugNonterm : $$1 s
3 s : expr
4 expr : expr '*' expr
5 | expr '+' expr
6 | expr '/' expr
7 | expr '-' expr
8 | '(' expr ')'
9 | ID
10 | CONST
state 0
$accept : . yyyAugNonterm $end (0)
$$1 : . (1)
. reduce 1
yyyAugNonterm goto 1
$$1 goto 2
state 1
$accept : yyyAugNonterm . $end (0)
$end accept
state 2
yyyAugNonterm : $$1 . s (2)
ID shift 3
CONST shift 4
'(' shift 5
. error
s goto 6
expr goto 7
state 3
expr : ID . (9)
. reduce 9
state 4
expr : CONST . (10)
. reduce 10
state 5
expr : '(' . expr ')' (8)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 8
state 6
yyyAugNonterm : $$1 s . (2)
. reduce 2
state 7
s : expr . (3)
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
'+' shift 9
'-' shift 10
'*' shift 11
'/' shift 12
$end reduce 3
state 8
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
expr : '(' expr . ')' (8)
'+' shift 9
'-' shift 10
'*' shift 11
'/' shift 12
')' shift 13
. error
state 9
expr : expr '+' . expr (5)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 14
state 10
expr : expr '-' . expr (7)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 15
state 11
expr : expr '*' . expr (4)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 16
state 12
expr : expr '/' . expr (6)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 17
state 13
expr : '(' expr ')' . (8)
. reduce 8
state 14
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr '+' expr . (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
'*' shift 11
'/' shift 12
$end reduce 5
'+' reduce 5
'-' reduce 5
')' reduce 5
state 15
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
expr : expr '-' expr . (7)
'*' shift 11
'/' shift 12
$end reduce 7
'+' reduce 7
'-' reduce 7
')' reduce 7
state 16
expr : expr . '*' expr (4)
expr : expr '*' expr . (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
. reduce 4
state 17
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr '/' expr . (6)
expr : expr . '-' expr (7)
'*' shift 11
$end reduce 6
'+' reduce 6
'-' reduce 6
'/' reduce 6
')' reduce 6
10 terminals, 5 nonterminals
11 grammar rules, 18 states
grammar parser grammar
symbol# value# symbol
0 0 $end
1 256 error
2 257 ID
3 258 CONST
4 43 '+'
5 45 '-'
6 42 '*'
7 47 '/'
8 40 '('
9 41 ')'
10 259 $accept
11 260 yyyAugNonterm
12 261 s
13 262 $$1
14 263 expr

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
#ifndef _expr.oxout__defines_h_
#define _expr.oxout__defines_h_
#define ID 257
#define CONST 258
#ifdef YYSTYPE
#undef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
#endif
#ifndef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
typedef union {
struct yyyOxAttrbs {
struct yyyStackItem *yyyOxStackItem;
} yyyOxAttrbs;
} YYSTYPE;
#endif /* !YYSTYPE_IS_DECLARED */
extern YYSTYPE expr.oxout_lval;
#endif /* _expr.oxout__defines_h_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
YACC: w - line 6 of "expr.Y", the precedence of '*' has been redeclared

View file

@ -0,0 +1,209 @@
0 $accept : yyyAugNonterm $end
1 $$1 :
2 yyyAugNonterm : $$1 s
3 s : expr
4 expr : expr '*' expr
5 | expr '+' expr
6 | expr '/' expr
7 | expr '-' expr
8 | '(' expr ')'
9 | ID
10 | CONST
state 0
$accept : . yyyAugNonterm $end (0)
$$1 : . (1)
. reduce 1
yyyAugNonterm goto 1
$$1 goto 2
state 1
$accept : yyyAugNonterm . $end (0)
$end accept
state 2
yyyAugNonterm : $$1 . s (2)
ID shift 3
CONST shift 4
'(' shift 5
. error
s goto 6
expr goto 7
state 3
expr : ID . (9)
. reduce 9
state 4
expr : CONST . (10)
. reduce 10
state 5
expr : '(' . expr ')' (8)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 8
state 6
yyyAugNonterm : $$1 s . (2)
. reduce 2
state 7
s : expr . (3)
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
'+' shift 9
'-' shift 10
'*' shift 11
'/' shift 12
$end reduce 3
state 8
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
expr : '(' expr . ')' (8)
'+' shift 9
'-' shift 10
'*' shift 11
'/' shift 12
')' shift 13
. error
state 9
expr : expr '+' . expr (5)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 14
state 10
expr : expr '-' . expr (7)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 15
state 11
expr : expr '*' . expr (4)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 16
state 12
expr : expr '/' . expr (6)
ID shift 3
CONST shift 4
'(' shift 5
. error
expr goto 17
state 13
expr : '(' expr ')' . (8)
. reduce 8
state 14
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr '+' expr . (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
'*' shift 11
'/' shift 12
$end reduce 5
'+' reduce 5
'-' reduce 5
')' reduce 5
state 15
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
expr : expr '-' expr . (7)
'*' shift 11
'/' shift 12
$end reduce 7
'+' reduce 7
'-' reduce 7
')' reduce 7
state 16
expr : expr . '*' expr (4)
expr : expr '*' expr . (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr . '-' expr (7)
. reduce 4
state 17
expr : expr . '*' expr (4)
expr : expr . '+' expr (5)
expr : expr . '/' expr (6)
expr : expr '/' expr . (6)
expr : expr . '-' expr (7)
'*' shift 11
$end reduce 6
'+' reduce 6
'-' reduce 6
'/' reduce 6
')' reduce 6
10 terminals, 5 nonterminals
11 grammar rules, 18 states

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
#define ID 257
#define CONST 258
#ifdef YYSTYPE
#undef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
#endif
#ifndef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
typedef union {
struct yyyOxAttrbs {
struct yyyStackItem *yyyOxStackItem;
} yyyOxAttrbs;
} YYSTYPE;
#endif /* !YYSTYPE_IS_DECLARED */
extern YYSTYPE expr.oxout_lval;

View file

@ -50,12 +50,14 @@ INTERCEPTOR(void, free, void *ptr) {
asan_free(ptr, &stack, FROM_MALLOC);
}
#if SANITIZER_INTERCEPT_CFREE
INTERCEPTOR(void, cfree, void *ptr) {
GET_STACK_TRACE_FREE;
if (UNLIKELY(IsInDlsymAllocPool(ptr)))
return;
asan_free(ptr, &stack, FROM_MALLOC);
}
#endif // SANITIZER_INTERCEPT_CFREE
INTERCEPTOR(void*, malloc, uptr size) {
if (UNLIKELY(!asan_inited))
@ -85,22 +87,24 @@ INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
return asan_realloc(ptr, size, &stack);
}
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
GET_STACK_TRACE_MALLOC;
return asan_memalign(boundary, size, &stack, FROM_MALLOC);
}
INTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) {
GET_STACK_TRACE_MALLOC;
return asan_memalign(boundary, size, &stack, FROM_MALLOC);
}
INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) {
GET_STACK_TRACE_MALLOC;
void *res = asan_memalign(boundary, size, &stack, FROM_MALLOC);
DTLS_on_libc_memalign(res, size);
return res;
}
#endif // SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) {
GET_STACK_TRACE_MALLOC;
return asan_memalign(boundary, size, &stack, FROM_MALLOC);
}
INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
GET_CURRENT_PC_BP_SP;
@ -108,6 +112,7 @@ INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
return asan_malloc_usable_size(ptr, pc, bp);
}
#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
// We avoid including malloc.h for portability reasons.
// man mallinfo says the fields are "long", but the implementation uses int.
// It doesn't matter much -- we just need to make sure that the libc's mallinfo
@ -125,6 +130,7 @@ INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
INTERCEPTOR(int, mallopt, int cmd, int value) {
return -1;
}
#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
GET_STACK_TRACE_MALLOC;
@ -137,10 +143,12 @@ INTERCEPTOR(void*, valloc, uptr size) {
return asan_valloc(size, &stack);
}
#if SANITIZER_INTERCEPT_PVALLOC
INTERCEPTOR(void*, pvalloc, uptr size) {
GET_STACK_TRACE_MALLOC;
return asan_pvalloc(size, &stack);
}
#endif // SANITIZER_INTERCEPT_PVALLOC
INTERCEPTOR(void, malloc_stats, void) {
__asan_print_accumulated_stats();

View file

@ -55,11 +55,6 @@ void _free_base(void *ptr) {
free(ptr);
}
ALLOCATION_FUNCTION_ATTRIBUTE
void cfree(void *ptr) {
CHECK(!"cfree() should not be used on Windows");
}
ALLOCATION_FUNCTION_ATTRIBUTE
void *malloc(size_t size) {
GET_STACK_TRACE_MALLOC;

View file

@ -19,6 +19,7 @@
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_linux.h"
#include "sanitizer_common/sanitizer_platform_interceptors.h"
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
#include "sanitizer_common/sanitizer_tls_get_addr.h"
#include "lsan.h"
@ -86,11 +87,26 @@ INTERCEPTOR(void*, realloc, void *q, uptr size) {
return Reallocate(stack, q, size, 1);
}
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void*, memalign, uptr alignment, uptr size) {
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
return Allocate(stack, size, alignment, kAlwaysClearMemory);
}
#define LSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
void *res = Allocate(stack, size, alignment, kAlwaysClearMemory);
DTLS_on_libc_memalign(res, size);
return res;
}
#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign)
#else
#define LSAN_MAYBE_INTERCEPT_MEMALIGN
#define LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN
#endif // SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) {
ENSURE_LSAN_INITED;
@ -106,14 +122,6 @@ INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
return 0;
}
INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) {
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
void *res = Allocate(stack, size, alignment, kAlwaysClearMemory);
DTLS_on_libc_memalign(res, size);
return res;
}
INTERCEPTOR(void*, valloc, uptr size) {
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
@ -127,6 +135,7 @@ INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
return GetMallocUsableSize(ptr);
}
#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
struct fake_mallinfo {
int x[10];
};
@ -136,11 +145,18 @@ INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
internal_memset(&res, 0, sizeof(res));
return res;
}
#define LSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
INTERCEPTOR(int, mallopt, int cmd, int value) {
return -1;
}
#define LSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
#else
#define LSAN_MAYBE_INTERCEPT_MALLINFO
#define LSAN_MAYBE_INTERCEPT_MALLOPT
#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
#if SANITIZER_INTERCEPT_PVALLOC
INTERCEPTOR(void*, pvalloc, uptr size) {
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
@ -152,8 +168,17 @@ INTERCEPTOR(void*, pvalloc, uptr size) {
}
return Allocate(stack, size, GetPageSizeCached(), kAlwaysClearMemory);
}
#define LSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
#else
#define LSAN_MAYBE_INTERCEPT_PVALLOC
#endif // SANITIZER_INTERCEPT_PVALLOC
#if SANITIZER_INTERCEPT_CFREE
INTERCEPTOR(void, cfree, void *p) ALIAS(WRAPPER_NAME(free));
#define LSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)
#else
#define LSAN_MAYBE_INTERCEPT_CFREE
#endif // SANITIZER_INTERCEPT_CFREE
#define OPERATOR_NEW_BODY \
ENSURE_LSAN_INITED; \
@ -277,17 +302,18 @@ namespace __lsan {
void InitializeInterceptors() {
INTERCEPT_FUNCTION(malloc);
INTERCEPT_FUNCTION(free);
INTERCEPT_FUNCTION(cfree);
LSAN_MAYBE_INTERCEPT_CFREE;
INTERCEPT_FUNCTION(calloc);
INTERCEPT_FUNCTION(realloc);
INTERCEPT_FUNCTION(memalign);
LSAN_MAYBE_INTERCEPT_MEMALIGN;
LSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN;
INTERCEPT_FUNCTION(aligned_alloc);
INTERCEPT_FUNCTION(posix_memalign);
INTERCEPT_FUNCTION(__libc_memalign);
INTERCEPT_FUNCTION(valloc);
INTERCEPT_FUNCTION(pvalloc);
LSAN_MAYBE_INTERCEPT_PVALLOC;
INTERCEPT_FUNCTION(malloc_usable_size);
INTERCEPT_FUNCTION(mallinfo);
INTERCEPT_FUNCTION(mallopt);
LSAN_MAYBE_INTERCEPT_MALLINFO;
LSAN_MAYBE_INTERCEPT_MALLOPT;
INTERCEPT_FUNCTION(pthread_create);
INTERCEPT_FUNCTION(pthread_join);

View file

@ -318,4 +318,10 @@
#define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT___LXSTAT SANITIZER_INTERCEPT___XSTAT
#define SANITIZER_INTERCEPT___LXSTAT64 SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO (!SI_FREEBSD && !SI_MAC)
#define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC)
#define SANITIZER_INTERCEPT_PVALLOC (!SI_FREEBSD && !SI_MAC)
#define SANITIZER_INTERCEPT_CFREE (!SI_FREEBSD && !SI_MAC)
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

View file

@ -189,7 +189,7 @@ main(int argc, char **argv)
if (!min_len)
min_len = 4;
if (!*argv)
rc = handle_file("{standard input}");
rc = find_strings("{standard input}", 0, 0);
else while (*argv) {
if (handle_file(*argv) != 0)
rc = 1;
@ -205,13 +205,9 @@ handle_file(const char *name)
if (name == NULL)
return (1);
if (strcmp("{standard input}", name) != 0) {
if (freopen(name, "rb", stdin) == NULL) {
warnx("'%s': %s", name, strerror(errno));
return (1);
}
} else {
return (find_strings(name, (off_t)0, (off_t)0));
if (freopen(name, "rb", stdin) == NULL) {
warnx("'%s': %s", name, strerror(errno));
return (1);
}
fd = fileno(stdin);

View file

@ -765,6 +765,7 @@ const struct mips_cpu_info mips_cpu_info_table[] = {
/* MIPS64R2 */
{ "octeon", PROCESSOR_OCTEON, 65 },
{ "octeon+", PROCESSOR_OCTEON, 65 },
/* End marker */
{ 0, 0, 0 }

View file

@ -285,7 +285,10 @@ extern const struct mips_rtx_cost_data *mips_cost;
\
macro = concat ((PREFIX), "_", (INFO)->name, NULL); \
for (p = macro; *p != 0; p++) \
*p = TOUPPER (*p); \
if (*p == '+') \
*p = 'P'; \
else \
*p = TOUPPER (*p); \
\
builtin_define (macro); \
builtin_define_with_value ((PREFIX), (INFO)->name, 1); \

View file

@ -56,6 +56,27 @@ void eMrwlock_write_enter(rw, file, line)
}
void eMrwlock_try_upgrade(rw, file, line)
eMrwlock_t *rw;
char *file;
int line;
{
if (rw->eMrw_magic != EMM_MAGIC) {
fprintf(stderr, "%s:eMrwlock_write_enter(%p): bad magic: %#x\n",
rw->eMrw_owner, rw, rw->eMrw_magic);
abort();
}
if (rw->eMrw_read != 0 || rw->eMrw_write != 0) {
fprintf(stderr,
"%s:eMrwlock_try_upgrade(%p): already locked: %d/%d\n",
rw->eMrw_owner, rw, rw->eMrw_read, rw->eMrw_write);
abort();
}
rw->eMrw_write++;
rw->eMrw_heldin = file;
rw->eMrw_heldat = line;
}
void eMrwlock_downgrade(rw, file, line)
eMrwlock_t *rw;
char *file;

View file

@ -408,14 +408,16 @@ static void flushfilter(arg, filter)
}
closedevice();
return;
}
if (strchr(arg, 'i') || strchr(arg, 'I'))
} else if (strchr(arg, 'i') || strchr(arg, 'I'))
fl = FR_INQUE;
if (strchr(arg, 'o') || strchr(arg, 'O'))
else if (strchr(arg, 'o') || strchr(arg, 'O'))
fl = FR_OUTQUE;
if (strchr(arg, 'a') || strchr(arg, 'A'))
else if (strchr(arg, 'a') || strchr(arg, 'A'))
fl = FR_OUTQUE|FR_INQUE;
else {
fprintf(stderr, "Incorrect flush argument: %s\n", arg);
usage();
}
if (opts & OPT_INACTIVE)
fl |= FR_INACTIVE;
rem = fl;

View file

@ -1,3 +1,7 @@
Jan 29, 2017: Limited NFSv4 ACL support for Mac OS (Darwin)
Jan 10, 2017: POSIX.1e and NFSv4 ACL support for Solaris and derivates
Dec 27, 2016: NFSv4 ACL read and write support for pax
Deprecated functions: archive_entry_acl_text(), archive_entry_acl_text_w()

View file

@ -348,6 +348,15 @@ archive_acl_count(struct archive_acl *acl, int want_type)
return (count);
}
/*
* Return a bitmask of stored ACL types in an ACL list
*/
int
archive_acl_types(struct archive_acl *acl)
{
return (acl->acl_types);
}
/*
* Prepare for reading entries from the ACL data. Returns a count
* of entries matching "want_type", or zero if there are no
@ -1144,7 +1153,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
const wchar_t *s, *st;
int numfields, fields, n, r, ret;
int numfields, fields, n, r, sol, ret;
int type, types, tag, permset, id;
size_t len;
wchar_t sep;
@ -1192,6 +1201,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
}
n = 0;
sol = 0;
id = -1;
permset = 0;
name.start = name.end = NULL;
@ -1263,6 +1273,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
&& ismode_w(field[n + 1].start,
field[n + 1].end, &permset)) {
/* This is Solaris-style "other:rwx" */
sol = 1;
} else if (fields == (n + 3) &&
field[n + 1].start < field[n + 1].end) {
/* Invalid mask or other field */
@ -1287,9 +1298,12 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
continue;
}
/* Without "default:" we expect mode in field 2 */
if (permset == 0 && !ismode_w(field[n + 2].start,
field[n + 2].end, &permset)) {
/*
* Without "default:" we expect mode in field 2
* Exception: Solaris other and mask fields
*/
if (permset == 0 && !ismode_w(field[n + 2 - sol].start,
field[n + 2 - sol].end, &permset)) {
/* Invalid mode, skip entry */
ret = ARCHIVE_WARN;
continue;
@ -1615,7 +1629,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
} field[6], name;
const char *s, *st;
int numfields, fields, n, r, ret;
int numfields, fields, n, r, sol, ret;
int type, types, tag, permset, id;
size_t len;
char sep;
@ -1663,6 +1677,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
}
n = 0;
sol = 0;
id = -1;
permset = 0;
name.start = name.end = NULL;
@ -1734,6 +1749,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
&& ismode(field[n + 1].start,
field[n + 1].end, &permset)) {
/* This is Solaris-style "other:rwx" */
sol = 1;
} else if (fields == (n + 3) &&
field[n + 1].start < field[n + 1].end) {
/* Invalid mask or other field */
@ -1758,9 +1774,12 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
continue;
}
/* Without "default:" we expect mode in field 2 */
if (permset == 0 && !ismode(field[n + 2].start,
field[n + 2].end, &permset)) {
/*
* Without "default:" we expect mode in field 3
* Exception: Solaris other and mask fields
*/
if (permset == 0 && !ismode(field[n + 2 - sol].start,
field[n + 2 - sol].end, &permset)) {
/* Invalid mode, skip entry */
ret = ARCHIVE_WARN;
continue;

View file

@ -56,6 +56,7 @@ struct archive_acl {
void archive_acl_clear(struct archive_acl *);
void archive_acl_copy(struct archive_acl *, struct archive_acl *);
int archive_acl_count(struct archive_acl *, int);
int archive_acl_types(struct archive_acl *);
int archive_acl_reset(struct archive_acl *, int);
int archive_acl_next(struct archive *, struct archive_acl *, int,
int *, int *, int *, int *, const char **);

View file

@ -1447,7 +1447,7 @@ archive_entry_acl_add_entry_w(struct archive_entry *entry,
int
archive_entry_acl_types(struct archive_entry *entry)
{
return ((&entry->acl)->acl_types);
return (archive_acl_types(&entry->acl));
}
/*

View file

@ -80,7 +80,7 @@ archive_entry_strmode(struct archive_entry *entry)
if (mode & 0001) bp[9] = 't';
else bp[9] = 'T';
}
if (archive_entry_acl_count(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS))
if (archive_entry_acl_types(entry) != 0)
bp[10] = '+';
return (bp);

View file

@ -147,8 +147,25 @@
* acl_set_file(), and ACL_USER, we assume it has the rest of the
* POSIX.1e draft functions used in archive_read_extract.c.
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE && HAVE_ACL_USER
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
#if HAVE_ACL_USER
#define HAVE_POSIX_ACL 1
#elif HAVE_ACL_TYPE_EXTENDED
#define HAVE_DARWIN_ACL 1
#endif
#endif
/*
* If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
#define HAVE_SUN_ACL 1
#endif
/* Define if platform supports NFSv4 ACLs */
#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
#define HAVE_NFS4_ACL 1
#endif
/*

View file

@ -80,7 +80,7 @@ archive_random(void *buf, size_t nbytes)
success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
CRYPT_VERIFYCONTEXT);
if (!success && GetLastError() == NTE_BAD_KEYSET) {
if (!success && GetLastError() == (DWORD)NTE_BAD_KEYSET) {
success = CryptAcquireContext(&hProv, NULL, NULL,
PROV_RSA_FULL, CRYPT_NEWKEYSET);
}

View file

@ -38,6 +38,11 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_ACL_H
#include <sys/acl.h>
#endif
#ifdef HAVE_DARWIN_ACL
#include <membership.h>
#include <grp.h>
#include <pwd.h>
#endif
#ifdef HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif
@ -118,6 +123,15 @@ __FBSDID("$FreeBSD$");
#define ACL_GET_PERM acl_get_perm_np
#endif
/* NFSv4 platform ACL type */
#if HAVE_SUN_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
#elif HAVE_DARWIN_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
#elif HAVE_ACL_TYPE_NFS4
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
#endif
static int setup_acls(struct archive_read_disk *,
struct archive_entry *, int *fd);
static int setup_mac_metadata(struct archive_read_disk *,
@ -405,17 +419,38 @@ setup_mac_metadata(struct archive_read_disk *a,
}
#endif
#if HAVE_DARWIN_ACL
static int translate_guid(struct archive *, acl_entry_t,
int *, int *, const char **);
#ifdef HAVE_POSIX_ACL
static void add_trivial_nfs4_acl(struct archive_entry *);
#endif
#if HAVE_SUN_ACL
static int
sun_acl_is_trivial(acl_t *, mode_t, int *trivialp);
#endif
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
static int translate_acl(struct archive_read_disk *a,
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
struct archive_entry *entry,
#if HAVE_SUN_ACL
acl_t *acl,
#else
acl_t acl,
#endif
int archive_entry_acl_type);
static int
setup_acls(struct archive_read_disk *a,
struct archive_entry *entry, int *fd)
{
const char *accpath;
acl_t acl;
#if HAVE_SUN_ACL
acl_t *acl;
#else
acl_t acl;
#endif
int r;
accpath = archive_entry_sourcepath(entry);
@ -440,17 +475,20 @@ setup_acls(struct archive_read_disk *a,
acl = NULL;
#ifdef ACL_TYPE_NFS4
#if HAVE_NFS4_ACL
/* Try NFSv4 ACL first. */
if (*fd >= 0)
#if HAVE_ACL_GET_FD_NP
acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
#if HAVE_SUN_ACL
/* Solaris reads both POSIX.1e and NFSv4 ACL here */
facl_get(*fd, 0, &acl);
#elif HAVE_ACL_GET_FD_NP
acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
#else
acl = acl_get_fd(*fd);
#endif
#if HAVE_ACL_GET_LINK_NP
else if (!a->follow_symlinks)
acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
#else
else if ((!a->follow_symlinks)
&& (archive_entry_filetype(entry) == AE_IFLNK))
@ -459,12 +497,24 @@ setup_acls(struct archive_read_disk *a,
acl = NULL;
#endif
else
acl = acl_get_file(accpath, ACL_TYPE_NFS4);
#if HAVE_SUN_ACL
/* Solaris reads both POSIX.1e and NFSv4 ACLs here */
acl_get(accpath, 0, &acl);
#else
acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
#endif
#if HAVE_ACL_IS_TRIVIAL_NP
if (acl != NULL && acl_is_trivial_np(acl, &r) == 0) {
/* Ignore "trivial" ACLs that just mirror the file mode. */
if (r) {
#if HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL
/* Ignore "trivial" ACLs that just mirror the file mode. */
if (acl != NULL) {
#if HAVE_SUN_ACL
if (sun_acl_is_trivial(acl, archive_entry_mode(entry),
&r) == 0 && r == 1)
#elif HAVE_ACL_IS_TRIVIAL_NP
if (acl_is_trivial_np(acl, &r) == 0 && r == 1)
#endif
{
acl_free(acl);
acl = NULL;
/*
@ -474,17 +524,35 @@ setup_acls(struct archive_read_disk *a,
return (ARCHIVE_OK);
}
}
#endif
#endif /* HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL */
if (acl != NULL) {
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
acl_free(acl);
if (r != ARCHIVE_OK) {
archive_set_error(&a->archive, errno,
#if HAVE_SUN_ACL
"Couldn't translate ACLs: %s", accpath);
#else
"Couldn't translate NFSv4 ACLs: %s", accpath);
#endif
}
#if HAVE_DARWIN_ACL
/*
* Because Mac OS doesn't support owner@, group@ and everyone@
* ACLs we need to add NFSv4 ACLs mirroring the file mode to
* the archive entry. Otherwise extraction on non-Mac platforms
* would lead to an invalid file mode.
*/
if (archive_entry_acl_count(entry,
ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0)
add_trivial_nfs4_acl(entry);
#endif
return (r);
}
#endif /* ACL_TYPE_NFS4 */
#endif /* HAVE_NFS4_ACL */
#if HAVE_POSIX_ACL
/* This code path is skipped on MacOS and Solaris */
/* Retrieve access ACL from file. */
if (*fd >= 0)
@ -513,8 +581,7 @@ setup_acls(struct archive_read_disk *a,
#endif
if (acl != NULL) {
r = translate_acl(a, entry, acl,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
acl_free(acl);
acl = NULL;
if (r != ARCHIVE_OK) {
@ -544,71 +611,560 @@ setup_acls(struct archive_read_disk *a,
}
}
}
#endif /* HAVE_POSIX_ACL */
return (ARCHIVE_OK);
}
/*
* Translate system ACL into libarchive internal structure.
* Translate system ACL permissions into libarchive internal structure
*/
static struct {
int archive_perm;
int platform_perm;
int archive_perm;
int platform_perm;
} acl_perm_map[] = {
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
#ifdef ACL_TYPE_NFS4
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
{ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
#else /* POSIX.1e ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
#endif
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
};
#ifdef ACL_TYPE_NFS4
#if HAVE_NFS4_ACL
/*
* Translate system NFSv4 inheritance flags into libarchive internal structure
*/
static struct {
int archive_inherit;
int platform_inherit;
int archive_inherit;
int platform_inherit;
} acl_inherit_map[] = {
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
#if HAVE_SUN_ACL /* Solaris ACL inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
#else /* FreeBSD NFSv4 ACL inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
};
#endif
#endif /* HAVE_NFS4_ACL */
#if HAVE_DARWIN_ACL
static int translate_guid(struct archive *a, acl_entry_t acl_entry,
int *ae_id, int *ae_tag, const char **ae_name)
{
void *q;
uid_t ugid;
int r, idtype;
struct passwd *pwd;
struct group *grp;
q = acl_get_qualifier(acl_entry);
if (q == NULL)
return (1);
r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
if (r != 0) {
acl_free(q);
return (1);
}
if (idtype == ID_TYPE_UID) {
*ae_tag = ARCHIVE_ENTRY_ACL_USER;
pwd = getpwuuid(q);
if (pwd == NULL) {
*ae_id = ugid;
*ae_name = NULL;
} else {
*ae_id = pwd->pw_uid;
*ae_name = archive_read_disk_uname(a, *ae_id);
}
} else if (idtype == ID_TYPE_GID) {
*ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
grp = getgruuid(q);
if (grp == NULL) {
*ae_id = ugid;
*ae_name = NULL;
} else {
*ae_id = grp->gr_gid;
*ae_name = archive_read_disk_gname(a, *ae_id);
}
} else
r = 1;
acl_free(q);
return (r);
}
/*
* Add trivial NFSv4 ACL entries from mode
*/
static void
add_trivial_nfs4_acl(struct archive_entry *entry)
{
mode_t mode;
int i;
const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA;
const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE;
const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_WRITE_ACL |
ARCHIVE_ENTRY_ACL_WRITE_OWNER;
struct {
const int type;
const int tag;
int permset;
} tacl_entry[] = {
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
{ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
{ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0},
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset},
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset},
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset}
};
mode = archive_entry_mode(entry);
/* Permissions for everyone@ */
if (mode & 0004)
tacl_entry[5].permset |= rperm;
if (mode & 0002)
tacl_entry[5].permset |= wperm;
if (mode & 0001)
tacl_entry[5].permset |= eperm;
/* Permissions for group@ */
if (mode & 0040)
tacl_entry[4].permset |= rperm;
else if (mode & 0004)
tacl_entry[2].permset |= rperm;
if (mode & 0020)
tacl_entry[4].permset |= wperm;
else if (mode & 0002)
tacl_entry[2].permset |= wperm;
if (mode & 0010)
tacl_entry[4].permset |= eperm;
else if (mode & 0001)
tacl_entry[2].permset |= eperm;
/* Permissions for owner@ */
if (mode & 0400) {
tacl_entry[3].permset |= rperm;
if (!(mode & 0040) && (mode & 0004))
tacl_entry[0].permset |= rperm;
} else if ((mode & 0040) || (mode & 0004))
tacl_entry[1].permset |= rperm;
if (mode & 0200) {
tacl_entry[3].permset |= wperm;
if (!(mode & 0020) && (mode & 0002))
tacl_entry[0].permset |= wperm;
} else if ((mode & 0020) || (mode & 0002))
tacl_entry[1].permset |= wperm;
if (mode & 0100) {
tacl_entry[3].permset |= eperm;
if (!(mode & 0010) && (mode & 0001))
tacl_entry[0].permset |= eperm;
} else if ((mode & 0010) || (mode & 0001))
tacl_entry[1].permset |= eperm;
for (i = 0; i < 6; i++) {
if (tacl_entry[i].permset != 0) {
archive_entry_acl_add_entry(entry,
tacl_entry[i].type, tacl_entry[i].permset,
tacl_entry[i].tag, -1, NULL);
}
}
return;
}
#elif HAVE_SUN_ACL
/*
* Check if acl is trivial
* This is a FreeBSD acl_is_trivial_np() implementation for Solaris
*/
static int
sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
{
int i, p;
const uint32_t rperm = ACE_READ_DATA;
const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
const uint32_t eperm = ACE_EXECUTE;
const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
ACE_READ_ACL | ACE_SYNCHRONIZE;
const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
ace_t *ace;
ace_t tace[6];
if (acl == NULL || trivialp == NULL)
return (-1);
*trivialp = 0;
/* ACL_IS_TRIVIAL flag must be set for both POSIX.1e and NFSv4 ACLs */
if ((acl->acl_flags & ACL_IS_TRIVIAL) == 0)
return (0);
/*
* POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
* FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
* incuding mask.
*/
if (acl->acl_type == ACLENT_T) {
if (acl->acl_cnt == 4)
*trivialp = 1;
return (0);
}
if (acl->acl_type != ACE_T || acl->acl_entry_size != sizeof(ace_t))
return (-1);
/*
* Continue with checking NFSv4 ACLs
*
* Create list of trivial ace's to be compared
*/
/* owner@ allow pre */
tace[0].a_flags = ACE_OWNER;
tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
tace[0].a_access_mask = 0;
/* owner@ deny */
tace[1].a_flags = ACE_OWNER;
tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
tace[1].a_access_mask = 0;
/* group@ deny */
tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
tace[2].a_access_mask = 0;
/* owner@ allow */
tace[3].a_flags = ACE_OWNER;
tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
tace[3].a_access_mask = ownset;
/* group@ allow */
tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
tace[4].a_access_mask = pubset;
/* everyone@ allow */
tace[5].a_flags = ACE_EVERYONE;
tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
tace[5].a_access_mask = pubset;
/* Permissions for everyone@ */
if (mode & 0004)
tace[5].a_access_mask |= rperm;
if (mode & 0002)
tace[5].a_access_mask |= wperm;
if (mode & 0001)
tace[5].a_access_mask |= eperm;
/* Permissions for group@ */
if (mode & 0040)
tace[4].a_access_mask |= rperm;
else if (mode & 0004)
tace[2].a_access_mask |= rperm;
if (mode & 0020)
tace[4].a_access_mask |= wperm;
else if (mode & 0002)
tace[2].a_access_mask |= wperm;
if (mode & 0010)
tace[4].a_access_mask |= eperm;
else if (mode & 0001)
tace[2].a_access_mask |= eperm;
/* Permissions for owner@ */
if (mode & 0400) {
tace[3].a_access_mask |= rperm;
if (!(mode & 0040) && (mode & 0004))
tace[0].a_access_mask |= rperm;
} else if ((mode & 0040) || (mode & 0004))
tace[1].a_access_mask |= rperm;
if (mode & 0200) {
tace[3].a_access_mask |= wperm;
if (!(mode & 0020) && (mode & 0002))
tace[0].a_access_mask |= wperm;
} else if ((mode & 0020) || (mode & 0002))
tace[1].a_access_mask |= wperm;
if (mode & 0100) {
tace[3].a_access_mask |= eperm;
if (!(mode & 0010) && (mode & 0001))
tace[0].a_access_mask |= eperm;
} else if ((mode & 0010) || (mode & 0001))
tace[1].a_access_mask |= eperm;
/* Check if the acl count matches */
p = 3;
for (i = 0; i < 3; i++) {
if (tace[i].a_access_mask != 0)
p++;
}
if (acl->acl_cnt != p)
return (0);
p = 0;
for (i = 0; i < 6; i++) {
if (tace[i].a_access_mask != 0) {
ace = &((ace_t *)acl->acl_aclp)[p];
/*
* Illumos added ACE_DELETE_CHILD to write perms for
* directories. We have to check against that, too.
*/
if (ace->a_flags != tace[i].a_flags ||
ace->a_type != tace[i].a_type ||
(ace->a_access_mask != tace[i].a_access_mask &&
((acl->acl_flags & ACL_IS_DIR) == 0 ||
(tace[i].a_access_mask & wperm) == 0 ||
ace->a_access_mask !=
(tace[i].a_access_mask | ACE_DELETE_CHILD))))
return (0);
p++;
}
}
*trivialp = 1;
return (0);
}
#endif /* HAVE_SUN_ACL */
#if HAVE_SUN_ACL
/*
* Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
*/
static int
translate_acl(struct archive_read_disk *a,
struct archive_entry *entry, acl_t *acl, int default_entry_acl_type)
{
int e, i;
int ae_id, ae_tag, ae_perm;
int entry_acl_type;
const char *ae_name;
aclent_t *aclent;
ace_t *ace;
(void)default_entry_acl_type;
if (acl->acl_cnt <= 0)
return (ARCHIVE_OK);
for (e = 0; e < acl->acl_cnt; e++) {
ae_name = NULL;
ae_tag = 0;
ae_perm = 0;
if (acl->acl_type == ACE_T) {
ace = &((ace_t *)acl->acl_aclp)[e];
ae_id = ace->a_who;
switch(ace->a_type) {
case ACE_ACCESS_ALLOWED_ACE_TYPE:
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
break;
case ACE_ACCESS_DENIED_ACE_TYPE:
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
break;
case ACE_SYSTEM_AUDIT_ACE_TYPE:
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
break;
case ACE_SYSTEM_ALARM_ACE_TYPE:
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
break;
default:
/* Unknown entry type, skip */
continue;
}
if ((ace->a_flags & ACE_OWNER) != 0)
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
else if ((ace->a_flags & ACE_GROUP) != 0)
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
else if ((ace->a_flags & ACE_EVERYONE) != 0)
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) {
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
ae_name = archive_read_disk_gname(&a->archive,
ae_id);
} else {
ae_tag = ARCHIVE_ENTRY_ACL_USER;
ae_name = archive_read_disk_uname(&a->archive,
ae_id);
}
for (i = 0; i < (int)(sizeof(acl_inherit_map) /
sizeof(acl_inherit_map[0])); ++i) {
if ((ace->a_flags &
acl_inherit_map[i].platform_inherit) != 0)
ae_perm |=
acl_inherit_map[i].archive_inherit;
}
for (i = 0; i < (int)(sizeof(acl_perm_map) /
sizeof(acl_perm_map[0])); ++i) {
if ((ace->a_access_mask &
acl_perm_map[i].platform_perm) != 0)
ae_perm |=
acl_perm_map[i].archive_perm;
}
} else {
aclent = &((aclent_t *)acl->acl_aclp)[e];
if ((aclent->a_type & ACL_DEFAULT) != 0)
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
else
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
ae_id = aclent->a_id;
switch(aclent->a_type) {
case DEF_USER:
case USER:
ae_name = archive_read_disk_uname(&a->archive,
ae_id);
ae_tag = ARCHIVE_ENTRY_ACL_USER;
break;
case DEF_GROUP:
case GROUP:
ae_name = archive_read_disk_gname(&a->archive,
ae_id);
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
break;
case DEF_CLASS_OBJ:
case CLASS_OBJ:
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
break;
case DEF_USER_OBJ:
case USER_OBJ:
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
break;
case DEF_GROUP_OBJ:
case GROUP_OBJ:
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
break;
case DEF_OTHER_OBJ:
case OTHER_OBJ:
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
break;
default:
/* Unknown tag type, skip */
continue;
}
if ((aclent->a_perm & 1) != 0)
ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
if ((aclent->a_perm & 2) != 0)
ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
if ((aclent->a_perm & 4) != 0)
ae_perm |= ARCHIVE_ENTRY_ACL_READ;
} /* default_entry_acl_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4 */
archive_entry_acl_add_entry(entry, entry_acl_type,
ae_perm, ae_tag, ae_id, ae_name);
}
return (ARCHIVE_OK);
}
#else /* !HAVE_SUN_ACL */
/*
* Translate POSIX.1e (Linux), FreeBSD (both POSIX.1e and NFSv4) and
* MacOS (NFSv4 only) ACLs into libarchive internal structure
*/
static int
translate_acl(struct archive_read_disk *a,
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
{
acl_tag_t acl_tag;
#ifdef ACL_TYPE_NFS4
#if HAVE_ACL_TYPE_NFS4
acl_entry_type_t acl_type;
acl_flagset_t acl_flagset;
int brand;
#endif
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
acl_flagset_t acl_flagset;
#endif
acl_entry_t acl_entry;
acl_permset_t acl_permset;
int i, entry_acl_type;
int r, s, ae_id, ae_tag, ae_perm;
#if !HAVE_DARWIN_ACL
void *q;
#endif
const char *ae_name;
#ifdef ACL_TYPE_NFS4
#if HAVE_ACL_TYPE_NFS4
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
// Make sure the "brand" on this ACL is consistent
// with the default_entry_acl_type bits provided.
@ -643,14 +1199,19 @@ translate_acl(struct archive_read_disk *a,
}
#endif
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
if (s == -1) {
archive_set_error(&a->archive, errno,
"Failed to get first ACL entry");
return (ARCHIVE_WARN);
}
while (s == 1) {
#if HAVE_DARWIN_ACL
while (s == 0)
#else /* FreeBSD, Linux */
while (s == 1)
#endif
{
ae_id = -1;
ae_name = NULL;
ae_perm = 0;
@ -661,14 +1222,25 @@ translate_acl(struct archive_read_disk *a,
return (ARCHIVE_WARN);
}
switch (acl_tag) {
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
case ACL_USER:
ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
ae_name = archive_read_disk_uname(&a->archive, ae_id);
q = acl_get_qualifier(acl_entry);
if (q != NULL) {
ae_id = (int)*(uid_t *)q;
acl_free(q);
ae_name = archive_read_disk_uname(&a->archive,
ae_id);
}
ae_tag = ARCHIVE_ENTRY_ACL_USER;
break;
case ACL_GROUP:
ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
ae_name = archive_read_disk_gname(&a->archive, ae_id);
q = acl_get_qualifier(acl_entry);
if (q != NULL) {
ae_id = (int)*(gid_t *)q;
acl_free(q);
ae_name = archive_read_disk_gname(&a->archive,
ae_id);
}
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
break;
case ACL_MASK:
@ -683,21 +1255,44 @@ translate_acl(struct archive_read_disk *a,
case ACL_OTHER:
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
break;
#ifdef ACL_TYPE_NFS4
#if HAVE_ACL_TYPE_NFS4
case ACL_EVERYONE:
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
break;
#endif
#else /* HAVE_DARWIN_ACL */
case ACL_EXTENDED_ALLOW:
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
r = translate_guid(&a->archive, acl_entry, &ae_id,
&ae_tag, &ae_name);
break;
case ACL_EXTENDED_DENY:
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
r = translate_guid(&a->archive, acl_entry, &ae_id,
&ae_tag, &ae_name);
break;
#endif /* HAVE_DARWIN_ACL */
default:
/* Skip types that libarchive can't support. */
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
continue;
}
#if HAVE_DARWIN_ACL
/* Skip if translate_guid() above failed */
if (r != 0) {
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
continue;
}
#endif
#if !HAVE_DARWIN_ACL
// XXX acl_type maps to allow/deny/audit/YYYY bits
entry_acl_type = default_entry_acl_type;
#ifdef ACL_TYPE_NFS4
#endif
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
#if HAVE_ACL_TYPE_NFS4
/*
* acl_get_entry_type_np() fails with non-NFSv4 ACLs
*/
@ -724,6 +1319,7 @@ translate_acl(struct archive_read_disk *a,
"Invalid NFSv4 ACL entry type");
return (ARCHIVE_WARN);
}
#endif /* HAVE_ACL_TYPE_NFS4 */
/*
* Libarchive stores "flag" (NFSv4 inheritance bits)
@ -736,7 +1332,7 @@ translate_acl(struct archive_read_disk *a,
"Failed to get flagset from a NFSv4 ACL entry");
return (ARCHIVE_WARN);
}
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
r = acl_get_flag_np(acl_flagset,
acl_inherit_map[i].platform_inherit);
if (r == -1) {
@ -746,9 +1342,9 @@ translate_acl(struct archive_read_disk *a,
return (ARCHIVE_WARN);
} else if (r)
ae_perm |= acl_inherit_map[i].archive_inherit;
}
}
}
#endif
#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL */
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
archive_set_error(&a->archive, errno,
@ -774,15 +1370,18 @@ translate_acl(struct archive_read_disk *a,
ae_id, ae_name);
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
#if !HAVE_DARWIN_ACL
if (s == -1) {
archive_set_error(&a->archive, errno,
"Failed to get next ACL entry");
return (ARCHIVE_WARN);
}
#endif
}
return (ARCHIVE_OK);
}
#else
#endif /* !HAVE_SUN_ACL */
#else /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
static int
setup_acls(struct archive_read_disk *a,
struct archive_entry *entry, int *fd)
@ -792,7 +1391,7 @@ setup_acls(struct archive_read_disk *a,
(void)fd; /* UNUSED */
return (ARCHIVE_OK);
}
#endif
#endif /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
#if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \

View file

@ -222,7 +222,7 @@ file_open(struct archive *a, void *client_data)
void *buffer;
const char *filename = NULL;
const wchar_t *wfilename = NULL;
int fd;
int fd = -1;
int is_disk_like = 0;
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */
@ -277,7 +277,7 @@ file_open(struct archive *a, void *client_data)
#else
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Unexpedted operation in archive_read_open_filename");
return (ARCHIVE_FATAL);
goto fail;
#endif
}
if (fstat(fd, &st) != 0) {
@ -287,7 +287,7 @@ file_open(struct archive *a, void *client_data)
else
archive_set_error(a, errno, "Can't stat '%s'",
filename);
return (ARCHIVE_FATAL);
goto fail;
}
/*
@ -356,11 +356,9 @@ file_open(struct archive *a, void *client_data)
mine->block_size = new_block_size;
}
buffer = malloc(mine->block_size);
if (mine == NULL || buffer == NULL) {
if (buffer == NULL) {
archive_set_error(a, ENOMEM, "No memory");
free(mine);
free(buffer);
return (ARCHIVE_FATAL);
goto fail;
}
mine->buffer = buffer;
mine->fd = fd;
@ -372,6 +370,14 @@ file_open(struct archive *a, void *client_data)
mine->use_lseek = 1;
return (ARCHIVE_OK);
fail:
/*
* Don't close file descriptors not opened or ones pointing referring
* to `FNT_STDIN`.
*/
if (fd != -1 && fd != 0)
close(fd);
return (ARCHIVE_FATAL);
}
static ssize_t

View file

@ -706,6 +706,11 @@ lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p)
/* Make sure we have a whole block. */
read_buf = __archive_read_filter_ahead(self->upstream,
4 + compressed, NULL);
if (read_buf == NULL) {
archive_set_error(&(self->archive->archive),
ARCHIVE_ERRNO_MISC, "truncated lz4 input");
return (ARCHIVE_FATAL);
}
ret = LZ4_decompress_safe(read_buf + 4, state->out_block,
compressed, (int)state->out_block_size);
if (ret < 0) {

View file

@ -430,6 +430,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
&state->child_stdout);
if (child == -1) {
free(state->out_buf);
archive_string_free(&state->description);
free(state);
archive_set_error(&self->archive->archive, EINVAL,
"Can't initialize filter; unable to run program \"%s\"",
@ -441,6 +442,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
if (state->child == NULL) {
child_stop(self, state);
free(state->out_buf);
archive_string_free(&state->description);
free(state);
archive_set_error(&self->archive->archive, EINVAL,
"Can't initialize filter; unable to run program \"%s\"",

View file

@ -1495,6 +1495,8 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
/* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */
if (mszip > 0) {
if (bytes_avail <= 0)
goto nomszip;
if (bytes_avail <= mszip) {
if (mszip == 2) {
if (cab->stream.next_in[0] != 0x43)

View file

@ -434,7 +434,8 @@ archive_read_format_cpio_read_header(struct archive_read *a,
* header. XXX */
/* Compare name to "TRAILER!!!" to test for end-of-archive. */
if (namelength == 11 && strcmp((const char *)h, "TRAILER!!!") == 0) {
if (namelength == 11 && memcmp((const char *)h, "TRAILER!!!",
11) == 0) {
/* TODO: Store file location of start of block. */
archive_clear_error(&a->archive);
return (ARCHIVE_EOF);

View file

@ -1864,7 +1864,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
if ((file->utf16be_name = malloc(name_len)) == NULL) {
archive_set_error(&a->archive, ENOMEM,
"No memory for file name");
return (NULL);
goto fail;
}
memcpy(file->utf16be_name, p, name_len);
file->utf16be_bytes = name_len;
@ -1943,10 +1943,8 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
file->symlink_continues = 0;
rr_start += iso9660->suspOffset;
r = parse_rockridge(a, file, rr_start, rr_end);
if (r != ARCHIVE_OK) {
free(file);
return (NULL);
}
if (r != ARCHIVE_OK)
goto fail;
/*
* A file size of symbolic link files in ISO images
* made by makefs is not zero and its location is
@ -1990,7 +1988,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Rockridge RE");
return (NULL);
goto fail;
}
/*
* Sanity check: file does not have "CL" extension.
@ -1999,7 +1997,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Rockridge RE and CL");
return (NULL);
goto fail;
}
/*
* Sanity check: The file type must be a directory.
@ -2008,7 +2006,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Rockridge RE");
return (NULL);
goto fail;
}
} else if (parent != NULL && parent->rr_moved)
file->rr_moved_has_re_only = 0;
@ -2022,7 +2020,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Rockridge CL");
return (NULL);
goto fail;
}
/*
* Sanity check: The file type must be a regular file.
@ -2031,7 +2029,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Rockridge CL");
return (NULL);
goto fail;
}
parent->subdirs++;
/* Overwrite an offset and a number of this "CL" entry
@ -2049,7 +2047,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Rockridge CL");
return (NULL);
goto fail;
}
}
if (file->cl_offset == file->offset ||
@ -2057,7 +2055,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
archive_set_error(&a->archive,
ARCHIVE_ERRNO_MISC,
"Invalid Rockridge CL");
return (NULL);
goto fail;
}
}
}
@ -2088,6 +2086,10 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
#endif
register_file(iso9660, file);
return (file);
fail:
archive_string_free(&file->name);
free(file);
return (NULL);
}
static int

View file

@ -924,6 +924,9 @@ lha_read_file_header_1(struct archive_read *a, struct lha *lha)
/* Get a real compressed file size. */
lha->compsize -= extdsize - 2;
if (lha->compsize < 0)
goto invalid; /* Invalid compressed file size */
if (sum_calculated != headersum) {
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"LHa header sum error");

View file

@ -715,13 +715,13 @@ detect_form(struct archive_read *a, int *is_form_d)
}
} else
break;
} else if (strncmp(p, "/set", 4) == 0) {
} else if (len > 4 && strncmp(p, "/set", 4) == 0) {
if (bid_keyword_list(p+4, len-4, 0, 0) <= 0)
break;
/* This line continues. */
if (p[len-nl-1] == '\\')
multiline = 2;
} else if (strncmp(p, "/unset", 6) == 0) {
} else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
if (bid_keyword_list(p+6, len-6, 1, 0) <= 0)
break;
/* This line continues. */
@ -1019,11 +1019,11 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
if (*p != '/') {
r = process_add_entry(a, mtree, &global, p, len,
&last_entry, is_form_d);
} else if (strncmp(p, "/set", 4) == 0) {
} else if (len > 4 && strncmp(p, "/set", 4) == 0) {
if (p[4] != ' ' && p[4] != '\t')
break;
r = process_global_set(a, &global, p);
} else if (strncmp(p, "/unset", 6) == 0) {
} else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
if (p[6] != ' ' && p[6] != '\t')
break;
r = process_global_unset(a, &global, p);

View file

@ -944,7 +944,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
{
const struct archive_entry_header_ustar *header;
size_t size;
int err;
int err, acl_type;
int64_t type;
char *acl, *p;
@ -989,11 +989,12 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
switch ((int)type & ~0777777) {
case 01000000:
/* POSIX.1e ACL */
acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
break;
case 03000000:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Solaris NFSv4 ACLs not supported");
return (ARCHIVE_WARN);
/* NFSv4 ACL */
acl_type = ARCHIVE_ENTRY_ACL_TYPE_NFS4;
break;
default:
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
"Malformed Solaris ACL attribute (unsupported type %o)",
@ -1023,7 +1024,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
}
archive_strncpy(&(tar->localname), acl, p - acl);
err = archive_acl_from_text_l(archive_entry_acl(entry),
tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, tar->sconv_acl);
tar->localname.s, acl_type, tar->sconv_acl);
if (err != ARCHIVE_OK) {
if (errno == ENOMEM) {
archive_set_error(&a->archive, ENOMEM,

View file

@ -534,7 +534,7 @@ xstrpisotime(const char *s, char **endptr)
/* as a courtesy to our callers, and since this is a non-standard
* routine, we skip leading whitespace */
while (isspace((unsigned char)*s))
while (isblank((unsigned char)*s))
++s;
/* read year */

View file

@ -933,6 +933,7 @@ xar_cleanup(struct archive_read *a)
}
for (i = 0; i < xar->file_queue.used; i++)
file_free(xar->file_queue.files[i]);
free(xar->file_queue.files);
while (xar->unknowntags != NULL) {
struct unknown_tag *tag;
@ -3047,7 +3048,7 @@ xml2_read_cb(void *context, char *buffer, int len)
struct xar *xar;
const void *d;
size_t outbytes;
size_t used;
size_t used = 0;
int r;
a = (struct archive_read *)context;
@ -3171,6 +3172,9 @@ expat_xmlattr_setup(struct archive_read *a,
value = strdup(atts[1]);
if (attr == NULL || name == NULL || value == NULL) {
archive_set_error(&a->archive, ENOMEM, "Out of memory");
free(attr);
free(name);
free(value);
return (ARCHIVE_FATAL);
}
attr->name = name;

View file

@ -905,6 +905,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
archive_wstrcat(&s, wp);
archive_wstrappend_wchar(&s, L'/');
archive_entry_copy_pathname_w(entry, s.s);
archive_wstring_free(&s);
}
} else {
cp = archive_entry_pathname(entry);
@ -915,6 +916,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
archive_strcat(&s, cp);
archive_strappend_char(&s, '/');
archive_entry_set_pathname(entry, s.s);
archive_string_free(&s);
}
}
}

View file

@ -200,6 +200,7 @@ __archive_write_program_free(struct archive_write_program_data *data)
if (data->child)
CloseHandle(data->child);
#endif
free(data->program_name);
free(data->child_buf);
free(data);
}

View file

@ -34,6 +34,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
#define _ACL_PRIVATE /* For debugging */
#include <sys/acl.h>
#endif
#if HAVE_DARWIN_ACL
#include <membership.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
@ -43,7 +46,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
#include "archive_acl_private.h"
#include "archive_write_disk_private.h"
#ifndef HAVE_POSIX_ACL
#if !HAVE_POSIX_ACL && !HAVE_NFS4_ACL
/* Default empty function body to satisfy mainline code. */
int
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
@ -56,47 +59,111 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
return (ARCHIVE_OK);
}
#else
#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
#if HAVE_SUN_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
#elif HAVE_DARWIN_ACL
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
#elif HAVE_ACL_TYPE_NFS4
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
#endif
static int set_acl(struct archive *, int fd, const char *,
struct archive_acl *,
acl_type_t, int archive_entry_acl_type, const char *tn);
/*
* XXX TODO: What about ACL types other than ACCESS and DEFAULT?
*/
int
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
struct archive_acl *abstract_acl)
{
int ret;
int ret = ARCHIVE_OK;
if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) > 0) {
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
if (ret != ARCHIVE_OK)
return (ret);
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
#if !HAVE_DARWIN_ACL
if ((archive_acl_types(abstract_acl)
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
#if HAVE_SUN_ACL
/* Solaris writes POSIX.1e access and default ACLs together */
ret = set_acl(a, fd, name, abstract_acl, ACLENT_T,
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
#else /* HAVE_POSIX_ACL */
if ((archive_acl_types(abstract_acl)
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
ret = set_acl(a, fd, name, abstract_acl,
ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
"access");
if (ret != ARCHIVE_OK)
return (ret);
}
if ((archive_acl_types(abstract_acl)
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
ret = set_acl(a, fd, name, abstract_acl,
ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
"default");
#endif /* !HAVE_SUN_ACL */
/* Simultaeous POSIX.1e and NFSv4 is not supported */
return (ret);
#ifdef ACL_TYPE_NFS4
} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
}
#endif /* !HAVE_DARWIN_ACL */
#if HAVE_NFS4_ACL
if ((archive_acl_types(abstract_acl) &
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
ret = set_acl(a, fd, name, abstract_acl,
ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
return (ret);
#endif
} else
return ARCHIVE_OK;
}
#endif /* HAVE_NFS4_ACL */
return (ret);
}
/*
* Translate system ACL permissions into libarchive internal structure
*/
static struct {
int archive_perm;
int platform_perm;
} acl_perm_map[] = {
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
{ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
#else /* POSIX.1e ACL permissions */
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
#ifdef ACL_TYPE_NFS4
#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
@ -114,13 +181,32 @@ static struct {
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
#endif
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
};
#ifdef ACL_TYPE_NFS4
#if HAVE_NFS4_ACL
/*
* Translate system NFSv4 inheritance flags into libarchive internal structure
*/
static struct {
int archive_inherit;
int platform_inherit;
} acl_inherit_map[] = {
#if HAVE_SUN_ACL /* Solaris NFSv4 inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
#else /* FreeBSD NFSv4 ACL inheritance flags */
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
@ -128,23 +214,36 @@ static struct {
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
};
#endif
#endif /* HAVE_NFS4_ACL */
static int
set_acl(struct archive *a, int fd, const char *name,
struct archive_acl *abstract_acl,
acl_type_t acl_type, int ae_requested_type, const char *tname)
{
#if HAVE_SUN_ACL
aclent_t *aclent;
ace_t *ace;
int e, r;
acl_t *acl;
#else
acl_t acl;
acl_entry_t acl_entry;
acl_permset_t acl_permset;
#ifdef ACL_TYPE_NFS4
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
acl_flagset_t acl_flagset;
int r;
#endif
#endif /* HAVE_SUN_ACL */
#if HAVE_ACL_TYPE_NFS4
int r;
#endif
int ret;
int ae_type, ae_permset, ae_tag, ae_id;
#if HAVE_DARWIN_ACL
uuid_t ae_uuid;
#endif
uid_t ae_uid;
gid_t ae_gid;
const char *ae_name;
@ -155,32 +254,165 @@ set_acl(struct archive *a, int fd, const char *name,
entries = archive_acl_reset(abstract_acl, ae_requested_type);
if (entries == 0)
return (ARCHIVE_OK);
#if HAVE_SUN_ACL
acl = NULL;
acl = malloc(sizeof(acl_t));
if (acl == NULL) {
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Invalid ACL type");
return (ARCHIVE_FAILED);
}
if (acl_type == ACE_T)
acl->acl_entry_size = sizeof(ace_t);
else if (acl_type == ACLENT_T)
acl->acl_entry_size = sizeof(aclent_t);
else {
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Invalid ACL type");
acl_free(acl);
return (ARCHIVE_FAILED);
}
acl->acl_type = acl_type;
acl->acl_cnt = entries;
acl->acl_aclp = malloc(entries * acl->acl_entry_size);
if (acl->acl_aclp == NULL) {
archive_set_error(a, errno,
"Can't allocate memory for acl buffer");
acl_free(acl);
return (ARCHIVE_FAILED);
}
#else /* !HAVE_SUN_ACL */
acl = acl_init(entries);
if (acl == (acl_t)NULL) {
archive_set_error(a, errno,
"Failed to initialize ACL working storage");
return (ARCHIVE_FAILED);
}
#endif /* !HAVE_SUN_ACL */
#if HAVE_SUN_ACL
e = 0;
#endif
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
#if HAVE_SUN_ACL
ace = NULL;
aclent = NULL;
if (acl->acl_type == ACE_T) {
ace = &((ace_t *)acl->acl_aclp)[e];
ace->a_who = -1;
ace->a_access_mask = 0;
ace->a_flags = 0;
} else {
aclent = &((aclent_t *)acl->acl_aclp)[e];
aclent->a_id = -1;
aclent->a_type = 0;
aclent->a_perm = 0;
}
#else /* !HAVE_SUN_ACL */
#if HAVE_DARWIN_ACL
/*
* Mac OS doesn't support NFSv4 ACLs for
* owner@, group@ and everyone@.
* We skip any of these ACLs found.
*/
if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
continue;
#endif
if (acl_create_entry(&acl, &acl_entry) != 0) {
archive_set_error(a, errno,
"Failed to create a new ACL entry");
ret = ARCHIVE_FAILED;
goto exit_free;
}
#endif /* !HAVE_SUN_ACL */
#if HAVE_DARWIN_ACL
switch (ae_type) {
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
break;
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
break;
default:
/* We don't support any other types on MacOS */
continue;
}
#endif
switch (ae_tag) {
#if HAVE_SUN_ACL
case ARCHIVE_ENTRY_ACL_USER:
acl_set_tag_type(acl_entry, ACL_USER);
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
acl_set_qualifier(acl_entry, &ae_uid);
if (acl->acl_type == ACE_T)
ace->a_who = ae_uid;
else {
aclent->a_id = ae_uid;
aclent->a_type |= USER;
}
break;
case ARCHIVE_ENTRY_ACL_GROUP:
acl_set_tag_type(acl_entry, ACL_GROUP);
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
acl_set_qualifier(acl_entry, &ae_gid);
if (acl->acl_type == ACE_T) {
ace->a_who = ae_gid;
ace->a_flags |= ACE_IDENTIFIER_GROUP;
} else {
aclent->a_id = ae_gid;
aclent->a_type |= GROUP;
}
break;
case ARCHIVE_ENTRY_ACL_USER_OBJ:
if (acl->acl_type == ACE_T)
ace->a_flags |= ACE_OWNER;
else
aclent->a_type |= USER_OBJ;
break;
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
if (acl->acl_type == ACE_T) {
ace->a_flags |= ACE_GROUP;
ace->a_flags |= ACE_IDENTIFIER_GROUP;
} else
aclent->a_type |= GROUP_OBJ;
break;
case ARCHIVE_ENTRY_ACL_MASK:
aclent->a_type |= CLASS_OBJ;
break;
case ARCHIVE_ENTRY_ACL_OTHER:
aclent->a_type |= OTHER_OBJ;
break;
case ARCHIVE_ENTRY_ACL_EVERYONE:
ace->a_flags |= ACE_EVERYONE;
break;
#else /* !HAVE_SUN_ACL */
case ARCHIVE_ENTRY_ACL_USER:
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
acl_set_tag_type(acl_entry, ACL_USER);
acl_set_qualifier(acl_entry, &ae_uid);
#else /* MacOS */
if (mbr_identifier_to_uuid(ID_TYPE_UID, &ae_uid,
sizeof(uid_t), ae_uuid) != 0)
continue;
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
continue;
#endif /* HAVE_DARWIN_ACL */
break;
case ARCHIVE_ENTRY_ACL_GROUP:
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
acl_set_tag_type(acl_entry, ACL_GROUP);
acl_set_qualifier(acl_entry, &ae_gid);
#else /* MacOS */
if (mbr_identifier_to_uuid(ID_TYPE_GID, &ae_gid,
sizeof(gid_t), ae_uuid) != 0)
continue;
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
continue;
#endif /* HAVE_DARWIN_ACL */
break;
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
case ARCHIVE_ENTRY_ACL_USER_OBJ:
acl_set_tag_type(acl_entry, ACL_USER_OBJ);
break;
@ -193,11 +425,13 @@ set_acl(struct archive *a, int fd, const char *name,
case ARCHIVE_ENTRY_ACL_OTHER:
acl_set_tag_type(acl_entry, ACL_OTHER);
break;
#ifdef ACL_TYPE_NFS4
#if HAVE_ACL_TYPE_NFS4 /* FreeBSD only */
case ARCHIVE_ENTRY_ACL_EVERYONE:
acl_set_tag_type(acl_entry, ACL_EVERYONE);
break;
#endif
#endif /* !HAVE_DARWIN_ACL */
#endif /* !HAVE_SUN_ACL */
default:
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Unknown ACL tag");
@ -205,9 +439,45 @@ set_acl(struct archive *a, int fd, const char *name,
goto exit_free;
}
#ifdef ACL_TYPE_NFS4
#if HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL
r = 0;
switch (ae_type) {
#if HAVE_SUN_ACL
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
if (ace != NULL)
ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
else
r = -1;
break;
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
if (ace != NULL)
ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
else
r = -1;
break;
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
if (ace != NULL)
ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
else
r = -1;
break;
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
if (ace != NULL)
ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
else
r = -1;
break;
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
if (aclent == NULL)
r = -1;
break;
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
if (aclent != NULL)
aclent->a_type |= ACL_DEFAULT;
else
r = -1;
break;
#else /* !HAVE_SUN_ACL */
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
break;
@ -224,20 +494,35 @@ set_acl(struct archive *a, int fd, const char *name,
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
// These don't translate directly into the system ACL.
break;
#endif /* !HAVE_SUN_ACL */
default:
archive_set_error(a, ARCHIVE_ERRNO_MISC,
"Unknown ACL entry type");
ret = ARCHIVE_FAILED;
goto exit_free;
}
if (r != 0) {
#if HAVE_SUN_ACL
errno = EINVAL;
#endif
archive_set_error(a, errno,
"Failed to set ACL entry type");
ret = ARCHIVE_FAILED;
goto exit_free;
}
#endif
#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL */
#if HAVE_SUN_ACL
if (acl->acl_type == ACLENT_T) {
if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
aclent->a_perm |= 1;
if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
aclent->a_perm |= 2;
if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
aclent->a_perm |= 4;
} else
#else
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
archive_set_error(a, errno,
"Failed to get ACL permission set");
@ -250,9 +535,13 @@ set_acl(struct archive *a, int fd, const char *name,
ret = ARCHIVE_FAILED;
goto exit_free;
}
#endif /* !HAVE_SUN_ACL */
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
if (ae_permset & acl_perm_map[i].archive_perm)
if (ae_permset & acl_perm_map[i].archive_perm) {
#if HAVE_SUN_ACL
ace->a_access_mask |=
acl_perm_map[i].platform_perm;
#else
if (acl_add_perm(acl_permset,
acl_perm_map[i].platform_perm) != 0) {
archive_set_error(a, errno,
@ -260,10 +549,20 @@ set_acl(struct archive *a, int fd, const char *name,
ret = ARCHIVE_FAILED;
goto exit_free;
}
#endif
}
}
#ifdef ACL_TYPE_NFS4
if (acl_type == ACL_TYPE_NFS4) {
#if HAVE_NFS4_ACL
#if HAVE_SUN_ACL
if (acl_type == ACE_T)
#elif HAVE_DARWIN_ACL
if (acl_type == ACL_TYPE_EXTENDED)
#else /* FreeBSD */
if (acl_type == ACL_TYPE_NFS4)
#endif
{
#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
/*
* acl_get_flagset_np() fails with non-NFSv4 ACLs
*/
@ -279,8 +578,13 @@ set_acl(struct archive *a, int fd, const char *name,
ret = ARCHIVE_FAILED;
goto exit_free;
}
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
for (i = 0; i < (int)(sizeof(acl_inherit_map) /sizeof(acl_inherit_map[0])); ++i) {
if (ae_permset & acl_inherit_map[i].archive_inherit) {
#if HAVE_SUN_ACL
ace->a_flags |=
acl_inherit_map[i].platform_inherit;
#else /* !HAVE_SUN_ACL */
if (acl_add_flag_np(acl_flagset,
acl_inherit_map[i].platform_inherit) != 0) {
archive_set_error(a, errno,
@ -288,19 +592,29 @@ set_acl(struct archive *a, int fd, const char *name,
ret = ARCHIVE_FAILED;
goto exit_free;
}
#endif /* HAVE_SUN_ACL */
}
}
}
#endif /* HAVE_NFS4_ACL */
#if HAVE_SUN_ACL
e++;
#endif
}
#if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL
/* Try restoring the ACL through 'fd' if we can. */
#if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD
#if HAVE_ACL_SET_FD_NP
if (fd >= 0) {
#if HAVE_SUN_ACL || HAVE_ACL_SET_FD_NP
if (fd >= 0)
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
if (fd >= 0 && acl_type == ACL_TYPE_ACCESS)
#endif
{
#if HAVE_SUN_ACL
if (facl_set(fd, acl) == 0)
#elif HAVE_ACL_SET_FD_NP
if (acl_set_fd_np(fd, acl, acl_type) == 0)
#else /* HAVE_ACL_SET_FD */
if (fd >= 0 && acl_type == ACL_TYPE_ACCESS) {
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
if (acl_set_fd(fd, acl) == 0)
#endif
ret = ARCHIVE_OK;
@ -314,13 +628,16 @@ set_acl(struct archive *a, int fd, const char *name,
}
}
} else
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD */
#if HAVE_ACL_SET_LINK_NP
if (acl_set_link_np(name, acl_type, acl) != 0) {
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
#if HAVE_SUN_ACL
if (acl_set(name, acl) != 0)
#elif HAVE_ACL_SET_LINK_NP
if (acl_set_link_np(name, acl_type, acl) != 0)
#else
/* TODO: Skip this if 'name' is a symlink. */
if (acl_set_file(name, acl_type, acl) != 0) {
if (acl_set_file(name, acl_type, acl) != 0)
#endif
{
if (errno == EOPNOTSUPP) {
/* Filesystem doesn't support ACLs */
ret = ARCHIVE_OK;
@ -334,4 +651,4 @@ set_acl(struct archive *a, int fd, const char *name,
acl_free(acl);
return (ret);
}
#endif
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */

View file

@ -110,6 +110,18 @@ __FBSDID("$FreeBSD$");
#include <sys/fcntl1.h>
#endif
/*
* Macro to cast st_mtime and time_t to an int64 so that 2 numbers can reliably be compared.
*
* It assumes that the input is an integer type of no more than 64 bits.
* If the number is less than zero, t must be a signed type, so it fits in
* int64_t. Otherwise, it's a nonnegative value so we can cast it to uint64_t
* without loss. But it could be a large unsigned value, so we have to clip it
* to INT64_MAX.*
*/
#define to_int64_time(t) \
((t) < 0 ? (int64_t)(t) : (uint64_t)(t) > (uint64_t)INT64_MAX ? INT64_MAX : (int64_t)(t))
#if __APPLE__
#include <TargetConditionals.h>
#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && HAVE_QUARANTINE_H
@ -1690,10 +1702,25 @@ _archive_write_disk_finish_entry(struct archive *_a)
* ACLs that prevent attribute changes (including time).
*/
if (a->todo & TODO_ACLS) {
int r2 = archive_write_disk_set_acls(&a->archive, a->fd,
archive_entry_pathname(a->entry),
archive_entry_acl(a->entry));
int r2;
#ifdef HAVE_DARWIN_ACL
/*
* On Mac OS, platform ACLs are stored also in mac_metadata by
* the operating system. If mac_metadata is present it takes
* precedence and we skip extracting libarchive NFSv4 ACLs
*/
const void *metadata;
size_t metadata_size;
metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
if (metadata == NULL || metadata_size == 0) {
#endif
r2 = archive_write_disk_set_acls(&a->archive, a->fd,
archive_entry_pathname(a->entry),
archive_entry_acl(a->entry));
if (r2 < ret) ret = r2;
#ifdef HAVE_DARWIN_ACL
}
#endif
}
finish_metadata:
@ -2065,6 +2092,7 @@ create_filesystem_object(struct archive_write_disk *a)
archive_set_error(&a->archive, error_number, "%s",
error_string.s);
free(linkname_copy);
archive_string_free(&error_string);
/*
* EPERM is more appropriate than error_number for our
* callers
@ -2077,6 +2105,7 @@ create_filesystem_object(struct archive_write_disk *a)
archive_set_error(&a->archive, error_number, "%s",
error_string.s);
free(linkname_copy);
archive_string_free(&error_string);
/*
* EPERM is more appropriate than error_number for our
* callers
@ -2084,6 +2113,7 @@ create_filesystem_object(struct archive_write_disk *a)
return (EPERM);
}
free(linkname_copy);
archive_string_free(&error_string);
r = link(linkname, a->name) ? errno : 0;
/*
* New cpio and pax formats allow hardlink entries
@ -2252,8 +2282,12 @@ _archive_write_disk_close(struct archive *_a)
if (p->fixup & TODO_MODE_BASE)
chmod(p->name, p->mode);
if (p->fixup & TODO_ACLS)
archive_write_disk_set_acls(&a->archive,
-1, p->name, &p->acl);
#ifdef HAVE_DARWIN_ACL
if (p->mac_metadata == NULL ||
p->mac_metadata_size == 0)
#endif
archive_write_disk_set_acls(&a->archive,
-1, p->name, &p->acl);
if (p->fixup & TODO_FFLAGS)
set_fflags_platform(a, -1, p->name,
p->mode, p->fflags_set, 0);
@ -4125,10 +4159,10 @@ older(struct stat *st, struct archive_entry *entry)
{
/* First, test the seconds and return if we have a definite answer. */
/* Definitely older. */
if (st->st_mtime < archive_entry_mtime(entry))
if (to_int64_time(st->st_mtime) < to_int64_time(archive_entry_mtime(entry)))
return (1);
/* Definitely younger. */
if (st->st_mtime > archive_entry_mtime(entry))
if (to_int64_time(st->st_mtime) > to_int64_time(archive_entry_mtime(entry)))
return (0);
/* If this platform supports fractional seconds, try those. */
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC

View file

@ -66,6 +66,7 @@ Freeze the settings, open the archive, and prepare for writing entries.
This is the most generic form of this function, which accepts
pointers to three callback functions which will be invoked by
the compression layer to write the constructed archive.
This does not alter the default archive padding.
.It Fn archive_write_open_fd
A convenience form of
.Fn archive_write_open
@ -123,12 +124,21 @@ is currently in use.
You should be careful to ensure that this variable
remains allocated until after the archive is
closed.
This function will disable padding unless you
have specifically set the block size.
.El
More information about the
.Va struct archive
object and the overall design of the library can be found in the
.Xr libarchive 3
overview.
.Pp
Note that the convenience forms above vary in how
they block the output.
See
.Xr archive_write_blocksize 3
if you need to control the block size used for writes
or the end-of-file padding behavior.
.\"
.Sh CLIENT CALLBACKS
To use this library, you will need to define and register
@ -226,6 +236,7 @@ functions.
.Xr tar 1 ,
.Xr libarchive 3 ,
.Xr archive_write 3 ,
.Xr archive_write_blocksize 3 ,
.Xr archive_write_filter 3 ,
.Xr archive_write_format 3 ,
.Xr archive_write_new 3 ,

View file

@ -478,15 +478,15 @@ archive_write_gnutar_header(struct archive_write *a,
archive_entry_set_pathname(temp, "././@LongLink");
archive_entry_set_size(temp, length);
ret = archive_format_gnutar_header(a, buff, temp, 'K');
archive_entry_free(temp);
if (ret < ARCHIVE_WARN)
goto exit_write_header;
ret = __archive_write_output(a, buff, 512);
if(ret < ARCHIVE_WARN)
if (ret < ARCHIVE_WARN)
goto exit_write_header;
archive_entry_free(temp);
/* Write name and trailing null byte. */
ret = __archive_write_output(a, gnutar->linkname, length);
if(ret < ARCHIVE_WARN)
if (ret < ARCHIVE_WARN)
goto exit_write_header;
/* Pad to 512 bytes */
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
@ -508,12 +508,12 @@ archive_write_gnutar_header(struct archive_write *a,
archive_entry_set_pathname(temp, "././@LongLink");
archive_entry_set_size(temp, length);
ret = archive_format_gnutar_header(a, buff, temp, 'L');
archive_entry_free(temp);
if (ret < ARCHIVE_WARN)
goto exit_write_header;
ret = __archive_write_output(a, buff, 512);
if(ret < ARCHIVE_WARN)
goto exit_write_header;
archive_entry_free(temp);
/* Write pathname + trailing null byte. */
ret = __archive_write_output(a, pathname, length);
if(ret < ARCHIVE_WARN)

View file

@ -2524,7 +2524,8 @@ get_tmfromtime(struct tm *tm, time_t *t)
tzset();
localtime_r(t, tm);
#elif HAVE__LOCALTIME64_S
_localtime64_s(tm, t);
__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
_localtime64_s(tm, &tmp_t);
#else
memcpy(tm, localtime(t), sizeof(*tm));
#endif
@ -2553,7 +2554,7 @@ set_date_time(unsigned char *p, time_t t)
static void
set_date_time_null(unsigned char *p)
{
memset(p, '0', 16);
memset(p, (int)'0', 16);
p[16] = 0;
}
@ -4073,7 +4074,8 @@ write_information_block(struct archive_write *a)
memset(info.s, 0, info_size);
opt = 0;
#if defined(HAVE__CTIME64_S)
_ctime64_s(buf, sizeof(buf), &(iso9660->birth_time));
__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
#elif defined(HAVE_CTIME_R)
ctime_r(&(iso9660->birth_time), buf);
#else

View file

@ -1961,6 +1961,7 @@ file_free(struct file *file)
archive_string_free(&(file->basename));
archive_string_free(&(file->symlink));
archive_string_free(&(file->script));
archive_entry_free(file->entry);
free(file);
}

View file

@ -216,6 +216,12 @@ invalid_parameter_handler(const wchar_t * expression,
unsigned int line, uintptr_t pReserved)
{
/* nop */
// Silence unused-parameter compiler warnings.
(void)expression;
(void)function;
(void)file;
(void)line;
(void)pReserved;
}
#endif
@ -1412,6 +1418,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
failure_start(file, line, "assertFileMode not yet implemented for Windows");
(void)mode; /* UNUSED */
(void)r; /* UNUSED */
(void)pathname; /* UNUSED */
(void)expected_mode; /* UNUSED */
#else
{
struct stat st;

View file

@ -120,6 +120,32 @@
#define O_BINARY 0
#endif
/*
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
* acl_set_file(), and ACL_USER, we assume it has the rest of the
* POSIX.1e draft functions used in archive_read_extract.c.
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
#if HAVE_ACL_USER
#define HAVE_POSIX_ACL 1
#elif HAVE_ACL_TYPE_EXTENDED
#define HAVE_DARWIN_ACL 1
#endif
#endif
/*
* If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
*/
#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
#define HAVE_SUN_ACL 1
#endif
/* Define if platform supports NFSv4 ACLs */
#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
#define HAVE_NFS4_ACL 1
#endif
/*
* Redefine DEFINE_TEST for use in defining the test functions.
*/

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2010 Tim Kientzle
* Copyright (c) 2017 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -25,10 +26,15 @@
#include "test.h"
__FBSDID("$FreeBSD$");
#if defined(__FreeBSD__) && __FreeBSD__ >= 8
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
#define _ACL_PRIVATE
#include <sys/acl.h>
#if HAVE_DARWIN_ACL
#include <membership.h>
#endif
#endif
#if HAVE_NFS4_ACL
struct myacl_t {
int type;
int permset;
@ -38,11 +44,12 @@ struct myacl_t {
};
static struct myacl_t acls_reg[] = {
#if !HAVE_DARWIN_ACL
/* For this test, we need the file owner to be able to read and write the ACL. */
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
#endif
/* An entry for each type. */
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
@ -84,17 +91,53 @@ static struct myacl_t acls_reg[] = {
// ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" },
#if !HAVE_DARWIN_ACL
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
#else /* MacOS - mode 0654 */
{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_WRITE_ACL |
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
#endif
};
static const int acls_reg_cnt = (int)(sizeof(acls_reg)/sizeof(acls_reg[0]));
static struct myacl_t acls_dir[] = {
/* For this test, we need to be able to read and write the ACL. */
#if !HAVE_DARWIN_ACL
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
#endif
/* An entry for each type. */
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
@ -144,6 +187,9 @@ static struct myacl_t acls_dir[] = {
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
ARCHIVE_ENTRY_ACL_USER, 305, "user305" },
#endif
#if 0
@ -161,12 +207,47 @@ static struct myacl_t acls_dir[] = {
ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
#if !HAVE_DARWIN_ACL
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
#else /* MacOS - mode 0654 */
{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_WRITE_ACL |
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
#endif
};
static const int acls_dir_cnt = (int)(sizeof(acls_dir)/sizeof(acls_dir[0]));
static void
set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
{
@ -188,9 +269,50 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
}
static int
#ifdef HAVE_SUN_ACL
acl_permset_to_bitmap(uint32_t a_access_mask)
#else
acl_permset_to_bitmap(acl_permset_t opaque_ps)
#endif
{
static struct { int machine; int portable; } perms[] = {
#ifdef HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
{ACE_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
{ACE_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
{ACE_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
{ACE_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
{ACE_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
{ACE_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
{ACE_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
{ACE_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
{ACE_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
{ACE_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
{ACE_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
{ACE_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
{ACE_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
{ACE_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
{ACE_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
{ACE_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
{ACE_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL permissions */
{ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
{ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
{ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
{ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
{ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
{ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
{ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
{ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
{ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
{ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
{ACL_READ_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
{ACL_WRITE_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
{ACL_READ_SECURITY, ARCHIVE_ENTRY_ACL_READ_ACL},
{ACL_WRITE_SECURITY, ARCHIVE_ENTRY_ACL_WRITE_ACL},
{ACL_CHANGE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE},
#else /* FreeBSD NFSv4 ACL permissions */
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
{ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
{ACL_READ, ARCHIVE_ENTRY_ACL_READ},
@ -210,51 +332,201 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
{ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
{ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
#endif
};
int i, permset = 0;
for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
#if HAVE_SUN_ACL
if (a_access_mask & perms[i].machine)
#else
if (acl_get_perm_np(opaque_ps, perms[i].machine))
#endif
permset |= perms[i].portable;
return permset;
}
static int
#if HAVE_SUN_ACL
acl_flagset_to_bitmap(uint16_t a_flags)
#else
acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
#endif
{
static struct { int machine; int portable; } flags[] = {
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL inheritance flags */
{ACE_FILE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
{ACE_DIRECTORY_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
{ACE_NO_PROPAGATE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
{ACE_INHERIT_ONLY_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
{ACE_SUCCESSFUL_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
{ACE_FAILED_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
{ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL inheritance flags */
{ACL_ENTRY_INHERITED, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED},
{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
{ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
{ACL_ENTRY_LIMIT_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
{ACL_ENTRY_ONLY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY}
#else /* FreeBSD NFSv4 ACL inheritance flags */
{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
{ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
{ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
{ACL_ENTRY_SUCCESSFUL_ACCESS, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
{ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
{ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
#endif
};
int i, flagset = 0;
for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
#if HAVE_SUN_ACL
if (a_flags & flags[i].machine)
#else
if (acl_get_flag_np(opaque_fs, flags[i].machine))
#endif
flagset |= flags[i].portable;
return flagset;
}
static int
#if HAVE_SUN_ACL
acl_match(ace_t *ace, struct myacl_t *myacl)
#else
acl_match(acl_entry_t aclent, struct myacl_t *myacl)
#endif
{
#if !HAVE_SUN_ACL
#if HAVE_DARWIN_ACL
void *q;
uid_t ugid;
int r, idtype;
#else
gid_t g, *gp;
uid_t u, *up;
acl_entry_type_t entry_type;
#endif /* !HAVE_DARWIN_ACL */
acl_tag_t tag_type;
acl_permset_t opaque_ps;
acl_flagset_t opaque_fs;
#endif /* !HAVE_SUN_ACL */
int perms;
#if HAVE_SUN_ACL
perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags);
#else
acl_get_tag_type(aclent, &tag_type);
#if !HAVE_DARWIN_ACL
acl_get_entry_type_np(aclent, &entry_type);
#endif
/* translate the silly opaque permset to a bitmap */
acl_get_permset(aclent, &opaque_ps);
acl_get_flagset_np(aclent, &opaque_fs);
perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
#endif
if (perms != myacl->permset)
return (0);
#if HAVE_SUN_ACL
switch (ace->a_type) {
case ACE_ACCESS_ALLOWED_ACE_TYPE:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
return (0);
break;
case ACE_ACCESS_DENIED_ACE_TYPE:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
return (0);
break;
case ACE_SYSTEM_AUDIT_ACE_TYPE:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT)
return (0);
break;
case ACE_SYSTEM_ALARM_ACE_TYPE:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM)
return (0);
break;
default:
return (0);
}
if (ace->a_flags & ACE_OWNER) {
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ)
return (0);
} else if (ace->a_flags & ACE_GROUP) {
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ)
return (0);
} else if (ace->a_flags & ACE_EVERYONE) {
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE)
return (0);
} else if (ace->a_flags & ACE_IDENTIFIER_GROUP) {
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
return (0);
if ((gid_t)myacl->qual != ace->a_who)
return (0);
} else {
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
return (0);
if ((uid_t)myacl->qual != ace->a_who)
return (0);
}
#elif HAVE_DARWIN_ACL
r = 0;
switch (tag_type) {
case ACL_EXTENDED_ALLOW:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
return (0);
break;
case ACL_EXTENDED_DENY:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
return (0);
break;
default:
return (0);
}
q = acl_get_qualifier(aclent);
if (q == NULL)
return (0);
r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
acl_free(q);
if (r != 0)
return (0);
switch (idtype) {
case ID_TYPE_UID:
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
return (0);
if ((uid_t)myacl->qual != ugid)
return (0);
break;
case ID_TYPE_GID:
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
return (0);
if ((gid_t)myacl->qual != ugid)
return (0);
break;
default:
return (0);
}
#else /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
switch (entry_type) {
case ACL_ENTRY_TYPE_ALLOW:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
return (0);
break;
case ACL_ENTRY_TYPE_DENY:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
return (0);
break;
case ACL_ENTRY_TYPE_AUDIT:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT)
return (0);
case ACL_ENTRY_TYPE_ALARM:
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM)
return (0);
default:
return (0);
}
switch (tag_type) {
case ACL_USER_OBJ:
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
@ -287,17 +559,29 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
break;
}
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
return (1);
}
static void
compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start, int end)
compare_acls(
#if HAVE_SUN_ACL
acl_t *acl,
#else
acl_t acl,
#endif
struct myacl_t *myacls, const char *filename, int start, int end)
{
int *marker;
int entry_id = ACL_FIRST_ENTRY;
int matched;
int i, n;
#if HAVE_SUN_ACL
int e;
ace_t *acl_entry;
#else
int entry_id = ACL_FIRST_ENTRY;
acl_entry_t acl_entry;
#endif
n = end - start;
marker = malloc(sizeof(marker[0]) * (n + 1));
@ -313,10 +597,20 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
* Iterate over acls in system acl object, try to match each
* one with an item in the myacls array.
*/
while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
#if HAVE_SUN_ACL
for (e = 0; e < acl->acl_cnt; e++)
#elif HAVE_DARWIN_ACL
while (0 == acl_get_entry(acl, entry_id, &acl_entry))
#else
while (1 == acl_get_entry(acl, entry_id, &acl_entry))
#endif
{
#if HAVE_SUN_ACL
acl_entry = &((ace_t *)acl->acl_aclp)[e];
#else
/* After the first time... */
entry_id = ACL_NEXT_ENTRY;
#endif
/* Search for a matching entry (tag and qualifier) */
for (i = 0, matched = 0; i < n && !matched; i++) {
if (acl_match(acl_entry, &myacls[marker[i]])) {
@ -327,7 +621,8 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
}
}
failure("ACL entry on file %s that shouldn't be there", filename);
failure("ACL entry on file %s that shouldn't be there",
filename);
assert(matched == 1);
}
@ -368,7 +663,8 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
* Iterate over acls in entry, try to match each
* one with an item in the myacls array.
*/
assertEqualInt(n, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
assertEqualInt(n, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
while (ARCHIVE_OK == archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) {
@ -403,54 +699,110 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
}
free(marker);
}
#endif
#endif /* HAVE_NFS4_ACL */
/*
* Verify ACL restore-to-disk. This test is FreeBSD-specific.
* Verify ACL restore-to-disk. This test is Platform-specific.
*/
DEFINE_TEST(test_acl_freebsd_nfs4)
DEFINE_TEST(test_acl_platform_nfs4)
{
#if !defined(__FreeBSD__)
skipping("FreeBSD-specific NFS4 ACL restore test");
#elif __FreeBSD__ < 8
skipping("NFS4 ACLs supported only on FreeBSD 8.0 and later");
#if !HAVE_NFS4_ACL
skipping("NFS4 ACLs are not supported on this platform");
#else
char buff[64];
struct stat st;
struct archive *a;
struct archive_entry *ae;
int i, n;
char *func;
#if HAVE_DARWIN_ACL /* On MacOS we skip trivial ACLs in some tests */
const int regcnt = acls_reg_cnt - 4;
const int dircnt = acls_dir_cnt - 4;
#else
const int regcnt = acls_reg_cnt;
const int dircnt = acls_dir_cnt;
#endif
#if HAVE_SUN_ACL
acl_t *acl;
#else /* !HAVE_SUN_ACL */
#if HAVE_DARWIN_ACL
acl_entry_t aclent;
acl_permset_t permset;
const uid_t uid = 1000;
uuid_t uuid;
#endif /* HAVE_DARWIN_ACL */
acl_t acl;
#endif /* !HAVE_SUN_ACL */
/*
* First, do a quick manual set/read of ACL data to
* verify that the local filesystem does support ACLs.
* If it doesn't, we'll simply skip the remaining tests.
*/
#if HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4
acl = acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
assert((void *)acl != NULL);
#elif HAVE_DARWIN_ACL
acl = acl_init(1);
assert((void *)acl != NULL);
assertEqualInt(0, acl_create_entry(&acl, &aclent));
assertEqualInt(0, acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW));
assertEqualInt(0, acl_get_permset(aclent, &permset));
assertEqualInt(0, acl_add_perm(permset, ACL_READ_DATA));
assertEqualInt(0, acl_add_perm(permset, ACL_WRITE_DATA));
assertEqualInt(0, acl_add_perm(permset, ACL_APPEND_DATA));
assertEqualInt(0, acl_add_perm(permset, ACL_EXECUTE));
assertEqualInt(0, acl_set_permset(aclent, permset));
assertEqualInt(0, mbr_identifier_to_uuid(ID_TYPE_UID, &uid,
sizeof(uid_t), uuid));
assertEqualInt(0, acl_set_qualifier(aclent, uuid));
#endif
/* Create a test dir and try to set an ACL on it. */
if (!assertMakeDir("pretest", 0755)) {
#if !HAVE_SUN_ACL
acl_free(acl);
#endif
return;
}
#if HAVE_SUN_ACL
func = "acl_get()";
n = acl_get("pretest", 0, &acl);
#else
func = "acl_set_file()";
#if HAVE_DARWIN_ACL
n = acl_set_file("pretest", ACL_TYPE_EXTENDED, acl);
#else
n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
#endif
acl_free(acl);
if (n != 0 && errno == EOPNOTSUPP) {
skipping("NFS4 ACL tests require that NFS4 ACLs"
" be enabled on the filesystem");
return;
#endif
if (n != 0) {
#if HAVE_SUN_ACL
if (errno == ENOSYS)
#else
if (errno == EOPNOTSUPP || errno == EINVAL)
#endif
{
skipping("NFS4 ACL is not supported on this filesystem");
return;
}
}
if (n != 0 && errno == EINVAL) {
skipping("This filesystem does not support NFS4 ACLs");
return;
}
failure("acl_set_file(): errno = %d (%s)",
errno, strerror(errno));
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
#if HAVE_SUN_ACL
if (acl->acl_type != ACE_T) {
acl_free(acl);
skipping("NFS4 ACL is not supported on this filesystem");
return;
}
acl_free(acl);
#endif
/* Create a write-to-disk object. */
assert(NULL != (a = archive_write_disk_new()));
archive_write_disk_set_options(a,
@ -464,7 +816,7 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
archive_entry_set_perm(ae, 0654);
archive_entry_set_mtime(ae, 123456, 7890);
archive_entry_set_size(ae, 0);
set_acls(ae, acls_reg, 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
set_acls(ae, acls_reg, 0, acls_reg_cnt);
/* Write the entry to disk, including ACLs. */
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
@ -474,10 +826,10 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
archive_entry_set_filetype(ae, AE_IFDIR);
archive_entry_set_perm(ae, 0654);
archive_entry_set_mtime(ae, 123456, 7890);
set_acls(ae, acls_dir, 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
set_acls(ae, acls_dir, 0, acls_dir_cnt);
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
for (i = 0; i < acls_dir_cnt; ++i) {
sprintf(buff, "dir%d", i);
archive_entry_set_pathname(ae, buff);
archive_entry_set_filetype(ae, AE_IFDIR);
@ -496,28 +848,62 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
/* Verify the data on disk. */
assertEqualInt(0, stat("testall", &st));
assertEqualInt(st.st_mtime, 123456);
#if HAVE_SUN_ACL
n = acl_get("testall", 0, &acl);
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file("testall", ACL_TYPE_EXTENDED);
#else
acl = acl_get_file("testall", ACL_TYPE_NFS4);
#endif
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
assert(acl != (acl_t)NULL);
compare_acls(acl, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
#endif
compare_acls(acl, acls_reg, "testall", 0, regcnt);
acl_free(acl);
/* Verify single-permission dirs on disk. */
for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
sprintf(buff, "dir%d", i);
assertEqualInt(0, stat(buff, &st));
assertEqualInt(st.st_mtime, 123456 + i);
acl = acl_get_file(buff, ACL_TYPE_NFS4);
assert(acl != (acl_t)NULL);
compare_acls(acl, acls_dir, buff, i, i + 1);
acl_free(acl);
for (i = 0; i < dircnt; ++i) {
sprintf(buff, "dir%d", i);
assertEqualInt(0, stat(buff, &st));
assertEqualInt(st.st_mtime, 123456 + i);
#if HAVE_SUN_ACL
n = acl_get(buff, 0, &acl);
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file(buff, ACL_TYPE_EXTENDED);
#else
acl = acl_get_file(buff, ACL_TYPE_NFS4);
#endif
failure("acl_get_file(): errno = %d (%s)", errno,
strerror(errno));
assert(acl != (acl_t)NULL);
#endif
compare_acls(acl, acls_dir, buff, i, i + 1);
acl_free(acl);
}
/* Verify "dirall" on disk. */
assertEqualInt(0, stat("dirall", &st));
assertEqualInt(st.st_mtime, 123456);
#if HAVE_SUN_ACL
n = acl_get("dirall", 0, &acl);
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
#if HAVE_DARWIN_ACL
acl = acl_get_file("dirall", ACL_TYPE_EXTENDED);
#else
acl = acl_get_file("dirall", ACL_TYPE_NFS4);
#endif
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
assert(acl != (acl_t)NULL);
compare_acls(acl, acls_dir, "dirall", 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
#endif
compare_acls(acl, acls_dir, "dirall", 0, dircnt);
acl_free(acl);
/* Read and compare ACL via archive_read_disk */
@ -528,7 +914,7 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
archive_entry_set_pathname(ae, "testall");
assertEqualInt(ARCHIVE_OK,
archive_read_disk_entry_from_file(a, ae, -1, NULL));
compare_entry_acls(ae, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
compare_entry_acls(ae, acls_reg, "testall", 0, acls_reg_cnt);
archive_entry_free(ae);
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
@ -539,9 +925,9 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
assert(ae != NULL);
archive_entry_set_pathname(ae, "dirall");
assertEqualInt(ARCHIVE_OK,
archive_read_disk_entry_from_file(a, ae, -1, NULL));
compare_entry_acls(ae, acls_dir, "dirall", 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
archive_read_disk_entry_from_file(a, ae, -1, NULL));
compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt);
archive_entry_free(ae);
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
#endif
#endif /* HAVE_NFS4_ACL */
}

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2008 Tim Kientzle
* Copyright (c) 2017 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -25,8 +26,14 @@
#include "test.h"
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $");
#if defined(__FreeBSD__) && __FreeBSD__ > 4
#if HAVE_POSIX_ACL || HAVE_SUN_ACL
#include <sys/acl.h>
#if HAVE_ACL_GET_PERM
#include <acl/libacl.h>
#define ACL_GET_PERM acl_get_perm
#elif HAVE_ACL_GET_PERM_NP
#define ACL_GET_PERM acl_get_perm_np
#endif
static struct archive_test_acl_t acls2[] = {
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
@ -48,18 +55,34 @@ static struct archive_test_acl_t acls2[] = {
};
static int
acl_entry_get_perm(acl_entry_t aclent) {
#if HAVE_SUN_ACL
acl_entry_get_perm(aclent_t *aclent)
#else
acl_entry_get_perm(acl_entry_t aclent)
#endif
{
int permset = 0;
#if HAVE_POSIX_ACL
acl_permset_t opaque_ps;
#endif
#if HAVE_SUN_ACL
if (aclent->a_perm & 1)
permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
if (aclent->a_perm & 2)
permset |= ARCHIVE_ENTRY_ACL_WRITE;
if (aclent->a_perm & 4)
permset |= ARCHIVE_ENTRY_ACL_READ;
#else
/* translate the silly opaque permset to a bitmap */
acl_get_permset(aclent, &opaque_ps);
if (acl_get_perm_np(opaque_ps, ACL_EXECUTE))
if (ACL_GET_PERM(opaque_ps, ACL_EXECUTE))
permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
if (acl_get_perm_np(opaque_ps, ACL_WRITE))
if (ACL_GET_PERM(opaque_ps, ACL_WRITE))
permset |= ARCHIVE_ENTRY_ACL_WRITE;
if (acl_get_perm_np(opaque_ps, ACL_READ))
if (ACL_GET_PERM(opaque_ps, ACL_READ))
permset |= ARCHIVE_ENTRY_ACL_READ;
#endif
return permset;
}
@ -105,45 +128,96 @@ acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_ta
#endif
static int
#if HAVE_SUN_ACL
acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl)
#else
acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
#endif
{
#if HAVE_POSIX_ACL
gid_t g, *gp;
uid_t u, *up;
acl_tag_t tag_type;
#endif
if (myacl->permset != acl_entry_get_perm(aclent))
return (0);
#if HAVE_SUN_ACL
switch (aclent->a_type)
#else
acl_get_tag_type(aclent, &tag_type);
switch (tag_type) {
switch (tag_type)
#endif
{
#if HAVE_SUN_ACL
case DEF_USER_OBJ:
case USER_OBJ:
#else
case ACL_USER_OBJ:
#endif
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
break;
#if HAVE_SUN_ACL
case DEF_USER:
case USER:
#else
case ACL_USER:
#endif
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
return (0);
#if HAVE_SUN_ACL
if ((uid_t)myacl->qual != aclent->a_id)
return (0);
#else
up = acl_get_qualifier(aclent);
u = *up;
acl_free(up);
if ((uid_t)myacl->qual != u)
return (0);
#endif
break;
#if HAVE_SUN_ACL
case DEF_GROUP_OBJ:
case GROUP_OBJ:
#else
case ACL_GROUP_OBJ:
#endif
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
break;
#if HAVE_SUN_ACL
case DEF_GROUP:
case GROUP:
#else
case ACL_GROUP:
#endif
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
return (0);
#if HAVE_SUN_ACL
if ((gid_t)myacl->qual != aclent->a_id)
return (0);
#else
gp = acl_get_qualifier(aclent);
g = *gp;
acl_free(gp);
if ((gid_t)myacl->qual != g)
return (0);
#endif
break;
#if HAVE_SUN_ACL
case DEF_CLASS_OBJ:
case CLASS_OBJ:
#else
case ACL_MASK:
#endif
if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
break;
#if HAVE_SUN_ACL
case DEF_OTHER_OBJ:
case OTHER_OBJ:
#else
case ACL_OTHER:
#endif
if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0);
break;
}
@ -151,13 +225,22 @@ acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
}
static void
#if HAVE_SUN_ACL
compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n)
#else
compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
#endif
{
int *marker;
int entry_id = ACL_FIRST_ENTRY;
int matched;
int i;
#if HAVE_SUN_ACL
int e;
aclent_t *acl_entry;
#else
int entry_id = ACL_FIRST_ENTRY;
acl_entry_t acl_entry;
#endif
/* Count ACL entries in myacls array and allocate an indirect array. */
marker = malloc(sizeof(marker[0]) * n);
@ -170,9 +253,14 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
* Iterate over acls in system acl object, try to match each
* one with an item in the myacls array.
*/
#if HAVE_SUN_ACL
for(e = 0; e < acl->acl_cnt; e++) {
acl_entry = &((aclent_t *)acl->acl_aclp)[e];
#else
while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
/* After the first time... */
entry_id = ACL_NEXT_ENTRY;
#endif
/* Search for a matching entry (tag and qualifier) */
for (i = 0, matched = 0; i < n && !matched; i++) {
@ -205,30 +293,41 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
/*
* Verify ACL restore-to-disk. This test is FreeBSD-specific.
* Verify ACL restore-to-disk. This test is Platform-specific.
*/
DEFINE_TEST(test_acl_freebsd_posix1e_restore)
DEFINE_TEST(test_acl_platform_posix1e_restore)
{
#if !defined(__FreeBSD__)
skipping("FreeBSD-specific ACL restore test");
#elif __FreeBSD__ < 5
skipping("ACL restore supported only on FreeBSD 5.0 and later");
#else
#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
skipping("POSIX.1e ACLs are not supported on this platform");
#else /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
struct stat st;
struct archive *a;
struct archive_entry *ae;
int n, fd;
char *func;
#if HAVE_SUN_ACL
acl_t *acl, *acl2;
#else
acl_t acl;
#endif
/*
* First, do a quick manual set/read of ACL data to
* verify that the local filesystem does support ACLs.
* If it doesn't, we'll simply skip the remaining tests.
*/
#if HAVE_SUN_ACL
n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl);
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
assert((void *)acl != NULL);
/* Create a test file and try to set an ACL on it. */
#endif
/* Create a test file and try ACL on it. */
fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
failure("Could not create test file?!");
if (!assert(fd >= 0)) {
@ -236,21 +335,51 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
return;
}
n = acl_set_fd(fd, acl);
acl_free(acl);
if (n != 0 && errno == EOPNOTSUPP) {
#if HAVE_SUN_ACL
n = facl_get(fd, 0, &acl2);
if (n != 0) {
close(fd);
skipping("ACL tests require that ACL support be enabled on the filesystem");
acl_free(acl);
}
if (errno == ENOSYS) {
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
if (n != 0 && errno == EINVAL) {
close(fd);
skipping("This filesystem does not support POSIX.1e ACLs");
return;
}
failure("acl_set_fd(): errno = %d (%s)",
errno, strerror(errno));
failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
if (acl2->acl_type != ACLENT_T) {
acl_free(acl2);
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
acl_free(acl2);
func = "facl_set()";
n = facl_set(fd, acl);
#else
func = "acl_set_fd()";
n = acl_set_fd(fd, acl);
#endif
acl_free(acl);
if (n != 0) {
#if HAVE_SUN_ACL
if (errno == ENOSYS)
#else
if (errno == EOPNOTSUPP || errno == EINVAL)
#endif
{
close(fd);
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
}
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
#if HAVE_SUN_ACL
#endif
close(fd);
/* Create a write-to-disk object. */
@ -275,28 +404,38 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
/* Verify the data on disk. */
assertEqualInt(0, stat("test0", &st));
assertEqualInt(st.st_mtime, 123456);
#if HAVE_SUN_ACL
n = acl_get("test0", 0, &acl);
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
acl = acl_get_file("test0", ACL_TYPE_ACCESS);
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
assert(acl != (acl_t)NULL);
#endif
compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0]));
acl_free(acl);
#endif
#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
}
/*
* Verify ACL read-from-disk. This test is FreeBSD-specific.
* Verify ACL read-from-disk. This test is Platform-specific.
*/
DEFINE_TEST(test_acl_freebsd_posix1e_read)
DEFINE_TEST(test_acl_platform_posix1e_read)
{
#if !defined(__FreeBSD__)
skipping("FreeBSD-specific ACL read test");
#elif __FreeBSD__ < 5
skipping("ACL read supported only on FreeBSD 5.0 and later");
#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
skipping("POSIX.1e ACLs are not supported on this platform");
#else
struct archive *a;
struct archive_entry *ae;
int n, fd;
const char *acl1_text, *acl2_text;
acl_t acl1, acl2;
int n, fd, flags, dflags;
char *func, *acl_text;
const char *acl1_text, *acl2_text, *acl3_text;
#if HAVE_SUN_ACL
acl_t *acl, *acl1, *acl2, *acl3;
#else
acl_t acl1, acl2, acl3;
#endif
/*
* Manually construct a directory and two files with
@ -305,6 +444,17 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
*/
/* Create a test file f1 with acl1 */
#if HAVE_SUN_ACL
acl1_text = "user::rwx,"
"group::rwx,"
"other:rwx,"
"user:1:rw-,"
"group:15:r-x,"
"mask:rwx";
n = acl_fromtext(acl1_text, &acl1);
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
acl1_text = "user::rwx\n"
"group::rwx\n"
"other::rwx\n"
@ -312,28 +462,59 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
"group:15:r-x\n"
"mask::rwx";
acl1 = acl_from_text(acl1_text);
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
assert((void *)acl1 != NULL);
#endif
fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
failure("Could not create test file?!");
if (!assert(fd >= 0)) {
acl_free(acl1);
return;
}
n = acl_set_fd(fd, acl1);
acl_free(acl1);
if (n != 0 && errno == EOPNOTSUPP) {
#if HAVE_SUN_ACL
/* Check if Solars filesystem supports POSIX.1e ACLs */
n = facl_get(fd, 0, &acl);
if (n != 0)
close(fd);
skipping("ACL tests require that ACL support be enabled on the filesystem");
if (n != 0 && errno == ENOSYS) {
acl_free(acl1);
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
if (n != 0 && errno == EINVAL) {
close(fd);
skipping("This filesystem does not support POSIX.1e ACLs");
return;
}
failure("acl_set_fd(): errno = %d (%s)",
errno, strerror(errno));
failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
if (acl->acl_type != ACLENT_T) {
acl_free(acl);
acl_free(acl1);
close(fd);
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
func = "facl_set()";
n = facl_set(fd, acl1);
#else
func = "acl_set_fd()";
n = acl_set_fd(fd, acl1);
#endif
acl_free(acl1);
if (n != 0) {
#if HAVE_SUN_ACL
if (errno == ENOSYS)
#else
if (errno == EOPNOTSUPP || errno == EINVAL)
#endif
{
close(fd);
skipping("POSIX.1e ACLs are not supported on this filesystem");
return;
}
}
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
close(fd);
assertMakeDir("d", 0700);
@ -349,6 +530,17 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
* to read ACLs, resulting in reading the ACL from a like-named
* file in the wrong directory.
*/
#if HAVE_SUN_ACL
acl2_text = "user::rwx,"
"group::rwx,"
"other:---,"
"user:1:r--,"
"group:15:r--,"
"mask:rwx";
n = acl_fromtext(acl2_text, &acl2);
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
acl2_text = "user::rwx\n"
"group::rwx\n"
"other::---\n"
@ -356,46 +548,106 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
"group:15:r--\n"
"mask::rwx";
acl2 = acl_from_text(acl2_text);
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
assert((void *)acl2 != NULL);
#endif
fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
failure("Could not create test file?!");
if (!assert(fd >= 0)) {
acl_free(acl2);
return;
}
#if HAVE_SUN_ACL
func = "facl_set()";
n = facl_set(fd, acl2);
#else
func = "acl_set_fd()";
n = acl_set_fd(fd, acl2);
#endif
acl_free(acl2);
if (n != 0 && errno == EOPNOTSUPP) {
if (n != 0)
close(fd);
skipping("ACL tests require that ACL support be enabled on the filesystem");
return;
}
if (n != 0 && errno == EINVAL) {
close(fd);
skipping("This filesystem does not support POSIX.1e ACLs");
return;
}
failure("acl_set_fd(): errno = %d (%s)",
errno, strerror(errno));
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
close(fd);
/* Create directory d2 with default ACLs */
assertMakeDir("d2", 0755);
#if HAVE_SUN_ACL
acl3_text = "user::rwx,"
"group::r-x,"
"other:r-x,"
"user:2:r--,"
"group:16:-w-,"
"mask:rwx,"
"default:user::rwx,"
"default:user:1:r--,"
"default:group::r-x,"
"default:group:15:r--,"
"default:mask:rwx,"
"default:other:r-x";
n = acl_fromtext(acl3_text, &acl3);
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
assertEqualInt(0, n);
#else
acl3_text = "user::rwx\n"
"user:1:r--\n"
"group::r-x\n"
"group:15:r--\n"
"mask::rwx\n"
"other::r-x";
acl3 = acl_from_text(acl3_text);
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
assert((void *)acl3 != NULL);
#endif
#if HAVE_SUN_ACL
func = "acl_set()";
n = acl_set("d2", acl3);
#else
func = "acl_set_file()";
n = acl_set_file("d2", ACL_TYPE_DEFAULT, acl3);
#endif
acl_free(acl3);
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
assertEqualInt(0, n);
/* Create a read-from-disk object. */
assert(NULL != (a = archive_read_disk_new()));
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
assert(NULL != (ae = archive_entry_new()));
#if HAVE_SUN_ACL
flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E
| ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA
| ARCHIVE_ENTRY_ACL_STYLE_SOLARIS;
dflags = flags;
#else
flags = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
dflags = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
#endif
/* Walk the dir until we see both of the files */
while (ARCHIVE_OK == archive_read_next_header2(a, ae)) {
archive_read_disk_descend(a);
if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl1_text);
acl_text = archive_entry_acl_to_text(ae, NULL, flags);
assertEqualString(acl_text, acl1_text);
free(acl_text);
} else if (strcmp(archive_entry_pathname(ae), "./d/f1") == 0) {
assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl2_text);
acl_text = archive_entry_acl_to_text(ae, NULL, flags);
assertEqualString(acl_text, acl2_text);
free(acl_text);
} else if (strcmp(archive_entry_pathname(ae), "./d2") == 0) {
acl_text = archive_entry_acl_to_text(ae, NULL, dflags);
assertEqualString(acl_text, acl3_text);
free(acl_text);
}
}
archive_free(a);
archive_entry_free(ae);
assertEqualInt(ARCHIVE_OK, archive_free(a));
#endif
}

View file

@ -242,8 +242,8 @@ convert_s_to_ws(const char *s)
static void
compare_acl_text(struct archive_entry *ae, int flags, const char *s)
{
const char *text;
const wchar_t *wtext;
char *text;
wchar_t *wtext;
wchar_t *ws;
ssize_t slen;
@ -257,9 +257,10 @@ compare_acl_text(struct archive_entry *ae, int flags, const char *s)
assertEqualWString(wtext, ws);
if (wtext != NULL) {
assertEqualInt(wcslen(wtext), slen);
free(ws);
ws = NULL;
}
free(text);
free(wtext);
free(ws);
}
DEFINE_TEST(test_acl_from_text)
@ -395,6 +396,9 @@ DEFINE_TEST(test_acl_from_text)
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
archive_entry_acl_clear(ae);
free(ws);
archive_entry_free(ae);
}
DEFINE_TEST(test_acl_to_text)
@ -453,4 +457,6 @@ DEFINE_TEST(test_acl_to_text)
/* NFSv4 ACLs like "getfacl -i" on FreeBSD */
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[10]);
archive_entry_free(ae);
}

View file

@ -67,6 +67,8 @@ test_archive_string_ensure(void)
assert(&s == archive_string_ensure(&s, EXTENT + 1));
assertNonNULLString(0, 2 * EXTENT, s);
archive_string_free(&s);
}
static void
@ -92,6 +94,8 @@ test_archive_strcat(void)
/* non-empty target, non-empty source */
assert(&s == archive_strcat(&s, "baz"));
assertExactString(8, EXTENT, "fubarbaz", s);
archive_string_free(&s);
}
static void
@ -109,6 +113,8 @@ test_archive_strappend_char(void)
/* non-empty target */
archive_strappend_char(&s, 'Y');
assertExactString(2, EXTENT, "XY", s);
archive_string_free(&s);
}
/* archive_strnXXX() tests focus on length handling.
@ -134,6 +140,8 @@ test_archive_strncat(void)
/* long read is ok too! */
assert(&s == archive_strncat(&s, "snafu", 8));
assertExactString(13, EXTENT, "snafubarsnafu", s);
archive_string_free(&s);
}
static void
@ -155,6 +163,8 @@ test_archive_strncpy(void)
/* long read is ok too! */
assert(&s == archive_strncpy(&s, "snafu", 8));
assertExactString(5, EXTENT, "snafu", s);
archive_string_free(&s);
}
static void
@ -176,6 +186,8 @@ test_archive_strcpy(void)
/* dirty target, empty source */
assert(&s == archive_strcpy(&s, ""));
assertExactString(0, EXTENT, "", s);
archive_string_free(&s);
}
static void
@ -222,6 +234,11 @@ test_archive_string_concat(void)
archive_string_concat(&t, &s);
assertExactString(5, EXTENT, "snafu", s);
assertExactString(5, EXTENT, "snafu", t);
archive_string_free(&v);
archive_string_free(&u);
archive_string_free(&t);
archive_string_free(&s);
}
static void
@ -274,6 +291,11 @@ test_archive_string_copy(void)
archive_string_copy(&t, &s);
assertExactString(5, EXTENT, "fubar", s);
assertExactString(5, EXTENT, "fubar", t);
archive_string_free(&v);
archive_string_free(&u);
archive_string_free(&t);
archive_string_free(&s);
}
static void
@ -328,6 +350,8 @@ test_archive_string_sprintf(void)
archive_string_empty(&s);
archive_string_sprintf(&s, "%d", 1234567890);
assertExactString(10, 8 * EXTENT, "1234567890", s);
archive_string_free(&s);
}
DEFINE_TEST(test_archive_string)

View file

@ -142,6 +142,8 @@ test_compat_gtar_2(void)
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR);
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
DEFINE_TEST(test_compat_gtar)

View file

@ -1,5 +1,6 @@
/*-
* Copyright (c) 2003-2009 Tim Kientzle
* Copyright (c) 2016 Martin Matuska
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -26,101 +27,239 @@
__FBSDID("$FreeBSD$");
/*
* Exercise support for reading Solaris-style ACL data
* from tar archives.
* Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created
* with Solaris tar.
*
* This should work on all systems, regardless of whether local
* filesystems support ACLs or not.
* This should work on all systems, regardless of whether local filesystems
* support ACLs or not.
*/
static struct archive_test_acl_t acls0[] = {
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE |
ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
ARCHIVE_ENTRY_ACL_USER, 71, "lp" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_USER, 666, "666" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_USER, 1000, "1000" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
};
static struct archive_test_acl_t acls1[] = {
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
};
static struct archive_test_acl_t acls2[] = {
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" },
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0,
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
};
static struct archive_test_acl_t acls3[] = {
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_WRITE_ACL |
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_GROUP, 12, "daemon" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_GROUP, 2, "bin" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_USER, 4, "adm" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_WRITE_ACL |
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
};
static struct archive_test_acl_t acls4[] = {
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_WRITE_ACL |
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT |
ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
ARCHIVE_ENTRY_ACL_USER, 1100, "1100" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
ARCHIVE_ENTRY_ACL_GROUP, 4, "adm" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_WRITE_DATA |
ARCHIVE_ENTRY_ACL_APPEND_DATA |
ARCHIVE_ENTRY_ACL_DELETE_CHILD |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_WRITE_ACL |
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_EXECUTE |
ARCHIVE_ENTRY_ACL_READ_DATA |
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
ARCHIVE_ENTRY_ACL_READ_ACL |
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
};
DEFINE_TEST(test_compat_solaris_tar_acl)
{
char name[] = "test_compat_solaris_tar_acl.tar";
struct archive *a;
struct archive_entry *ae;
const char *reference1 = "test_compat_solaris_tar_acl.tar";
int type, permset, tag, qual;
const char *name;
/* Sample file generated on Solaris 10 */
extract_reference_file(reference1);
/* Read archive file */
assert(NULL != (a = archive_read_new()));
assertA(0 == archive_read_support_format_all(a));
assertA(0 == archive_read_support_filter_all(a));
assertA(0 == archive_read_open_filename(a, reference1, 512));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
extract_reference_file(name);
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name,
10240));
/* Archive has 1 entry with some ACLs set on it. */
/* First item has access ACLs */
assertA(0 == archive_read_next_header(a, &ae));
failure("One extended ACL should flag all ACLs to be returned.");
assertEqualInt(7, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0644);
failure("Basic ACLs should set mode to 0644, not %04o",
archive_entry_mode(ae)&0777);
assertEqualInt((archive_entry_mode(ae) & 0777), 0644);
assertEqualInt(7, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
assertEqualInt(006, permset);
assertEqualInt(ARCHIVE_ENTRY_ACL_USER_OBJ, tag);
assertEqualInt(-1, qual);
assert(name == NULL);
assert((archive_entry_mode(ae) & 0777) == 0644);
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
assertEqualInt(004, permset);
assertEqualInt(ARCHIVE_ENTRY_ACL_GROUP_OBJ, tag);
assertEqualInt(-1, qual);
assert(name == NULL);
/* Second item has default and access ACLs */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0750);
failure("Basic ACLs should set mode to 0750, not %04o",
archive_entry_mode(ae)&0777);
assert((archive_entry_mode(ae) & 0777) == 0750);
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0750);
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
assertEqualInt(004, permset);
assertEqualInt(ARCHIVE_ENTRY_ACL_OTHER, tag);
assertEqualInt(-1, qual);
assert(name == NULL);
/* Third item has NFS4 ACLs */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(6, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
assertEqualInt(001, permset);
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
assertEqualInt(71, qual);
assertEqualString(name, "lp");
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
assertEqualInt(004, permset);
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
assertEqualInt(666, qual);
assertEqualString(name, "666");
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
assertEqualInt(007, permset);
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
assertEqualInt(1000, qual);
assertEqualString(name, "trasz");
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
assertEqualInt(004, permset);
assertEqualInt(ARCHIVE_ENTRY_ACL_MASK, tag);
assertEqualInt(-1, qual);
assertEqualString(name, NULL);
assertEqualInt(ARCHIVE_EOF, archive_entry_acl_next(ae,
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
&type, &permset, &tag, &qual, &name));
/* Fourth item has NFS4 ACLs and inheritance flags */
assertA(0 == archive_read_next_header(a, &ae));
assertEqualInt(5, archive_entry_acl_reset(ae,
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
/* Close the archive. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));

View file

@ -1,61 +1,163 @@
$FreeBSD$
begin 644 test_acl_solaris.tar
M9FEL92UW:71H+7!O<VEX+6%C;',`````````````````````````````````
M````````````````````````````````````````````````````````````
M`````````````#`P,#`V-#0`,#`P,3<U,``P,#`P,#`P`#`P,#`P,#`P,30T
M`#$Q,3<T-C`T,34W`#`P,34Q-S8`00``````````````````````````````
M````````````````````````````````````````````````````````````
M``````````````````````````````````````````!U<W1A<@`P,'1R87-Z
M````````````````````````````````````<F]O=```````````````````
M```````````````````P,#`P,C$P`#`P,#`P,3``````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M```````````````````````Q,#`P,#`W`'5S97(Z.G)W+2QU<V5R.FQP.BTM
M>#HW,2QU<V5R.C8V-CIR+2TZ-C8V+'5S97(Z=')A<WHZ<G=X.C$P,#`L9W)O
M=7`Z.G(M+2QM87-K.G(M+2QO=&AE<CIR+2T``````````3````````/-@```
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````!%&8`````````&L`````,3`P,#`P-P!U
begin 644 test_compat_solaris_tar_acl.tar
M9FEL92UW:71H+7!O<VEX+6%C;',
M
M # P,# V-#0 ,# P,3<U, P,# P,# P # P,# P,# P,30S
M #$Q,3<T-C T,34W # P,30Q,C$ 00
M
M !U<W1A<@ P,
M <F]O=
M P,# P-#$T # P,# P,#,
M
M
M
M Q,# P,# W '5S97(Z.G)W+2QU<V5R.FQP.BTM
M>#HW,2QU<V5R.C8V-CIR+2TZ-C8V+'5S97(Z,3 P,#IR=W@Z,3 P,"QG<F]U
M<#HZ<BTM+&UA<VLZ<BTM+&]T:&5R.G(M+0 # !
M
M
M
M
M
M
M (Q@@( &L ,3 P,# P-P!U
M<V5R.CIR=RTL=7-E<CIL<#HM+7@Z-S$L=7-E<CHV-C8Z<BTM.C8V-BQU<V5R
M.G1R87-Z.G)W>#HQ,#`P+&=R;W5P.CIR+2TL;6%S:SIR+69I;&4M=VET:"UP
M;W-I>"UA8VQS````````````````````````````````````````````````
M```````````````````````````````````````````````````````````P
M,#`P-C0T`#`P,#$W-3``,#`P,#`P,``P,#`P,#`P,#`P,``Q,3$W-#8P-#$U
M-P`P,#$U,30T`#``````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````=7-T87(`,#!T<F%S>@``````````````
M`````````````````````')O;W0`````````````````````````````````
M````,#`P,#(Q,``P,#`P,#$P````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
M````````````````````````````````````````````````````````````
H````````````````````````````````````````````````````````
`
M.C$P,# Z<G=X.C$P,# L9W)O=7 Z.G(M+2QM87-K.G(M+69I;&4M=VET:"UP
M;W-I>"UA8VQS
M P
M,# P-C0T # P,#$W-3 ,# P,# P, P,# P,# P,# P, Q,3$W-#8P-#$U
M-P P,#$T,#<P #
M
M =7-T87( ,#
M ')O;W0
M ,# P,#0Q- P,# P,# S
M
M
M
M 9&ER+7=I=&@M<&]S:7@M86-L<R\
M
M # P,# W-3 ,# P,3<U, P,# P,# P # P,# P
M,# P,S P #$S,#,V-3$R,C4T # P,30P,C, 00
M
M !U<W1A<@ P
M, <F]O=
M P,# P-#$T # P,# P,#,
M
M
M
M Q,# P,#$T '5S97(Z.G)W>"QU<V5R
M.F)I;CIR=W@Z,BQG<F]U<#HZ<BUX+&=R;W5P.G-Y<SIR+7@Z,RQM87-K.G(M
M>"QO=&AE<CHM+2TL9&5F875L='5S97(Z.G)W>"QD969A=6QT=7-E<CIB:6XZ
M<G=X.C(L9&5F875L=&=R;W5P.CIR+7@L9&5F875L=&=R;W5P.G-Y<SIR+7@Z
M,RQD969A=6QT;6%S:SIR=W@L9&5F875L=&]T:&5R.BTM+0 @ #C%
M" @
M
M
M
M
M
M &1I<BUW
M:71H+7!O<VEX+6%C;',O
M
M P,# P-S4P # P,#$W-3 ,# P,# P, P,# P,# P,# P, Q,S S
M-C4Q,C(U- P,#$T,# T #4
M
M =7-T87( ,#
M ')O;W0
M ,# P,#0Q- P,# P,# S
M
M
M
M 9FEL92UW:71H+6YF<W8T+6%C;',
M
M # P,# V-# ,# P,3<U, P,# P,# P
M # P,# P,# P,S8T #$S,#,V-3$S-C0Q # P,30P,34 00
M
M !U
M<W1A<@ P, <F]O=
M P,# P-#$T # R,# P,#(
M
M
M
M S,# P,# V &=R;W5P.F1A
M96UO;CIR=WAP+2UA05)78T-O<SHM+2TM+2TM.F1E;GDZ,3(L9W)O=7 Z8FEN
M.G)W>' M+2TM+2TM+2US.BTM+2TM+2TZ86QL;W<Z,BQU<V5R.F%D;3IR+2TM
M+2UA+5(M8RTM<SHM+2TM+2TM.F%L;&]W.C0L;W=N97) .G)W+7 M+6%!4E=C
M0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7! .G(M+2TM+6$M4BUC+2US.BTM+2TM
M+2TZ86QL;W<L979E<GEO;F5 .BTM+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL
M;W< &@
M
M F-8(" #[ #,P,# P,#8
M9W)O=7 Z9&%E;6]N.G)W>' M+6%!4E=C0V]S.BTM+2TM+2TZ9&5N>3HQ,BQG
M<F]U<#IB:6XZ<G=X<"TM+2TM+2TM+7,Z+2TM+2TM+3IA;&QO=SHR+'5S97(Z
M861M.G(M+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL;W<Z-"QO=VYE<D Z<G<M
M<&9I;&4M=VET:"UN9G-V-"UA8VQS
M
M P,# P-C0P # P,#$W-3 ,# P,# P, P,# P,# P,# P
M, Q,S S-C4Q,S8T,0 P,#$S-S4W #
M
M =7-T87( ,#
M ')O;W0
M ,# P,#0Q- P,C P,# R
M
M
M
M 9&ER+7=I=&@M;F9S=C0M86-L<R\
M
M # P,# W-3 ,# P,# P, P
M,# P,# P # P,# P,# P,S$T #$S,#,V-3$S-S,U # P,30V,C, 00
M
M
M !U<W1A<@ P,')O;W0
M<F]O= P,# P-#$T # R,# P
M,#(
M
M
M S,# P,# U '5S
M97(Z,3$P,#IR=WAP+2UA05)78T-O<SIF9&DM+2TM.F%L;&]W.C$Q,# L9W)O
M=7 Z861M.G(M+2TM+6$M4BUC+2US.F9D+2TM+2TZ86QL;W<Z-"QO=VYE<D Z
M<G=X<"U$84%25V-#;W,Z+2TM+2TM+3IA;&QO=RQG<F]U<$ Z<BUX+2TM82U2
M+6,M+7,Z+2TM+2TM+3IA;&QO=RQE=F5R>6]N94 Z+2TM+2TM82U2+6,M+7,Z
M+2TM+2TM+3IA;&QO=P 4
M
M "HUP@( -, ,S P,# P-0!U<V5R.C$Q,# Z<G=X
M<"TM84%25V-#;W,Z9F1I+2TM+3IA;&QO=SHQ,3 P+&=R;W5P.F%D;3IR+2TM
M+2UA+5(M8RTM<SIF9"TM+2TM.F%L;&]W.C0L;W=N97) .G)W>' M1&%!4E=C
M0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7! .G(M>"TM+6$M4BUC+2US.BTM+2TM
M+2TZ86QL;W<L979E<GEO;F5 .BTM+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL
M;W< &1I<BUW:71H+6YF<W8T+6%C;',O
M
M P,# P-S4P # P,# P,# ,# P,# P, P,# P
M,# P,# P, Q,S S-C4Q,S<S-0 P,#$T-3<W #4
M
M =7-T87(
M,#!R;V]T ')O;W0
M ,# P,#0Q- P,C P,# R
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
M
-
end

View file

@ -406,10 +406,12 @@ DEFINE_TEST(test_fuzz_tar)
"test_read_format_tar_empty_filename.tar",
NULL
};
#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H
static const char *fileset9[] = {
"test_compat_lzop_1.tar.lzo",
NULL
};
#endif
static const struct files filesets[] = {
{0, fileset1}, /* Exercise bzip2 decompressor. */
{1, fileset1},
@ -420,7 +422,9 @@ DEFINE_TEST(test_fuzz_tar)
{0, fileset6}, /* Exercise xz decompressor. */
{0, fileset7},
{0, fileset8},
#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H
{0, fileset9}, /* Exercise lzo decompressor. */
#endif
{1, NULL}
};
test_fuzz(filesets);

View file

@ -1320,11 +1320,13 @@ test_callbacks(void)
assertUtimes("cb", 886622, 0, 886622, 0);
assert((ae = archive_entry_new()) != NULL);
if (assert((a = archive_read_disk_new()) != NULL)) {
assert((a = archive_read_disk_new()) != NULL);
if (a == NULL) {
archive_entry_free(ae);
return;
}
if (assert((m = archive_match_new()) != NULL)) {
assert((m = archive_match_new()) != NULL);
if (m == NULL) {
archive_entry_free(ae);
archive_read_free(a);
archive_match_free(m);
@ -1377,6 +1379,10 @@ test_callbacks(void)
/* Close the disk object. */
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
/* Reset name filter */
assertEqualIntA(a, ARCHIVE_OK,
archive_read_disk_set_matching(a, NULL, NULL, NULL));
/*
* Test2: Traversals with a metadata filter.
*/
@ -1394,7 +1400,7 @@ test_callbacks(void)
while (file_count--) {
archive_entry_clear(ae);
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
failure("File 'cb/f1' should be exclueded");
failure("File 'cb/f1' should be excluded");
assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0);
if (strcmp(archive_entry_pathname(ae), "cb") == 0) {
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);

View file

@ -39,13 +39,16 @@ DEFINE_TEST(test_read_filter_lzop)
assert((a = archive_read_new()) != NULL);
r = archive_read_support_filter_lzop(a);
if (r != ARCHIVE_OK) {
if (r == ARCHIVE_WARN && !canLzop()) {
if (!canLzop()) {
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
skipping("lzop compression is not supported "
"on this platform");
} else
return;
} else if (r != ARCHIVE_WARN) {
assertEqualIntA(a, ARCHIVE_OK, r);
return;
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK,

View file

@ -36,12 +36,16 @@ DEFINE_TEST(test_read_filter_lzop_multiple_parts)
assert((a = archive_read_new()) != NULL);
r = archive_read_support_filter_lzop(a);
if (r != ARCHIVE_OK) {
if (r == ARCHIVE_WARN && !canLzop()) {
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
if (!canLzop()) {
skipping("lzop compression is not supported "
"on this platform");
} else if (r == ARCHIVE_WARN) {
skipping("lzop multiple parts decoding is not "
"supported via external program");
} else
assertEqualIntA(a, ARCHIVE_OK, r);
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
return;
}
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));

View file

@ -126,6 +126,7 @@ test_basic(void)
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
verify_basic(a, 0);
free(p);
}
/*
@ -195,6 +196,7 @@ test_info_zip_ux(void)
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
verify_info_zip_ux(a, 0);
free(p);
}
/*
@ -258,6 +260,7 @@ test_extract_length_at_end(void)
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
verify_extract_length_at_end(a, 0);
free(p);
}
static void
@ -294,6 +297,8 @@ test_symlink(void)
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(p);
}
DEFINE_TEST(test_read_format_zip)

View file

@ -63,6 +63,8 @@ verify(const char *refname)
assertEqualInt(archive_entry_is_encrypted(ae), 0);
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(p);
}
DEFINE_TEST(test_read_format_zip_comment_stored)

View file

@ -112,4 +112,6 @@ DEFINE_TEST(test_read_format_zip_mac_metadata)
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(p);
}

View file

@ -53,6 +53,7 @@ test_malformed1(void)
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(p);
}
DEFINE_TEST(test_read_format_zip_malformed)

View file

@ -65,6 +65,8 @@ DEFINE_TEST(test_read_format_zip_nested)
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(p);
/* Inspect inner Zip. */
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));

View file

@ -53,6 +53,8 @@ verify_padded_archive(const char *refname)
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(p);
}
/*

View file

@ -60,4 +60,6 @@ DEFINE_TEST(test_read_format_zip_sfx)
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
free(p);
}

View file

@ -72,6 +72,9 @@ DEFINE_TEST(test_write_disk_secure746a)
/* Verify that target file contents are unchanged. */
assertTextFileContents("unmodified", "../target/foo");
assertEqualIntA(a, ARCHIVE_FATAL, archive_write_close(a));
archive_write_free(a);
#endif
}

View file

@ -56,6 +56,7 @@ DEFINE_TEST(test_write_filter_lz4)
} else {
assertEqualInt(ARCHIVE_OK, r);
}
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
buffsize = 2000000;
assert(NULL != (buff = (char *)malloc(buffsize)));
@ -299,6 +300,7 @@ test_options(const char *options)
} else {
assertEqualInt(ARCHIVE_OK, r);
}
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
buffsize = 2000000;
assert(NULL != (buff = (char *)malloc(buffsize)));

View file

@ -43,12 +43,12 @@ DEFINE_TEST(test_write_filter_lzop)
assert((a = archive_write_new()) != NULL);
r = archive_write_add_filter_lzop(a);
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
if (r != ARCHIVE_OK) {
if (canLzop() && r == ARCHIVE_WARN)
use_prog = 1;
else {
skipping("lzop writing not supported on this platform");
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
return;
}
}
@ -92,7 +92,7 @@ DEFINE_TEST(test_write_filter_lzop)
assert((a = archive_read_new()) != NULL);
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
r = archive_read_support_filter_lzop(a);
if (r == ARCHIVE_WARN) {
if (r == ARCHIVE_WARN && !use_prog) {
skipping("Can't verify lzop writing by reading back;"
" lzop reading not fully supported on this platform");
} else {
@ -212,7 +212,7 @@ DEFINE_TEST(test_write_filter_lzop)
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
r = archive_read_support_filter_lzop(a);
if (r == ARCHIVE_WARN) {
if (r == ARCHIVE_WARN && !use_prog) {
skipping("lzop reading not fully supported on this platform");
} else {
assertEqualIntA(a, ARCHIVE_OK,

View file

@ -470,5 +470,6 @@ DEFINE_TEST(test_write_format_zip_large)
assertEqualMem(cd_start, "PK\001\002", 4);
fileblocks_free(fileblocks);
free(buff);
free(nulldata);
}

View file

@ -49,6 +49,8 @@ verify_zip_filesize(uint64_t size, int expected)
archive_entry_set_size(ae, size);
assertEqualInt(expected, archive_write_header(a, ae));
archive_entry_free(ae);
/* Don't actually write 4GB! ;-) */
assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
}

View file

@ -45,25 +45,25 @@ DEFINE_TEST(test_option_uid_uname)
/* Again with both --uid and --uname */
failure("Error invoking %s c", testprog);
assertEqualInt(0,
systemf("%s cf archive2 --uid=17 --uname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt",
systemf("%s cf archive2 --uid=65123 --uname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt",
testprog));
assertEmptyFile("stdout2.txt");
assertEmptyFile("stderr2.txt");
data = slurpfile(&s, "archive2");
/* Should force uid and uname fields in ustar header. */
assertEqualMem(data + 108, "000021 \0", 8);
assertEqualMem(data + 108, "177143 \0", 8);
assertEqualMem(data + 265, "foofoofoo\0", 10);
free(data);
/* Again with just --uid */
failure("Error invoking %s c", testprog);
assertEqualInt(0,
systemf("%s cf archive3 --uid=17 --format=ustar file >stdout3.txt 2>stderr3.txt",
systemf("%s cf archive3 --uid=65123 --format=ustar file >stdout3.txt 2>stderr3.txt",
testprog));
assertEmptyFile("stdout3.txt");
assertEmptyFile("stderr3.txt");
data = slurpfile(&s, "archive3");
assertEqualMem(data + 108, "000021 \0", 8);
assertEqualMem(data + 108, "177143 \0", 8);
/* Uname field in ustar header should be empty. */
assertEqualMem(data + 265, "\0", 1);
free(data);

View file

@ -140,6 +140,7 @@ safe_fprintf(FILE *f, const char *fmt, ...)
} else {
/* Leave fmtbuff pointing to the truncated
* string in fmtbuff_stack. */
fmtbuff = fmtbuff_stack;
length = sizeof(fmtbuff_stack) - 1;
break;
}

View file

@ -495,10 +495,29 @@ namespace llvm {
/// The typedef for ExprValueMap.
///
typedef DenseMap<const SCEV *, SetVector<Value *>> ExprValueMapType;
typedef std::pair<Value *, ConstantInt *> ValueOffsetPair;
typedef DenseMap<const SCEV *, SetVector<ValueOffsetPair>> ExprValueMapType;
/// ExprValueMap -- This map records the original values from which
/// the SCEV expr is generated from.
///
/// We want to represent the mapping as SCEV -> ValueOffsetPair instead
/// of SCEV -> Value:
/// Suppose we know S1 expands to V1, and
/// S1 = S2 + C_a
/// S3 = S2 + C_b
/// where C_a and C_b are different SCEVConstants. Then we'd like to
/// expand S3 as V1 - C_a + C_b instead of expanding S2 literally.
/// It is helpful when S2 is a complex SCEV expr.
///
/// In order to do that, we represent ExprValueMap as a mapping from
/// SCEV to ValueOffsetPair. We will save both S1->{V1, 0} and
/// S2->{V1, C_a} into the map when we create SCEV for V1. When S3
/// is expanded, it will first expand S2 to V1 - C_a because of
/// S2->{V1, C_a} in the map, then expand S3 to V1 - C_a + C_b.
///
/// Note: S->{V, Offset} in the ExprValueMap means S can be expanded
/// to V - Offset.
ExprValueMapType ExprValueMap;
/// The typedef for ValueExprMap.
@ -1181,7 +1200,7 @@ namespace llvm {
bool containsAddRecurrence(const SCEV *S);
/// Return the Value set from which the SCEV expr is generated.
SetVector<Value *> *getSCEVValues(const SCEV *S);
SetVector<ValueOffsetPair> *getSCEVValues(const SCEV *S);
/// Erase Value from ValueExprMap and ExprValueMap.
void eraseValueFromMap(Value *V);

View file

@ -14,6 +14,7 @@
#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
#include "llvm/ADT/Optional.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
#include "llvm/Analysis/TargetFolder.h"
@ -284,7 +285,15 @@ namespace llvm {
void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); }
/// \brief Try to find LLVM IR value for S available at the point At.
/// Try to find existing LLVM IR value for S available at the point At.
Value *getExactExistingExpansion(const SCEV *S, const Instruction *At,
Loop *L);
/// Try to find the ValueOffsetPair for S. The function is mainly
/// used to check whether S can be expanded cheaply.
/// If this returns a non-None value, we know we can codegen the
/// `ValueOffsetPair` into a suitable expansion identical with S
/// so that S can be expanded cheaply.
///
/// L is a hint which tells in which loop to look for the suitable value.
/// On success return value which is equivalent to the expanded S at point
@ -292,7 +301,9 @@ namespace llvm {
///
/// Note that this function does not perform an exhaustive search. I.e if it
/// didn't find any value it does not mean that there is no such value.
Value *findExistingExpansion(const SCEV *S, const Instruction *At, Loop *L);
///
Optional<ScalarEvolution::ValueOffsetPair>
getRelatedExistingExpansion(const SCEV *S, const Instruction *At, Loop *L);
private:
LLVMContext &getContext() const { return SE.getContext(); }
@ -325,7 +336,8 @@ namespace llvm {
PointerType *PTy, Type *Ty, Value *V);
/// \brief Find a previous Value in ExprValueMap for expand.
Value *FindValueInExprValueMap(const SCEV *S, const Instruction *InsertPt);
ScalarEvolution::ValueOffsetPair
FindValueInExprValueMap(const SCEV *S, const Instruction *InsertPt);
Value *expand(const SCEV *S);

Some files were not shown because too many files have changed in this diff Show more