MFhead@r313243
This commit is contained in:
commit
9b3ece1c2e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/netbsd-tests-upstream-01-2017/; revision=313244
5
Makefile
5
Makefile
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -50,6 +50,8 @@ LIB32WMAKEFLAGS= LD="${XLD} -m elf32btsmip_fbsd"
|
||||
LIB32WMAKEFLAGS+= OBJCOPY="${XOBJCOPY}"
|
||||
.endif
|
||||
|
||||
LIB32WMAKEFLAGS+= NM="${XNM}"
|
||||
|
||||
|
||||
LIB32CFLAGS= -DCOMPAT_32BIT
|
||||
LIB32DTRACE= ${DTRACE} -32
|
||||
|
@ -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
|
||||
|
4
UPDATING
4
UPDATING
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
/*
|
||||
|
@ -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 }
|
||||
|
@ -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 } },
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
20161202
|
||||
20170201
|
||||
|
14
contrib/byacc/aclocal.m4
vendored
14
contrib/byacc/aclocal.m4
vendored
@ -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];
|
||||
|
6
contrib/byacc/config.guess
vendored
6
contrib/byacc/config.guess
vendored
@ -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."
|
||||
|
11
contrib/byacc/config.sub
vendored
11
contrib/byacc/config.sub
vendored
@ -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
|
||||
;;
|
||||
|
365
contrib/byacc/configure
vendored
365
contrib/byacc/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
|
@ -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 *
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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/
|
||||
|
@ -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;
|
||||
}
|
||||
|
1
contrib/byacc/test/btyacc/expr.oxout.error
Normal file
1
contrib/byacc/test/btyacc/expr.oxout.error
Normal file
@ -0,0 +1 @@
|
||||
YACC: w - line 6 of "expr.Y", the precedence of '*' has been redeclared
|
227
contrib/byacc/test/btyacc/expr.oxout.output
Normal file
227
contrib/byacc/test/btyacc/expr.oxout.output
Normal 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
|
2752
contrib/byacc/test/btyacc/expr.oxout.tab.c
Normal file
2752
contrib/byacc/test/btyacc/expr.oxout.tab.c
Normal file
File diff suppressed because it is too large
Load Diff
20
contrib/byacc/test/btyacc/expr.oxout.tab.h
Normal file
20
contrib/byacc/test/btyacc/expr.oxout.tab.h
Normal 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_ */
|
1446
contrib/byacc/test/expr.oxout.y
Normal file
1446
contrib/byacc/test/expr.oxout.y
Normal file
File diff suppressed because it is too large
Load Diff
1
contrib/byacc/test/yacc/expr.oxout.error
Normal file
1
contrib/byacc/test/yacc/expr.oxout.error
Normal file
@ -0,0 +1 @@
|
||||
YACC: w - line 6 of "expr.Y", the precedence of '*' has been redeclared
|
209
contrib/byacc/test/yacc/expr.oxout.output
Normal file
209
contrib/byacc/test/yacc/expr.oxout.output
Normal 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
|
1958
contrib/byacc/test/yacc/expr.oxout.tab.c
Normal file
1958
contrib/byacc/test/yacc/expr.oxout.tab.c
Normal file
File diff suppressed because it is too large
Load Diff
15
contrib/byacc/test/yacc/expr.oxout.tab.h
Normal file
15
contrib/byacc/test/yacc/expr.oxout.tab.h
Normal 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;
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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 }
|
||||
|
@ -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); \
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 **);
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) || \
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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\"",
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 ,
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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 */
|
||||
}
|
@ -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
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)));
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user