From ceea0553c3c84629a79c4626c30df6aba5f1fbb4 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Sun, 5 Apr 2026 02:40:56 +1200
Subject: [PATCH v2 6/6] pg_waldump: Use astreamer_libarchive_reader.

If this build supports libarchive, use astreamer_libarchive_reader
instead of astreamer_tar_parser to read WAL archives.  It supports
modern tar formats.

Reviewed-by:
Discussion: https://postgr.es/m/CA%2BhUKGJYThZZp0AfvEbzNX_ZQ22pTpcjtgT0J_Pb%2BHAGH%3DQChw%40mail.gmail.com
---
 src/bin/pg_waldump/Makefile          | 5 +++++
 src/bin/pg_waldump/archive_waldump.c | 5 +++++
 src/bin/pg_waldump/meson.build       | 2 +-
 src/bin/pg_waldump/t/001_basic.pl    | 9 ++++++++-
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/bin/pg_waldump/Makefile b/src/bin/pg_waldump/Makefile
index aabb87566a2..09005bf4ba4 100644
--- a/src/bin/pg_waldump/Makefile
+++ b/src/bin/pg_waldump/Makefile
@@ -23,6 +23,11 @@ OBJS = \
 override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
 LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils
 
+ifeq ($(with_libarchive), yes)
+# XXX figure out where this should go
+LDFLAGS_INTERNAL += $(LIBARCHIVE_LIBS)
+endif
+
 RMGRDESCSOURCES = $(sort $(notdir $(wildcard $(top_srcdir)/src/backend/access/rmgrdesc/*desc*.c)))
 RMGRDESCOBJS = $(patsubst %.c,%.o,$(RMGRDESCSOURCES))
 
diff --git a/src/bin/pg_waldump/archive_waldump.c b/src/bin/pg_waldump/archive_waldump.c
index b27888a5056..07b81ec4871 100644
--- a/src/bin/pg_waldump/archive_waldump.c
+++ b/src/bin/pg_waldump/archive_waldump.c
@@ -139,6 +139,10 @@ init_archive_reader(XLogDumpPrivate *privateInfo,
 
 	streamer = astreamer_waldump_new(privateInfo);
 
+#ifdef USE_LIBARCHIVE
+	/* libarchive will decode the tar archive. */
+	streamer = astreamer_libarchive_reader_new(streamer, pathname);
+#else
 	/* We must first parse the tar archive. */
 	streamer = astreamer_tar_parser_new(streamer);
 
@@ -152,6 +156,7 @@ init_archive_reader(XLogDumpPrivate *privateInfo,
 
 	/* And before that, we have to read the file. */
 	streamer = astreamer_plain_reader_new(streamer, pathname);
+#endif
 
 	privateInfo->archive_streamer = streamer;
 
diff --git a/src/bin/pg_waldump/meson.build b/src/bin/pg_waldump/meson.build
index 5296f21b82c..0b2c4021107 100644
--- a/src/bin/pg_waldump/meson.build
+++ b/src/bin/pg_waldump/meson.build
@@ -19,7 +19,7 @@ endif
 
 pg_waldump = executable('pg_waldump',
   pg_waldump_sources,
-  dependencies: [frontend_code, libpq, lz4, zstd],
+  dependencies: [frontend_code, libarchive, libpq, lz4, zstd],
   c_args: ['-DFRONTEND'], # needed for xlogreader et al
   kwargs: default_bin_args,
 )
diff --git a/src/bin/pg_waldump/t/001_basic.pl b/src/bin/pg_waldump/t/001_basic.pl
index 7dd1c3dd63e..62a15228b38 100644
--- a/src/bin/pg_waldump/t/001_basic.pl
+++ b/src/bin/pg_waldump/t/001_basic.pl
@@ -11,7 +11,13 @@ use Test::More;
 use List::Util qw(shuffle);
 
 my $tar = $ENV{TAR};
-my @tar_p_flags = tar_portability_options($tar);
+my @tar_p_flags;
+
+# If we don't have libarchive, then we tell tar to stick to ustar format that
+# astreamer_tar.c can decode.  Otherwise we should be able to accept anything
+# that any current tar produces.
+@tar_p_flags = tar_portability_options($tar)
+  if !check_pg_config("#define USE_LIBARCHIVE");
 
 program_help_ok('pg_waldump');
 program_version_ok('pg_waldump');
@@ -373,6 +379,7 @@ my @scenarios = (
 		'compression_flags' => '-czf',
 		'is_archive' => 1,
 		'enabled' => check_pg_config("#define HAVE_LIBZ 1")
+		  || check_pg_config("#define USE_LIBARCHIVE")
 	});
 
 for my $scenario (@scenarios)
-- 
2.53.0

