Merge ^/head r313055 through r313300.

This commit is contained in:
Dimitry Andric 2017-02-05 20:03:05 +00:00
commit f9edb08480
294 changed files with 17425 additions and 2629 deletions

View File

@ -242,13 +242,11 @@ SUBDIR+= ${_DIR}
# of a LOCAL_DIRS directory. This allows LOCAL_DIRS=foo and
# LOCAL_LIB_DIRS=foo/lib to behave as expected.
.for _DIR in ${LOCAL_DIRS:M*/} ${LOCAL_DIRS:N*/:S|$|/|}
_REDUNDENT_LIB_DIRS+= ${LOCAL_LIB_DIRS:M${_DIR}*}
_REDUNDANT_LIB_DIRS+= ${LOCAL_LIB_DIRS:M${_DIR}*}
.endfor
.for _DIR in ${LOCAL_LIB_DIRS}
.if empty(_REDUNDENT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile)
.if empty(_REDUNDANT_LIB_DIRS:M${_DIR}) && exists(${.CURDIR}/${_DIR}/Makefile)
SUBDIR+= ${_DIR}
.else
.warning ${_DIR} not added to SUBDIR list. See UPDATING 20141121.
.endif
.endfor
@ -1954,6 +1952,7 @@ native-xtools: .PHONY
usr.bin/mktemp \
usr.bin/mt \
usr.bin/patch \
usr.bin/readelf \
usr.bin/sed \
usr.bin/sort \
usr.bin/tar \

View File

@ -77,7 +77,7 @@ main(int argc, char **argv)
}
EOF
cc -c -xO2 test.c
cc -c -O2 test.c
if [ $? -ne 0 ]; then
print -u2 "failed to compile test.c"
exit 1

View File

@ -25,7 +25,7 @@
#
# ident "%Z%%M% %I% %E% SMI"
# Make sure <unistd.h> defines _DTRACE_VERSION
# Make sure <sys/sdt.h> defines _DTRACE_VERSION
DIR=/var/tmp/dtest.$$
@ -33,7 +33,7 @@ mkdir $DIR
cd $DIR
cat > test.c <<EOF
#include <unistd.h>
#include <sys/sdt.h>
int
main(int argc, char **argv)
@ -46,7 +46,7 @@ main(int argc, char **argv)
}
EOF
cc -xarch=generic -o test test.c
cc -o test test.c
if [ $? -ne 0 ]; then
print -u2 "failed to compile test.c"
exit 1

View File

@ -462,18 +462,8 @@ dof_add_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
dt_buf_write(dtp, &ddo->ddo_enoffs, pip->pi_enoffs,
pip->pi_nenoffs * sizeof (uint32_t), sizeof (uint32_t));
/*
* If pi_rname isn't set, the relocation will be against the
* function name. If it is, the relocation will be against
* pi_rname. This will be used if the function is scoped
* locally so an alternate symbol is added for the purpose
* of this relocation.
*/
if (pip->pi_rname == NULL)
dofr.dofr_name = dofpr.dofpr_func;
else
dofr.dofr_name = dof_add_string(ddo, pip->pi_rname);
dofr.dofr_type = DOF_RELO_SETX;
dofr.dofr_name = dof_add_string(ddo, pip->pi_rname);
dofr.dofr_type = DOF_RELO_DOFREL;
dofr.dofr_offset = dt_buf_len(&ddo->ddo_probes);
dofr.dofr_data = 0;

View File

