Merge ^/head r313055 through r313300.
This commit is contained in:
commit
f9edb08480
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,33 @@
|
||||
2017-02-01 Thomas E. Dickey <dickey@invisible-island.net>
|
||||
|
||||
* test/btyacc/expr.oxout.error, test/btyacc/expr.oxout.output, test/btyacc/expr.oxout.tab.c, test/btyacc/expr.oxout.tab.h, test/yacc/expr.oxout.error, test/yacc/expr.oxout.output, test/yacc/expr.oxout.tab.c, test/yacc/expr.oxout.tab.h:
|
||||
RCS_BASE
|
||||
|
||||
* package/debian/copyright: update copyright
|
||||
|
||||
* reader.c, defs.h, main.c:
|
||||
avoid using regex.h since some low-end platforms do not have this
|
||||
|
||||
* test/expr.oxout.y: RCS_BASE
|
||||
|
||||
* configure: regen
|
||||
|
||||
* aclocal.m4: quiet a strict gcc warning in CF_MKSTEMP
|
||||
|
||||
2017-02-01 Tom.Shields
|
||||
|
||||
* main.c, reader.c, defs.h:
|
||||
process #line directives, like bison and flex
|
||||
|
||||
2017-02-01 Thomas E. Dickey <dickey@invisible-island.net>
|
||||
|
||||
* VERSION, package/byacc.spec, package/debian/changelog, package/mingw-byacc.spec, package/pkgsrc/Makefile:
|
||||
bump
|
||||
|
||||
2016-12-31 Thomas E. Dickey <dickey@invisible-island.net>
|
||||
|
||||
* config.guess, config.sub: 2017-01-01
|
||||
|
||||
2016-12-02 Thomas E. Dickey <dickey@invisible-island.net>
|
||||
|
||||
* test/btyacc/quote_calc4-s.tab.c, test/btyacc/varsyntax_calc1.tab.c, test/btyacc/error.tab.c, test/btyacc/grammar.tab.c, test/btyacc/inherit0.tab.c, test/btyacc/inherit1.tab.c, test/btyacc/inherit2.tab.c, test/btyacc/ok_syntax1.tab.c, test/btyacc/pure_calc.tab.c, test/btyacc/pure_error.tab.c, test/btyacc/quote_calc-s.tab.c, test/btyacc/quote_calc.tab.c, test/btyacc/quote_calc2-s.tab.c, test/btyacc/quote_calc2.tab.c, test/btyacc/quote_calc3-s.tab.c, test/btyacc/quote_calc3.tab.c, test/btyacc/quote_calc4.tab.c, test/btyacc/calc.tab.c, test/btyacc/calc1.tab.c, test/btyacc/calc2.tab.c, test/btyacc/calc3.tab.c, test/btyacc/code_calc.code.c, test/btyacc/code_error.code.c, test/btyacc/empty.tab.c, test/btyacc/err_inherit3.tab.c, test/btyacc/err_inherit4.tab.c, test/btyacc/err_syntax10.tab.c, test/btyacc/err_syntax11.tab.c, test/btyacc/err_syntax12.tab.c, test/btyacc/err_syntax18.tab.c, test/btyacc/err_syntax20.tab.c, test/btyacc/rename_debug.c, test/btyacc/btyacc_calc1.tab.c, test/btyacc/btyacc_demo.tab.c, test/btyacc/btyacc_destroy1.tab.c, test/btyacc/btyacc_destroy2.tab.c, test/btyacc/btyacc_destroy3.tab.c, btyaccpar.c:
|
||||
|
@ -1,4 +1,4 @@
|
||||
MANIFEST for byacc-20161202, version t20161202
|
||||
MANIFEST for byacc-20170201, version t20170201
|
||||
--------------------------------------------------------------------------------
|
||||
MANIFEST this file
|
||||
ACKNOWLEDGEMENTS original version of byacc - 1993
|
||||
@ -77,6 +77,22 @@ test/btyacc/btyacc_demo.error reference output for testing
|
||||
test/btyacc/btyacc_demo.output reference output for testing
|
||||
test/btyacc/btyacc_demo.tab.c reference output for testing
|
||||
test/btyacc/btyacc_demo.tab.h reference output for testing
|
||||
test/btyacc/btyacc_demo2.error reference output for testing
|
||||
test/btyacc/btyacc_demo2.output reference output for testing
|
||||
test/btyacc/btyacc_demo2.tab.c reference output for testing
|
||||
test/btyacc/btyacc_demo2.tab.h reference output for testing
|
||||
test/btyacc/btyacc_destroy1.error reference output for testing
|
||||
test/btyacc/btyacc_destroy1.output reference output for testing
|
||||
test/btyacc/btyacc_destroy1.tab.c reference output for testing
|
||||
test/btyacc/btyacc_destroy1.tab.h reference output for testing
|
||||
test/btyacc/btyacc_destroy2.error reference output for testing
|
||||
test/btyacc/btyacc_destroy2.output reference output for testing
|
||||
test/btyacc/btyacc_destroy2.tab.c reference output for testing
|
||||
test/btyacc/btyacc_destroy2.tab.h reference output for testing
|
||||
test/btyacc/btyacc_destroy3.error reference output for testing
|
||||
test/btyacc/btyacc_destroy3.output reference output for testing
|
||||
test/btyacc/btyacc_destroy3.tab.c reference output for testing
|
||||
test/btyacc/btyacc_destroy3.tab.h reference output for testing
|
||||
test/btyacc/calc.error reference output for testing
|
||||
test/btyacc/calc.output reference output for testing
|
||||
test/btyacc/calc.tab.c reference output for testing
|
||||
@ -256,6 +272,10 @@ test/btyacc/error.error reference output for testing
|
||||
test/btyacc/error.output reference output for testing
|
||||
test/btyacc/error.tab.c reference output for testing
|
||||
test/btyacc/error.tab.h reference output for testing
|
||||
test/btyacc/expr.oxout.error reference output for testing
|
||||
test/btyacc/expr.oxout.output reference output for testing
|
||||
test/btyacc/expr.oxout.tab.c reference output for testing
|
||||
test/btyacc/expr.oxout.tab.h reference output for testing
|
||||
test/btyacc/grammar.dot reference output for testing
|
||||
test/btyacc/grammar.error reference output for testing
|
||||
test/btyacc/grammar.output reference output for testing
|
||||
@ -359,6 +379,9 @@ test/btyacc/varsyntax_calc1.tab.h reference output for testing
|
||||
test subdirectory
|
||||
test/btyacc_calc1.y testcase for btyacc
|
||||
test/btyacc_demo.y testcase for btyacc
|
||||
test/btyacc_destroy1.y btyacc test-case for %parse-param
|
||||
test/btyacc_destroy2.y btyacc test-case for %parse-param
|
||||
test/btyacc_destroy3.y btyacc test-case for %parse-param
|
||||
test/calc.y example from VMS freeware version of byacc
|
||||
test/calc1.y advanced example from Steve Johnson's paper.
|
||||
test/calc2.y test-cases and reference files for %lex-param / %parse-param
|
||||
@ -403,6 +426,7 @@ test/err_syntax8.y testcase for used_reserved()
|
||||
test/err_syntax8a.y testcase for used_reserved()
|
||||
test/err_syntax9.y testcase for tokenized_start()
|
||||
test/error.y original version of byacc - 1993
|
||||
test/expr.oxout.y test-case for "#line" feature
|
||||
test/grammar.y grammar from cproto
|
||||
test/inherit0.y testcase for btyacc
|
||||
test/inherit1.y testcase for btyacc
|
||||
@ -577,6 +601,10 @@ test/yacc/error.error reference output for testing
|
||||
test/yacc/error.output reference output for testing
|
||||
test/yacc/error.tab.c reference output for testing
|
||||
test/yacc/error.tab.h reference output for testing
|
||||
test/yacc/expr.oxout.error reference output for testing
|
||||
test/yacc/expr.oxout.output reference output for testing
|
||||
test/yacc/expr.oxout.tab.c reference output for testing
|
||||
test/yacc/expr.oxout.tab.h reference output for testing
|
||||
test/yacc/grammar.dot reference output for testing
|
||||
test/yacc/grammar.error reference output for testing
|
||||
test/yacc/grammar.output reference output for testing
|
||||
|
@ -1 +1 @@
|
||||
20161202
|
||||
20170201
|
||||
|
14
contrib/byacc/aclocal.m4
vendored
14
contrib/byacc/aclocal.m4
vendored
@ -1,7 +1,7 @@
|
||||
dnl $Id: aclocal.m4,v 1.41 2016/12/02 13:03:06 tom Exp $
|
||||
dnl $Id: aclocal.m4,v 1.42 2017/02/01 10:12:21 tom Exp $
|
||||
dnl Macros for byacc configure script (Thomas E. Dickey)
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl Copyright 2004-2015,2016 Thomas E. Dickey
|
||||
dnl Copyright 2004-2016,2017 Thomas E. Dickey
|
||||
dnl
|
||||
dnl Permission is hereby granted, free of charge, to any person obtaining a
|
||||
dnl copy of this software and associated documentation files (the
|
||||
@ -803,20 +803,26 @@ fi
|
||||
test "$cf_cv_mixedcase" = yes && AC_DEFINE(MIXEDCASE_FILENAMES,1,[Define to 1 if filesystem supports mixed-case filenames.])
|
||||
])dnl
|
||||
dnl ---------------------------------------------------------------------------
|
||||
dnl CF_MKSTEMP version: 9 updated: 2012/10/03 04:34:49
|
||||
dnl CF_MKSTEMP version: 10 updated: 2017/01/21 11:12:16
|
||||
dnl ----------
|
||||
dnl Check for a working mkstemp. This creates two files, checks that they are
|
||||
dnl successfully created and distinct (AmigaOS apparently fails on the last).
|
||||
AC_DEFUN([CF_MKSTEMP],[
|
||||
AC_CHECK_HEADERS( \
|
||||
unistd.h \
|
||||
)
|
||||
AC_CACHE_CHECK(for working mkstemp, cf_cv_func_mkstemp,[
|
||||
rm -rf conftest*
|
||||
AC_TRY_RUN([
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
int main()
|
||||
int main(void)
|
||||
{
|
||||
char *tmpl = "conftestXXXXXX";
|
||||
char name[2][80];
|
||||
|
6
contrib/byacc/config.guess
vendored
6
contrib/byacc/config.guess
vendored
@ -1,8 +1,8 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2016 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2016-10-02'
|
||||
timestamp='2017-01-01'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@ -50,7 +50,7 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright 1992-2016 Free Software Foundation, Inc.
|
||||
Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
11
contrib/byacc/config.sub
vendored
11
contrib/byacc/config.sub
vendored
@ -1,8 +1,8 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2016 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2016-11-19'
|
||||
timestamp='2017-01-01'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@ -67,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2016 Free Software Foundation, Inc.
|
||||
Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@ -1409,7 +1409,7 @@ case $os in
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
|
||||
| -onefs* | -tirtos* | -phoenix* | -fuchsia*)
|
||||
| -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@ -1638,6 +1638,9 @@ case $basic_machine in
|
||||
sparc-* | *-sun)
|
||||
os=-sunos4.1.1
|
||||
;;
|
||||
pru-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-be)
|
||||
os=-beos
|
||||
;;
|
||||
|
365
contrib/byacc/configure
vendored
365
contrib/byacc/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/* $Id: defs.h,v 1.54 2016/12/02 19:27:56 tom Exp $ */
|
||||
/* $Id: defs.h,v 1.56 2017/02/02 00:44:38 tom Exp $ */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
@ -313,6 +313,7 @@ extern const char *const trailer[];
|
||||
|
||||
extern char *code_file_name;
|
||||
extern char *input_file_name;
|
||||
extern size_t input_file_name_len;
|
||||
extern char *defines_file_name;
|
||||
extern char *externs_file_name;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: main.c,v 1.57 2016/12/02 18:44:44 tom Exp $ */
|
||||
/* $Id: main.c,v 1.59 2017/02/02 00:44:38 tom Exp $ */
|
||||
|
||||
#include <signal.h>
|
||||
#ifndef _WIN32
|
||||
@ -48,13 +48,13 @@ const char *myname = "yacc";
|
||||
int lineno;
|
||||
int outline;
|
||||
|
||||
static char empty_string[] = "";
|
||||
static char default_file_prefix[] = "y";
|
||||
|
||||
static char *file_prefix = default_file_prefix;
|
||||
|
||||
char *code_file_name;
|
||||
char *input_file_name = empty_string;
|
||||
char *input_file_name;
|
||||
size_t input_file_name_len = 0;
|
||||
char *defines_file_name;
|
||||
char *externs_file_name;
|
||||
|
||||
@ -381,7 +381,10 @@ getargs(int argc, char *argv[])
|
||||
no_more_options:;
|
||||
if (i + 1 != argc)
|
||||
usage();
|
||||
input_file_name = argv[i];
|
||||
input_file_name_len = strlen(argv[i]);
|
||||
input_file_name = TMALLOC(char, input_file_name_len + 1);
|
||||
NO_SPACE(input_file_name);
|
||||
strcpy(input_file_name, argv[i]);
|
||||
}
|
||||
|
||||
void *
|
||||
|
@ -1,8 +1,8 @@
|
||||
Summary: byacc - public domain Berkeley LALR Yacc parser generator
|
||||
%define AppProgram byacc
|
||||
%define AppVersion 20161202
|
||||
%define AppVersion 20170201
|
||||
%define UseProgram yacc
|
||||
# $XTermId: byacc.spec,v 1.32 2016/12/02 12:58:46 tom Exp $
|
||||
# $XTermId: byacc.spec,v 1.33 2017/02/01 09:55:04 tom Exp $
|
||||
Name: %{AppProgram}
|
||||
Version: %{AppVersion}
|
||||
Release: 1
|
||||
|
@ -1,3 +1,9 @@
|
||||
byacc (20170201) unstable; urgency=low
|
||||
|
||||
* maintenance updates
|
||||
|
||||
-- Thomas E. Dickey <dickey@invisible-island.net> Wed, 01 Feb 2017 04:55:04 -0500
|
||||
|
||||
byacc (20161202) unstable; urgency=low
|
||||
|
||||
* maintenance updates
|
||||
|
@ -36,7 +36,7 @@ skeleton.c with the bug report. Do not expect rapid responses.
|
||||
|
||||
Files: aclocal.m4
|
||||
Licence: other-BSD
|
||||
Copyright: 2004-2015,2016 by Thomas E. Dickey
|
||||
Copyright: 2004-2016,2017 by Thomas E. Dickey
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
|
@ -1,8 +1,8 @@
|
||||
Summary: byacc - public domain Berkeley LALR Yacc parser generator
|
||||
%define AppProgram byacc
|
||||
%define AppVersion 20161202
|
||||
%define AppVersion 20170201
|
||||
%define UseProgram yacc
|
||||
# $XTermId: mingw-byacc.spec,v 1.14 2016/12/02 12:58:46 tom Exp $
|
||||
# $XTermId: mingw-byacc.spec,v 1.15 2017/02/01 09:55:04 tom Exp $
|
||||
Name: %{AppProgram}
|
||||
Version: %{AppVersion}
|
||||
Release: 1
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $NetBSD: Makefile,v 1.9 2008/07/24 17:13:00 tonnerre Exp $
|
||||
#
|
||||
|
||||
DISTNAME= byacc-20161202
|
||||
DISTNAME= byacc-20170201
|
||||
PKGREVISION= 1
|
||||
CATEGORIES= devel
|
||||
MASTER_SITES= ftp://invisible-island.net/byacc/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: reader.c,v 1.66 2016/12/02 20:14:34 tom Exp $ */
|
||||
/* $Id: reader.c,v 1.68 2017/02/02 01:05:36 tom Exp $ */
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
@ -108,6 +108,134 @@ cachec(int c)
|
||||
++cinc;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ldSPC1,
|
||||
ldSPC2,
|
||||
ldNAME,
|
||||
ldSPC3,
|
||||
ldNUM,
|
||||
ldSPC4,
|
||||
ldFILE,
|
||||
ldOK,
|
||||
ldERR
|
||||
}
|
||||
LINE_DIR;
|
||||
|
||||
/*
|
||||
* Expect this pattern:
|
||||
* /^[[:space:]]*#[[:space:]]*
|
||||
* line[[:space:]]+
|
||||
* [[:digit:]]+
|
||||
* ([[:space:]]*|[[:space:]]+"[^"]+")/
|
||||
*/
|
||||
static int
|
||||
line_directive(void)
|
||||
{
|
||||
#define UNLESS(what) if (what) { ld = ldERR; break; }
|
||||
int n;
|
||||
int line_1st = -1;
|
||||
int name_1st = -1;
|
||||
int name_end = -1;
|
||||
LINE_DIR ld = ldSPC1;
|
||||
for (n = 0; (ld <= ldOK) && (line[n] != '\0'); ++n)
|
||||
{
|
||||
int ch = UCH(line[n]);
|
||||
switch (ld)
|
||||
{
|
||||
case ldSPC1:
|
||||
if (isspace(ch))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
UNLESS(ch != '#');
|
||||
ld = ldSPC2;
|
||||
break;
|
||||
case ldSPC2:
|
||||
if (isspace(ch))
|
||||
{
|
||||
break;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
case ldNAME:
|
||||
UNLESS(strncmp(line + n, "line", 4));
|
||||
n += 4;
|
||||
if (line[n] == '\0')
|
||||
{
|
||||
ld = ldOK;
|
||||
break;
|
||||
}
|
||||
else
|
||||
UNLESS(!isspace(UCH(line[n])));
|
||||
ld = ldSPC3;
|
||||
break;
|
||||
case ldSPC3:
|
||||
if (isspace(ch))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
UNLESS(!isdigit(ch));
|
||||
line_1st = n;
|
||||
ld = ldNUM;
|
||||
/* FALLTHRU */
|
||||
case ldNUM:
|
||||
if (isdigit(ch))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
UNLESS(!isspace(ch));
|
||||
ld = ldSPC4;
|
||||
break;
|
||||
case ldSPC4:
|
||||
if (isspace(ch))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
UNLESS(ch != '"');
|
||||
UNLESS(line[n + 1] == '"');
|
||||
ld = ldFILE;
|
||||
name_1st = n;
|
||||
break;
|
||||
case ldFILE:
|
||||
if (ch != '"')
|
||||
{
|
||||
break;
|
||||
}
|
||||
ld = ldOK;
|
||||
name_end = n;
|
||||
/* FALLTHRU */
|
||||
case ldERR:
|
||||
case ldOK:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ld == ldOK)
|
||||
{
|
||||
size_t need = (size_t) (name_end - name_1st);
|
||||
if (need > input_file_name_len)
|
||||
{
|
||||
input_file_name_len = need;
|
||||
input_file_name = TREALLOC(char, input_file_name, need + 1);
|
||||
NO_SPACE(input_file_name);
|
||||
}
|
||||
memcpy(input_file_name, line + name_1st + 1, need - 1);
|
||||
input_file_name[need - 1] = '\0';
|
||||
}
|
||||
|
||||
if (ld >= ldNUM && ld < ldERR)
|
||||
{
|
||||
lineno = (int)strtol(line + line_1st, NULL, 10) - 1;
|
||||
}
|
||||
|
||||
return (ld == ldOK);
|
||||
#undef UNLESS
|
||||
}
|
||||
|
||||
static void
|
||||
get_line(void)
|
||||
{
|
||||
@ -115,49 +243,53 @@ get_line(void)
|
||||
int c;
|
||||
int i;
|
||||
|
||||
if (saw_eof || (c = getc(f)) == EOF)
|
||||
do
|
||||
{
|
||||
if (line)
|
||||
if (saw_eof || (c = getc(f)) == EOF)
|
||||
{
|
||||
FREE(line);
|
||||
line = 0;
|
||||
if (line)
|
||||
{
|
||||
FREE(line);
|
||||
line = 0;
|
||||
}
|
||||
cptr = 0;
|
||||
saw_eof = 1;
|
||||
return;
|
||||
}
|
||||
cptr = 0;
|
||||
saw_eof = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (line == NULL || linesize != (LINESIZE + 1))
|
||||
{
|
||||
if (line)
|
||||
FREE(line);
|
||||
linesize = LINESIZE + 1;
|
||||
line = TMALLOC(char, linesize);
|
||||
NO_SPACE(line);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
++lineno;
|
||||
for (;;)
|
||||
{
|
||||
line[i++] = (char)c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
if ((i + 3) >= linesize)
|
||||
if (line == NULL || linesize != (LINESIZE + 1))
|
||||
{
|
||||
linesize += LINESIZE;
|
||||
line = TREALLOC(char, line, linesize);
|
||||
if (line)
|
||||
FREE(line);
|
||||
linesize = LINESIZE + 1;
|
||||
line = TMALLOC(char, linesize);
|
||||
NO_SPACE(line);
|
||||
}
|
||||
c = getc(f);
|
||||
if (c == EOF)
|
||||
|
||||
i = 0;
|
||||
++lineno;
|
||||
for (;;)
|
||||
{
|
||||
line[i++] = '\n';
|
||||
saw_eof = 1;
|
||||
break;
|
||||
line[i++] = (char)c;
|
||||
if (c == '\n')
|
||||
break;
|
||||
if ((i + 3) >= linesize)
|
||||
{
|
||||
linesize += LINESIZE;
|
||||
line = TREALLOC(char, line, linesize);
|
||||
NO_SPACE(line);
|
||||
}
|
||||
c = getc(f);
|
||||
if (c == EOF)
|
||||
{
|
||||
line[i++] = '\n';
|
||||
saw_eof = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
line[i] = '\0';
|
||||
}
|
||||
line[i] = '\0';
|
||||
while (line_directive());
|
||||
cptr = line;
|
||||
return;
|
||||
}
|
||||
|
1
contrib/byacc/test/btyacc/expr.oxout.error
Normal file
1
contrib/byacc/test/btyacc/expr.oxout.error
Normal file
@ -0,0 +1 @@
|
||||
YACC: w - line 6 of "expr.Y", the precedence of '*' has been redeclared
|
227
contrib/byacc/test/btyacc/expr.oxout.output
Normal file
227
contrib/byacc/test/btyacc/expr.oxout.output
Normal file
@ -0,0 +1,227 @@
|
||||
0 $accept : yyyAugNonterm $end
|
||||
|
||||
1 $$1 :
|
||||
|
||||
2 yyyAugNonterm : $$1 s
|
||||
|
||||
3 s : expr
|
||||
|
||||
4 expr : expr '*' expr
|
||||
5 | expr '+' expr
|
||||
6 | expr '/' expr
|
||||
7 | expr '-' expr
|
||||
8 | '(' expr ')'
|
||||
9 | ID
|
||||
10 | CONST
|
||||
|
||||
state 0
|
||||
$accept : . yyyAugNonterm $end (0)
|
||||
$$1 : . (1)
|
||||
|
||||
. reduce 1
|
||||
|
||||
yyyAugNonterm goto 1
|
||||
$$1 goto 2
|
||||
|
||||
|
||||
state 1
|
||||
$accept : yyyAugNonterm . $end (0)
|
||||
|
||||
$end accept
|
||||
|
||||
|
||||
state 2
|
||||
yyyAugNonterm : $$1 . s (2)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
s goto 6
|
||||
expr goto 7
|
||||
|
||||
|
||||
state 3
|
||||
expr : ID . (9)
|
||||
|
||||
. reduce 9
|
||||
|
||||
|
||||
state 4
|
||||
expr : CONST . (10)
|
||||
|
||||
. reduce 10
|
||||
|
||||
|
||||
state 5
|
||||
expr : '(' . expr ')' (8)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 8
|
||||
|
||||
|
||||
state 6
|
||||
yyyAugNonterm : $$1 s . (2)
|
||||
|
||||
. reduce 2
|
||||
|
||||
|
||||
state 7
|
||||
s : expr . (3)
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
|
||||
'+' shift 9
|
||||
'-' shift 10
|
||||
'*' shift 11
|
||||
'/' shift 12
|
||||
$end reduce 3
|
||||
|
||||
|
||||
state 8
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
expr : '(' expr . ')' (8)
|
||||
|
||||
'+' shift 9
|
||||
'-' shift 10
|
||||
'*' shift 11
|
||||
'/' shift 12
|
||||
')' shift 13
|
||||
. error
|
||||
|
||||
|
||||
state 9
|
||||
expr : expr '+' . expr (5)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 14
|
||||
|
||||
|
||||
state 10
|
||||
expr : expr '-' . expr (7)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 15
|
||||
|
||||
|
||||
state 11
|
||||
expr : expr '*' . expr (4)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 16
|
||||
|
||||
|
||||
state 12
|
||||
expr : expr '/' . expr (6)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 17
|
||||
|
||||
|
||||
state 13
|
||||
expr : '(' expr ')' . (8)
|
||||
|
||||
. reduce 8
|
||||
|
||||
|
||||
state 14
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr '+' expr . (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
|
||||
'*' shift 11
|
||||
'/' shift 12
|
||||
$end reduce 5
|
||||
'+' reduce 5
|
||||
'-' reduce 5
|
||||
')' reduce 5
|
||||
|
||||
|
||||
state 15
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
expr : expr '-' expr . (7)
|
||||
|
||||
'*' shift 11
|
||||
'/' shift 12
|
||||
$end reduce 7
|
||||
'+' reduce 7
|
||||
'-' reduce 7
|
||||
')' reduce 7
|
||||
|
||||
|
||||
state 16
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr '*' expr . (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
|
||||
. reduce 4
|
||||
|
||||
|
||||
state 17
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr '/' expr . (6)
|
||||
expr : expr . '-' expr (7)
|
||||
|
||||
'*' shift 11
|
||||
$end reduce 6
|
||||
'+' reduce 6
|
||||
'-' reduce 6
|
||||
'/' reduce 6
|
||||
')' reduce 6
|
||||
|
||||
|
||||
10 terminals, 5 nonterminals
|
||||
11 grammar rules, 18 states
|
||||
|
||||
grammar parser grammar
|
||||
symbol# value# symbol
|
||||
0 0 $end
|
||||
1 256 error
|
||||
2 257 ID
|
||||
3 258 CONST
|
||||
4 43 '+'
|
||||
5 45 '-'
|
||||
6 42 '*'
|
||||
7 47 '/'
|
||||
8 40 '('
|
||||
9 41 ')'
|
||||
10 259 $accept
|
||||
11 260 yyyAugNonterm
|
||||
12 261 s
|
||||
13 262 $$1
|
||||
14 263 expr
|
2752
contrib/byacc/test/btyacc/expr.oxout.tab.c
Normal file
2752
contrib/byacc/test/btyacc/expr.oxout.tab.c
Normal file
File diff suppressed because it is too large
Load Diff
20
contrib/byacc/test/btyacc/expr.oxout.tab.h
Normal file
20
contrib/byacc/test/btyacc/expr.oxout.tab.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef _expr.oxout__defines_h_
|
||||
#define _expr.oxout__defines_h_
|
||||
|
||||
#define ID 257
|
||||
#define CONST 258
|
||||
#ifdef YYSTYPE
|
||||
#undef YYSTYPE_IS_DECLARED
|
||||
#define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
#ifndef YYSTYPE_IS_DECLARED
|
||||
#define YYSTYPE_IS_DECLARED 1
|
||||
typedef union {
|
||||
struct yyyOxAttrbs {
|
||||
struct yyyStackItem *yyyOxStackItem;
|
||||
} yyyOxAttrbs;
|
||||
} YYSTYPE;
|
||||
#endif /* !YYSTYPE_IS_DECLARED */
|
||||
extern YYSTYPE expr.oxout_lval;
|
||||
|
||||
#endif /* _expr.oxout__defines_h_ */
|
1446
contrib/byacc/test/expr.oxout.y
Normal file
1446
contrib/byacc/test/expr.oxout.y
Normal file
File diff suppressed because it is too large
Load Diff
1
contrib/byacc/test/yacc/expr.oxout.error
Normal file
1
contrib/byacc/test/yacc/expr.oxout.error
Normal file
@ -0,0 +1 @@
|
||||
YACC: w - line 6 of "expr.Y", the precedence of '*' has been redeclared
|
209
contrib/byacc/test/yacc/expr.oxout.output
Normal file
209
contrib/byacc/test/yacc/expr.oxout.output
Normal file
@ -0,0 +1,209 @@
|
||||
0 $accept : yyyAugNonterm $end
|
||||
|
||||
1 $$1 :
|
||||
|
||||
2 yyyAugNonterm : $$1 s
|
||||
|
||||
3 s : expr
|
||||
|
||||
4 expr : expr '*' expr
|
||||
5 | expr '+' expr
|
||||
6 | expr '/' expr
|
||||
7 | expr '-' expr
|
||||
8 | '(' expr ')'
|
||||
9 | ID
|
||||
10 | CONST
|
||||
|
||||
state 0
|
||||
$accept : . yyyAugNonterm $end (0)
|
||||
$$1 : . (1)
|
||||
|
||||
. reduce 1
|
||||
|
||||
yyyAugNonterm goto 1
|
||||
$$1 goto 2
|
||||
|
||||
|
||||
state 1
|
||||
$accept : yyyAugNonterm . $end (0)
|
||||
|
||||
$end accept
|
||||
|
||||
|
||||
state 2
|
||||
yyyAugNonterm : $$1 . s (2)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
s goto 6
|
||||
expr goto 7
|
||||
|
||||
|
||||
state 3
|
||||
expr : ID . (9)
|
||||
|
||||
. reduce 9
|
||||
|
||||
|
||||
state 4
|
||||
expr : CONST . (10)
|
||||
|
||||
. reduce 10
|
||||
|
||||
|
||||
state 5
|
||||
expr : '(' . expr ')' (8)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 8
|
||||
|
||||
|
||||
state 6
|
||||
yyyAugNonterm : $$1 s . (2)
|
||||
|
||||
. reduce 2
|
||||
|
||||
|
||||
state 7
|
||||
s : expr . (3)
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
|
||||
'+' shift 9
|
||||
'-' shift 10
|
||||
'*' shift 11
|
||||
'/' shift 12
|
||||
$end reduce 3
|
||||
|
||||
|
||||
state 8
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
expr : '(' expr . ')' (8)
|
||||
|
||||
'+' shift 9
|
||||
'-' shift 10
|
||||
'*' shift 11
|
||||
'/' shift 12
|
||||
')' shift 13
|
||||
. error
|
||||
|
||||
|
||||
state 9
|
||||
expr : expr '+' . expr (5)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 14
|
||||
|
||||
|
||||
state 10
|
||||
expr : expr '-' . expr (7)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 15
|
||||
|
||||
|
||||
state 11
|
||||
expr : expr '*' . expr (4)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 16
|
||||
|
||||
|
||||
state 12
|
||||
expr : expr '/' . expr (6)
|
||||
|
||||
ID shift 3
|
||||
CONST shift 4
|
||||
'(' shift 5
|
||||
. error
|
||||
|
||||
expr goto 17
|
||||
|
||||
|
||||
state 13
|
||||
expr : '(' expr ')' . (8)
|
||||
|
||||
. reduce 8
|
||||
|
||||
|
||||
state 14
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr '+' expr . (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
|
||||
'*' shift 11
|
||||
'/' shift 12
|
||||
$end reduce 5
|
||||
'+' reduce 5
|
||||
'-' reduce 5
|
||||
')' reduce 5
|
||||
|
||||
|
||||
state 15
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
expr : expr '-' expr . (7)
|
||||
|
||||
'*' shift 11
|
||||
'/' shift 12
|
||||
$end reduce 7
|
||||
'+' reduce 7
|
||||
'-' reduce 7
|
||||
')' reduce 7
|
||||
|
||||
|
||||
state 16
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr '*' expr . (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr . '-' expr (7)
|
||||
|
||||
. reduce 4
|
||||
|
||||
|
||||
state 17
|
||||
expr : expr . '*' expr (4)
|
||||
expr : expr . '+' expr (5)
|
||||
expr : expr . '/' expr (6)
|
||||
expr : expr '/' expr . (6)
|
||||
expr : expr . '-' expr (7)
|
||||
|
||||
'*' shift 11
|
||||
$end reduce 6
|
||||
'+' reduce 6
|
||||
'-' reduce 6
|
||||
'/' reduce 6
|
||||
')' reduce 6
|
||||
|
||||
|
||||
10 terminals, 5 nonterminals
|
||||
11 grammar rules, 18 states
|
1958
contrib/byacc/test/yacc/expr.oxout.tab.c
Normal file
1958
contrib/byacc/test/yacc/expr.oxout.tab.c
Normal file
File diff suppressed because it is too large
Load Diff
15
contrib/byacc/test/yacc/expr.oxout.tab.h
Normal file
15
contrib/byacc/test/yacc/expr.oxout.tab.h
Normal file
@ -0,0 +1,15 @@
|
||||
#define ID 257
|
||||
#define CONST 258
|
||||
#ifdef YYSTYPE
|
||||
#undef YYSTYPE_IS_DECLARED
|
||||
#define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
#ifndef YYSTYPE_IS_DECLARED
|
||||
#define YYSTYPE_IS_DECLARED 1
|
||||
typedef union {
|
||||
struct yyyOxAttrbs {
|
||||
struct yyyStackItem *yyyOxStackItem;
|
||||
} yyyOxAttrbs;
|
||||
} YYSTYPE;
|
||||
#endif /* !YYSTYPE_IS_DECLARED */
|
||||
extern YYSTYPE expr.oxout_lval;
|
@ -1,3 +1,7 @@
|
||||
Jan 29, 2017: Limited NFSv4 ACL support for Mac OS (Darwin)
|
||||
|
||||
Jan 10, 2017: POSIX.1e and NFSv4 ACL support for Solaris and derivates
|
||||
|
||||
Dec 27, 2016: NFSv4 ACL read and write support for pax
|
||||
Deprecated functions: archive_entry_acl_text(), archive_entry_acl_text_w()
|
||||
|
||||
|
@ -348,6 +348,15 @@ archive_acl_count(struct archive_acl *acl, int want_type)
|
||||
return (count);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a bitmask of stored ACL types in an ACL list
|
||||
*/
|
||||
int
|
||||
archive_acl_types(struct archive_acl *acl)
|
||||
{
|
||||
return (acl->acl_types);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare for reading entries from the ACL data. Returns a count
|
||||
* of entries matching "want_type", or zero if there are no
|
||||
@ -1144,7 +1153,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
|
||||
const wchar_t *s, *st;
|
||||
|
||||
int numfields, fields, n, r, ret;
|
||||
int numfields, fields, n, r, sol, ret;
|
||||
int type, types, tag, permset, id;
|
||||
size_t len;
|
||||
wchar_t sep;
|
||||
@ -1192,6 +1201,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
}
|
||||
|
||||
n = 0;
|
||||
sol = 0;
|
||||
id = -1;
|
||||
permset = 0;
|
||||
name.start = name.end = NULL;
|
||||
@ -1263,6 +1273,7 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
&& ismode_w(field[n + 1].start,
|
||||
field[n + 1].end, &permset)) {
|
||||
/* This is Solaris-style "other:rwx" */
|
||||
sol = 1;
|
||||
} else if (fields == (n + 3) &&
|
||||
field[n + 1].start < field[n + 1].end) {
|
||||
/* Invalid mask or other field */
|
||||
@ -1287,9 +1298,12 @@ archive_acl_from_text_w(struct archive_acl *acl, const wchar_t *text,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Without "default:" we expect mode in field 2 */
|
||||
if (permset == 0 && !ismode_w(field[n + 2].start,
|
||||
field[n + 2].end, &permset)) {
|
||||
/*
|
||||
* Without "default:" we expect mode in field 2
|
||||
* Exception: Solaris other and mask fields
|
||||
*/
|
||||
if (permset == 0 && !ismode_w(field[n + 2 - sol].start,
|
||||
field[n + 2 - sol].end, &permset)) {
|
||||
/* Invalid mode, skip entry */
|
||||
ret = ARCHIVE_WARN;
|
||||
continue;
|
||||
@ -1615,7 +1629,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
} field[6], name;
|
||||
|
||||
const char *s, *st;
|
||||
int numfields, fields, n, r, ret;
|
||||
int numfields, fields, n, r, sol, ret;
|
||||
int type, types, tag, permset, id;
|
||||
size_t len;
|
||||
char sep;
|
||||
@ -1663,6 +1677,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
}
|
||||
|
||||
n = 0;
|
||||
sol = 0;
|
||||
id = -1;
|
||||
permset = 0;
|
||||
name.start = name.end = NULL;
|
||||
@ -1734,6 +1749,7 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
&& ismode(field[n + 1].start,
|
||||
field[n + 1].end, &permset)) {
|
||||
/* This is Solaris-style "other:rwx" */
|
||||
sol = 1;
|
||||
} else if (fields == (n + 3) &&
|
||||
field[n + 1].start < field[n + 1].end) {
|
||||
/* Invalid mask or other field */
|
||||
@ -1758,9 +1774,12 @@ archive_acl_from_text_l(struct archive_acl *acl, const char *text,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Without "default:" we expect mode in field 2 */
|
||||
if (permset == 0 && !ismode(field[n + 2].start,
|
||||
field[n + 2].end, &permset)) {
|
||||
/*
|
||||
* Without "default:" we expect mode in field 3
|
||||
* Exception: Solaris other and mask fields
|
||||
*/
|
||||
if (permset == 0 && !ismode(field[n + 2 - sol].start,
|
||||
field[n + 2 - sol].end, &permset)) {
|
||||
/* Invalid mode, skip entry */
|
||||
ret = ARCHIVE_WARN;
|
||||
continue;
|
||||
|
@ -56,6 +56,7 @@ struct archive_acl {
|
||||
void archive_acl_clear(struct archive_acl *);
|
||||
void archive_acl_copy(struct archive_acl *, struct archive_acl *);
|
||||
int archive_acl_count(struct archive_acl *, int);
|
||||
int archive_acl_types(struct archive_acl *);
|
||||
int archive_acl_reset(struct archive_acl *, int);
|
||||
int archive_acl_next(struct archive *, struct archive_acl *, int,
|
||||
int *, int *, int *, int *, const char **);
|
||||
|
@ -1447,7 +1447,7 @@ archive_entry_acl_add_entry_w(struct archive_entry *entry,
|
||||
int
|
||||
archive_entry_acl_types(struct archive_entry *entry)
|
||||
{
|
||||
return ((&entry->acl)->acl_types);
|
||||
return (archive_acl_types(&entry->acl));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -80,7 +80,7 @@ archive_entry_strmode(struct archive_entry *entry)
|
||||
if (mode & 0001) bp[9] = 't';
|
||||
else bp[9] = 'T';
|
||||
}
|
||||
if (archive_entry_acl_count(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS))
|
||||
if (archive_entry_acl_types(entry) != 0)
|
||||
bp[10] = '+';
|
||||
|
||||
return (bp);
|
||||
|
@ -147,8 +147,25 @@
|
||||
* acl_set_file(), and ACL_USER, we assume it has the rest of the
|
||||
* POSIX.1e draft functions used in archive_read_extract.c.
|
||||
*/
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE && HAVE_ACL_USER
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
|
||||
#if HAVE_ACL_USER
|
||||
#define HAVE_POSIX_ACL 1
|
||||
#elif HAVE_ACL_TYPE_EXTENDED
|
||||
#define HAVE_DARWIN_ACL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
|
||||
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
|
||||
*/
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
|
||||
#define HAVE_SUN_ACL 1
|
||||
#endif
|
||||
|
||||
/* Define if platform supports NFSv4 ACLs */
|
||||
#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
|
||||
#define HAVE_NFS4_ACL 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -80,7 +80,7 @@ archive_random(void *buf, size_t nbytes)
|
||||
|
||||
success = CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT);
|
||||
if (!success && GetLastError() == NTE_BAD_KEYSET) {
|
||||
if (!success && GetLastError() == (DWORD)NTE_BAD_KEYSET) {
|
||||
success = CryptAcquireContext(&hProv, NULL, NULL,
|
||||
PROV_RSA_FULL, CRYPT_NEWKEYSET);
|
||||
}
|
||||
|
@ -38,6 +38,11 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef HAVE_SYS_ACL_H
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
#include <membership.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_EXTATTR_H
|
||||
#include <sys/extattr.h>
|
||||
#endif
|
||||
@ -118,6 +123,15 @@ __FBSDID("$FreeBSD$");
|
||||
#define ACL_GET_PERM acl_get_perm_np
|
||||
#endif
|
||||
|
||||
/* NFSv4 platform ACL type */
|
||||
#if HAVE_SUN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
|
||||
#elif HAVE_DARWIN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
|
||||
#elif HAVE_ACL_TYPE_NFS4
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
|
||||
#endif
|
||||
|
||||
static int setup_acls(struct archive_read_disk *,
|
||||
struct archive_entry *, int *fd);
|
||||
static int setup_mac_metadata(struct archive_read_disk *,
|
||||
@ -405,17 +419,38 @@ setup_mac_metadata(struct archive_read_disk *a,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
static int translate_guid(struct archive *, acl_entry_t,
|
||||
int *, int *, const char **);
|
||||
|
||||
#ifdef HAVE_POSIX_ACL
|
||||
static void add_trivial_nfs4_acl(struct archive_entry *);
|
||||
#endif
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
static int
|
||||
sun_acl_is_trivial(acl_t *, mode_t, int *trivialp);
|
||||
#endif
|
||||
|
||||
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
|
||||
static int translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int archive_entry_acl_type);
|
||||
struct archive_entry *entry,
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl,
|
||||
#else
|
||||
acl_t acl,
|
||||
#endif
|
||||
int archive_entry_acl_type);
|
||||
|
||||
static int
|
||||
setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
{
|
||||
const char *accpath;
|
||||
acl_t acl;
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl;
|
||||
#else
|
||||
acl_t acl;
|
||||
#endif
|
||||
int r;
|
||||
|
||||
accpath = archive_entry_sourcepath(entry);
|
||||
@ -440,17 +475,20 @@ setup_acls(struct archive_read_disk *a,
|
||||
|
||||
acl = NULL;
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_NFS4_ACL
|
||||
/* Try NFSv4 ACL first. */
|
||||
if (*fd >= 0)
|
||||
#if HAVE_ACL_GET_FD_NP
|
||||
acl = acl_get_fd_np(*fd, ACL_TYPE_NFS4);
|
||||
#if HAVE_SUN_ACL
|
||||
/* Solaris reads both POSIX.1e and NFSv4 ACL here */
|
||||
facl_get(*fd, 0, &acl);
|
||||
#elif HAVE_ACL_GET_FD_NP
|
||||
acl = acl_get_fd_np(*fd, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
|
||||
#else
|
||||
acl = acl_get_fd(*fd);
|
||||
#endif
|
||||
#if HAVE_ACL_GET_LINK_NP
|
||||
else if (!a->follow_symlinks)
|
||||
acl = acl_get_link_np(accpath, ACL_TYPE_NFS4);
|
||||
acl = acl_get_link_np(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
|
||||
#else
|
||||
else if ((!a->follow_symlinks)
|
||||
&& (archive_entry_filetype(entry) == AE_IFLNK))
|
||||
@ -459,12 +497,24 @@ setup_acls(struct archive_read_disk *a,
|
||||
acl = NULL;
|
||||
#endif
|
||||
else
|
||||
acl = acl_get_file(accpath, ACL_TYPE_NFS4);
|
||||
#if HAVE_SUN_ACL
|
||||
/* Solaris reads both POSIX.1e and NFSv4 ACLs here */
|
||||
acl_get(accpath, 0, &acl);
|
||||
#else
|
||||
acl = acl_get_file(accpath, ARCHIVE_PLATFORM_ACL_TYPE_NFS4);
|
||||
#endif
|
||||
|
||||
#if HAVE_ACL_IS_TRIVIAL_NP
|
||||
if (acl != NULL && acl_is_trivial_np(acl, &r) == 0) {
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (r) {
|
||||
|
||||
#if HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL
|
||||
/* Ignore "trivial" ACLs that just mirror the file mode. */
|
||||
if (acl != NULL) {
|
||||
#if HAVE_SUN_ACL
|
||||
if (sun_acl_is_trivial(acl, archive_entry_mode(entry),
|
||||
&r) == 0 && r == 1)
|
||||
#elif HAVE_ACL_IS_TRIVIAL_NP
|
||||
if (acl_is_trivial_np(acl, &r) == 0 && r == 1)
|
||||
#endif
|
||||
{
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
/*
|
||||
@ -474,17 +524,35 @@ setup_acls(struct archive_read_disk *a,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_ACL_IS_TRIVIAL_NP || HAVE_SUN_ACL */
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4);
|
||||
acl_free(acl);
|
||||
if (r != ARCHIVE_OK) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
#if HAVE_SUN_ACL
|
||||
"Couldn't translate ACLs: %s", accpath);
|
||||
#else
|
||||
"Couldn't translate NFSv4 ACLs: %s", accpath);
|
||||
#endif
|
||||
}
|
||||
#if HAVE_DARWIN_ACL
|
||||
/*
|
||||
* Because Mac OS doesn't support owner@, group@ and everyone@
|
||||
* ACLs we need to add NFSv4 ACLs mirroring the file mode to
|
||||
* the archive entry. Otherwise extraction on non-Mac platforms
|
||||
* would lead to an invalid file mode.
|
||||
*/
|
||||
if (archive_entry_acl_count(entry,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0)
|
||||
add_trivial_nfs4_acl(entry);
|
||||
#endif
|
||||
return (r);
|
||||
}
|
||||
#endif /* ACL_TYPE_NFS4 */
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
#if HAVE_POSIX_ACL
|
||||
/* This code path is skipped on MacOS and Solaris */
|
||||
|
||||
/* Retrieve access ACL from file. */
|
||||
if (*fd >= 0)
|
||||
@ -513,8 +581,7 @@ setup_acls(struct archive_read_disk *a,
|
||||
#endif
|
||||
|
||||
if (acl != NULL) {
|
||||
r = translate_acl(a, entry, acl,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
r = translate_acl(a, entry, acl, ARCHIVE_ENTRY_ACL_TYPE_ACCESS);
|
||||
acl_free(acl);
|
||||
acl = NULL;
|
||||
if (r != ARCHIVE_OK) {
|
||||
@ -544,71 +611,560 @@ setup_acls(struct archive_read_disk *a,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_POSIX_ACL */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate system ACL into libarchive internal structure.
|
||||
* Translate system ACL permissions into libarchive internal structure
|
||||
*/
|
||||
|
||||
static struct {
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
} acl_perm_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
|
||||
#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#else /* POSIX.1e ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_NFS4_ACL
|
||||
/*
|
||||
* Translate system NFSv4 inheritance flags into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
} acl_inherit_map[] = {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
#if HAVE_SUN_ACL /* Solaris ACL inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
|
||||
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
|
||||
#else /* FreeBSD NFSv4 ACL inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_INHERIT_ONLY},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
|
||||
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
#endif
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
static int translate_guid(struct archive *a, acl_entry_t acl_entry,
|
||||
int *ae_id, int *ae_tag, const char **ae_name)
|
||||
{
|
||||
void *q;
|
||||
uid_t ugid;
|
||||
int r, idtype;
|
||||
struct passwd *pwd;
|
||||
struct group *grp;
|
||||
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q == NULL)
|
||||
return (1);
|
||||
r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
|
||||
if (r != 0) {
|
||||
acl_free(q);
|
||||
return (1);
|
||||
}
|
||||
if (idtype == ID_TYPE_UID) {
|
||||
*ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
pwd = getpwuuid(q);
|
||||
if (pwd == NULL) {
|
||||
*ae_id = ugid;
|
||||
*ae_name = NULL;
|
||||
} else {
|
||||
*ae_id = pwd->pw_uid;
|
||||
*ae_name = archive_read_disk_uname(a, *ae_id);
|
||||
}
|
||||
} else if (idtype == ID_TYPE_GID) {
|
||||
*ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
grp = getgruuid(q);
|
||||
if (grp == NULL) {
|
||||
*ae_id = ugid;
|
||||
*ae_name = NULL;
|
||||
} else {
|
||||
*ae_id = grp->gr_gid;
|
||||
*ae_name = archive_read_disk_gname(a, *ae_id);
|
||||
}
|
||||
} else
|
||||
r = 1;
|
||||
|
||||
acl_free(q);
|
||||
return (r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add trivial NFSv4 ACL entries from mode
|
||||
*/
|
||||
static void
|
||||
add_trivial_nfs4_acl(struct archive_entry *entry)
|
||||
{
|
||||
mode_t mode;
|
||||
int i;
|
||||
const int rperm = ARCHIVE_ENTRY_ACL_READ_DATA;
|
||||
const int wperm = ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA;
|
||||
const int eperm = ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
const int pubset = ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE;
|
||||
const int ownset = pubset | ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER;
|
||||
|
||||
struct {
|
||||
const int type;
|
||||
const int tag;
|
||||
int permset;
|
||||
} tacl_entry[] = {
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_USER_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_USER_OBJ, ownset},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_GROUP_OBJ, pubset},
|
||||
{ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EVERYONE, pubset}
|
||||
};
|
||||
|
||||
mode = archive_entry_mode(entry);
|
||||
|
||||
/* Permissions for everyone@ */
|
||||
if (mode & 0004)
|
||||
tacl_entry[5].permset |= rperm;
|
||||
if (mode & 0002)
|
||||
tacl_entry[5].permset |= wperm;
|
||||
if (mode & 0001)
|
||||
tacl_entry[5].permset |= eperm;
|
||||
|
||||
/* Permissions for group@ */
|
||||
if (mode & 0040)
|
||||
tacl_entry[4].permset |= rperm;
|
||||
else if (mode & 0004)
|
||||
tacl_entry[2].permset |= rperm;
|
||||
if (mode & 0020)
|
||||
tacl_entry[4].permset |= wperm;
|
||||
else if (mode & 0002)
|
||||
tacl_entry[2].permset |= wperm;
|
||||
if (mode & 0010)
|
||||
tacl_entry[4].permset |= eperm;
|
||||
else if (mode & 0001)
|
||||
tacl_entry[2].permset |= eperm;
|
||||
|
||||
/* Permissions for owner@ */
|
||||
if (mode & 0400) {
|
||||
tacl_entry[3].permset |= rperm;
|
||||
if (!(mode & 0040) && (mode & 0004))
|
||||
tacl_entry[0].permset |= rperm;
|
||||
} else if ((mode & 0040) || (mode & 0004))
|
||||
tacl_entry[1].permset |= rperm;
|
||||
if (mode & 0200) {
|
||||
tacl_entry[3].permset |= wperm;
|
||||
if (!(mode & 0020) && (mode & 0002))
|
||||
tacl_entry[0].permset |= wperm;
|
||||
} else if ((mode & 0020) || (mode & 0002))
|
||||
tacl_entry[1].permset |= wperm;
|
||||
if (mode & 0100) {
|
||||
tacl_entry[3].permset |= eperm;
|
||||
if (!(mode & 0010) && (mode & 0001))
|
||||
tacl_entry[0].permset |= eperm;
|
||||
} else if ((mode & 0010) || (mode & 0001))
|
||||
tacl_entry[1].permset |= eperm;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (tacl_entry[i].permset != 0) {
|
||||
archive_entry_acl_add_entry(entry,
|
||||
tacl_entry[i].type, tacl_entry[i].permset,
|
||||
tacl_entry[i].tag, -1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
#elif HAVE_SUN_ACL
|
||||
/*
|
||||
* Check if acl is trivial
|
||||
* This is a FreeBSD acl_is_trivial_np() implementation for Solaris
|
||||
*/
|
||||
static int
|
||||
sun_acl_is_trivial(acl_t *acl, mode_t mode, int *trivialp)
|
||||
{
|
||||
int i, p;
|
||||
const uint32_t rperm = ACE_READ_DATA;
|
||||
const uint32_t wperm = ACE_WRITE_DATA | ACE_APPEND_DATA;
|
||||
const uint32_t eperm = ACE_EXECUTE;
|
||||
const uint32_t pubset = ACE_READ_ATTRIBUTES | ACE_READ_NAMED_ATTRS |
|
||||
ACE_READ_ACL | ACE_SYNCHRONIZE;
|
||||
const uint32_t ownset = pubset | ACE_WRITE_ATTRIBUTES |
|
||||
ACE_WRITE_NAMED_ATTRS | ACE_WRITE_ACL | ACE_WRITE_OWNER;
|
||||
|
||||
ace_t *ace;
|
||||
ace_t tace[6];
|
||||
|
||||
if (acl == NULL || trivialp == NULL)
|
||||
return (-1);
|
||||
|
||||
*trivialp = 0;
|
||||
|
||||
/* ACL_IS_TRIVIAL flag must be set for both POSIX.1e and NFSv4 ACLs */
|
||||
if ((acl->acl_flags & ACL_IS_TRIVIAL) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* POSIX.1e ACLs marked with ACL_IS_TRIVIAL are compatible with
|
||||
* FreeBSD acl_is_trivial_np(). On Solaris they have 4 entries,
|
||||
* incuding mask.
|
||||
*/
|
||||
if (acl->acl_type == ACLENT_T) {
|
||||
if (acl->acl_cnt == 4)
|
||||
*trivialp = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (acl->acl_type != ACE_T || acl->acl_entry_size != sizeof(ace_t))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Continue with checking NFSv4 ACLs
|
||||
*
|
||||
* Create list of trivial ace's to be compared
|
||||
*/
|
||||
|
||||
/* owner@ allow pre */
|
||||
tace[0].a_flags = ACE_OWNER;
|
||||
tace[0].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[0].a_access_mask = 0;
|
||||
|
||||
/* owner@ deny */
|
||||
tace[1].a_flags = ACE_OWNER;
|
||||
tace[1].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
tace[1].a_access_mask = 0;
|
||||
|
||||
/* group@ deny */
|
||||
tace[2].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
|
||||
tace[2].a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
tace[2].a_access_mask = 0;
|
||||
|
||||
/* owner@ allow */
|
||||
tace[3].a_flags = ACE_OWNER;
|
||||
tace[3].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[3].a_access_mask = ownset;
|
||||
|
||||
/* group@ allow */
|
||||
tace[4].a_flags = ACE_GROUP | ACE_IDENTIFIER_GROUP;
|
||||
tace[4].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[4].a_access_mask = pubset;
|
||||
|
||||
/* everyone@ allow */
|
||||
tace[5].a_flags = ACE_EVERYONE;
|
||||
tace[5].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
tace[5].a_access_mask = pubset;
|
||||
|
||||
/* Permissions for everyone@ */
|
||||
if (mode & 0004)
|
||||
tace[5].a_access_mask |= rperm;
|
||||
if (mode & 0002)
|
||||
tace[5].a_access_mask |= wperm;
|
||||
if (mode & 0001)
|
||||
tace[5].a_access_mask |= eperm;
|
||||
|
||||
/* Permissions for group@ */
|
||||
if (mode & 0040)
|
||||
tace[4].a_access_mask |= rperm;
|
||||
else if (mode & 0004)
|
||||
tace[2].a_access_mask |= rperm;
|
||||
if (mode & 0020)
|
||||
tace[4].a_access_mask |= wperm;
|
||||
else if (mode & 0002)
|
||||
tace[2].a_access_mask |= wperm;
|
||||
if (mode & 0010)
|
||||
tace[4].a_access_mask |= eperm;
|
||||
else if (mode & 0001)
|
||||
tace[2].a_access_mask |= eperm;
|
||||
|
||||
/* Permissions for owner@ */
|
||||
if (mode & 0400) {
|
||||
tace[3].a_access_mask |= rperm;
|
||||
if (!(mode & 0040) && (mode & 0004))
|
||||
tace[0].a_access_mask |= rperm;
|
||||
} else if ((mode & 0040) || (mode & 0004))
|
||||
tace[1].a_access_mask |= rperm;
|
||||
if (mode & 0200) {
|
||||
tace[3].a_access_mask |= wperm;
|
||||
if (!(mode & 0020) && (mode & 0002))
|
||||
tace[0].a_access_mask |= wperm;
|
||||
} else if ((mode & 0020) || (mode & 0002))
|
||||
tace[1].a_access_mask |= wperm;
|
||||
if (mode & 0100) {
|
||||
tace[3].a_access_mask |= eperm;
|
||||
if (!(mode & 0010) && (mode & 0001))
|
||||
tace[0].a_access_mask |= eperm;
|
||||
} else if ((mode & 0010) || (mode & 0001))
|
||||
tace[1].a_access_mask |= eperm;
|
||||
|
||||
/* Check if the acl count matches */
|
||||
p = 3;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (tace[i].a_access_mask != 0)
|
||||
p++;
|
||||
}
|
||||
if (acl->acl_cnt != p)
|
||||
return (0);
|
||||
|
||||
p = 0;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (tace[i].a_access_mask != 0) {
|
||||
ace = &((ace_t *)acl->acl_aclp)[p];
|
||||
/*
|
||||
* Illumos added ACE_DELETE_CHILD to write perms for
|
||||
* directories. We have to check against that, too.
|
||||
*/
|
||||
if (ace->a_flags != tace[i].a_flags ||
|
||||
ace->a_type != tace[i].a_type ||
|
||||
(ace->a_access_mask != tace[i].a_access_mask &&
|
||||
((acl->acl_flags & ACL_IS_DIR) == 0 ||
|
||||
(tace[i].a_access_mask & wperm) == 0 ||
|
||||
ace->a_access_mask !=
|
||||
(tace[i].a_access_mask | ACE_DELETE_CHILD))))
|
||||
return (0);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
*trivialp = 1;
|
||||
return (0);
|
||||
}
|
||||
#endif /* HAVE_SUN_ACL */
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
/*
|
||||
* Translate Solaris POSIX.1e and NFSv4 ACLs into libarchive internal ACL
|
||||
*/
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t *acl, int default_entry_acl_type)
|
||||
{
|
||||
int e, i;
|
||||
int ae_id, ae_tag, ae_perm;
|
||||
int entry_acl_type;
|
||||
const char *ae_name;
|
||||
aclent_t *aclent;
|
||||
ace_t *ace;
|
||||
|
||||
(void)default_entry_acl_type;
|
||||
|
||||
if (acl->acl_cnt <= 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
for (e = 0; e < acl->acl_cnt; e++) {
|
||||
ae_name = NULL;
|
||||
ae_tag = 0;
|
||||
ae_perm = 0;
|
||||
|
||||
if (acl->acl_type == ACE_T) {
|
||||
ace = &((ace_t *)acl->acl_aclp)[e];
|
||||
ae_id = ace->a_who;
|
||||
|
||||
switch(ace->a_type) {
|
||||
case ACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
break;
|
||||
case ACE_ACCESS_DENIED_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
break;
|
||||
case ACE_SYSTEM_AUDIT_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
break;
|
||||
case ACE_SYSTEM_ALARM_ACE_TYPE:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALARM;
|
||||
break;
|
||||
default:
|
||||
/* Unknown entry type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ace->a_flags & ACE_OWNER) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
else if ((ace->a_flags & ACE_GROUP) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
else if ((ace->a_flags & ACE_EVERYONE) != 0)
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
else if ((ace->a_flags & ACE_IDENTIFIER_GROUP) != 0) {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
} else {
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) /
|
||||
sizeof(acl_inherit_map[0])); ++i) {
|
||||
if ((ace->a_flags &
|
||||
acl_inherit_map[i].platform_inherit) != 0)
|
||||
ae_perm |=
|
||||
acl_inherit_map[i].archive_inherit;
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)(sizeof(acl_perm_map) /
|
||||
sizeof(acl_perm_map[0])); ++i) {
|
||||
if ((ace->a_access_mask &
|
||||
acl_perm_map[i].platform_perm) != 0)
|
||||
ae_perm |=
|
||||
acl_perm_map[i].archive_perm;
|
||||
}
|
||||
} else {
|
||||
aclent = &((aclent_t *)acl->acl_aclp)[e];
|
||||
if ((aclent->a_type & ACL_DEFAULT) != 0)
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
|
||||
else
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
ae_id = aclent->a_id;
|
||||
|
||||
switch(aclent->a_type) {
|
||||
case DEF_USER:
|
||||
case USER:
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
break;
|
||||
case DEF_GROUP:
|
||||
case GROUP:
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
break;
|
||||
case DEF_CLASS_OBJ:
|
||||
case CLASS_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_MASK;
|
||||
break;
|
||||
case DEF_USER_OBJ:
|
||||
case USER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
|
||||
break;
|
||||
case DEF_GROUP_OBJ:
|
||||
case GROUP_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
|
||||
break;
|
||||
case DEF_OTHER_OBJ:
|
||||
case OTHER_OBJ:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
default:
|
||||
/* Unknown tag type, skip */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((aclent->a_perm & 1) != 0)
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
if ((aclent->a_perm & 2) != 0)
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;
|
||||
if ((aclent->a_perm & 4) != 0)
|
||||
ae_perm |= ARCHIVE_ENTRY_ACL_READ;
|
||||
} /* default_entry_acl_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4 */
|
||||
|
||||
archive_entry_acl_add_entry(entry, entry_acl_type,
|
||||
ae_perm, ae_tag, ae_id, ae_name);
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
/*
|
||||
* Translate POSIX.1e (Linux), FreeBSD (both POSIX.1e and NFSv4) and
|
||||
* MacOS (NFSv4 only) ACLs into libarchive internal structure
|
||||
*/
|
||||
static int
|
||||
translate_acl(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, acl_t acl, int default_entry_acl_type)
|
||||
{
|
||||
acl_tag_t acl_tag;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
acl_entry_type_t acl_type;
|
||||
acl_flagset_t acl_flagset;
|
||||
int brand;
|
||||
#endif
|
||||
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
|
||||
acl_flagset_t acl_flagset;
|
||||
#endif
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
int i, entry_acl_type;
|
||||
int r, s, ae_id, ae_tag, ae_perm;
|
||||
#if !HAVE_DARWIN_ACL
|
||||
void *q;
|
||||
#endif
|
||||
const char *ae_name;
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
// FreeBSD "brands" ACLs as POSIX.1e or NFSv4
|
||||
// Make sure the "brand" on this ACL is consistent
|
||||
// with the default_entry_acl_type bits provided.
|
||||
@ -643,14 +1199,19 @@ translate_acl(struct archive_read_disk *a,
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get first ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
while (s == 1) {
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
while (s == 0)
|
||||
#else /* FreeBSD, Linux */
|
||||
while (s == 1)
|
||||
#endif
|
||||
{
|
||||
ae_id = -1;
|
||||
ae_name = NULL;
|
||||
ae_perm = 0;
|
||||
@ -661,14 +1222,25 @@ translate_acl(struct archive_read_disk *a,
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
switch (acl_tag) {
|
||||
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
|
||||
case ACL_USER:
|
||||
ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
|
||||
ae_name = archive_read_disk_uname(&a->archive, ae_id);
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(uid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_uname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_USER;
|
||||
break;
|
||||
case ACL_GROUP:
|
||||
ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
|
||||
ae_name = archive_read_disk_gname(&a->archive, ae_id);
|
||||
q = acl_get_qualifier(acl_entry);
|
||||
if (q != NULL) {
|
||||
ae_id = (int)*(gid_t *)q;
|
||||
acl_free(q);
|
||||
ae_name = archive_read_disk_gname(&a->archive,
|
||||
ae_id);
|
||||
}
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
|
||||
break;
|
||||
case ACL_MASK:
|
||||
@ -683,21 +1255,44 @@ translate_acl(struct archive_read_disk *a,
|
||||
case ACL_OTHER:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
|
||||
break;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
case ACL_EVERYONE:
|
||||
ae_tag = ARCHIVE_ENTRY_ACL_EVERYONE;
|
||||
break;
|
||||
#endif
|
||||
#else /* HAVE_DARWIN_ACL */
|
||||
case ACL_EXTENDED_ALLOW:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_ALLOW;
|
||||
r = translate_guid(&a->archive, acl_entry, &ae_id,
|
||||
&ae_tag, &ae_name);
|
||||
break;
|
||||
case ACL_EXTENDED_DENY:
|
||||
entry_acl_type = ARCHIVE_ENTRY_ACL_TYPE_DENY;
|
||||
r = translate_guid(&a->archive, acl_entry, &ae_id,
|
||||
&ae_tag, &ae_name);
|
||||
break;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
default:
|
||||
/* Skip types that libarchive can't support. */
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if HAVE_DARWIN_ACL
|
||||
/* Skip if translate_guid() above failed */
|
||||
if (r != 0) {
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HAVE_DARWIN_ACL
|
||||
// XXX acl_type maps to allow/deny/audit/YYYY bits
|
||||
entry_acl_type = default_entry_acl_type;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#endif
|
||||
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
|
||||
if (default_entry_acl_type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
/*
|
||||
* acl_get_entry_type_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
@ -724,6 +1319,7 @@ translate_acl(struct archive_read_disk *a,
|
||||
"Invalid NFSv4 ACL entry type");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#endif /* HAVE_ACL_TYPE_NFS4 */
|
||||
|
||||
/*
|
||||
* Libarchive stores "flag" (NFSv4 inheritance bits)
|
||||
@ -736,7 +1332,7 @@ translate_acl(struct archive_read_disk *a,
|
||||
"Failed to get flagset from a NFSv4 ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
||||
r = acl_get_flag_np(acl_flagset,
|
||||
acl_inherit_map[i].platform_inherit);
|
||||
if (r == -1) {
|
||||
@ -746,9 +1342,9 @@ translate_acl(struct archive_read_disk *a,
|
||||
return (ARCHIVE_WARN);
|
||||
} else if (r)
|
||||
ae_perm |= acl_inherit_map[i].archive_inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL */
|
||||
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
@ -774,15 +1370,18 @@ translate_acl(struct archive_read_disk *a,
|
||||
ae_id, ae_name);
|
||||
|
||||
s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
|
||||
#if !HAVE_DARWIN_ACL
|
||||
if (s == -1) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Failed to get next ACL entry");
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#else
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
#else /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
|
||||
static int
|
||||
setup_acls(struct archive_read_disk *a,
|
||||
struct archive_entry *entry, int *fd)
|
||||
@ -792,7 +1391,7 @@ setup_acls(struct archive_read_disk *a,
|
||||
(void)fd; /* UNUSED */
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
#endif
|
||||
#endif /* !HAVE_POSIX_ACL && !HAVE_NFS4_ACL */
|
||||
|
||||
#if (HAVE_FGETXATTR && HAVE_FLISTXATTR && HAVE_LISTXATTR && \
|
||||
HAVE_LLISTXATTR && HAVE_GETXATTR && HAVE_LGETXATTR) || \
|
||||
|
@ -222,7 +222,7 @@ file_open(struct archive *a, void *client_data)
|
||||
void *buffer;
|
||||
const char *filename = NULL;
|
||||
const wchar_t *wfilename = NULL;
|
||||
int fd;
|
||||
int fd = -1;
|
||||
int is_disk_like = 0;
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
|
||||
off_t mediasize = 0; /* FreeBSD-specific, so off_t okay here. */
|
||||
@ -277,7 +277,7 @@ file_open(struct archive *a, void *client_data)
|
||||
#else
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unexpedted operation in archive_read_open_filename");
|
||||
return (ARCHIVE_FATAL);
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
if (fstat(fd, &st) != 0) {
|
||||
@ -287,7 +287,7 @@ file_open(struct archive *a, void *client_data)
|
||||
else
|
||||
archive_set_error(a, errno, "Can't stat '%s'",
|
||||
filename);
|
||||
return (ARCHIVE_FATAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -356,11 +356,9 @@ file_open(struct archive *a, void *client_data)
|
||||
mine->block_size = new_block_size;
|
||||
}
|
||||
buffer = malloc(mine->block_size);
|
||||
if (mine == NULL || buffer == NULL) {
|
||||
if (buffer == NULL) {
|
||||
archive_set_error(a, ENOMEM, "No memory");
|
||||
free(mine);
|
||||
free(buffer);
|
||||
return (ARCHIVE_FATAL);
|
||||
goto fail;
|
||||
}
|
||||
mine->buffer = buffer;
|
||||
mine->fd = fd;
|
||||
@ -372,6 +370,14 @@ file_open(struct archive *a, void *client_data)
|
||||
mine->use_lseek = 1;
|
||||
|
||||
return (ARCHIVE_OK);
|
||||
fail:
|
||||
/*
|
||||
* Don't close file descriptors not opened or ones pointing referring
|
||||
* to `FNT_STDIN`.
|
||||
*/
|
||||
if (fd != -1 && fd != 0)
|
||||
close(fd);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
|
@ -706,6 +706,11 @@ lz4_filter_read_legacy_stream(struct archive_read_filter *self, const void **p)
|
||||
/* Make sure we have a whole block. */
|
||||
read_buf = __archive_read_filter_ahead(self->upstream,
|
||||
4 + compressed, NULL);
|
||||
if (read_buf == NULL) {
|
||||
archive_set_error(&(self->archive->archive),
|
||||
ARCHIVE_ERRNO_MISC, "truncated lz4 input");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
ret = LZ4_decompress_safe(read_buf + 4, state->out_block,
|
||||
compressed, (int)state->out_block_size);
|
||||
if (ret < 0) {
|
||||
|
@ -430,6 +430,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
&state->child_stdout);
|
||||
if (child == -1) {
|
||||
free(state->out_buf);
|
||||
archive_string_free(&state->description);
|
||||
free(state);
|
||||
archive_set_error(&self->archive->archive, EINVAL,
|
||||
"Can't initialize filter; unable to run program \"%s\"",
|
||||
@ -441,6 +442,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
|
||||
if (state->child == NULL) {
|
||||
child_stop(self, state);
|
||||
free(state->out_buf);
|
||||
archive_string_free(&state->description);
|
||||
free(state);
|
||||
archive_set_error(&self->archive->archive, EINVAL,
|
||||
"Can't initialize filter; unable to run program \"%s\"",
|
||||
|
@ -1495,6 +1495,8 @@ cab_read_ahead_cfdata_deflate(struct archive_read *a, ssize_t *avail)
|
||||
|
||||
/* Cut out a tow-byte MSZIP signature(0x43, 0x4b). */
|
||||
if (mszip > 0) {
|
||||
if (bytes_avail <= 0)
|
||||
goto nomszip;
|
||||
if (bytes_avail <= mszip) {
|
||||
if (mszip == 2) {
|
||||
if (cab->stream.next_in[0] != 0x43)
|
||||
|
@ -434,7 +434,8 @@ archive_read_format_cpio_read_header(struct archive_read *a,
|
||||
* header. XXX */
|
||||
|
||||
/* Compare name to "TRAILER!!!" to test for end-of-archive. */
|
||||
if (namelength == 11 && strcmp((const char *)h, "TRAILER!!!") == 0) {
|
||||
if (namelength == 11 && memcmp((const char *)h, "TRAILER!!!",
|
||||
11) == 0) {
|
||||
/* TODO: Store file location of start of block. */
|
||||
archive_clear_error(&a->archive);
|
||||
return (ARCHIVE_EOF);
|
||||
|
@ -1864,7 +1864,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
if ((file->utf16be_name = malloc(name_len)) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory for file name");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
memcpy(file->utf16be_name, p, name_len);
|
||||
file->utf16be_bytes = name_len;
|
||||
@ -1943,10 +1943,8 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
file->symlink_continues = 0;
|
||||
rr_start += iso9660->suspOffset;
|
||||
r = parse_rockridge(a, file, rr_start, rr_end);
|
||||
if (r != ARCHIVE_OK) {
|
||||
free(file);
|
||||
return (NULL);
|
||||
}
|
||||
if (r != ARCHIVE_OK)
|
||||
goto fail;
|
||||
/*
|
||||
* A file size of symbolic link files in ISO images
|
||||
* made by makefs is not zero and its location is
|
||||
@ -1990,7 +1988,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge RE");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
/*
|
||||
* Sanity check: file does not have "CL" extension.
|
||||
@ -1999,7 +1997,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge RE and CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
/*
|
||||
* Sanity check: The file type must be a directory.
|
||||
@ -2008,7 +2006,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge RE");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
} else if (parent != NULL && parent->rr_moved)
|
||||
file->rr_moved_has_re_only = 0;
|
||||
@ -2022,7 +2020,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
/*
|
||||
* Sanity check: The file type must be a regular file.
|
||||
@ -2031,7 +2029,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
parent->subdirs++;
|
||||
/* Overwrite an offset and a number of this "CL" entry
|
||||
@ -2049,7 +2047,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (file->cl_offset == file->offset ||
|
||||
@ -2057,7 +2055,7 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_MISC,
|
||||
"Invalid Rockridge CL");
|
||||
return (NULL);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2088,6 +2086,10 @@ parse_file_info(struct archive_read *a, struct file_info *parent,
|
||||
#endif
|
||||
register_file(iso9660, file);
|
||||
return (file);
|
||||
fail:
|
||||
archive_string_free(&file->name);
|
||||
free(file);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -924,6 +924,9 @@ lha_read_file_header_1(struct archive_read *a, struct lha *lha)
|
||||
/* Get a real compressed file size. */
|
||||
lha->compsize -= extdsize - 2;
|
||||
|
||||
if (lha->compsize < 0)
|
||||
goto invalid; /* Invalid compressed file size */
|
||||
|
||||
if (sum_calculated != headersum) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"LHa header sum error");
|
||||
|
@ -715,13 +715,13 @@ detect_form(struct archive_read *a, int *is_form_d)
|
||||
}
|
||||
} else
|
||||
break;
|
||||
} else if (strncmp(p, "/set", 4) == 0) {
|
||||
} else if (len > 4 && strncmp(p, "/set", 4) == 0) {
|
||||
if (bid_keyword_list(p+4, len-4, 0, 0) <= 0)
|
||||
break;
|
||||
/* This line continues. */
|
||||
if (p[len-nl-1] == '\\')
|
||||
multiline = 2;
|
||||
} else if (strncmp(p, "/unset", 6) == 0) {
|
||||
} else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
|
||||
if (bid_keyword_list(p+6, len-6, 1, 0) <= 0)
|
||||
break;
|
||||
/* This line continues. */
|
||||
@ -1019,11 +1019,11 @@ read_mtree(struct archive_read *a, struct mtree *mtree)
|
||||
if (*p != '/') {
|
||||
r = process_add_entry(a, mtree, &global, p, len,
|
||||
&last_entry, is_form_d);
|
||||
} else if (strncmp(p, "/set", 4) == 0) {
|
||||
} else if (len > 4 && strncmp(p, "/set", 4) == 0) {
|
||||
if (p[4] != ' ' && p[4] != '\t')
|
||||
break;
|
||||
r = process_global_set(a, &global, p);
|
||||
} else if (strncmp(p, "/unset", 6) == 0) {
|
||||
} else if (len > 6 && strncmp(p, "/unset", 6) == 0) {
|
||||
if (p[6] != ' ' && p[6] != '\t')
|
||||
break;
|
||||
r = process_global_unset(a, &global, p);
|
||||
|
@ -944,7 +944,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
||||
{
|
||||
const struct archive_entry_header_ustar *header;
|
||||
size_t size;
|
||||
int err;
|
||||
int err, acl_type;
|
||||
int64_t type;
|
||||
char *acl, *p;
|
||||
|
||||
@ -989,11 +989,12 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
||||
switch ((int)type & ~0777777) {
|
||||
case 01000000:
|
||||
/* POSIX.1e ACL */
|
||||
acl_type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
break;
|
||||
case 03000000:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Solaris NFSv4 ACLs not supported");
|
||||
return (ARCHIVE_WARN);
|
||||
/* NFSv4 ACL */
|
||||
acl_type = ARCHIVE_ENTRY_ACL_TYPE_NFS4;
|
||||
break;
|
||||
default:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Malformed Solaris ACL attribute (unsupported type %o)",
|
||||
@ -1023,7 +1024,7 @@ header_Solaris_ACL(struct archive_read *a, struct tar *tar,
|
||||
}
|
||||
archive_strncpy(&(tar->localname), acl, p - acl);
|
||||
err = archive_acl_from_text_l(archive_entry_acl(entry),
|
||||
tar->localname.s, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, tar->sconv_acl);
|
||||
tar->localname.s, acl_type, tar->sconv_acl);
|
||||
if (err != ARCHIVE_OK) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
|
@ -534,7 +534,7 @@ xstrpisotime(const char *s, char **endptr)
|
||||
|
||||
/* as a courtesy to our callers, and since this is a non-standard
|
||||
* routine, we skip leading whitespace */
|
||||
while (isspace((unsigned char)*s))
|
||||
while (isblank((unsigned char)*s))
|
||||
++s;
|
||||
|
||||
/* read year */
|
||||
|
@ -933,6 +933,7 @@ xar_cleanup(struct archive_read *a)
|
||||
}
|
||||
for (i = 0; i < xar->file_queue.used; i++)
|
||||
file_free(xar->file_queue.files[i]);
|
||||
free(xar->file_queue.files);
|
||||
while (xar->unknowntags != NULL) {
|
||||
struct unknown_tag *tag;
|
||||
|
||||
@ -3047,7 +3048,7 @@ xml2_read_cb(void *context, char *buffer, int len)
|
||||
struct xar *xar;
|
||||
const void *d;
|
||||
size_t outbytes;
|
||||
size_t used;
|
||||
size_t used = 0;
|
||||
int r;
|
||||
|
||||
a = (struct archive_read *)context;
|
||||
@ -3171,6 +3172,9 @@ expat_xmlattr_setup(struct archive_read *a,
|
||||
value = strdup(atts[1]);
|
||||
if (attr == NULL || name == NULL || value == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
free(attr);
|
||||
free(name);
|
||||
free(value);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
attr->name = name;
|
||||
|
@ -905,6 +905,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
archive_wstrcat(&s, wp);
|
||||
archive_wstrappend_wchar(&s, L'/');
|
||||
archive_entry_copy_pathname_w(entry, s.s);
|
||||
archive_wstring_free(&s);
|
||||
}
|
||||
} else {
|
||||
cp = archive_entry_pathname(entry);
|
||||
@ -915,6 +916,7 @@ zip_read_local_file_header(struct archive_read *a, struct archive_entry *entry,
|
||||
archive_strcat(&s, cp);
|
||||
archive_strappend_char(&s, '/');
|
||||
archive_entry_set_pathname(entry, s.s);
|
||||
archive_string_free(&s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +200,7 @@ __archive_write_program_free(struct archive_write_program_data *data)
|
||||
if (data->child)
|
||||
CloseHandle(data->child);
|
||||
#endif
|
||||
free(data->program_name);
|
||||
free(data->child_buf);
|
||||
free(data);
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
|
||||
#define _ACL_PRIVATE /* For debugging */
|
||||
#include <sys/acl.h>
|
||||
#endif
|
||||
#if HAVE_DARWIN_ACL
|
||||
#include <membership.h>
|
||||
#endif
|
||||
#ifdef HAVE_ERRNO_H
|
||||
#include <errno.h>
|
||||
#endif
|
||||
@ -43,7 +46,7 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_disk.c 201159 2009-12-29 0
|
||||
#include "archive_acl_private.h"
|
||||
#include "archive_write_disk_private.h"
|
||||
|
||||
#ifndef HAVE_POSIX_ACL
|
||||
#if !HAVE_POSIX_ACL && !HAVE_NFS4_ACL
|
||||
/* Default empty function body to satisfy mainline code. */
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
@ -56,47 +59,111 @@ archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
#else
|
||||
#else /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACE_T
|
||||
#elif HAVE_DARWIN_ACL
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_EXTENDED
|
||||
#elif HAVE_ACL_TYPE_NFS4
|
||||
#define ARCHIVE_PLATFORM_ACL_TYPE_NFS4 ACL_TYPE_NFS4
|
||||
#endif
|
||||
|
||||
static int set_acl(struct archive *, int fd, const char *,
|
||||
struct archive_acl *,
|
||||
acl_type_t, int archive_entry_acl_type, const char *tn);
|
||||
|
||||
/*
|
||||
* XXX TODO: What about ACL types other than ACCESS and DEFAULT?
|
||||
*/
|
||||
int
|
||||
archive_write_disk_set_acls(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl)
|
||||
{
|
||||
int ret;
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) > 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
|
||||
#if !HAVE_DARWIN_ACL
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
/* Solaris writes POSIX.1e access and default ACLs together */
|
||||
ret = set_acl(a, fd, name, abstract_acl, ACLENT_T,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_POSIX1E, "posix1e");
|
||||
#else /* HAVE_POSIX_ACL */
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
"access");
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ret);
|
||||
}
|
||||
if ((archive_acl_types(abstract_acl)
|
||||
& ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_TYPE_DEFAULT,
|
||||
"default");
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
/* Simultaeous POSIX.1e and NFSv4 is not supported */
|
||||
return (ret);
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
} else if (archive_acl_count(abstract_acl, ARCHIVE_ENTRY_ACL_TYPE_NFS4) > 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_NFS4,
|
||||
}
|
||||
#endif /* !HAVE_DARWIN_ACL */
|
||||
#if HAVE_NFS4_ACL
|
||||
if ((archive_acl_types(abstract_acl) &
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
ret = set_acl(a, fd, name, abstract_acl,
|
||||
ARCHIVE_PLATFORM_ACL_TYPE_NFS4,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, "nfs4");
|
||||
return (ret);
|
||||
#endif
|
||||
} else
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate system ACL permissions into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_perm;
|
||||
int platform_perm;
|
||||
} acl_perm_map[] = {
|
||||
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACE_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACE_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACE_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACE_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACE_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACE_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACE_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACE_READ_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACE_WRITE_NAMED_ATTRS},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACE_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACE_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACE_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACE_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACE_READ_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACE_WRITE_ACL},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACE_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACE_SYNCHRONIZE}
|
||||
#elif HAVE_DARWIN_ACL /* MacOS ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_FILE, ACL_ADD_FILE},
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE, ACL_DELETE},
|
||||
{ARCHIVE_ENTRY_ACL_APPEND_DATA, ACL_APPEND_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY, ACL_ADD_SUBDIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_DELETE_CHILD, ACL_DELETE_CHILD},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS, ACL_READ_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS, ACL_WRITE_EXTATTRIBUTES},
|
||||
{ARCHIVE_ENTRY_ACL_READ_ACL, ACL_READ_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_ACL, ACL_WRITE_SECURITY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_CHANGE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#else /* POSIX.1e ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_EXECUTE, ACL_EXECUTE},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE, ACL_WRITE},
|
||||
{ARCHIVE_ENTRY_ACL_READ, ACL_READ},
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4 /* FreeBSD NFSv4 ACL permissions */
|
||||
{ARCHIVE_ENTRY_ACL_READ_DATA, ACL_READ_DATA},
|
||||
{ARCHIVE_ENTRY_ACL_LIST_DIRECTORY, ACL_LIST_DIRECTORY},
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_DATA, ACL_WRITE_DATA},
|
||||
@ -114,13 +181,32 @@ static struct {
|
||||
{ARCHIVE_ENTRY_ACL_WRITE_OWNER, ACL_WRITE_OWNER},
|
||||
{ARCHIVE_ENTRY_ACL_SYNCHRONIZE, ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_NFS4_ACL
|
||||
/*
|
||||
* Translate system NFSv4 inheritance flags into libarchive internal structure
|
||||
*/
|
||||
static struct {
|
||||
int archive_inherit;
|
||||
int platform_inherit;
|
||||
} acl_inherit_map[] = {
|
||||
#if HAVE_SUN_ACL /* Solaris NFSv4 inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACE_FILE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACE_DIRECTORY_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACE_NO_PROPAGATE_INHERIT_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACE_INHERIT_ONLY_ACE},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACE_SUCCESSFUL_ACCESS_ACE_FLAG},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACE_FAILED_ACCESS_ACE_FLAG},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACE_INHERITED_ACE}
|
||||
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_LIMIT_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, ACL_ENTRY_ONLY_INHERIT}
|
||||
#else /* FreeBSD NFSv4 ACL inheritance flags */
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
@ -128,23 +214,36 @@ static struct {
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS, ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS, ACL_ENTRY_FAILED_ACCESS},
|
||||
{ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}
|
||||
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
};
|
||||
#endif
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
static int
|
||||
set_acl(struct archive *a, int fd, const char *name,
|
||||
struct archive_acl *abstract_acl,
|
||||
acl_type_t acl_type, int ae_requested_type, const char *tname)
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
aclent_t *aclent;
|
||||
ace_t *ace;
|
||||
int e, r;
|
||||
acl_t *acl;
|
||||
#else
|
||||
acl_t acl;
|
||||
acl_entry_t acl_entry;
|
||||
acl_permset_t acl_permset;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4 || HAVE_DARWIN_ACL
|
||||
acl_flagset_t acl_flagset;
|
||||
int r;
|
||||
#endif
|
||||
#endif /* HAVE_SUN_ACL */
|
||||
#if HAVE_ACL_TYPE_NFS4
|
||||
int r;
|
||||
#endif
|
||||
int ret;
|
||||
int ae_type, ae_permset, ae_tag, ae_id;
|
||||
#if HAVE_DARWIN_ACL
|
||||
uuid_t ae_uuid;
|
||||
#endif
|
||||
uid_t ae_uid;
|
||||
gid_t ae_gid;
|
||||
const char *ae_name;
|
||||
@ -155,32 +254,165 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
entries = archive_acl_reset(abstract_acl, ae_requested_type);
|
||||
if (entries == 0)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
acl = NULL;
|
||||
acl = malloc(sizeof(acl_t));
|
||||
if (acl == NULL) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ACL type");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (acl_type == ACE_T)
|
||||
acl->acl_entry_size = sizeof(ace_t);
|
||||
else if (acl_type == ACLENT_T)
|
||||
acl->acl_entry_size = sizeof(aclent_t);
|
||||
else {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid ACL type");
|
||||
acl_free(acl);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
acl->acl_type = acl_type;
|
||||
acl->acl_cnt = entries;
|
||||
|
||||
acl->acl_aclp = malloc(entries * acl->acl_entry_size);
|
||||
if (acl->acl_aclp == NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Can't allocate memory for acl buffer");
|
||||
acl_free(acl);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
acl = acl_init(entries);
|
||||
if (acl == (acl_t)NULL) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to initialize ACL working storage");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
#if HAVE_SUN_ACL
|
||||
e = 0;
|
||||
#endif
|
||||
while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
|
||||
&ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
|
||||
#if HAVE_SUN_ACL
|
||||
ace = NULL;
|
||||
aclent = NULL;
|
||||
if (acl->acl_type == ACE_T) {
|
||||
ace = &((ace_t *)acl->acl_aclp)[e];
|
||||
ace->a_who = -1;
|
||||
ace->a_access_mask = 0;
|
||||
ace->a_flags = 0;
|
||||
} else {
|
||||
aclent = &((aclent_t *)acl->acl_aclp)[e];
|
||||
aclent->a_id = -1;
|
||||
aclent->a_type = 0;
|
||||
aclent->a_perm = 0;
|
||||
}
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
#if HAVE_DARWIN_ACL
|
||||
/*
|
||||
* Mac OS doesn't support NFSv4 ACLs for
|
||||
* owner@, group@ and everyone@.
|
||||
* We skip any of these ACLs found.
|
||||
*/
|
||||
if (ae_tag == ARCHIVE_ENTRY_ACL_USER_OBJ ||
|
||||
ae_tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ ||
|
||||
ae_tag == ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
continue;
|
||||
#endif
|
||||
if (acl_create_entry(&acl, &acl_entry) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to create a new ACL entry");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
#if HAVE_DARWIN_ACL
|
||||
switch (ae_type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
acl_set_tag_type(acl_entry, ACL_EXTENDED_ALLOW);
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
acl_set_tag_type(acl_entry, ACL_EXTENDED_DENY);
|
||||
break;
|
||||
default:
|
||||
/* We don't support any other types on MacOS */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
switch (ae_tag) {
|
||||
#if HAVE_SUN_ACL
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
acl_set_tag_type(acl_entry, ACL_USER);
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
acl_set_qualifier(acl_entry, &ae_uid);
|
||||
if (acl->acl_type == ACE_T)
|
||||
ace->a_who = ae_uid;
|
||||
else {
|
||||
aclent->a_id = ae_uid;
|
||||
aclent->a_type |= USER;
|
||||
}
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP);
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
acl_set_qualifier(acl_entry, &ae_gid);
|
||||
if (acl->acl_type == ACE_T) {
|
||||
ace->a_who = ae_gid;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
} else {
|
||||
aclent->a_id = ae_gid;
|
||||
aclent->a_type |= GROUP;
|
||||
}
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
if (acl->acl_type == ACE_T)
|
||||
ace->a_flags |= ACE_OWNER;
|
||||
else
|
||||
aclent->a_type |= USER_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
if (acl->acl_type == ACE_T) {
|
||||
ace->a_flags |= ACE_GROUP;
|
||||
ace->a_flags |= ACE_IDENTIFIER_GROUP;
|
||||
} else
|
||||
aclent->a_type |= GROUP_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
aclent->a_type |= CLASS_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
aclent->a_type |= OTHER_OBJ;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
ace->a_flags |= ACE_EVERYONE;
|
||||
break;
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
|
||||
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
|
||||
acl_set_tag_type(acl_entry, ACL_USER);
|
||||
acl_set_qualifier(acl_entry, &ae_uid);
|
||||
#else /* MacOS */
|
||||
if (mbr_identifier_to_uuid(ID_TYPE_UID, &ae_uid,
|
||||
sizeof(uid_t), ae_uuid) != 0)
|
||||
continue;
|
||||
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
|
||||
continue;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
|
||||
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
|
||||
acl_set_tag_type(acl_entry, ACL_GROUP);
|
||||
acl_set_qualifier(acl_entry, &ae_gid);
|
||||
#else /* MacOS */
|
||||
if (mbr_identifier_to_uuid(ID_TYPE_GID, &ae_gid,
|
||||
sizeof(gid_t), ae_uuid) != 0)
|
||||
continue;
|
||||
if (acl_set_qualifier(acl_entry, &ae_uuid) != 0)
|
||||
continue;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
break;
|
||||
#if !HAVE_DARWIN_ACL /* FreeBSD, Linux */
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
acl_set_tag_type(acl_entry, ACL_USER_OBJ);
|
||||
break;
|
||||
@ -193,11 +425,13 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
acl_set_tag_type(acl_entry, ACL_OTHER);
|
||||
break;
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4 /* FreeBSD only */
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
acl_set_tag_type(acl_entry, ACL_EVERYONE);
|
||||
break;
|
||||
#endif
|
||||
#endif /* !HAVE_DARWIN_ACL */
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown ACL tag");
|
||||
@ -205,9 +439,45 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
#if HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL
|
||||
r = 0;
|
||||
switch (ae_type) {
|
||||
#if HAVE_SUN_ACL
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
if (ace != NULL)
|
||||
ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
|
||||
if (aclent == NULL)
|
||||
r = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
if (aclent != NULL)
|
||||
aclent->a_type |= ACL_DEFAULT;
|
||||
else
|
||||
r = -1;
|
||||
break;
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
r = acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
|
||||
break;
|
||||
@ -224,20 +494,35 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
|
||||
// These don't translate directly into the system ACL.
|
||||
break;
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
default:
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
if (r != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
errno = EINVAL;
|
||||
#endif
|
||||
archive_set_error(a, errno,
|
||||
"Failed to set ACL entry type");
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_ACL_TYPE_NFS4 || HAVE_SUN_ACL */
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl->acl_type == ACLENT_T) {
|
||||
if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
|
||||
aclent->a_perm |= 1;
|
||||
if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
|
||||
aclent->a_perm |= 2;
|
||||
if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
|
||||
aclent->a_perm |= 4;
|
||||
} else
|
||||
#else
|
||||
if (acl_get_permset(acl_entry, &acl_permset) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
"Failed to get ACL permission set");
|
||||
@ -250,9 +535,13 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
|
||||
if (ae_permset & acl_perm_map[i].archive_perm)
|
||||
if (ae_permset & acl_perm_map[i].archive_perm) {
|
||||
#if HAVE_SUN_ACL
|
||||
ace->a_access_mask |=
|
||||
acl_perm_map[i].platform_perm;
|
||||
#else
|
||||
if (acl_add_perm(acl_permset,
|
||||
acl_perm_map[i].platform_perm) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
@ -260,10 +549,20 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ACL_TYPE_NFS4
|
||||
if (acl_type == ACL_TYPE_NFS4) {
|
||||
#if HAVE_NFS4_ACL
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl_type == ACE_T)
|
||||
#elif HAVE_DARWIN_ACL
|
||||
if (acl_type == ACL_TYPE_EXTENDED)
|
||||
#else /* FreeBSD */
|
||||
if (acl_type == ACL_TYPE_NFS4)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_POSIX_ACL || HAVE_DARWIN_ACL
|
||||
/*
|
||||
* acl_get_flagset_np() fails with non-NFSv4 ACLs
|
||||
*/
|
||||
@ -279,8 +578,13 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_DARWIN_ACL */
|
||||
for (i = 0; i < (int)(sizeof(acl_inherit_map) /sizeof(acl_inherit_map[0])); ++i) {
|
||||
if (ae_permset & acl_inherit_map[i].archive_inherit) {
|
||||
#if HAVE_SUN_ACL
|
||||
ace->a_flags |=
|
||||
acl_inherit_map[i].platform_inherit;
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
if (acl_add_flag_np(acl_flagset,
|
||||
acl_inherit_map[i].platform_inherit) != 0) {
|
||||
archive_set_error(a, errno,
|
||||
@ -288,19 +592,29 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_free;
|
||||
}
|
||||
#endif /* HAVE_SUN_ACL */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
#if HAVE_SUN_ACL
|
||||
e++;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL
|
||||
/* Try restoring the ACL through 'fd' if we can. */
|
||||
#if HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD
|
||||
#if HAVE_ACL_SET_FD_NP
|
||||
if (fd >= 0) {
|
||||
#if HAVE_SUN_ACL || HAVE_ACL_SET_FD_NP
|
||||
if (fd >= 0)
|
||||
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
|
||||
if (fd >= 0 && acl_type == ACL_TYPE_ACCESS)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
if (facl_set(fd, acl) == 0)
|
||||
#elif HAVE_ACL_SET_FD_NP
|
||||
if (acl_set_fd_np(fd, acl, acl_type) == 0)
|
||||
#else /* HAVE_ACL_SET_FD */
|
||||
if (fd >= 0 && acl_type == ACL_TYPE_ACCESS) {
|
||||
#else /* !HAVE_SUN_ACL && !HAVE_ACL_SET_FD_NP */
|
||||
if (acl_set_fd(fd, acl) == 0)
|
||||
#endif
|
||||
ret = ARCHIVE_OK;
|
||||
@ -314,13 +628,16 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD */
|
||||
#if HAVE_ACL_SET_LINK_NP
|
||||
if (acl_set_link_np(name, acl_type, acl) != 0) {
|
||||
#endif /* HAVE_ACL_SET_FD_NP || HAVE_ACL_SET_FD || HAVE_SUN_ACL */
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl_set(name, acl) != 0)
|
||||
#elif HAVE_ACL_SET_LINK_NP
|
||||
if (acl_set_link_np(name, acl_type, acl) != 0)
|
||||
#else
|
||||
/* TODO: Skip this if 'name' is a symlink. */
|
||||
if (acl_set_file(name, acl_type, acl) != 0) {
|
||||
if (acl_set_file(name, acl_type, acl) != 0)
|
||||
#endif
|
||||
{
|
||||
if (errno == EOPNOTSUPP) {
|
||||
/* Filesystem doesn't support ACLs */
|
||||
ret = ARCHIVE_OK;
|
||||
@ -334,4 +651,4 @@ set_acl(struct archive *a, int fd, const char *name,
|
||||
acl_free(acl);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_POSIX_ACL || HAVE_NFS4_ACL */
|
||||
|
@ -110,6 +110,18 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/fcntl1.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro to cast st_mtime and time_t to an int64 so that 2 numbers can reliably be compared.
|
||||
*
|
||||
* It assumes that the input is an integer type of no more than 64 bits.
|
||||
* If the number is less than zero, t must be a signed type, so it fits in
|
||||
* int64_t. Otherwise, it's a nonnegative value so we can cast it to uint64_t
|
||||
* without loss. But it could be a large unsigned value, so we have to clip it
|
||||
* to INT64_MAX.*
|
||||
*/
|
||||
#define to_int64_time(t) \
|
||||
((t) < 0 ? (int64_t)(t) : (uint64_t)(t) > (uint64_t)INT64_MAX ? INT64_MAX : (int64_t)(t))
|
||||
|
||||
#if __APPLE__
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && HAVE_QUARANTINE_H
|
||||
@ -1690,10 +1702,25 @@ _archive_write_disk_finish_entry(struct archive *_a)
|
||||
* ACLs that prevent attribute changes (including time).
|
||||
*/
|
||||
if (a->todo & TODO_ACLS) {
|
||||
int r2 = archive_write_disk_set_acls(&a->archive, a->fd,
|
||||
archive_entry_pathname(a->entry),
|
||||
archive_entry_acl(a->entry));
|
||||
int r2;
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
/*
|
||||
* On Mac OS, platform ACLs are stored also in mac_metadata by
|
||||
* the operating system. If mac_metadata is present it takes
|
||||
* precedence and we skip extracting libarchive NFSv4 ACLs
|
||||
*/
|
||||
const void *metadata;
|
||||
size_t metadata_size;
|
||||
metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
|
||||
if (metadata == NULL || metadata_size == 0) {
|
||||
#endif
|
||||
r2 = archive_write_disk_set_acls(&a->archive, a->fd,
|
||||
archive_entry_pathname(a->entry),
|
||||
archive_entry_acl(a->entry));
|
||||
if (r2 < ret) ret = r2;
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
finish_metadata:
|
||||
@ -2065,6 +2092,7 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
archive_set_error(&a->archive, error_number, "%s",
|
||||
error_string.s);
|
||||
free(linkname_copy);
|
||||
archive_string_free(&error_string);
|
||||
/*
|
||||
* EPERM is more appropriate than error_number for our
|
||||
* callers
|
||||
@ -2077,6 +2105,7 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
archive_set_error(&a->archive, error_number, "%s",
|
||||
error_string.s);
|
||||
free(linkname_copy);
|
||||
archive_string_free(&error_string);
|
||||
/*
|
||||
* EPERM is more appropriate than error_number for our
|
||||
* callers
|
||||
@ -2084,6 +2113,7 @@ create_filesystem_object(struct archive_write_disk *a)
|
||||
return (EPERM);
|
||||
}
|
||||
free(linkname_copy);
|
||||
archive_string_free(&error_string);
|
||||
r = link(linkname, a->name) ? errno : 0;
|
||||
/*
|
||||
* New cpio and pax formats allow hardlink entries
|
||||
@ -2252,8 +2282,12 @@ _archive_write_disk_close(struct archive *_a)
|
||||
if (p->fixup & TODO_MODE_BASE)
|
||||
chmod(p->name, p->mode);
|
||||
if (p->fixup & TODO_ACLS)
|
||||
archive_write_disk_set_acls(&a->archive,
|
||||
-1, p->name, &p->acl);
|
||||
#ifdef HAVE_DARWIN_ACL
|
||||
if (p->mac_metadata == NULL ||
|
||||
p->mac_metadata_size == 0)
|
||||
#endif
|
||||
archive_write_disk_set_acls(&a->archive,
|
||||
-1, p->name, &p->acl);
|
||||
if (p->fixup & TODO_FFLAGS)
|
||||
set_fflags_platform(a, -1, p->name,
|
||||
p->mode, p->fflags_set, 0);
|
||||
@ -4125,10 +4159,10 @@ older(struct stat *st, struct archive_entry *entry)
|
||||
{
|
||||
/* First, test the seconds and return if we have a definite answer. */
|
||||
/* Definitely older. */
|
||||
if (st->st_mtime < archive_entry_mtime(entry))
|
||||
if (to_int64_time(st->st_mtime) < to_int64_time(archive_entry_mtime(entry)))
|
||||
return (1);
|
||||
/* Definitely younger. */
|
||||
if (st->st_mtime > archive_entry_mtime(entry))
|
||||
if (to_int64_time(st->st_mtime) > to_int64_time(archive_entry_mtime(entry)))
|
||||
return (0);
|
||||
/* If this platform supports fractional seconds, try those. */
|
||||
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
|
@ -66,6 +66,7 @@ Freeze the settings, open the archive, and prepare for writing entries.
|
||||
This is the most generic form of this function, which accepts
|
||||
pointers to three callback functions which will be invoked by
|
||||
the compression layer to write the constructed archive.
|
||||
This does not alter the default archive padding.
|
||||
.It Fn archive_write_open_fd
|
||||
A convenience form of
|
||||
.Fn archive_write_open
|
||||
@ -123,12 +124,21 @@ is currently in use.
|
||||
You should be careful to ensure that this variable
|
||||
remains allocated until after the archive is
|
||||
closed.
|
||||
This function will disable padding unless you
|
||||
have specifically set the block size.
|
||||
.El
|
||||
More information about the
|
||||
.Va struct archive
|
||||
object and the overall design of the library can be found in the
|
||||
.Xr libarchive 3
|
||||
overview.
|
||||
.Pp
|
||||
Note that the convenience forms above vary in how
|
||||
they block the output.
|
||||
See
|
||||
.Xr archive_write_blocksize 3
|
||||
if you need to control the block size used for writes
|
||||
or the end-of-file padding behavior.
|
||||
.\"
|
||||
.Sh CLIENT CALLBACKS
|
||||
To use this library, you will need to define and register
|
||||
@ -226,6 +236,7 @@ functions.
|
||||
.Xr tar 1 ,
|
||||
.Xr libarchive 3 ,
|
||||
.Xr archive_write 3 ,
|
||||
.Xr archive_write_blocksize 3 ,
|
||||
.Xr archive_write_filter 3 ,
|
||||
.Xr archive_write_format 3 ,
|
||||
.Xr archive_write_new 3 ,
|
||||
|
@ -478,15 +478,15 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
archive_entry_set_pathname(temp, "././@LongLink");
|
||||
archive_entry_set_size(temp, length);
|
||||
ret = archive_format_gnutar_header(a, buff, temp, 'K');
|
||||
archive_entry_free(temp);
|
||||
if (ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
ret = __archive_write_output(a, buff, 512);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
if (ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
archive_entry_free(temp);
|
||||
/* Write name and trailing null byte. */
|
||||
ret = __archive_write_output(a, gnutar->linkname, length);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
if (ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
/* Pad to 512 bytes */
|
||||
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)length));
|
||||
@ -508,12 +508,12 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
archive_entry_set_pathname(temp, "././@LongLink");
|
||||
archive_entry_set_size(temp, length);
|
||||
ret = archive_format_gnutar_header(a, buff, temp, 'L');
|
||||
archive_entry_free(temp);
|
||||
if (ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
ret = __archive_write_output(a, buff, 512);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
goto exit_write_header;
|
||||
archive_entry_free(temp);
|
||||
/* Write pathname + trailing null byte. */
|
||||
ret = __archive_write_output(a, pathname, length);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
|
@ -2524,7 +2524,8 @@ get_tmfromtime(struct tm *tm, time_t *t)
|
||||
tzset();
|
||||
localtime_r(t, tm);
|
||||
#elif HAVE__LOCALTIME64_S
|
||||
_localtime64_s(tm, t);
|
||||
__time64_t tmp_t = (__time64_t) *t; //time_t may be shorter than 64 bits
|
||||
_localtime64_s(tm, &tmp_t);
|
||||
#else
|
||||
memcpy(tm, localtime(t), sizeof(*tm));
|
||||
#endif
|
||||
@ -2553,7 +2554,7 @@ set_date_time(unsigned char *p, time_t t)
|
||||
static void
|
||||
set_date_time_null(unsigned char *p)
|
||||
{
|
||||
memset(p, '0', 16);
|
||||
memset(p, (int)'0', 16);
|
||||
p[16] = 0;
|
||||
}
|
||||
|
||||
@ -4073,7 +4074,8 @@ write_information_block(struct archive_write *a)
|
||||
memset(info.s, 0, info_size);
|
||||
opt = 0;
|
||||
#if defined(HAVE__CTIME64_S)
|
||||
_ctime64_s(buf, sizeof(buf), &(iso9660->birth_time));
|
||||
__time64_t iso9660_birth_time_tmp = (__time64_t) iso9660->birth_time; //time_t may be shorter than 64 bits
|
||||
_ctime64_s(buf, sizeof(buf), &(iso9660_birth_time_tmp));
|
||||
#elif defined(HAVE_CTIME_R)
|
||||
ctime_r(&(iso9660->birth_time), buf);
|
||||
#else
|
||||
|
@ -1961,6 +1961,7 @@ file_free(struct file *file)
|
||||
archive_string_free(&(file->basename));
|
||||
archive_string_free(&(file->symlink));
|
||||
archive_string_free(&(file->script));
|
||||
archive_entry_free(file->entry);
|
||||
free(file);
|
||||
}
|
||||
|
||||
|
@ -216,6 +216,12 @@ invalid_parameter_handler(const wchar_t * expression,
|
||||
unsigned int line, uintptr_t pReserved)
|
||||
{
|
||||
/* nop */
|
||||
// Silence unused-parameter compiler warnings.
|
||||
(void)expression;
|
||||
(void)function;
|
||||
(void)file;
|
||||
(void)line;
|
||||
(void)pReserved;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1412,6 +1418,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect
|
||||
failure_start(file, line, "assertFileMode not yet implemented for Windows");
|
||||
(void)mode; /* UNUSED */
|
||||
(void)r; /* UNUSED */
|
||||
(void)pathname; /* UNUSED */
|
||||
(void)expected_mode; /* UNUSED */
|
||||
#else
|
||||
{
|
||||
struct stat st;
|
||||
|
@ -120,6 +120,32 @@
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this platform has <sys/acl.h>, acl_create(), acl_init(),
|
||||
* acl_set_file(), and ACL_USER, we assume it has the rest of the
|
||||
* POSIX.1e draft functions used in archive_read_extract.c.
|
||||
*/
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL_CREATE_ENTRY && HAVE_ACL_INIT && HAVE_ACL_SET_FILE
|
||||
#if HAVE_ACL_USER
|
||||
#define HAVE_POSIX_ACL 1
|
||||
#elif HAVE_ACL_TYPE_EXTENDED
|
||||
#define HAVE_DARWIN_ACL 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If this platform has <sys/acl.h>, acl_get(), facl_get(), acl_set(),
|
||||
* facl_set() and types aclent_t and ace_t it uses Solaris-style ACL functions
|
||||
*/
|
||||
#if HAVE_SYS_ACL_H && HAVE_ACL_GET && HAVE_FACL_GET && HAVE_ACL_SET && HAVE_FACL_SET && HAVE_ACLENT_T && HAVE_ACE_T
|
||||
#define HAVE_SUN_ACL 1
|
||||
#endif
|
||||
|
||||
/* Define if platform supports NFSv4 ACLs */
|
||||
#if (HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4) || HAVE_SUN_ACL || HAVE_DARWIN_ACL
|
||||
#define HAVE_NFS4_ACL 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Redefine DEFINE_TEST for use in defining the test functions.
|
||||
*/
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2010 Tim Kientzle
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,10 +26,15 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ >= 8
|
||||
#if HAVE_POSIX_ACL || HAVE_NFS4_ACL
|
||||
#define _ACL_PRIVATE
|
||||
#include <sys/acl.h>
|
||||
#if HAVE_DARWIN_ACL
|
||||
#include <membership.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_NFS4_ACL
|
||||
struct myacl_t {
|
||||
int type;
|
||||
int permset;
|
||||
@ -38,11 +44,12 @@ struct myacl_t {
|
||||
};
|
||||
|
||||
static struct myacl_t acls_reg[] = {
|
||||
#if !HAVE_DARWIN_ACL
|
||||
/* For this test, we need the file owner to be able to read and write the ACL. */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL | ARCHIVE_ENTRY_ACL_WRITE_ACL | ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS | ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
|
||||
|
||||
#endif
|
||||
/* An entry for each type. */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 108, "user108" },
|
||||
@ -84,17 +91,53 @@ static struct myacl_t acls_reg[] = {
|
||||
// ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 136, "group136" },
|
||||
#if !HAVE_DARWIN_ACL
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
|
||||
#else /* MacOS - mode 0654 */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
|
||||
#endif
|
||||
};
|
||||
|
||||
static const int acls_reg_cnt = (int)(sizeof(acls_reg)/sizeof(acls_reg[0]));
|
||||
|
||||
static struct myacl_t acls_dir[] = {
|
||||
/* For this test, we need to be able to read and write the ACL. */
|
||||
#if !HAVE_DARWIN_ACL
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_READ_ACL,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, ""},
|
||||
#endif
|
||||
|
||||
/* An entry for each type. */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
@ -144,6 +187,9 @@ static struct myacl_t acls_dir[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
|
||||
ARCHIVE_ENTRY_ACL_USER, 304, "user304" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA | ARCHIVE_ENTRY_ACL_ENTRY_INHERITED,
|
||||
ARCHIVE_ENTRY_ACL_USER, 305, "user305" },
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
@ -161,12 +207,47 @@ static struct myacl_t acls_dir[] = {
|
||||
ARCHIVE_ENTRY_ACL_USER, 501, "user501" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 502, "group502" },
|
||||
#if !HAVE_DARWIN_ACL
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
|
||||
#else /* MacOS - mode 0654 */
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, -1, "" }
|
||||
#endif
|
||||
};
|
||||
|
||||
static const int acls_dir_cnt = (int)(sizeof(acls_dir)/sizeof(acls_dir[0]));
|
||||
|
||||
static void
|
||||
set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
|
||||
{
|
||||
@ -188,9 +269,50 @@ set_acls(struct archive_entry *ae, struct myacl_t *acls, int start, int end)
|
||||
}
|
||||
|
||||
static int
|
||||
#ifdef HAVE_SUN_ACL
|
||||
acl_permset_to_bitmap(uint32_t a_access_mask)
|
||||
#else
|
||||
acl_permset_to_bitmap(acl_permset_t opaque_ps)
|
||||
#endif
|
||||
{
|
||||
static struct { int machine; int portable; } perms[] = {
|
||||
#ifdef HAVE_SUN_ACL /* Solaris NFSv4 ACL permissions */
|
||||
{ACE_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
|
||||
{ACE_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
|
||||
{ACE_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
|
||||
{ACE_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
|
||||
{ACE_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
|
||||
{ACE_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
|
||||
{ACE_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
|
||||
{ACE_READ_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
|
||||
{ACE_WRITE_NAMED_ATTRS, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
|
||||
{ACE_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
|
||||
{ACE_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
|
||||
{ACE_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
|
||||
{ACE_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
|
||||
{ACE_READ_ACL, ARCHIVE_ENTRY_ACL_READ_ACL},
|
||||
{ACE_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
|
||||
{ACE_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
|
||||
{ACE_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
|
||||
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL permissions */
|
||||
{ACL_READ_DATA, ARCHIVE_ENTRY_ACL_READ_DATA},
|
||||
{ACL_LIST_DIRECTORY, ARCHIVE_ENTRY_ACL_LIST_DIRECTORY},
|
||||
{ACL_WRITE_DATA, ARCHIVE_ENTRY_ACL_WRITE_DATA},
|
||||
{ACL_ADD_FILE, ARCHIVE_ENTRY_ACL_ADD_FILE},
|
||||
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
|
||||
{ACL_DELETE, ARCHIVE_ENTRY_ACL_DELETE},
|
||||
{ACL_APPEND_DATA, ARCHIVE_ENTRY_ACL_APPEND_DATA},
|
||||
{ACL_ADD_SUBDIRECTORY, ARCHIVE_ENTRY_ACL_ADD_SUBDIRECTORY},
|
||||
{ACL_DELETE_CHILD, ARCHIVE_ENTRY_ACL_DELETE_CHILD},
|
||||
{ACL_READ_ATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES},
|
||||
{ACL_WRITE_ATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES},
|
||||
{ACL_READ_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS},
|
||||
{ACL_WRITE_EXTATTRIBUTES, ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS},
|
||||
{ACL_READ_SECURITY, ARCHIVE_ENTRY_ACL_READ_ACL},
|
||||
{ACL_WRITE_SECURITY, ARCHIVE_ENTRY_ACL_WRITE_ACL},
|
||||
{ACL_CHANGE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
|
||||
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE},
|
||||
#else /* FreeBSD NFSv4 ACL permissions */
|
||||
{ACL_EXECUTE, ARCHIVE_ENTRY_ACL_EXECUTE},
|
||||
{ACL_WRITE, ARCHIVE_ENTRY_ACL_WRITE},
|
||||
{ACL_READ, ARCHIVE_ENTRY_ACL_READ},
|
||||
@ -210,51 +332,201 @@ acl_permset_to_bitmap(acl_permset_t opaque_ps)
|
||||
{ACL_WRITE_ACL, ARCHIVE_ENTRY_ACL_WRITE_ACL},
|
||||
{ACL_WRITE_OWNER, ARCHIVE_ENTRY_ACL_WRITE_OWNER},
|
||||
{ACL_SYNCHRONIZE, ARCHIVE_ENTRY_ACL_SYNCHRONIZE}
|
||||
#endif
|
||||
};
|
||||
int i, permset = 0;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(perms)/sizeof(perms[0])); ++i)
|
||||
#if HAVE_SUN_ACL
|
||||
if (a_access_mask & perms[i].machine)
|
||||
#else
|
||||
if (acl_get_perm_np(opaque_ps, perms[i].machine))
|
||||
#endif
|
||||
permset |= perms[i].portable;
|
||||
return permset;
|
||||
}
|
||||
|
||||
static int
|
||||
#if HAVE_SUN_ACL
|
||||
acl_flagset_to_bitmap(uint16_t a_flags)
|
||||
#else
|
||||
acl_flagset_to_bitmap(acl_flagset_t opaque_fs)
|
||||
#endif
|
||||
{
|
||||
static struct { int machine; int portable; } flags[] = {
|
||||
#if HAVE_SUN_ACL /* Solaris NFSv4 ACL inheritance flags */
|
||||
{ACE_FILE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
|
||||
{ACE_DIRECTORY_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ACE_NO_PROPAGATE_INHERIT_ACE, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ACE_INHERIT_ONLY_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
|
||||
{ACE_SUCCESSFUL_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ACE_FAILED_ACCESS_ACE_FLAG, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
|
||||
{ACE_INHERITED_ACE, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED}
|
||||
#elif HAVE_DARWIN_ACL /* MacOS NFSv4 ACL inheritance flags */
|
||||
{ACL_ENTRY_INHERITED, ARCHIVE_ENTRY_ACL_ENTRY_INHERITED},
|
||||
{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
|
||||
{ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ACL_ENTRY_LIMIT_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ACL_ENTRY_ONLY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY}
|
||||
#else /* FreeBSD NFSv4 ACL inheritance flags */
|
||||
{ACL_ENTRY_FILE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT},
|
||||
{ACL_ENTRY_DIRECTORY_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT},
|
||||
{ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT},
|
||||
{ACL_ENTRY_SUCCESSFUL_ACCESS, ARCHIVE_ENTRY_ACL_ENTRY_SUCCESSFUL_ACCESS},
|
||||
{ACL_ENTRY_NO_PROPAGATE_INHERIT, ARCHIVE_ENTRY_ACL_ENTRY_FAILED_ACCESS},
|
||||
{ACL_ENTRY_INHERIT_ONLY, ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY},
|
||||
#endif
|
||||
};
|
||||
int i, flagset = 0;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(flags)/sizeof(flags[0])); ++i)
|
||||
#if HAVE_SUN_ACL
|
||||
if (a_flags & flags[i].machine)
|
||||
#else
|
||||
if (acl_get_flag_np(opaque_fs, flags[i].machine))
|
||||
#endif
|
||||
flagset |= flags[i].portable;
|
||||
return flagset;
|
||||
}
|
||||
|
||||
static int
|
||||
#if HAVE_SUN_ACL
|
||||
acl_match(ace_t *ace, struct myacl_t *myacl)
|
||||
#else
|
||||
acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
#endif
|
||||
{
|
||||
#if !HAVE_SUN_ACL
|
||||
#if HAVE_DARWIN_ACL
|
||||
void *q;
|
||||
uid_t ugid;
|
||||
int r, idtype;
|
||||
#else
|
||||
gid_t g, *gp;
|
||||
uid_t u, *up;
|
||||
acl_entry_type_t entry_type;
|
||||
#endif /* !HAVE_DARWIN_ACL */
|
||||
acl_tag_t tag_type;
|
||||
acl_permset_t opaque_ps;
|
||||
acl_flagset_t opaque_fs;
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
int perms;
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
perms = acl_permset_to_bitmap(ace->a_access_mask) | acl_flagset_to_bitmap(ace->a_flags);
|
||||
#else
|
||||
acl_get_tag_type(aclent, &tag_type);
|
||||
#if !HAVE_DARWIN_ACL
|
||||
acl_get_entry_type_np(aclent, &entry_type);
|
||||
#endif
|
||||
|
||||
/* translate the silly opaque permset to a bitmap */
|
||||
acl_get_permset(aclent, &opaque_ps);
|
||||
acl_get_flagset_np(aclent, &opaque_fs);
|
||||
perms = acl_permset_to_bitmap(opaque_ps) | acl_flagset_to_bitmap(opaque_fs);
|
||||
#endif
|
||||
if (perms != myacl->permset)
|
||||
return (0);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
switch (ace->a_type) {
|
||||
case ACE_ACCESS_ALLOWED_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
return (0);
|
||||
break;
|
||||
case ACE_ACCESS_DENIED_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
|
||||
return (0);
|
||||
break;
|
||||
case ACE_SYSTEM_AUDIT_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT)
|
||||
return (0);
|
||||
break;
|
||||
case ACE_SYSTEM_ALARM_ACE_TYPE:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (ace->a_flags & ACE_OWNER) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ)
|
||||
return (0);
|
||||
} else if (ace->a_flags & ACE_GROUP) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ)
|
||||
return (0);
|
||||
} else if (ace->a_flags & ACE_EVERYONE) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE)
|
||||
return (0);
|
||||
} else if (ace->a_flags & ACE_IDENTIFIER_GROUP) {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
|
||||
return (0);
|
||||
if ((gid_t)myacl->qual != ace->a_who)
|
||||
return (0);
|
||||
} else {
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
|
||||
return (0);
|
||||
if ((uid_t)myacl->qual != ace->a_who)
|
||||
return (0);
|
||||
}
|
||||
#elif HAVE_DARWIN_ACL
|
||||
r = 0;
|
||||
switch (tag_type) {
|
||||
case ACL_EXTENDED_ALLOW:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
return (0);
|
||||
break;
|
||||
case ACL_EXTENDED_DENY:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
q = acl_get_qualifier(aclent);
|
||||
if (q == NULL)
|
||||
return (0);
|
||||
r = mbr_uuid_to_id((const unsigned char *)q, &ugid, &idtype);
|
||||
acl_free(q);
|
||||
if (r != 0)
|
||||
return (0);
|
||||
switch (idtype) {
|
||||
case ID_TYPE_UID:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
|
||||
return (0);
|
||||
if ((uid_t)myacl->qual != ugid)
|
||||
return (0);
|
||||
break;
|
||||
case ID_TYPE_GID:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
|
||||
return (0);
|
||||
if ((gid_t)myacl->qual != ugid)
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
#else /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
switch (entry_type) {
|
||||
case ACL_ENTRY_TYPE_ALLOW:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALLOW)
|
||||
return (0);
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_DENY:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_DENY)
|
||||
return (0);
|
||||
break;
|
||||
case ACL_ENTRY_TYPE_AUDIT:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_AUDIT)
|
||||
return (0);
|
||||
case ACL_ENTRY_TYPE_ALARM:
|
||||
if (myacl->type != ARCHIVE_ENTRY_ACL_TYPE_ALARM)
|
||||
return (0);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
|
||||
switch (tag_type) {
|
||||
case ACL_USER_OBJ:
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
|
||||
@ -287,17 +559,29 @@ acl_match(acl_entry_t aclent, struct myacl_t *myacl)
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_EVERYONE) return (0);
|
||||
break;
|
||||
}
|
||||
#endif /* !HAVE_SUN_ACL && !HAVE_DARWIN_ACL */
|
||||
return (1);
|
||||
}
|
||||
|
||||
static void
|
||||
compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start, int end)
|
||||
compare_acls(
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl,
|
||||
#else
|
||||
acl_t acl,
|
||||
#endif
|
||||
struct myacl_t *myacls, const char *filename, int start, int end)
|
||||
{
|
||||
int *marker;
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
int matched;
|
||||
int i, n;
|
||||
#if HAVE_SUN_ACL
|
||||
int e;
|
||||
ace_t *acl_entry;
|
||||
#else
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
acl_entry_t acl_entry;
|
||||
#endif
|
||||
|
||||
n = end - start;
|
||||
marker = malloc(sizeof(marker[0]) * (n + 1));
|
||||
@ -313,10 +597,20 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
|
||||
* Iterate over acls in system acl object, try to match each
|
||||
* one with an item in the myacls array.
|
||||
*/
|
||||
while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
|
||||
#if HAVE_SUN_ACL
|
||||
for (e = 0; e < acl->acl_cnt; e++)
|
||||
#elif HAVE_DARWIN_ACL
|
||||
while (0 == acl_get_entry(acl, entry_id, &acl_entry))
|
||||
#else
|
||||
while (1 == acl_get_entry(acl, entry_id, &acl_entry))
|
||||
#endif
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
acl_entry = &((ace_t *)acl->acl_aclp)[e];
|
||||
#else
|
||||
/* After the first time... */
|
||||
entry_id = ACL_NEXT_ENTRY;
|
||||
|
||||
#endif
|
||||
/* Search for a matching entry (tag and qualifier) */
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
if (acl_match(acl_entry, &myacls[marker[i]])) {
|
||||
@ -327,7 +621,8 @@ compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start,
|
||||
}
|
||||
}
|
||||
|
||||
failure("ACL entry on file %s that shouldn't be there", filename);
|
||||
failure("ACL entry on file %s that shouldn't be there",
|
||||
filename);
|
||||
assert(matched == 1);
|
||||
}
|
||||
|
||||
@ -368,7 +663,8 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
|
||||
* Iterate over acls in entry, try to match each
|
||||
* one with an item in the myacls array.
|
||||
*/
|
||||
assertEqualInt(n, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
assertEqualInt(n, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
while (ARCHIVE_OK == archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, &type, &permset, &tag, &qual, &name)) {
|
||||
|
||||
@ -403,54 +699,110 @@ compare_entry_acls(struct archive_entry *ae, struct myacl_t *myacls, const char
|
||||
}
|
||||
free(marker);
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
|
||||
/*
|
||||
* Verify ACL restore-to-disk. This test is FreeBSD-specific.
|
||||
* Verify ACL restore-to-disk. This test is Platform-specific.
|
||||
*/
|
||||
|
||||
DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
DEFINE_TEST(test_acl_platform_nfs4)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
skipping("FreeBSD-specific NFS4 ACL restore test");
|
||||
#elif __FreeBSD__ < 8
|
||||
skipping("NFS4 ACLs supported only on FreeBSD 8.0 and later");
|
||||
#if !HAVE_NFS4_ACL
|
||||
skipping("NFS4 ACLs are not supported on this platform");
|
||||
#else
|
||||
char buff[64];
|
||||
struct stat st;
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
int i, n;
|
||||
char *func;
|
||||
#if HAVE_DARWIN_ACL /* On MacOS we skip trivial ACLs in some tests */
|
||||
const int regcnt = acls_reg_cnt - 4;
|
||||
const int dircnt = acls_dir_cnt - 4;
|
||||
#else
|
||||
const int regcnt = acls_reg_cnt;
|
||||
const int dircnt = acls_dir_cnt;
|
||||
#endif
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl;
|
||||
#else /* !HAVE_SUN_ACL */
|
||||
#if HAVE_DARWIN_ACL
|
||||
acl_entry_t aclent;
|
||||
acl_permset_t permset;
|
||||
const uid_t uid = 1000;
|
||||
uuid_t uuid;
|
||||
#endif /* HAVE_DARWIN_ACL */
|
||||
acl_t acl;
|
||||
#endif /* !HAVE_SUN_ACL */
|
||||
|
||||
/*
|
||||
* First, do a quick manual set/read of ACL data to
|
||||
* verify that the local filesystem does support ACLs.
|
||||
* If it doesn't, we'll simply skip the remaining tests.
|
||||
*/
|
||||
#if HAVE_POSIX_ACL && HAVE_ACL_TYPE_NFS4
|
||||
acl = acl_from_text("owner@:rwxp::allow,group@:rwp:f:allow");
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl != NULL);
|
||||
#elif HAVE_DARWIN_ACL
|
||||
acl = acl_init(1);
|
||||
assert((void *)acl != NULL);
|
||||
assertEqualInt(0, acl_create_entry(&acl, &aclent));
|
||||
assertEqualInt(0, acl_set_tag_type(aclent, ACL_EXTENDED_ALLOW));
|
||||
assertEqualInt(0, acl_get_permset(aclent, &permset));
|
||||
assertEqualInt(0, acl_add_perm(permset, ACL_READ_DATA));
|
||||
assertEqualInt(0, acl_add_perm(permset, ACL_WRITE_DATA));
|
||||
assertEqualInt(0, acl_add_perm(permset, ACL_APPEND_DATA));
|
||||
assertEqualInt(0, acl_add_perm(permset, ACL_EXECUTE));
|
||||
assertEqualInt(0, acl_set_permset(aclent, permset));
|
||||
assertEqualInt(0, mbr_identifier_to_uuid(ID_TYPE_UID, &uid,
|
||||
sizeof(uid_t), uuid));
|
||||
assertEqualInt(0, acl_set_qualifier(aclent, uuid));
|
||||
#endif
|
||||
|
||||
/* Create a test dir and try to set an ACL on it. */
|
||||
if (!assertMakeDir("pretest", 0755)) {
|
||||
#if !HAVE_SUN_ACL
|
||||
acl_free(acl);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
func = "acl_get()";
|
||||
n = acl_get("pretest", 0, &acl);
|
||||
#else
|
||||
func = "acl_set_file()";
|
||||
#if HAVE_DARWIN_ACL
|
||||
n = acl_set_file("pretest", ACL_TYPE_EXTENDED, acl);
|
||||
#else
|
||||
n = acl_set_file("pretest", ACL_TYPE_NFS4, acl);
|
||||
#endif
|
||||
acl_free(acl);
|
||||
if (n != 0 && errno == EOPNOTSUPP) {
|
||||
skipping("NFS4 ACL tests require that NFS4 ACLs"
|
||||
" be enabled on the filesystem");
|
||||
return;
|
||||
#endif
|
||||
if (n != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
if (errno == ENOSYS)
|
||||
#else
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL)
|
||||
#endif
|
||||
{
|
||||
skipping("NFS4 ACL is not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (n != 0 && errno == EINVAL) {
|
||||
skipping("This filesystem does not support NFS4 ACLs");
|
||||
return;
|
||||
}
|
||||
failure("acl_set_file(): errno = %d (%s)",
|
||||
errno, strerror(errno));
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
if (acl->acl_type != ACE_T) {
|
||||
acl_free(acl);
|
||||
skipping("NFS4 ACL is not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
acl_free(acl);
|
||||
#endif
|
||||
|
||||
/* Create a write-to-disk object. */
|
||||
assert(NULL != (a = archive_write_disk_new()));
|
||||
archive_write_disk_set_options(a,
|
||||
@ -464,7 +816,7 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
archive_entry_set_perm(ae, 0654);
|
||||
archive_entry_set_mtime(ae, 123456, 7890);
|
||||
archive_entry_set_size(ae, 0);
|
||||
set_acls(ae, acls_reg, 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
|
||||
set_acls(ae, acls_reg, 0, acls_reg_cnt);
|
||||
|
||||
/* Write the entry to disk, including ACLs. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
||||
@ -474,10 +826,10 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
archive_entry_set_filetype(ae, AE_IFDIR);
|
||||
archive_entry_set_perm(ae, 0654);
|
||||
archive_entry_set_mtime(ae, 123456, 7890);
|
||||
set_acls(ae, acls_dir, 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
|
||||
set_acls(ae, acls_dir, 0, acls_dir_cnt);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
|
||||
|
||||
for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
|
||||
for (i = 0; i < acls_dir_cnt; ++i) {
|
||||
sprintf(buff, "dir%d", i);
|
||||
archive_entry_set_pathname(ae, buff);
|
||||
archive_entry_set_filetype(ae, AE_IFDIR);
|
||||
@ -496,28 +848,62 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
/* Verify the data on disk. */
|
||||
assertEqualInt(0, stat("testall", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_get("testall", 0, &acl);
|
||||
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
acl = acl_get_file("testall", ACL_TYPE_EXTENDED);
|
||||
#else
|
||||
acl = acl_get_file("testall", ACL_TYPE_NFS4);
|
||||
#endif
|
||||
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
compare_acls(acl, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
|
||||
#endif
|
||||
compare_acls(acl, acls_reg, "testall", 0, regcnt);
|
||||
acl_free(acl);
|
||||
|
||||
/* Verify single-permission dirs on disk. */
|
||||
for (i = 0; i < (int)(sizeof(acls_dir)/sizeof(acls_dir[0])); ++i) {
|
||||
sprintf(buff, "dir%d", i);
|
||||
assertEqualInt(0, stat(buff, &st));
|
||||
assertEqualInt(st.st_mtime, 123456 + i);
|
||||
acl = acl_get_file(buff, ACL_TYPE_NFS4);
|
||||
assert(acl != (acl_t)NULL);
|
||||
compare_acls(acl, acls_dir, buff, i, i + 1);
|
||||
acl_free(acl);
|
||||
for (i = 0; i < dircnt; ++i) {
|
||||
sprintf(buff, "dir%d", i);
|
||||
assertEqualInt(0, stat(buff, &st));
|
||||
assertEqualInt(st.st_mtime, 123456 + i);
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_get(buff, 0, &acl);
|
||||
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
acl = acl_get_file(buff, ACL_TYPE_EXTENDED);
|
||||
#else
|
||||
acl = acl_get_file(buff, ACL_TYPE_NFS4);
|
||||
#endif
|
||||
failure("acl_get_file(): errno = %d (%s)", errno,
|
||||
strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
#endif
|
||||
compare_acls(acl, acls_dir, buff, i, i + 1);
|
||||
acl_free(acl);
|
||||
}
|
||||
|
||||
/* Verify "dirall" on disk. */
|
||||
assertEqualInt(0, stat("dirall", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_get("dirall", 0, &acl);
|
||||
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
#if HAVE_DARWIN_ACL
|
||||
acl = acl_get_file("dirall", ACL_TYPE_EXTENDED);
|
||||
#else
|
||||
acl = acl_get_file("dirall", ACL_TYPE_NFS4);
|
||||
#endif
|
||||
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
compare_acls(acl, acls_dir, "dirall", 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
|
||||
#endif
|
||||
compare_acls(acl, acls_dir, "dirall", 0, dircnt);
|
||||
acl_free(acl);
|
||||
|
||||
/* Read and compare ACL via archive_read_disk */
|
||||
@ -528,7 +914,7 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
archive_entry_set_pathname(ae, "testall");
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_read_disk_entry_from_file(a, ae, -1, NULL));
|
||||
compare_entry_acls(ae, acls_reg, "testall", 0, (int)(sizeof(acls_reg)/sizeof(acls_reg[0])));
|
||||
compare_entry_acls(ae, acls_reg, "testall", 0, acls_reg_cnt);
|
||||
archive_entry_free(ae);
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
@ -539,9 +925,9 @@ DEFINE_TEST(test_acl_freebsd_nfs4)
|
||||
assert(ae != NULL);
|
||||
archive_entry_set_pathname(ae, "dirall");
|
||||
assertEqualInt(ARCHIVE_OK,
|
||||
archive_read_disk_entry_from_file(a, ae, -1, NULL));
|
||||
compare_entry_acls(ae, acls_dir, "dirall", 0, (int)(sizeof(acls_dir)/sizeof(acls_dir[0])));
|
||||
archive_read_disk_entry_from_file(a, ae, -1, NULL));
|
||||
compare_entry_acls(ae, acls_dir, "dirall", 0, acls_dir_cnt);
|
||||
archive_entry_free(ae);
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
#endif
|
||||
#endif /* HAVE_NFS4_ACL */
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2008 Tim Kientzle
|
||||
* Copyright (c) 2017 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -25,8 +26,14 @@
|
||||
#include "test.h"
|
||||
__FBSDID("$FreeBSD: head/lib/libarchive/test/test_acl_freebsd.c 189427 2009-03-06 04:21:23Z kientzle $");
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ > 4
|
||||
#if HAVE_POSIX_ACL || HAVE_SUN_ACL
|
||||
#include <sys/acl.h>
|
||||
#if HAVE_ACL_GET_PERM
|
||||
#include <acl/libacl.h>
|
||||
#define ACL_GET_PERM acl_get_perm
|
||||
#elif HAVE_ACL_GET_PERM_NP
|
||||
#define ACL_GET_PERM acl_get_perm_np
|
||||
#endif
|
||||
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE | ARCHIVE_ENTRY_ACL_READ,
|
||||
@ -48,18 +55,34 @@ static struct archive_test_acl_t acls2[] = {
|
||||
};
|
||||
|
||||
static int
|
||||
acl_entry_get_perm(acl_entry_t aclent) {
|
||||
#if HAVE_SUN_ACL
|
||||
acl_entry_get_perm(aclent_t *aclent)
|
||||
#else
|
||||
acl_entry_get_perm(acl_entry_t aclent)
|
||||
#endif
|
||||
{
|
||||
int permset = 0;
|
||||
#if HAVE_POSIX_ACL
|
||||
acl_permset_t opaque_ps;
|
||||
#endif
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
if (aclent->a_perm & 1)
|
||||
permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
if (aclent->a_perm & 2)
|
||||
permset |= ARCHIVE_ENTRY_ACL_WRITE;
|
||||
if (aclent->a_perm & 4)
|
||||
permset |= ARCHIVE_ENTRY_ACL_READ;
|
||||
#else
|
||||
/* translate the silly opaque permset to a bitmap */
|
||||
acl_get_permset(aclent, &opaque_ps);
|
||||
if (acl_get_perm_np(opaque_ps, ACL_EXECUTE))
|
||||
if (ACL_GET_PERM(opaque_ps, ACL_EXECUTE))
|
||||
permset |= ARCHIVE_ENTRY_ACL_EXECUTE;
|
||||
if (acl_get_perm_np(opaque_ps, ACL_WRITE))
|
||||
if (ACL_GET_PERM(opaque_ps, ACL_WRITE))
|
||||
permset |= ARCHIVE_ENTRY_ACL_WRITE;
|
||||
if (acl_get_perm_np(opaque_ps, ACL_READ))
|
||||
if (ACL_GET_PERM(opaque_ps, ACL_READ))
|
||||
permset |= ARCHIVE_ENTRY_ACL_READ;
|
||||
#endif
|
||||
return permset;
|
||||
}
|
||||
|
||||
@ -105,45 +128,96 @@ acl_get_specific_entry(acl_t acl, acl_tag_t requested_tag_type, int requested_ta
|
||||
#endif
|
||||
|
||||
static int
|
||||
#if HAVE_SUN_ACL
|
||||
acl_match(aclent_t *aclent, struct archive_test_acl_t *myacl)
|
||||
#else
|
||||
acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_POSIX_ACL
|
||||
gid_t g, *gp;
|
||||
uid_t u, *up;
|
||||
acl_tag_t tag_type;
|
||||
#endif
|
||||
|
||||
if (myacl->permset != acl_entry_get_perm(aclent))
|
||||
return (0);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
switch (aclent->a_type)
|
||||
#else
|
||||
acl_get_tag_type(aclent, &tag_type);
|
||||
switch (tag_type) {
|
||||
switch (tag_type)
|
||||
#endif
|
||||
{
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_USER_OBJ:
|
||||
case USER_OBJ:
|
||||
#else
|
||||
case ACL_USER_OBJ:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER_OBJ) return (0);
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_USER:
|
||||
case USER:
|
||||
#else
|
||||
case ACL_USER:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_USER)
|
||||
return (0);
|
||||
#if HAVE_SUN_ACL
|
||||
if ((uid_t)myacl->qual != aclent->a_id)
|
||||
return (0);
|
||||
#else
|
||||
up = acl_get_qualifier(aclent);
|
||||
u = *up;
|
||||
acl_free(up);
|
||||
if ((uid_t)myacl->qual != u)
|
||||
return (0);
|
||||
#endif
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_GROUP_OBJ:
|
||||
case GROUP_OBJ:
|
||||
#else
|
||||
case ACL_GROUP_OBJ:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP_OBJ) return (0);
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_GROUP:
|
||||
case GROUP:
|
||||
#else
|
||||
case ACL_GROUP:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_GROUP)
|
||||
return (0);
|
||||
#if HAVE_SUN_ACL
|
||||
if ((gid_t)myacl->qual != aclent->a_id)
|
||||
return (0);
|
||||
#else
|
||||
gp = acl_get_qualifier(aclent);
|
||||
g = *gp;
|
||||
acl_free(gp);
|
||||
if ((gid_t)myacl->qual != g)
|
||||
return (0);
|
||||
#endif
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_CLASS_OBJ:
|
||||
case CLASS_OBJ:
|
||||
#else
|
||||
case ACL_MASK:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_MASK) return (0);
|
||||
break;
|
||||
#if HAVE_SUN_ACL
|
||||
case DEF_OTHER_OBJ:
|
||||
case OTHER_OBJ:
|
||||
#else
|
||||
case ACL_OTHER:
|
||||
#endif
|
||||
if (myacl->tag != ARCHIVE_ENTRY_ACL_OTHER) return (0);
|
||||
break;
|
||||
}
|
||||
@ -151,13 +225,22 @@ acl_match(acl_entry_t aclent, struct archive_test_acl_t *myacl)
|
||||
}
|
||||
|
||||
static void
|
||||
#if HAVE_SUN_ACL
|
||||
compare_acls(acl_t *acl, struct archive_test_acl_t *myacls, int n)
|
||||
#else
|
||||
compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
#endif
|
||||
{
|
||||
int *marker;
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
int matched;
|
||||
int i;
|
||||
#if HAVE_SUN_ACL
|
||||
int e;
|
||||
aclent_t *acl_entry;
|
||||
#else
|
||||
int entry_id = ACL_FIRST_ENTRY;
|
||||
acl_entry_t acl_entry;
|
||||
#endif
|
||||
|
||||
/* Count ACL entries in myacls array and allocate an indirect array. */
|
||||
marker = malloc(sizeof(marker[0]) * n);
|
||||
@ -170,9 +253,14 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
* Iterate over acls in system acl object, try to match each
|
||||
* one with an item in the myacls array.
|
||||
*/
|
||||
#if HAVE_SUN_ACL
|
||||
for(e = 0; e < acl->acl_cnt; e++) {
|
||||
acl_entry = &((aclent_t *)acl->acl_aclp)[e];
|
||||
#else
|
||||
while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
|
||||
/* After the first time... */
|
||||
entry_id = ACL_NEXT_ENTRY;
|
||||
#endif
|
||||
|
||||
/* Search for a matching entry (tag and qualifier) */
|
||||
for (i = 0, matched = 0; i < n && !matched; i++) {
|
||||
@ -205,30 +293,41 @@ compare_acls(acl_t acl, struct archive_test_acl_t *myacls, int n)
|
||||
|
||||
|
||||
/*
|
||||
* Verify ACL restore-to-disk. This test is FreeBSD-specific.
|
||||
* Verify ACL restore-to-disk. This test is Platform-specific.
|
||||
*/
|
||||
|
||||
DEFINE_TEST(test_acl_freebsd_posix1e_restore)
|
||||
DEFINE_TEST(test_acl_platform_posix1e_restore)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
skipping("FreeBSD-specific ACL restore test");
|
||||
#elif __FreeBSD__ < 5
|
||||
skipping("ACL restore supported only on FreeBSD 5.0 and later");
|
||||
#else
|
||||
#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
|
||||
skipping("POSIX.1e ACLs are not supported on this platform");
|
||||
#else /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
|
||||
struct stat st;
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
int n, fd;
|
||||
char *func;
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl, *acl2;
|
||||
#else
|
||||
acl_t acl;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* First, do a quick manual set/read of ACL data to
|
||||
* verify that the local filesystem does support ACLs.
|
||||
* If it doesn't, we'll simply skip the remaining tests.
|
||||
*/
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_fromtext("user::rwx,user:1:rw-,group::rwx,group:15:r-x,other:rwx,mask:rwx", &acl);
|
||||
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl = acl_from_text("u::rwx,u:1:rw,g::rwx,g:15:rx,o::rwx,m::rwx");
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl != NULL);
|
||||
/* Create a test file and try to set an ACL on it. */
|
||||
#endif
|
||||
|
||||
/* Create a test file and try ACL on it. */
|
||||
fd = open("pretest", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
failure("Could not create test file?!");
|
||||
if (!assert(fd >= 0)) {
|
||||
@ -236,21 +335,51 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
|
||||
return;
|
||||
}
|
||||
|
||||
n = acl_set_fd(fd, acl);
|
||||
acl_free(acl);
|
||||
if (n != 0 && errno == EOPNOTSUPP) {
|
||||
#if HAVE_SUN_ACL
|
||||
n = facl_get(fd, 0, &acl2);
|
||||
if (n != 0) {
|
||||
close(fd);
|
||||
skipping("ACL tests require that ACL support be enabled on the filesystem");
|
||||
acl_free(acl);
|
||||
}
|
||||
if (errno == ENOSYS) {
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
if (n != 0 && errno == EINVAL) {
|
||||
close(fd);
|
||||
skipping("This filesystem does not support POSIX.1e ACLs");
|
||||
return;
|
||||
}
|
||||
failure("acl_set_fd(): errno = %d (%s)",
|
||||
errno, strerror(errno));
|
||||
failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
if (acl2->acl_type != ACLENT_T) {
|
||||
acl_free(acl2);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
acl_free(acl2);
|
||||
|
||||
func = "facl_set()";
|
||||
n = facl_set(fd, acl);
|
||||
#else
|
||||
func = "acl_set_fd()";
|
||||
n = acl_set_fd(fd, acl);
|
||||
#endif
|
||||
acl_free(acl);
|
||||
if (n != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
if (errno == ENOSYS)
|
||||
#else
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL)
|
||||
#endif
|
||||
{
|
||||
close(fd);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
}
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
|
||||
#endif
|
||||
close(fd);
|
||||
|
||||
/* Create a write-to-disk object. */
|
||||
@ -275,28 +404,38 @@ DEFINE_TEST(test_acl_freebsd_posix1e_restore)
|
||||
/* Verify the data on disk. */
|
||||
assertEqualInt(0, stat("test0", &st));
|
||||
assertEqualInt(st.st_mtime, 123456);
|
||||
#if HAVE_SUN_ACL
|
||||
n = acl_get("test0", 0, &acl);
|
||||
failure("acl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl = acl_get_file("test0", ACL_TYPE_ACCESS);
|
||||
failure("acl_get_file(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert(acl != (acl_t)NULL);
|
||||
#endif
|
||||
compare_acls(acl, acls2, sizeof(acls2)/sizeof(acls2[0]));
|
||||
acl_free(acl);
|
||||
#endif
|
||||
#endif /* HAVE_SUN_ACL || HAVE_POSIX_ACL */
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify ACL read-from-disk. This test is FreeBSD-specific.
|
||||
* Verify ACL read-from-disk. This test is Platform-specific.
|
||||
*/
|
||||
DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
DEFINE_TEST(test_acl_platform_posix1e_read)
|
||||
{
|
||||
#if !defined(__FreeBSD__)
|
||||
skipping("FreeBSD-specific ACL read test");
|
||||
#elif __FreeBSD__ < 5
|
||||
skipping("ACL read supported only on FreeBSD 5.0 and later");
|
||||
#if !HAVE_SUN_ACL && !HAVE_POSIX_ACL
|
||||
skipping("POSIX.1e ACLs are not supported on this platform");
|
||||
#else
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
int n, fd;
|
||||
const char *acl1_text, *acl2_text;
|
||||
acl_t acl1, acl2;
|
||||
int n, fd, flags, dflags;
|
||||
char *func, *acl_text;
|
||||
const char *acl1_text, *acl2_text, *acl3_text;
|
||||
#if HAVE_SUN_ACL
|
||||
acl_t *acl, *acl1, *acl2, *acl3;
|
||||
#else
|
||||
acl_t acl1, acl2, acl3;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Manually construct a directory and two files with
|
||||
@ -305,6 +444,17 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
*/
|
||||
|
||||
/* Create a test file f1 with acl1 */
|
||||
#if HAVE_SUN_ACL
|
||||
acl1_text = "user::rwx,"
|
||||
"group::rwx,"
|
||||
"other:rwx,"
|
||||
"user:1:rw-,"
|
||||
"group:15:r-x,"
|
||||
"mask:rwx";
|
||||
n = acl_fromtext(acl1_text, &acl1);
|
||||
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl1_text = "user::rwx\n"
|
||||
"group::rwx\n"
|
||||
"other::rwx\n"
|
||||
@ -312,28 +462,59 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
"group:15:r-x\n"
|
||||
"mask::rwx";
|
||||
acl1 = acl_from_text(acl1_text);
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl1 != NULL);
|
||||
#endif
|
||||
fd = open("f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
failure("Could not create test file?!");
|
||||
if (!assert(fd >= 0)) {
|
||||
acl_free(acl1);
|
||||
return;
|
||||
}
|
||||
n = acl_set_fd(fd, acl1);
|
||||
acl_free(acl1);
|
||||
if (n != 0 && errno == EOPNOTSUPP) {
|
||||
#if HAVE_SUN_ACL
|
||||
/* Check if Solars filesystem supports POSIX.1e ACLs */
|
||||
n = facl_get(fd, 0, &acl);
|
||||
if (n != 0)
|
||||
close(fd);
|
||||
skipping("ACL tests require that ACL support be enabled on the filesystem");
|
||||
if (n != 0 && errno == ENOSYS) {
|
||||
acl_free(acl1);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
if (n != 0 && errno == EINVAL) {
|
||||
close(fd);
|
||||
skipping("This filesystem does not support POSIX.1e ACLs");
|
||||
return;
|
||||
}
|
||||
failure("acl_set_fd(): errno = %d (%s)",
|
||||
errno, strerror(errno));
|
||||
failure("facl_get(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
if (acl->acl_type != ACLENT_T) {
|
||||
acl_free(acl);
|
||||
acl_free(acl1);
|
||||
close(fd);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
|
||||
func = "facl_set()";
|
||||
n = facl_set(fd, acl1);
|
||||
#else
|
||||
func = "acl_set_fd()";
|
||||
n = acl_set_fd(fd, acl1);
|
||||
#endif
|
||||
acl_free(acl1);
|
||||
|
||||
if (n != 0) {
|
||||
#if HAVE_SUN_ACL
|
||||
if (errno == ENOSYS)
|
||||
#else
|
||||
if (errno == EOPNOTSUPP || errno == EINVAL)
|
||||
#endif
|
||||
{
|
||||
close(fd);
|
||||
skipping("POSIX.1e ACLs are not supported on this filesystem");
|
||||
return;
|
||||
}
|
||||
}
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
close(fd);
|
||||
|
||||
assertMakeDir("d", 0700);
|
||||
@ -349,6 +530,17 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
* to read ACLs, resulting in reading the ACL from a like-named
|
||||
* file in the wrong directory.
|
||||
*/
|
||||
#if HAVE_SUN_ACL
|
||||
acl2_text = "user::rwx,"
|
||||
"group::rwx,"
|
||||
"other:---,"
|
||||
"user:1:r--,"
|
||||
"group:15:r--,"
|
||||
"mask:rwx";
|
||||
n = acl_fromtext(acl2_text, &acl2);
|
||||
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl2_text = "user::rwx\n"
|
||||
"group::rwx\n"
|
||||
"other::---\n"
|
||||
@ -356,46 +548,106 @@ DEFINE_TEST(test_acl_freebsd_posix1e_read)
|
||||
"group:15:r--\n"
|
||||
"mask::rwx";
|
||||
acl2 = acl_from_text(acl2_text);
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl2 != NULL);
|
||||
#endif
|
||||
fd = open("d/f1", O_WRONLY | O_CREAT | O_EXCL, 0777);
|
||||
failure("Could not create test file?!");
|
||||
if (!assert(fd >= 0)) {
|
||||
acl_free(acl2);
|
||||
return;
|
||||
}
|
||||
#if HAVE_SUN_ACL
|
||||
func = "facl_set()";
|
||||
n = facl_set(fd, acl2);
|
||||
#else
|
||||
func = "acl_set_fd()";
|
||||
n = acl_set_fd(fd, acl2);
|
||||
#endif
|
||||
acl_free(acl2);
|
||||
if (n != 0 && errno == EOPNOTSUPP) {
|
||||
if (n != 0)
|
||||
close(fd);
|
||||
skipping("ACL tests require that ACL support be enabled on the filesystem");
|
||||
return;
|
||||
}
|
||||
if (n != 0 && errno == EINVAL) {
|
||||
close(fd);
|
||||
skipping("This filesystem does not support POSIX.1e ACLs");
|
||||
return;
|
||||
}
|
||||
failure("acl_set_fd(): errno = %d (%s)",
|
||||
errno, strerror(errno));
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
close(fd);
|
||||
|
||||
/* Create directory d2 with default ACLs */
|
||||
assertMakeDir("d2", 0755);
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
acl3_text = "user::rwx,"
|
||||
"group::r-x,"
|
||||
"other:r-x,"
|
||||
"user:2:r--,"
|
||||
"group:16:-w-,"
|
||||
"mask:rwx,"
|
||||
"default:user::rwx,"
|
||||
"default:user:1:r--,"
|
||||
"default:group::r-x,"
|
||||
"default:group:15:r--,"
|
||||
"default:mask:rwx,"
|
||||
"default:other:r-x";
|
||||
n = acl_fromtext(acl3_text, &acl3);
|
||||
failure("acl_fromtext(): errno = %d (%s)", errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
#else
|
||||
acl3_text = "user::rwx\n"
|
||||
"user:1:r--\n"
|
||||
"group::r-x\n"
|
||||
"group:15:r--\n"
|
||||
"mask::rwx\n"
|
||||
"other::r-x";
|
||||
acl3 = acl_from_text(acl3_text);
|
||||
failure("acl_from_text(): errno = %d (%s)", errno, strerror(errno));
|
||||
assert((void *)acl3 != NULL);
|
||||
#endif
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
func = "acl_set()";
|
||||
n = acl_set("d2", acl3);
|
||||
#else
|
||||
func = "acl_set_file()";
|
||||
n = acl_set_file("d2", ACL_TYPE_DEFAULT, acl3);
|
||||
#endif
|
||||
acl_free(acl3);
|
||||
|
||||
failure("%s: errno = %d (%s)", func, errno, strerror(errno));
|
||||
assertEqualInt(0, n);
|
||||
|
||||
/* Create a read-from-disk object. */
|
||||
assert(NULL != (a = archive_read_disk_new()));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
|
||||
assert(NULL != (ae = archive_entry_new()));
|
||||
|
||||
#if HAVE_SUN_ACL
|
||||
flags = ARCHIVE_ENTRY_ACL_TYPE_POSIX1E
|
||||
| ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA
|
||||
| ARCHIVE_ENTRY_ACL_STYLE_SOLARIS;
|
||||
dflags = flags;
|
||||
#else
|
||||
flags = ARCHIVE_ENTRY_ACL_TYPE_ACCESS;
|
||||
dflags = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT;
|
||||
#endif
|
||||
|
||||
/* Walk the dir until we see both of the files */
|
||||
while (ARCHIVE_OK == archive_read_next_header2(a, ae)) {
|
||||
archive_read_disk_descend(a);
|
||||
if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
|
||||
assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl1_text);
|
||||
|
||||
acl_text = archive_entry_acl_to_text(ae, NULL, flags);
|
||||
assertEqualString(acl_text, acl1_text);
|
||||
free(acl_text);
|
||||
} else if (strcmp(archive_entry_pathname(ae), "./d/f1") == 0) {
|
||||
assertEqualString(archive_entry_acl_to_text(ae, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS), acl2_text);
|
||||
acl_text = archive_entry_acl_to_text(ae, NULL, flags);
|
||||
assertEqualString(acl_text, acl2_text);
|
||||
free(acl_text);
|
||||
} else if (strcmp(archive_entry_pathname(ae), "./d2") == 0) {
|
||||
acl_text = archive_entry_acl_to_text(ae, NULL, dflags);
|
||||
assertEqualString(acl_text, acl3_text);
|
||||
free(acl_text);
|
||||
}
|
||||
}
|
||||
|
||||
archive_free(a);
|
||||
archive_entry_free(ae);
|
||||
assertEqualInt(ARCHIVE_OK, archive_free(a));
|
||||
#endif
|
||||
}
|
@ -242,8 +242,8 @@ convert_s_to_ws(const char *s)
|
||||
static void
|
||||
compare_acl_text(struct archive_entry *ae, int flags, const char *s)
|
||||
{
|
||||
const char *text;
|
||||
const wchar_t *wtext;
|
||||
char *text;
|
||||
wchar_t *wtext;
|
||||
wchar_t *ws;
|
||||
ssize_t slen;
|
||||
|
||||
@ -257,9 +257,10 @@ compare_acl_text(struct archive_entry *ae, int flags, const char *s)
|
||||
assertEqualWString(wtext, ws);
|
||||
if (wtext != NULL) {
|
||||
assertEqualInt(wcslen(wtext), slen);
|
||||
free(ws);
|
||||
ws = NULL;
|
||||
}
|
||||
free(text);
|
||||
free(wtext);
|
||||
free(ws);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_from_text)
|
||||
@ -395,6 +396,9 @@ DEFINE_TEST(test_acl_from_text)
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_entry_acl_clear(ae);
|
||||
|
||||
free(ws);
|
||||
archive_entry_free(ae);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_acl_to_text)
|
||||
@ -453,4 +457,6 @@ DEFINE_TEST(test_acl_to_text)
|
||||
|
||||
/* NFSv4 ACLs like "getfacl -i" on FreeBSD */
|
||||
compare_acl_text(ae, ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID, acltext[10]);
|
||||
|
||||
archive_entry_free(ae);
|
||||
}
|
||||
|
@ -67,6 +67,8 @@ test_archive_string_ensure(void)
|
||||
|
||||
assert(&s == archive_string_ensure(&s, EXTENT + 1));
|
||||
assertNonNULLString(0, 2 * EXTENT, s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -92,6 +94,8 @@ test_archive_strcat(void)
|
||||
/* non-empty target, non-empty source */
|
||||
assert(&s == archive_strcat(&s, "baz"));
|
||||
assertExactString(8, EXTENT, "fubarbaz", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -109,6 +113,8 @@ test_archive_strappend_char(void)
|
||||
/* non-empty target */
|
||||
archive_strappend_char(&s, 'Y');
|
||||
assertExactString(2, EXTENT, "XY", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
/* archive_strnXXX() tests focus on length handling.
|
||||
@ -134,6 +140,8 @@ test_archive_strncat(void)
|
||||
/* long read is ok too! */
|
||||
assert(&s == archive_strncat(&s, "snafu", 8));
|
||||
assertExactString(13, EXTENT, "snafubarsnafu", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -155,6 +163,8 @@ test_archive_strncpy(void)
|
||||
/* long read is ok too! */
|
||||
assert(&s == archive_strncpy(&s, "snafu", 8));
|
||||
assertExactString(5, EXTENT, "snafu", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -176,6 +186,8 @@ test_archive_strcpy(void)
|
||||
/* dirty target, empty source */
|
||||
assert(&s == archive_strcpy(&s, ""));
|
||||
assertExactString(0, EXTENT, "", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -222,6 +234,11 @@ test_archive_string_concat(void)
|
||||
archive_string_concat(&t, &s);
|
||||
assertExactString(5, EXTENT, "snafu", s);
|
||||
assertExactString(5, EXTENT, "snafu", t);
|
||||
|
||||
archive_string_free(&v);
|
||||
archive_string_free(&u);
|
||||
archive_string_free(&t);
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -274,6 +291,11 @@ test_archive_string_copy(void)
|
||||
archive_string_copy(&t, &s);
|
||||
assertExactString(5, EXTENT, "fubar", s);
|
||||
assertExactString(5, EXTENT, "fubar", t);
|
||||
|
||||
archive_string_free(&v);
|
||||
archive_string_free(&u);
|
||||
archive_string_free(&t);
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -328,6 +350,8 @@ test_archive_string_sprintf(void)
|
||||
archive_string_empty(&s);
|
||||
archive_string_sprintf(&s, "%d", 1234567890);
|
||||
assertExactString(10, 8 * EXTENT, "1234567890", s);
|
||||
|
||||
archive_string_free(&s);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_archive_string)
|
||||
|
@ -142,6 +142,8 @@ test_compat_gtar_2(void)
|
||||
assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
|
||||
assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_GNUTAR);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_compat_gtar)
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2009 Tim Kientzle
|
||||
* Copyright (c) 2016 Martin Matuska
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -26,101 +27,239 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Exercise support for reading Solaris-style ACL data
|
||||
* from tar archives.
|
||||
* Verify reading entries with POSIX.1e and NFSv4 ACLs from archives created
|
||||
* with Solaris tar.
|
||||
*
|
||||
* This should work on all systems, regardless of whether local
|
||||
* filesystems support ACLs or not.
|
||||
* This should work on all systems, regardless of whether local filesystems
|
||||
* support ACLs or not.
|
||||
*/
|
||||
|
||||
static struct archive_test_acl_t acls0[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_WRITE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 71, "lp" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 666, "666" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 1000, "1000" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls1[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls2[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, -1 ,"" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_USER, 2, "bin" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, -1, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 3, "sys" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_WRITE | ARCHIVE_ENTRY_ACL_READ,
|
||||
ARCHIVE_ENTRY_ACL_MASK, -1, ""},
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, -1, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls3[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_DENY,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 12, "daemon" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 2, "bin" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER, 4, "adm" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
static struct archive_test_acl_t acls4[] = {
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY,
|
||||
ARCHIVE_ENTRY_ACL_USER, 1100, "1100" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT |
|
||||
ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT,
|
||||
ARCHIVE_ENTRY_ACL_GROUP, 4, "adm" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_DATA |
|
||||
ARCHIVE_ENTRY_ACL_APPEND_DATA |
|
||||
ARCHIVE_ENTRY_ACL_DELETE_CHILD |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_ACL |
|
||||
ARCHIVE_ENTRY_ACL_WRITE_OWNER |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_EXECUTE |
|
||||
ARCHIVE_ENTRY_ACL_READ_DATA |
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, 0, "" },
|
||||
{ ARCHIVE_ENTRY_ACL_TYPE_ALLOW,
|
||||
ARCHIVE_ENTRY_ACL_READ_ATTRIBUTES |
|
||||
ARCHIVE_ENTRY_ACL_READ_NAMED_ATTRS |
|
||||
ARCHIVE_ENTRY_ACL_READ_ACL |
|
||||
ARCHIVE_ENTRY_ACL_SYNCHRONIZE,
|
||||
ARCHIVE_ENTRY_ACL_EVERYONE, 0, "" },
|
||||
};
|
||||
|
||||
DEFINE_TEST(test_compat_solaris_tar_acl)
|
||||
{
|
||||
char name[] = "test_compat_solaris_tar_acl.tar";
|
||||
struct archive *a;
|
||||
struct archive_entry *ae;
|
||||
const char *reference1 = "test_compat_solaris_tar_acl.tar";
|
||||
int type, permset, tag, qual;
|
||||
const char *name;
|
||||
|
||||
/* Sample file generated on Solaris 10 */
|
||||
extract_reference_file(reference1);
|
||||
/* Read archive file */
|
||||
assert(NULL != (a = archive_read_new()));
|
||||
assertA(0 == archive_read_support_format_all(a));
|
||||
assertA(0 == archive_read_support_filter_all(a));
|
||||
assertA(0 == archive_read_open_filename(a, reference1, 512));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
extract_reference_file(name);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name,
|
||||
10240));
|
||||
|
||||
/* Archive has 1 entry with some ACLs set on it. */
|
||||
/* First item has access ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
failure("One extended ACL should flag all ACLs to be returned.");
|
||||
assertEqualInt(7, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls0, sizeof(acls0)/sizeof(acls0[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0644);
|
||||
failure("Basic ACLs should set mode to 0644, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assertEqualInt((archive_entry_mode(ae) & 0777), 0644);
|
||||
assertEqualInt(7, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(006, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_USER_OBJ, tag);
|
||||
assertEqualInt(-1, qual);
|
||||
assert(name == NULL);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0644);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(004, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_GROUP_OBJ, tag);
|
||||
assertEqualInt(-1, qual);
|
||||
assert(name == NULL);
|
||||
/* Second item has default and access ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS));
|
||||
archive_test_compare_acls(ae, acls1, sizeof(acls1)/sizeof(acls1[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS, 0750);
|
||||
failure("Basic ACLs should set mode to 0750, not %04o",
|
||||
archive_entry_mode(ae)&0777);
|
||||
assert((archive_entry_mode(ae) & 0777) == 0750);
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT));
|
||||
archive_test_compare_acls(ae, acls2, sizeof(acls2)/sizeof(acls2[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, 0750);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(004, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_OTHER, tag);
|
||||
assertEqualInt(-1, qual);
|
||||
assert(name == NULL);
|
||||
/* Third item has NFS4 ACLs */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(6, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls3, sizeof(acls3)/sizeof(acls3[0]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(001, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
|
||||
assertEqualInt(71, qual);
|
||||
assertEqualString(name, "lp");
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(004, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
|
||||
assertEqualInt(666, qual);
|
||||
assertEqualString(name, "666");
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(007, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_USER, tag);
|
||||
assertEqualInt(1000, qual);
|
||||
assertEqualString(name, "trasz");
|
||||
|
||||
assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type);
|
||||
assertEqualInt(004, permset);
|
||||
assertEqualInt(ARCHIVE_ENTRY_ACL_MASK, tag);
|
||||
assertEqualInt(-1, qual);
|
||||
assertEqualString(name, NULL);
|
||||
|
||||
assertEqualInt(ARCHIVE_EOF, archive_entry_acl_next(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
&type, &permset, &tag, &qual, &name));
|
||||
/* Fourth item has NFS4 ACLs and inheritance flags */
|
||||
assertA(0 == archive_read_next_header(a, &ae));
|
||||
assertEqualInt(5, archive_entry_acl_reset(ae,
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4));
|
||||
archive_test_compare_acls(ae, acls4, sizeof(acls4)/sizeof(acls0[4]),
|
||||
ARCHIVE_ENTRY_ACL_TYPE_NFS4, 0);
|
||||
|
||||
/* Close the archive. */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
|
@ -1,61 +1,163 @@
|
||||
$FreeBSD$
|
||||
begin 644 test_acl_solaris.tar
|
||||
M9FEL92UW:71H+7!O<VEX+6%C;',`````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M`````````````#`P,#`V-#0`,#`P,3<U,``P,#`P,#`P`#`P,#`P,#`P,30T
|
||||
M`#$Q,3<T-C`T,34W`#`P,34Q-S8`00``````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M``````````````````````````````````````````!U<W1A<@`P,'1R87-Z
|
||||
M````````````````````````````````````<F]O=```````````````````
|
||||
M```````````````````P,#`P,C$P`#`P,#`P,3``````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M```````````````````````Q,#`P,#`W`'5S97(Z.G)W+2QU<V5R.FQP.BTM
|
||||
M>#HW,2QU<V5R.C8V-CIR+2TZ-C8V+'5S97(Z=')A<WHZ<G=X.C$P,#`L9W)O
|
||||
M=7`Z.G(M+2QM87-K.G(M+2QO=&AE<CIR+2T``````````3````````/-@```
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````!%&8`````````&L`````,3`P,#`P-P!U
|
||||
begin 644 test_compat_solaris_tar_acl.tar
|
||||
M9FEL92UW:71H+7!O<VEX+6%C;',
|
||||
M
|
||||
M # P,# V-#0 ,# P,3<U, P,# P,# P # P,# P,# P,30S
|
||||
M #$Q,3<T-C T,34W # P,30Q,C$ 00
|
||||
M
|
||||
M !U<W1A<@ P,
|
||||
M <F]O=
|
||||
M P,# P-#$T # P,# P,#,
|
||||
M
|
||||
M
|
||||
M
|
||||
M Q,# P,# W '5S97(Z.G)W+2QU<V5R.FQP.BTM
|
||||
M>#HW,2QU<V5R.C8V-CIR+2TZ-C8V+'5S97(Z,3 P,#IR=W@Z,3 P,"QG<F]U
|
||||
M<#HZ<BTM+&UA<VLZ<BTM+&]T:&5R.G(M+0 # !
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M (Q@@( &L ,3 P,# P-P!U
|
||||
M<V5R.CIR=RTL=7-E<CIL<#HM+7@Z-S$L=7-E<CHV-C8Z<BTM.C8V-BQU<V5R
|
||||
M.G1R87-Z.G)W>#HQ,#`P+&=R;W5P.CIR+2TL;6%S:SIR+69I;&4M=VET:"UP
|
||||
M;W-I>"UA8VQS````````````````````````````````````````````````
|
||||
M```````````````````````````````````````````````````````````P
|
||||
M,#`P-C0T`#`P,#$W-3``,#`P,#`P,``P,#`P,#`P,#`P,``Q,3$W-#8P-#$U
|
||||
M-P`P,#$U,30T`#``````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````=7-T87(`,#!T<F%S>@``````````````
|
||||
M`````````````````````')O;W0`````````````````````````````````
|
||||
M````,#`P,#(Q,``P,#`P,#$P````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
M````````````````````````````````````````````````````````````
|
||||
H````````````````````````````````````````````````````````
|
||||
`
|
||||
M.C$P,# Z<G=X.C$P,# L9W)O=7 Z.G(M+2QM87-K.G(M+69I;&4M=VET:"UP
|
||||
M;W-I>"UA8VQS
|
||||
M P
|
||||
M,# P-C0T # P,#$W-3 ,# P,# P, P,# P,# P,# P, Q,3$W-#8P-#$U
|
||||
M-P P,#$T,#<P #
|
||||
M
|
||||
M =7-T87( ,#
|
||||
M ')O;W0
|
||||
M ,# P,#0Q- P,# P,# S
|
||||
M
|
||||
M
|
||||
M
|
||||
M 9&ER+7=I=&@M<&]S:7@M86-L<R\
|
||||
M
|
||||
M # P,# W-3 ,# P,3<U, P,# P,# P # P,# P
|
||||
M,# P,S P #$S,#,V-3$R,C4T # P,30P,C, 00
|
||||
M
|
||||
M !U<W1A<@ P
|
||||
M, <F]O=
|
||||
M P,# P-#$T # P,# P,#,
|
||||
M
|
||||
M
|
||||
M
|
||||
M Q,# P,#$T '5S97(Z.G)W>"QU<V5R
|
||||
M.F)I;CIR=W@Z,BQG<F]U<#HZ<BUX+&=R;W5P.G-Y<SIR+7@Z,RQM87-K.G(M
|
||||
M>"QO=&AE<CHM+2TL9&5F875L='5S97(Z.G)W>"QD969A=6QT=7-E<CIB:6XZ
|
||||
M<G=X.C(L9&5F875L=&=R;W5P.CIR+7@L9&5F875L=&=R;W5P.G-Y<SIR+7@Z
|
||||
M,RQD969A=6QT;6%S:SIR=W@L9&5F875L=&]T:&5R.BTM+0 @ #C%
|
||||
M" @
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M &1I<BUW
|
||||
M:71H+7!O<VEX+6%C;',O
|
||||
M
|
||||
M P,# P-S4P # P,#$W-3 ,# P,# P, P,# P,# P,# P, Q,S S
|
||||
M-C4Q,C(U- P,#$T,# T #4
|
||||
M
|
||||
M =7-T87( ,#
|
||||
M ')O;W0
|
||||
M ,# P,#0Q- P,# P,# S
|
||||
M
|
||||
M
|
||||
M
|
||||
M 9FEL92UW:71H+6YF<W8T+6%C;',
|
||||
M
|
||||
M # P,# V-# ,# P,3<U, P,# P,# P
|
||||
M # P,# P,# P,S8T #$S,#,V-3$S-C0Q # P,30P,34 00
|
||||
M
|
||||
M !U
|
||||
M<W1A<@ P, <F]O=
|
||||
M P,# P-#$T # R,# P,#(
|
||||
M
|
||||
M
|
||||
M
|
||||
M S,# P,# V &=R;W5P.F1A
|
||||
M96UO;CIR=WAP+2UA05)78T-O<SHM+2TM+2TM.F1E;GDZ,3(L9W)O=7 Z8FEN
|
||||
M.G)W>' M+2TM+2TM+2US.BTM+2TM+2TZ86QL;W<Z,BQU<V5R.F%D;3IR+2TM
|
||||
M+2UA+5(M8RTM<SHM+2TM+2TM.F%L;&]W.C0L;W=N97) .G)W+7 M+6%!4E=C
|
||||
M0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7! .G(M+2TM+6$M4BUC+2US.BTM+2TM
|
||||
M+2TZ86QL;W<L979E<GEO;F5 .BTM+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL
|
||||
M;W< &@
|
||||
M
|
||||
M F-8(" #[ #,P,# P,#8
|
||||
M9W)O=7 Z9&%E;6]N.G)W>' M+6%!4E=C0V]S.BTM+2TM+2TZ9&5N>3HQ,BQG
|
||||
M<F]U<#IB:6XZ<G=X<"TM+2TM+2TM+7,Z+2TM+2TM+3IA;&QO=SHR+'5S97(Z
|
||||
M861M.G(M+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL;W<Z-"QO=VYE<D Z<G<M
|
||||
M<&9I;&4M=VET:"UN9G-V-"UA8VQS
|
||||
M
|
||||
M P,# P-C0P # P,#$W-3 ,# P,# P, P,# P,# P,# P
|
||||
M, Q,S S-C4Q,S8T,0 P,#$S-S4W #
|
||||
M
|
||||
M =7-T87( ,#
|
||||
M ')O;W0
|
||||
M ,# P,#0Q- P,C P,# R
|
||||
M
|
||||
M
|
||||
M
|
||||
M 9&ER+7=I=&@M;F9S=C0M86-L<R\
|
||||
M
|
||||
M # P,# W-3 ,# P,# P, P
|
||||
M,# P,# P # P,# P,# P,S$T #$S,#,V-3$S-S,U # P,30V,C, 00
|
||||
M
|
||||
M
|
||||
M !U<W1A<@ P,')O;W0
|
||||
M<F]O= P,# P-#$T # R,# P
|
||||
M,#(
|
||||
M
|
||||
M
|
||||
M S,# P,# U '5S
|
||||
M97(Z,3$P,#IR=WAP+2UA05)78T-O<SIF9&DM+2TM.F%L;&]W.C$Q,# L9W)O
|
||||
M=7 Z861M.G(M+2TM+6$M4BUC+2US.F9D+2TM+2TZ86QL;W<Z-"QO=VYE<D Z
|
||||
M<G=X<"U$84%25V-#;W,Z+2TM+2TM+3IA;&QO=RQG<F]U<$ Z<BUX+2TM82U2
|
||||
M+6,M+7,Z+2TM+2TM+3IA;&QO=RQE=F5R>6]N94 Z+2TM+2TM82U2+6,M+7,Z
|
||||
M+2TM+2TM+3IA;&QO=P 4
|
||||
M
|
||||
M "HUP@( -, ,S P,# P-0!U<V5R.C$Q,# Z<G=X
|
||||
M<"TM84%25V-#;W,Z9F1I+2TM+3IA;&QO=SHQ,3 P+&=R;W5P.F%D;3IR+2TM
|
||||
M+2UA+5(M8RTM<SIF9"TM+2TM.F%L;&]W.C0L;W=N97) .G)W>' M1&%!4E=C
|
||||
M0V]S.BTM+2TM+2TZ86QL;W<L9W)O=7! .G(M>"TM+6$M4BUC+2US.BTM+2TM
|
||||
M+2TZ86QL;W<L979E<GEO;F5 .BTM+2TM+6$M4BUC+2US.BTM+2TM+2TZ86QL
|
||||
M;W< &1I<BUW:71H+6YF<W8T+6%C;',O
|
||||
M
|
||||
M P,# P-S4P # P,# P,# ,# P,# P, P,# P
|
||||
M,# P,# P, Q,S S-C4Q,S<S-0 P,#$T-3<W #4
|
||||
M
|
||||
M =7-T87(
|
||||
M,#!R;V]T ')O;W0
|
||||
M ,# P,#0Q- P,C P,# R
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
M
|
||||
-
|
||||
|
||||
end
|
||||
|
@ -406,10 +406,12 @@ DEFINE_TEST(test_fuzz_tar)
|
||||
"test_read_format_tar_empty_filename.tar",
|
||||
NULL
|
||||
};
|
||||
#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H
|
||||
static const char *fileset9[] = {
|
||||
"test_compat_lzop_1.tar.lzo",
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
static const struct files filesets[] = {
|
||||
{0, fileset1}, /* Exercise bzip2 decompressor. */
|
||||
{1, fileset1},
|
||||
@ -420,7 +422,9 @@ DEFINE_TEST(test_fuzz_tar)
|
||||
{0, fileset6}, /* Exercise xz decompressor. */
|
||||
{0, fileset7},
|
||||
{0, fileset8},
|
||||
#if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H
|
||||
{0, fileset9}, /* Exercise lzo decompressor. */
|
||||
#endif
|
||||
{1, NULL}
|
||||
};
|
||||
test_fuzz(filesets);
|
||||
|
@ -1320,11 +1320,13 @@ test_callbacks(void)
|
||||
assertUtimes("cb", 886622, 0, 886622, 0);
|
||||
|
||||
assert((ae = archive_entry_new()) != NULL);
|
||||
if (assert((a = archive_read_disk_new()) != NULL)) {
|
||||
assert((a = archive_read_disk_new()) != NULL);
|
||||
if (a == NULL) {
|
||||
archive_entry_free(ae);
|
||||
return;
|
||||
}
|
||||
if (assert((m = archive_match_new()) != NULL)) {
|
||||
assert((m = archive_match_new()) != NULL);
|
||||
if (m == NULL) {
|
||||
archive_entry_free(ae);
|
||||
archive_read_free(a);
|
||||
archive_match_free(m);
|
||||
@ -1377,6 +1379,10 @@ test_callbacks(void)
|
||||
/* Close the disk object. */
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_close(a));
|
||||
|
||||
/* Reset name filter */
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
archive_read_disk_set_matching(a, NULL, NULL, NULL));
|
||||
|
||||
/*
|
||||
* Test2: Traversals with a metadata filter.
|
||||
*/
|
||||
@ -1394,7 +1400,7 @@ test_callbacks(void)
|
||||
while (file_count--) {
|
||||
archive_entry_clear(ae);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
|
||||
failure("File 'cb/f1' should be exclueded");
|
||||
failure("File 'cb/f1' should be excluded");
|
||||
assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0);
|
||||
if (strcmp(archive_entry_pathname(ae), "cb") == 0) {
|
||||
assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
|
||||
|
@ -39,13 +39,16 @@ DEFINE_TEST(test_read_filter_lzop)
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
r = archive_read_support_filter_lzop(a);
|
||||
if (r != ARCHIVE_OK) {
|
||||
if (r == ARCHIVE_WARN && !canLzop()) {
|
||||
if (!canLzop()) {
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
skipping("lzop compression is not supported "
|
||||
"on this platform");
|
||||
} else
|
||||
return;
|
||||
} else if (r != ARCHIVE_WARN) {
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
return;
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
|
@ -36,12 +36,16 @@ DEFINE_TEST(test_read_filter_lzop_multiple_parts)
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
r = archive_read_support_filter_lzop(a);
|
||||
if (r != ARCHIVE_OK) {
|
||||
if (r == ARCHIVE_WARN && !canLzop()) {
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
if (!canLzop()) {
|
||||
skipping("lzop compression is not supported "
|
||||
"on this platform");
|
||||
} else if (r == ARCHIVE_WARN) {
|
||||
skipping("lzop multiple parts decoding is not "
|
||||
"supported via external program");
|
||||
|
||||
} else
|
||||
assertEqualIntA(a, ARCHIVE_OK, r);
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
return;
|
||||
}
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
|
@ -126,6 +126,7 @@ test_basic(void)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
|
||||
verify_basic(a, 0);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -195,6 +196,7 @@ test_info_zip_ux(void)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
|
||||
verify_info_zip_ux(a, 0);
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -258,6 +260,7 @@ test_extract_length_at_end(void)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 108));
|
||||
verify_extract_length_at_end(a, 0);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -294,6 +297,8 @@ test_symlink(void)
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip)
|
||||
|
@ -63,6 +63,8 @@ verify(const char *refname)
|
||||
assertEqualInt(archive_entry_is_encrypted(ae), 0);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_comment_stored)
|
||||
|
@ -112,4 +112,6 @@ DEFINE_TEST(test_read_format_zip_mac_metadata)
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ test_malformed1(void)
|
||||
assertEqualIntA(a, ARCHIVE_OK, read_open_memory(a, p, s, 31));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
free(p);
|
||||
}
|
||||
|
||||
DEFINE_TEST(test_read_format_zip_malformed)
|
||||
|
@ -65,6 +65,8 @@ DEFINE_TEST(test_read_format_zip_nested)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
|
||||
/* Inspect inner Zip. */
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
|
||||
|
@ -53,6 +53,8 @@ verify_padded_archive(const char *refname)
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -60,4 +60,6 @@ DEFINE_TEST(test_read_format_zip_sfx)
|
||||
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
free(p);
|
||||
}
|
||||
|
@ -72,6 +72,9 @@ DEFINE_TEST(test_write_disk_secure746a)
|
||||
|
||||
/* Verify that target file contents are unchanged. */
|
||||
assertTextFileContents("unmodified", "../target/foo");
|
||||
|
||||
assertEqualIntA(a, ARCHIVE_FATAL, archive_write_close(a));
|
||||
archive_write_free(a);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ DEFINE_TEST(test_write_filter_lz4)
|
||||
} else {
|
||||
assertEqualInt(ARCHIVE_OK, r);
|
||||
}
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
buffsize = 2000000;
|
||||
assert(NULL != (buff = (char *)malloc(buffsize)));
|
||||
@ -299,6 +300,7 @@ test_options(const char *options)
|
||||
} else {
|
||||
assertEqualInt(ARCHIVE_OK, r);
|
||||
}
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
|
||||
buffsize = 2000000;
|
||||
assert(NULL != (buff = (char *)malloc(buffsize)));
|
||||
|
@ -43,12 +43,12 @@ DEFINE_TEST(test_write_filter_lzop)
|
||||
|
||||
assert((a = archive_write_new()) != NULL);
|
||||
r = archive_write_add_filter_lzop(a);
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
if (r != ARCHIVE_OK) {
|
||||
if (canLzop() && r == ARCHIVE_WARN)
|
||||
use_prog = 1;
|
||||
else {
|
||||
skipping("lzop writing not supported on this platform");
|
||||
assertEqualInt(ARCHIVE_OK, archive_write_free(a));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -92,7 +92,7 @@ DEFINE_TEST(test_write_filter_lzop)
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
r = archive_read_support_filter_lzop(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
if (r == ARCHIVE_WARN && !use_prog) {
|
||||
skipping("Can't verify lzop writing by reading back;"
|
||||
" lzop reading not fully supported on this platform");
|
||||
} else {
|
||||
@ -212,7 +212,7 @@ DEFINE_TEST(test_write_filter_lzop)
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
|
||||
r = archive_read_support_filter_lzop(a);
|
||||
if (r == ARCHIVE_WARN) {
|
||||
if (r == ARCHIVE_WARN && !use_prog) {
|
||||
skipping("lzop reading not fully supported on this platform");
|
||||
} else {
|
||||
assertEqualIntA(a, ARCHIVE_OK,
|
||||
|
@ -470,5 +470,6 @@ DEFINE_TEST(test_write_format_zip_large)
|
||||
assertEqualMem(cd_start, "PK\001\002", 4);
|
||||
|
||||
fileblocks_free(fileblocks);
|
||||
free(buff);
|
||||
free(nulldata);
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ verify_zip_filesize(uint64_t size, int expected)
|
||||
archive_entry_set_size(ae, size);
|
||||
assertEqualInt(expected, archive_write_header(a, ae));
|
||||
|
||||
archive_entry_free(ae);
|
||||
|
||||
/* Don't actually write 4GB! ;-) */
|
||||
assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
|
||||
}
|
||||
|
@ -45,25 +45,25 @@ DEFINE_TEST(test_option_uid_uname)
|
||||
/* Again with both --uid and --uname */
|
||||
failure("Error invoking %s c", testprog);
|
||||
assertEqualInt(0,
|
||||
systemf("%s cf archive2 --uid=17 --uname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt",
|
||||
systemf("%s cf archive2 --uid=65123 --uname=foofoofoo --format=ustar file >stdout2.txt 2>stderr2.txt",
|
||||
testprog));
|
||||
assertEmptyFile("stdout2.txt");
|
||||
assertEmptyFile("stderr2.txt");
|
||||
data = slurpfile(&s, "archive2");
|
||||
/* Should force uid and uname fields in ustar header. */
|
||||
assertEqualMem(data + 108, "000021 \0", 8);
|
||||
assertEqualMem(data + 108, "177143 \0", 8);
|
||||
assertEqualMem(data + 265, "foofoofoo\0", 10);
|
||||
free(data);
|
||||
|
||||
/* Again with just --uid */
|
||||
failure("Error invoking %s c", testprog);
|
||||
assertEqualInt(0,
|
||||
systemf("%s cf archive3 --uid=17 --format=ustar file >stdout3.txt 2>stderr3.txt",
|
||||
systemf("%s cf archive3 --uid=65123 --format=ustar file >stdout3.txt 2>stderr3.txt",
|
||||
testprog));
|
||||
assertEmptyFile("stdout3.txt");
|
||||
assertEmptyFile("stderr3.txt");
|
||||
data = slurpfile(&s, "archive3");
|
||||
assertEqualMem(data + 108, "000021 \0", 8);
|
||||
assertEqualMem(data + 108, "177143 \0", 8);
|
||||
/* Uname field in ustar header should be empty. */
|
||||
assertEqualMem(data + 265, "\0", 1);
|
||||
free(data);
|
||||
|
@ -140,6 +140,7 @@ safe_fprintf(FILE *f, const char *fmt, ...)
|
||||
} else {
|
||||
/* Leave fmtbuff pointing to the truncated
|
||||
* string in fmtbuff_stack. */
|
||||
fmtbuff = fmtbuff_stack;
|
||||
length = sizeof(fmtbuff_stack) - 1;
|
||||
break;
|
||||
}
|
||||
|
@ -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
|
||||
|
2
contrib/tcpdump/configure
vendored
2
contrib/tcpdump/configure
vendored
@ -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; }
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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]+";
|
||||
|
@ -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:"
|
||||
|
||||
|
@ -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:"
|
||||
|
||||
|
@ -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:"
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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]
|
||||
|
@ -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 .
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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(®ex, 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(®ex);
|
||||
goto copyasis;
|
||||
}
|
||||
if (*host)
|
||||
strncpy(res, host, sizeof editedhost - (res - editedhost) - 1);
|
||||
else
|
||||
*res = '\0';
|
||||
editedhost[sizeof editedhost - 1] = '\0';
|
||||
|
||||
found = !regexec(®ex, 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(®ex);
|
||||
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 {
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user