Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package tarix for openSUSE:Factory checked in at 2026-10-13 17:43:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/tarix (Old) and /work/SRC/openSUSE:Factory/.tarix.new.3698736 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "tarix" Tue Oct 13 17:43:46 2026 rev:3 rq:1384435 version:1.0.9 Changes: -------- --- /work/SRC/openSUSE:Factory/tarix/tarix.changes 2026-06-22 17:45:06.630714152 +0200 +++ /work/SRC/openSUSE:Factory/.tarix.new.3698736/tarix.changes 2026-10-13 17:44:27.307076902 +0200 @@ -1,0 +2,15 @@ +Mon Oct 12 18:33:13 UTC 2026 - Tomáš Chvátal <[email protected]> + +- Extend tarix-fuse3.patch with -D_FILE_OFFSET_BITS=64 for the + fuse_tarix build: libfuse3 requires a 64-bit off_t, so the + build failed on 32-bit targets (i586, armv7l) +- Add tarix-pax-headers.patch: keep POSIX pax extended headers + attached to the archive member they describe when extracting. + They were matched against the file list on their own before, + so filtered extractions leaked the headers of excluded + members and tar applied them to the wrong member +- Run the full upstream testsuite in %check: the pax header fix + makes 08-exclude pass with the POSIX tar format that openSUSE + uses by default, so failures are no longer ignored there + +------------------------------------------------------------------- New: ---- tarix-pax-headers.patch ----------(New B)---------- New: build failed on 32-bit targets (i586, armv7l) - Add tarix-pax-headers.patch: keep POSIX pax extended headers attached to the archive member they describe when extracting. ----------(New E)---------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ tarix.spec ++++++ --- /var/tmp/diff_new_pack.Czk6Ql/_old 2026-10-13 17:44:28.039107581 +0200 +++ /var/tmp/diff_new_pack.Czk6Ql/_new 2026-10-13 17:44:28.041107665 +0200 @@ -21,11 +21,12 @@ Release: 0 Summary: Simple Indexer for GNU and POSIX Tar Files License: GPL-2.0-only -Group: Productivity/Archiving/Backup URL: https://github.com/fastcat/tarix Source: https://github.com/fastcat/tarix/archive/tarix-%{version}.tar.gz # PATCH-FIX-UPSTREAM tarix-fuse3.patch boo#1242192 -- port the FUSE filesystem from libfuse2 to libfuse3 Patch0: tarix-fuse3.patch +# PATCH-FIX-UPSTREAM tarix-pax-headers.patch -- keep POSIX pax headers attached to the archive member they describe during extraction +Patch1: tarix-pax-headers.patch BuildRequires: pkgconfig BuildRequires: pkgconfig(fuse3) BuildRequires: pkgconfig(glib-2.0) @@ -51,8 +52,7 @@ %{buildroot}%{_bindir}/fuse_tarix %check -# Test: 08-exclude ...FAILED -make %{?_smp_mflags} CC="cc %{optflags} -std=c99" test ||: +%make_build CC="cc %{optflags} -std=c99" test %files %license LICENSE ++++++ tarix-fuse3.patch ++++++ --- /var/tmp/diff_new_pack.Czk6Ql/_old 2026-10-13 17:44:28.064108629 +0200 +++ /var/tmp/diff_new_pack.Czk6Ql/_new 2026-10-13 17:44:28.067108754 +0200 @@ -1,5 +1,5 @@ ---- a/Makefile 2026-06-22 13:13:42.245101145 +0200 -+++ b/Makefile 2026-06-22 13:13:42.313108724 +0200 +--- a/Makefile ++++ b/Makefile @@ -8,9 +8,9 @@ # silence-errors doesn't completely silence them @@ -12,8 +12,17 @@ LDFLAGS_GLIB:=$(strip $(shell pkg-config glib-2.0 --libs --silence-errors)) # disable fuse if it's not available ---- a/src/fuse_tarix.c 2026-06-22 13:13:42.257102483 +0200 -+++ b/src/fuse_tarix.c 2026-06-22 13:13:42.313108724 +0200 +@@ -67,7 +67,7 @@ + endif + OPTCFLAGS?= + CFLAGS=-Wall -Werror -std=gnu99 $(CFLAGS_O) $(OPTCFLAGS) +-CPPFLAGS_fuse_tarix:= ${CPPFLAGS_FUSE} ${CPPFLAGS_GLIB} ++CPPFLAGS_fuse_tarix:= ${CPPFLAGS_FUSE} ${CPPFLAGS_GLIB} -D_FILE_OFFSET_BITS=64 + LDFLAGS+=-lz + LDFLAGS_fuse_tarix:=${LDFLAGS_FUSE} ${LDFLAGS_GLIB} + CC?=gcc +--- a/src/fuse_tarix.c ++++ b/src/fuse_tarix.c @@ -19,7 +19,7 @@ #include "config.h" @@ -83,8 +92,8 @@ .utimens = tarix_utimens, }; ---- a/src/fuse_rofs.c 2026-06-22 13:13:42.273104266 +0200 -+++ b/src/fuse_rofs.c 2026-06-22 13:13:42.317109170 +0200 +--- a/src/fuse_rofs.c ++++ b/src/fuse_rofs.c @@ -25,26 +25,40 @@ return -EROFS; } ++++++ tarix-pax-headers.patch ++++++ --- a/src/extract_files.c +++ b/src/extract_files.c @@ -46,6 +46,13 @@ int zlib_level; t_streamp tsp; int outfd; + /* POSIX pax header entries ('x'/'g') held back until the archive + member they belong to is decided on; they immediately precede + their member and are contiguous, so a range is enough */ + int have_pending; + unsigned long pending_blocknum; + off64_t pending_offset; + unsigned long pending_blocklength; /* flags to pass to fnmatch, if 0, don't use fnmatch */ int glob_flags; /* if set, then matched items are excluded */ @@ -54,6 +61,55 @@ const struct files_list_state *files_list; }; +/* seek (if needed) to the given record and pass it through to the + output; returns 0 on success, nonzero on error like the caller */ +static int copy_blocks(struct extract_files_state *state, + unsigned long blocknum, off64_t offset, unsigned long blocklength) +{ + /* for the DMSG macro */ + int debug_messages = state->debug_messages; + off64_t destoff; + char passbuf[TARBLKSZ]; + + /* seek to the record start and then pass the record through */ + /* don't actually seek if we're already there */ + if (state->curpos != blocknum) + { + destoff = state->zlib_level ? offset : blocknum * TARBLKSZ; + DMSG("seeking to %lld\n", (long long)destoff); + if (ts_seek(state->tsp, destoff) != 0) + { + fprintf(stderr, "seek error\n"); + return 1; + } + state->curpos = blocknum; + } + DMSG("reading %ld records\n", blocklength); + for (unsigned long bnum = 0; bnum < blocklength; ++bnum) + { + int n; + if ((n = ts_read(state->tsp, passbuf, TARBLKSZ)) < TARBLKSZ) + { + if (n >= 0) + perror("partial tarfile read"); + else + ptserror("read tarfile", n, state->tsp); + return 2; + } + DMSG("read a rec, now at %lld, %ld left\n", + (long long)state->curpos, blocklength - bnum - 1); + ++state->curpos; + if ((n = write(state->outfd, passbuf, TARBLKSZ)) < TARBLKSZ) + { + perror((n > 0) ? "partial tarfile write" : "write tarfile"); + return 2; + } + DMSG("wrote rec\n"); + } + + return 0; +} + int extract_files_lineloop_processor(char *line, void *data) { struct extract_files_state *state = (struct extract_files_state*)data; @@ -62,8 +118,7 @@ size_t i; /* for the DMSG macro */ int debug_messages = state->debug_messages; - off64_t destoff; - + if (!state->gotheader) { if (init_index_parser(&state->ipstate, line) != 0) @@ -86,6 +141,26 @@ /* comment line */ return 0; + if (entry.recordtype == 'x' || entry.recordtype == 'g') + { + /* a pax header describes the member that follows it, it is not a + member of its own: never match it against the file list, hold it + until that member's extract decision is made so the two are + copied (or dropped) together */ + if (state->have_pending && + entry.blocknum == + state->pending_blocknum + state->pending_blocklength) + state->pending_blocklength += entry.blocklength; + else + { + state->have_pending = 1; + state->pending_blocknum = entry.blocknum; + state->pending_offset = entry.offset; + state->pending_blocklength = entry.blocklength; + } + return 0; + } + /* take action on the line */ for (i = 0; i < files_list->argc; ++i) { @@ -124,50 +199,28 @@ if (state->exclude_mode) extract = !extract; - + if (!extract) - return 0; - - char passbuf[TARBLKSZ]; - - DMSG("extracting %s\n", entry.filename); - /* seek to the record start and then pass the record through */ - /* don't actually seek if we're already there */ - if (state->curpos != entry.blocknum) { - destoff = state->zlib_level ? entry.offset : entry.blocknum * TARBLKSZ; - DMSG("seeking to %lld\n", (long long)destoff); - if (ts_seek(state->tsp, destoff) != 0) - { - fprintf(stderr, "seek error\n"); - return 1; - } - state->curpos = entry.blocknum; + /* the member is skipped, so are its held pax headers */ + state->have_pending = 0; + return 0; } - DMSG("reading %ld records\n", entry.blocklength); - for (unsigned long bnum = 0; bnum < entry.blocklength; ++bnum) + + if (state->have_pending) { - int n; - if ((n = ts_read(state->tsp, passbuf, TARBLKSZ)) < TARBLKSZ) - { - if (n >= 0) - perror("partial tarfile read"); - else - ptserror("read tarfile", n, state->tsp); - return 2; - } - DMSG("read a rec, now at %lld, %ld left\n", - (long long)state->curpos, entry.blocklength - bnum - 1); - ++state->curpos; - if ((n = write(state->outfd, passbuf, TARBLKSZ)) < TARBLKSZ) - { - perror((n > 0) ? "partial tarfile write" : "write tarfile"); - return 2; - } - DMSG("wrote rec\n"); + /* the member is extracted: its pax headers go first so they stay + attached to it */ + int ret = copy_blocks(state, state->pending_blocknum, + state->pending_offset, state->pending_blocklength); + state->have_pending = 0; + if (ret != 0) + return ret; } - - return 0; + + DMSG("extracting %s\n", entry.filename); + return copy_blocks(state, entry.blocknum, entry.offset, + entry.blocklength); } int extract_files(const char *indexfile, const char *tarfile,