@ -237,7 +237,7 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
rel->r_info = ELF32_R_INFO(count + dep->de_global,
R_386_32);
R_386_PC32);
#elif defined(__mips__)
/* XXX */
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
@ -253,15 +253,6 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
#elif defined(__riscv__)
/* XXX */
printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
#elif defined(__sparc)
/*
* Add 4 bytes to hit the low half of this 64-bit
* big-endian address.
*/
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset + 4;
rel->r_info = ELF32_R_INFO(count + dep->de_global,
R_SPARC_32);
#else
#error unknown ISA
#endif
@ -270,7 +261,7 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
sym->st_value = 0;
sym->st_size = 0;
sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_FUNC);
sym->st_other = 0;
sym->st_other = ELF32_ST_VISIBILITY(STV_HIDDEN);
sym->st_shndx = SHN_UNDEF;
rel++;
@ -287,11 +278,7 @@ printf("%s:%s(%d): DOODAD\n",__FUNCTION__,__FILE__,__LINE__);
sym->st_value = 0;
sym->st_size = dof->dofh_filesz;
sym->st_info = ELF32_ST_INFO(STB_GLOBAL, STT_OBJECT);
#ifdef illumos
sym->st_other = 0;
#else
sym->st_other = ELF32_ST_VISIBILITY(STV_HIDDEN);
#endif
sym->st_shndx = ESHDR_DOF;
sym++;
@ -448,18 +435,8 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
#elif defined(__i386) || defined(__amd64)
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
#ifdef illumos
rel->r_info = ELF64_R_INFO(count + dep->de_global,
R_AMD64_64);
#else
rel->r_info = ELF64_R_INFO(count + dep->de_global,
R_X86_64_RELATIVE);
#endif
#elif defined(__sparc)
rel->r_offset = s->dofs_offset +
dofr[j].dofr_offset;
rel->r_info = ELF64_R_INFO(count + dep->de_global,
R_SPARC_64);
R_X86_64_PC64);
#else
#error unknown ISA
#endif
@ -468,7 +445,7 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
sym->st_value = 0;
sym->st_size = 0;
sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_FUNC);
sym->st_other = 0;
sym->st_other = ELF64_ST_VISIBILITY(STV_HIDDEN);
sym->st_shndx = SHN_UNDEF;
rel++;
@ -485,11 +462,7 @@ prepare_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, dof_elf64_t *dep)
sym->st_value = 0;
sym->st_size = dof->dofh_filesz;
sym->st_info = GELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
#ifdef illumos
sym->st_other = 0;
#else
sym->st_other = ELF64_ST_VISIBILITY(STV_HIDDEN);
#endif
sym->st_shndx = ESHDR_DOF;
sym++;
@ -797,16 +770,15 @@ dump_elf64(dtrace_hdl_t *dtp, const dof_hdr_t *dof, int fd)
}
static int
dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
GElf_Sym *sym, int uses_funcdesc, Elf *elf)
dt_symtab_lookup(Elf_Data *data_sym, int start, int end, uintptr_t addr,
uint_t shn, GElf_Sym *sym, int uses_funcdesc, Elf *elf)
{
int i, ret = -1;
Elf64_Addr symval;
Elf_Scn *opd_scn;
Elf_Data *opd_desc;
GElf_Sym s;
int i;
for (i = 0; i < nsym && gelf_getsym(data_sym, i, sym) != NULL; i++) {
for (i = start; i < end && gelf_getsym(data_sym, i, sym) != NULL; i++) {
if (GELF_ST_TYPE(sym->st_info) == STT_FUNC) {
symval = sym->st_value;
if (uses_funcdesc) {
@ -816,20 +788,12 @@ dt_symtab_lookup(Elf_Data *data_sym, int nsym, uintptr_t addr, uint_t shn,
*(uint64_t*)((char *)opd_desc->d_buf + symval);
}
if ((uses_funcdesc || shn == sym->st_shndx) &&
symval <= addr &&
addr < symval + sym->st_size) {
if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL)
return (0);
ret = 0;
s = *sym;
}
symval <= addr && addr < symval + sym->st_size)
return (0);
}
}
if (ret == 0)
*sym = s;
return (ret);
return (-1);
}
#if defined(__aarch64__)
@ -1237,10 +1201,11 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
dt_provider_t *pvp;
dt_probe_t *prp;
uint32_t off, eclass, emachine1, emachine2;
size_t symsize, nsym, isym, istr, len;
size_t symsize, osym, nsym, isym, istr, len;
key_t objkey;
dt_link_pair_t *pair, *bufs = NULL;
dt_strtab_t *strtab;
void *tmp;
if ((fd = open64(obj, O_RDWR)) == -1) {
return (dt_link_error(dtp, elf, fd, bufs,
@ -1374,12 +1339,13 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
* target (text) section to replace the call instruction with
* one or more nops.
*
* If the function containing the probe is locally scoped
* (static), we create an alias used by the relocation in the
* generated object. The alias, a new symbol, will be global
* (so that the relocation from the generated object can be
* resolved), and hidden (so that it is converted to a local
* symbol at link time). Such aliases have this form:
* To avoid runtime overhead, the relocations added to the
* generated object should be resolved at static link time. We
* therefore create aliases for the functions that contain
* probes. An alias is global (so that the relocation from the
* generated object can be resolved), and hidden (so that its
* address is known at static link time). Such aliases have this
* form:
*
* $dtrace<key>.<function>
*
@ -1417,16 +1383,13 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
if (strncmp(s, dt_prefix, sizeof (dt_prefix) - 1) != 0)
continue;
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) != 0) {
if (dt_symtab_lookup(data_sym, 0, isym, rela.r_offset,
shdr_rel.sh_info, &fsym, (emachine1 == EM_PPC64),
elf) != 0) {
dt_strtab_destroy(strtab);
goto err;
}
if (GELF_ST_BIND(fsym.st_info) != STB_LOCAL)
continue;
if (fsym.st_name > data_str->d_size) {
dt_strtab_destroy(strtab);
goto err;
@ -1462,12 +1425,12 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
}
/*
* If needed, allocate the additional space for the symbol
* table and string table copying the old data into the new
* buffers, and marking the buffers as dirty. We inject those
* newly allocated buffers into the libelf data structures, but
* are still responsible for freeing them once we're done with
* the elf handle.
* If any probes were found, allocate the additional space for
* the symbol table and string table, copying the old data into
* the new buffers, and marking the buffers as dirty. We inject
* those newly allocated buffers into the libelf data
* structures, but are still responsible for freeing them once
* we're done with the elf handle.
*/
if (nsym > 0) {
/*
@ -1501,7 +1464,9 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
bufs = pair;
bcopy(data_str->d_buf, pair->dlp_str, data_str->d_size);
tmp = data_str->d_buf;
data_str->d_buf = pair->dlp_str;
pair->dlp_str = tmp;
data_str->d_size += len;
(void) elf_flagdata(data_str, ELF_C_SET, ELF_F_DIRTY);
@ -1509,16 +1474,20 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
(void) gelf_update_shdr(scn_str, &shdr_str);
bcopy(data_sym->d_buf, pair->dlp_sym, data_sym->d_size);
tmp = data_sym->d_buf;
data_sym->d_buf = pair->dlp_sym;
pair->dlp_sym = tmp;
data_sym->d_size += nsym * symsize;
(void) elf_flagdata(data_sym, ELF_C_SET, ELF_F_DIRTY);
shdr_sym.sh_size += nsym * symsize;
(void) gelf_update_shdr(scn_sym, &shdr_sym);
osym = isym;
nsym += isym;
} else {
dt_strtab_destroy(strtab);
continue;
}
/*
@ -1577,8 +1546,11 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
bcopy(s, pname, p - s);
pname[p - s] = '\0';
if (dt_symtab_lookup(data_sym, isym, rela.r_offset,
shdr_rel.sh_info, &fsym,
if (dt_symtab_lookup(data_sym, osym, isym,
rela.r_offset, shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) != 0 &&
dt_symtab_lookup(data_sym, 0, osym,
rela.r_offset, shdr_rel.sh_info, &fsym,
(emachine1 == EM_PPC64), elf) != 0)
goto err;
@ -1588,37 +1560,30 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
assert(GELF_ST_TYPE(fsym.st_info) == STT_FUNC);
/*
* If a NULL relocation name is passed to
* dt_probe_define(), the function name is used for the
* relocation. The relocation needs to use a mangled
* name if the symbol is locally scoped; the function
* name may need to change if we've found the global
* alias for the locally scoped symbol (we prefer
* global symbols to locals in dt_symtab_lookup()).
* If this is our first time encountering this symbol,
* emit an alias.
*/
s = (char *)data_str->d_buf + fsym.st_name;
r = NULL;
if (GELF_ST_BIND(fsym.st_info) == STB_LOCAL) {
if (strncmp(s, dt_symprefix,
sizeof (dt_symprefix) - 1) != 0) {
u_int bind = GELF_ST_BIND(fsym.st_info);
dsym = fsym;
dsym.st_name = istr;
dsym.st_info = GELF_ST_INFO(STB_GLOBAL,
STT_FUNC);
dsym.st_other =
ELF64_ST_VISIBILITY(STV_ELIMINATE);
dsym.st_info = GELF_ST_INFO(bind == STB_LOCAL ?
STB_GLOBAL : bind, STT_FUNC);
dsym.st_other = GELF_ST_VISIBILITY(STV_HIDDEN);
(void) gelf_update_sym(data_sym, isym, &dsym);
r = (char *)data_str->d_buf + istr;
istr += 1 + sprintf(r, dt_symfmt,
dt_symprefix, objkey, s);
r = (char *) data_str->d_buf + istr;
istr += 1 + sprintf(r, dt_symfmt, dt_symprefix, objkey,
s);
isym++;
assert(isym <= nsym);
} else if (strncmp(s, dt_symprefix,
strlen(dt_symprefix)) == 0) {
} else {
r = s;
if ((s = strchr(s, '.')) == NULL)
goto err;
s = strchr(s, '.');
assert(s != NULL);
s++;
}
@ -1697,9 +1662,6 @@ process_obj(dtrace_hdl_t *dtp, const char *obj, int *eprobesp)
(void) elf_end(elf);
(void) close(fd);
#ifndef illumos
if (nsym > 0)
#endif
while ((pair = bufs) != NULL) {
bufs = pair->dlp_next;
dt_free(dtp, pair->dlp_str);

View File

@ -545,9 +545,7 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) {
if (strcmp(pip->pi_fname, fname) == 0 &&
((rname == NULL && pip->pi_rname == NULL) ||
(rname != NULL && pip->pi_rname != NULL &&
strcmp(pip->pi_rname, rname) == 0)))
strcmp(pip->pi_rname, rname) == 0)
break;
}
@ -565,7 +563,7 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
if ((pip->pi_fname = strdup(fname)) == NULL)
goto nomem;
if (rname != NULL && (pip->pi_rname = strdup(rname)) == NULL)
if ((pip->pi_rname = strdup(rname)) == NULL)
goto nomem;
pip->pi_noffs = 0;
@ -605,7 +603,7 @@ dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
dt_dprintf("defined probe %s %s:%s %s() +0x%x (%s)\n",
isenabled ? "(is-enabled)" : "",
pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, fname, offset,
rname != NULL ? rname : fname);
rname);
assert(*noffs < *maxoffs);
(*offs)[(*noffs)++] = offset;

View File

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

View File

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

View File

@ -1 +1 @@
20161202
20170201

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,8 +9,8 @@
/* Define to 1 if you have the `bpf_dump' function. */
#undef HAVE_BPF_DUMP
/* Casper library support available */
#undef HAVE_CASPER
/* capsicum support available */
#undef HAVE_CAPSICUM
/* Define to 1 if you have the `cap_enter' function. */
#undef HAVE_CAP_ENTER

View File

@ -4593,7 +4593,7 @@ fi
$as_echo_n "checking whether to sandbox using capsicum... " >&6; }
if test "x$ac_lbl_capsicum_function_seen" = "xyes" -a "x$ac_lbl_capsicum_function_not_seen" != "xyes"; then
$as_echo "#define HAVE_CASPER 1" >>confdefs.h
$as_echo "#define HAVE_CAPSICUM 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }

View File

@ -228,7 +228,7 @@ if test ! -z "$with_sandbox-capsicum" && test "$with_sandbox-capsicum" != "no" ;
fi
AC_MSG_CHECKING([whether to sandbox using capsicum])
if test "x$ac_lbl_capsicum_function_seen" = "xyes" -a "x$ac_lbl_capsicum_function_not_seen" != "xyes"; then
AC_DEFINE(HAVE_CASPER, 1, [casper support available])
AC_DEFINE(HAVE_CAPSICUM, 1, [capsicum support available])
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)

View File

@ -75,18 +75,18 @@ The Regents of the University of California. All rights reserved.\n";
* to compile if <pcap.h> has already been included; including the headers
* in the opposite order works fine.
*/
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
#include <sys/capsicum.h>
#include <sys/sysctl.h>
#include <sys/nv.h>
#include <sys/ioccom.h>
#include <net/bpf.h>
#include <libgen.h>
#ifdef HAVE_CASPER
#include <libcasper.h>
#include <casper/cap_dns.h>
#include <sys/nv.h>
#include <sys/ioccom.h>
#include <net/bpf.h>
#endif /* HAVE_CASPER */
#endif /* __FreeBSD__ */
#endif /* HAVE_CAPSICUM */
#include <pcap.h>
#include <signal.h>
#include <stdio.h>
@ -249,7 +249,7 @@ struct dump_info {
char *CurrentFileName;
pcap_t *pd;
pcap_dumper_t *p;
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
int dirfd;
#endif
};
@ -789,7 +789,7 @@ tstamp_precision_to_string(int precision)
}
#endif
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
/*
* Ensure that, on a dump file's descriptor, we have all the rights
* necessary to make the standard I/O library work with an fdopen()ed
@ -1188,10 +1188,10 @@ main(int argc, char **argv)
#endif
int status;
FILE *VFile;
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
cap_rights_t rights;
#endif /* !__FreeBSD__ */
int cansandbox;
#endif /* HAVE_CAPSICUM */
int Oflag = 1; /* run filter code optimizer */
int yflag_dlt = -1;
const char *yflag_dlt_name = NULL;
@ -1685,7 +1685,7 @@ main(int argc, char **argv)
if (pd == NULL)
error("%s", ebuf);
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
cap_rights_init(&rights, CAP_READ);
if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
errno != ENOSYS) {
@ -1916,7 +1916,7 @@ main(int argc, char **argv)
if (pcap_setfilter(pd, &fcode) < 0)
error("%s", pcap_geterr(pd));
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
if (RFileName == NULL && VFileName == NULL) {
static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF };
@ -1966,11 +1966,11 @@ main(int argc, char **argv)
#endif /* HAVE_LIBCAP_NG */
if (p == NULL)
error("%s", pcap_geterr(pd));
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
set_dumper_capsicum_rights(p);
#endif
if (Cflag != 0 || Gflag != 0) {
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
dumpinfo.WFileName = strdup(basename(WFileName));
if (dumpinfo.WFileName == NULL) {
error("Unable to allocate memory for file %s",
@ -1992,7 +1992,7 @@ main(int argc, char **argv)
errno != ENOSYS) {
error("unable to limit dump descriptor fcntls");
}
#else /* !__FreeBSD__ */
#else /* !HAVE_CAPSICUM */
dumpinfo.WFileName = WFileName;
#endif
callback = dump_packet_and_trunc;
@ -2064,7 +2064,7 @@ main(int argc, char **argv)
(void)fflush(stderr);
}
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
cansandbox = (VFileName == NULL && zflag == NULL);
#ifdef HAVE_CASPER
cansandbox = (cansandbox && (ndo->ndo_nflag || capdns != NULL));
@ -2073,7 +2073,7 @@ main(int argc, char **argv)
#endif /* HAVE_CASPER */
if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
error("unable to enter the capability mode");
#endif /* __FreeBSD __ */
#endif /* HAVE_CAPSICUM */
do {
status = pcap_loop(pd, cnt, callback, pcap_userdata);
@ -2124,7 +2124,7 @@ main(int argc, char **argv)
pd = pcap_open_offline(RFileName, ebuf);
if (pd == NULL)
error("%s", ebuf);
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
cap_rights_init(&rights, CAP_READ);
if (cap_rights_limit(fileno(pcap_file(pd)),
&rights) < 0 && errno != ENOSYS) {
@ -2378,7 +2378,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
/* If the time is greater than the specified window, rotate */
if (t - Gflag_time >= Gflag) {
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
FILE *fp;
int fd;
#endif
@ -2437,7 +2437,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
capng_apply(CAPNG_SELECT_BOTH);
#endif /* HAVE_LIBCAP_NG */
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
fd = openat(dump_info->dirfd,
dump_info->CurrentFileName,
O_CREAT | O_WRONLY | O_TRUNC, 0644);
@ -2451,7 +2451,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
dump_info->CurrentFileName);
}
dump_info->p = pcap_dump_fopen(dump_info->pd, fp);
#else /* !__FreeBSD__ */
#else /* !HAVE_CAPSICUM */
dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
#endif
#ifdef HAVE_LIBCAP_NG
@ -2460,7 +2460,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
#endif /* HAVE_LIBCAP_NG */
if (dump_info->p == NULL)
error("%s", pcap_geterr(pd));
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
set_dumper_capsicum_rights(dump_info->p);
#endif
}
@ -2477,7 +2477,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
if (size == -1)
error("ftell fails on output file");
if (size > Cflag) {
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
FILE *fp;
int fd;
#endif
@ -2509,7 +2509,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
capng_apply(CAPNG_SELECT_BOTH);
#endif /* HAVE_LIBCAP_NG */
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
fd = openat(dump_info->dirfd, dump_info->CurrentFileName,
O_CREAT | O_WRONLY | O_TRUNC, 0644);
if (fd < 0) {
@ -2522,7 +2522,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
dump_info->CurrentFileName);
}
dump_info->p = pcap_dump_fopen(dump_info->pd, fp);
#else /* !__FreeBSD__ */
#else /* !HAVE_CAPSICUM */
dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
#endif
#ifdef HAVE_LIBCAP_NG
@ -2531,7 +2531,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
#endif /* HAVE_LIBCAP_NG */
if (dump_info->p == NULL)
error("%s", pcap_geterr(pd));
#ifdef __FreeBSD__
#ifdef HAVE_CAPSICUM
set_dumper_capsicum_rights(dump_info->p);
#endif
}

View File

@ -272,7 +272,7 @@ nomatch 10 {
match "bus" "pccard[0-9]+";
match "manufacturer" "0x1234";
match "product" "0x2323";
action "kldload if_deqna";
action "kldload -n if_deqna";
};
attach 10 {
device-name "deqna[0-9]+";

View File

@ -20,7 +20,12 @@ do
echo ''
case "$script" in
/*)
if [ -f "$script" ]
if [ -x "$script" ]
then
echo "Running $script:"
$script || rc=3
elif [ -f "$script" ]
then
echo "Running $script:"

View File

@ -17,7 +17,12 @@ do
echo ''
case "$script" in
/*)
if [ -f "$script" ]
if [ -x "$script" ]
then
echo "Running $script:"
$script || rc=3
elif [ -f "$script" ]
then
echo "Running $script:"

View File

@ -17,7 +17,12 @@ do
echo ''
case "$script" in
/*)
if [ -f "$script" ]
if [ -x "$script" ]
then
echo "Running $script:"
$script || rc=3
elif [ -f "$script" ]
then
echo "Running $script:"

View File

@ -41,6 +41,7 @@
#define HAVE_ACL_SET_FILE 1
#define HAVE_ACL_SET_LINK_NP 1
#define HAVE_ACL_USER 1
#define HAVE_ACL_TYPE_NFS4 1
#define HAVE_ARC4RANDOM_BUF 1
#define HAVE_EXTATTR_GET_FILE 1
#define HAVE_EXTATTR_LIST_FILE 1

View File

@ -22,10 +22,10 @@ CFLAGS+= -DHAVE_LIBLZMA=1 -DHAVE_LZMA_H=1
.PATH: ${_LIBARCHIVEDIR}/libarchive/test
TESTS_SRCS= \
test_acl_freebsd_nfs4.c \
test_acl_freebsd_posix1e.c \
test_acl_nfs4.c \
test_acl_pax.c \
test_acl_platform_nfs4.c \
test_acl_platform_posix1e.c \
test_acl_posix1e.c \
test_acl_text.c \
test_archive_api_feature.c \

View File

@ -82,7 +82,7 @@ ENTRY(longjmp)
/* Restore the signal mask */
mov x2, #0 /* oset */
add x1, x0, #(_JB_SIGMASK * 8) /* set */
mov x0, #3 /* SIG_BLOCK */
mov x0, #3 /* SIG_SETMASK */
bl sigprocmask
ldr x1, [sp, #16]

View File

@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd July 15, 2001
.Dd February 3, 2017
.Dt GETPEEREID 3
.Os
.Sh NAME
@ -57,8 +57,8 @@ on which either
.Xr connect 2
or
.Xr listen 2
have been called.
The effective used ID is placed in
has been called.
The effective user ID is placed in
.Fa euid ,
and the effective group ID in
.Fa egid .

View File

@ -28,7 +28,7 @@
.\" @(#)recv.2 8.3 (Berkeley) 2/21/94
.\" $FreeBSD$
.\"
.Dd August 18, 2016
.Dd February 3, 2017
.Dt RECV 2
.Os
.Sh NAME
@ -266,57 +266,10 @@ with no data buffer provided immediately after an
.Fn accept
system call.
.Pp
Open file descriptors are now passed as ancillary data for
With
.Dv AF_UNIX
domain sockets, with
.Fa cmsg_level
set to
.Dv SOL_SOCKET
and
.Fa cmsg_type
set to
.Dv SCM_RIGHTS .
The close-on-exec flag on received descriptors is set according to the
.Dv MSG_CMSG_CLOEXEC
flag passed to
.Fn recvmsg .
.Pp
Process credentials can also be passed as ancillary data for
.Dv AF_UNIX
domain sockets using a
.Fa cmsg_type
of
.Dv SCM_CREDS .
In this case,
.Fa cmsg_data
should be a structure of type
.Fa cmsgcred ,
which is defined in
.In sys/socket.h
as follows:
.Bd -literal
struct cmsgcred {
pid_t cmcred_pid; /* PID of sending process */
uid_t cmcred_uid; /* real UID of sending process */
uid_t cmcred_euid; /* effective UID of sending process */
gid_t cmcred_gid; /* real GID of sending process */
short cmcred_ngroups; /* number or groups */
gid_t cmcred_groups[CMGROUP_MAX]; /* groups */
};
.Ed
.Pp
If a sender supplies ancillary data with enough space for the above struct
tagged as
.Dv SCM_CREDS
control message type to the
.Fn sendmsg
system call, then kernel will fill in the credential information of the
sending process and deliver it to the receiver.
Since receiver usually has no control over a sender, this method of retrieving
credential information isn't reliable.
For reliable retrieval of remote side credentials it is advised to use the
.Dv LOCAL_CREDS
socket option on the receiving socket.
domain sockets, ancillary data can be used to pass file descriptors and
process credentials.
See
.Xr unix 4
for details.

View File

@ -28,7 +28,7 @@
.\" from: @(#)gettytab.5 8.4 (Berkeley) 4/19/94
.\" $FreeBSD$
.\" "
.Dd April 19, 1994
.Dd February 2, 2017
.Dt GETTYTAB 5
.Os
.Sh NAME
@ -118,7 +118,7 @@ character
.Em NOT
hangup line on last close
.It "he str" Ta Dv NULL Ta
.No "hostname editing string"
.No "hostname editing regular expression"
.It "hn str hostname hostname"
.It "ht bool false terminal has real tabs"
.It "hw bool false do cts/rts hardware flow control"
@ -302,18 +302,13 @@ but may also be overridden by the
table entry.
In either case it may be edited with the
.Va \&he
string.
A '@' in the
.Va \&he
string causes one character from the real hostname to
be copied to the final hostname.
A '#' in the
.Va \&he
string causes the next character of the real hostname
to be skipped.
Each character that
is neither '@' nor '#' is copied into the final hostname.
Surplus '@' and '#' characters are ignored.
POSIX
.Dq extended
regular expression, which is matched against the hostname.
If there are no parenthesized subexpressions in the pattern,
the entire matched string is used as the final hostname;
otherwise, the first matched subexpression is used instead.
If the pattern does not match, the original hostname is not modified.
.It \&%t
The tty name.
.It "\&%m, \&%r, \&%s, \&%v"
@ -528,10 +523,6 @@ of the delay algorithms are not implemented.
The terminal driver should support sane delay settings.
.Pp
The
.Va \&he
capability is stupid.
.Pp
The
.Xr termcap 5
format is horrid, something more rational should
have been chosen.

View File

@ -43,6 +43,7 @@ static const char rcsid[] =
#include <sys/time.h>
#include <poll.h>
#include <regex.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
@ -53,8 +54,6 @@ static const char rcsid[] =
#include "pathnames.h"
#include "extern.h"
/*
* Get a table entry.
*/
@ -469,42 +468,48 @@ adelay(int ms, struct delayval *dp)
char editedhost[MAXHOSTNAMELEN];
void
edithost(const char *pat)
edithost(const char *pattern)
{
const char *host = HN;
char *res = editedhost;
regex_t regex;
regmatch_t *match;
int found;
if (!pat)
pat = "";
while (*pat) {
switch (*pat) {
if (pattern == NULL || *pattern == '\0')
goto copyasis;
if (regcomp(&regex, pattern, REG_EXTENDED) != 0)
goto copyasis;
case '#':
if (*host)
host++;
break;
case '@':
if (*host)
*res++ = *host++;
break;
default:
*res++ = *pat;
break;
}
if (res == &editedhost[sizeof editedhost - 1]) {
*res = '\0';
return;
}
pat++;
match = calloc(regex.re_nsub + 1, sizeof(*match));
if (match == NULL) {
regfree(&regex);
goto copyasis;
}
if (*host)
strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
else
*res = '\0';
editedhost[sizeof editedhost - 1] = '\0';
found = !regexec(&regex, HN, regex.re_nsub + 1, match, 0);
if (found) {
size_t subex, totalsize;
/*
* We found a match. If there were no parenthesized
* subexpressions in the pattern, use entire matched
* string as ``editedhost''; otherwise use the first
* matched subexpression.
*/
subex = !!regex.re_nsub;
totalsize = match[subex].rm_eo - match[subex].rm_so + 1;
strlcpy(editedhost, HN + match[subex].rm_so, totalsize >
sizeof(editedhost) ? sizeof(editedhost) : totalsize);
}
free(match);
regfree(&regex);
if (found)
return;
/*
* In case of any errors, or if the pattern did not match, pass
* the original hostname as is.
*/
copyasis:
strlcpy(editedhost, HN, sizeof(editedhost));
}
static struct speedtab {

View File

@ -31,7 +31,6 @@ __FBSDID("$FreeBSD$");
#include <sys/capsicum.h>
#include <sys/endian.h>
#include <sys/kerneldump.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/wait.h>
@ -232,8 +231,6 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input,
pjdlog_errno(LOG_ERR, "Unable to read data from %s",
input);
goto failed;
} else if (bytes == 0) {
break;
}
if (bytes > 0) {
@ -249,10 +246,7 @@ decrypt(const char *privkeyfile, const char *keyfile, const char *input,
}
}
if (olen == 0)
continue;
if (write(ofd, buf, olen) != olen) {
if (olen > 0 && write(ofd, buf, olen) != olen) {
pjdlog_errno(LOG_ERR, "Unable to write data to %s",
output);
goto failed;
@ -274,7 +268,6 @@ int
main(int argc, char **argv)
{
char core[PATH_MAX], encryptedcore[PATH_MAX], keyfile[PATH_MAX];
struct stat sb;
const char *crashdir, *dumpnr, *privatekey;
int ch, debug;
size_t ii;
@ -297,16 +290,23 @@ main(int argc, char **argv)
usesyslog = true;
break;
case 'c':
strncpy(core, optarg, sizeof(core));
if (strlcpy(core, optarg, sizeof(core)) >= sizeof(core))
pjdlog_exitx(1, "Core file path is too long.");
break;
case 'd':
crashdir = optarg;
break;
case 'e':
strncpy(encryptedcore, optarg, sizeof(encryptedcore));
if (strlcpy(encryptedcore, optarg,
sizeof(encryptedcore)) >= sizeof(encryptedcore)) {
pjdlog_exitx(1, "Encrypted core file path is too long.");
}
break;
case 'k':
strncpy(keyfile, optarg, sizeof(keyfile));
if (strlcpy(keyfile, optarg, sizeof(keyfile)) >=
sizeof(keyfile)) {
pjdlog_exitx(1, "Key file path is too long.");
}
break;
case 'n':
dumpnr = optarg;
@ -362,7 +362,7 @@ main(int argc, char **argv)
pjdlog_debug_set(debug);
if (!decrypt(privatekey, keyfile, encryptedcore, core)) {
if (stat(core, &sb) == 0 && unlink(core) != 0)
if (unlink(core) == -1 && errno != ENOENT)
pjdlog_exit(1, "Unable to remove core");
exit(1);
}

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