Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Mar 2020 01:05:40 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r358925 - in stable/12/contrib/libarchive: cpio cpio/test libarchive libarchive/test
Message-ID:  <202003130105.02D15eu0033405@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Fri Mar 13 01:05:40 2020
New Revision: 358925
URL: https://svnweb.freebsd.org/changeset/base/358925

Log:
  MFC r358533:
  Sync libarchive with vendor.
  
  Relevant vendor changes:
    Issue #1257: Add testcase for ZIPX files with LZMA_STREAM_END marker
    PR #1331: cpio.5: fix hard link description
    Issue #1335: archive_read.c: fix UBSan warning about undefined behavior
    Issue #1338: XAR reader: fix UBSan warning about undefined behavior
    Issue #1339: bsdcpio_test: fix datatype in from_hex()
    Issue #1341: Safe writes: delete temporary file if rename fails.
    Issue #1341: Safe writes: improve error handling

Added:
  stable/12/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu
     - copied unchanged from r358533, head/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu
Modified:
  stable/12/contrib/libarchive/cpio/cpio.c
  stable/12/contrib/libarchive/cpio/cpio.h
  stable/12/contrib/libarchive/cpio/test/test_format_newc.c
  stable/12/contrib/libarchive/libarchive/archive_read.c
  stable/12/contrib/libarchive/libarchive/archive_read_open_filename.c
  stable/12/contrib/libarchive/libarchive/archive_read_support_format_xar.c
  stable/12/contrib/libarchive/libarchive/archive_util.c
  stable/12/contrib/libarchive/libarchive/archive_write_disk_posix.c
  stable/12/contrib/libarchive/libarchive/archive_write_set_format_xar.c
  stable/12/contrib/libarchive/libarchive/cpio.5
  stable/12/contrib/libarchive/libarchive/test/test_read_format_zip.c

Modified: stable/12/contrib/libarchive/cpio/cpio.c
==============================================================================
--- stable/12/contrib/libarchive/cpio/cpio.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/cpio/cpio.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -737,7 +737,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath
 	 */
 	destpath = srcpath;
 	if (cpio->destdir) {
-		len = strlen(cpio->destdir) + strlen(srcpath) + 8;
+		len = cpio->destdir_len + strlen(srcpath) + 8;
 		if (len >= cpio->pass_destpath_alloc) {
 			while (len >= cpio->pass_destpath_alloc) {
 				cpio->pass_destpath_alloc += 512;
@@ -1228,15 +1228,14 @@ mode_pass(struct cpio *cpio, const char *destdir)
 	struct lafe_line_reader *lr;
 	const char *p;
 	int r;
-	size_t destdir_len;
 
 	/* Ensure target dir has a trailing '/' to simplify path surgery. */
-	destdir_len = strlen(destdir);
-	cpio->destdir = malloc(destdir_len + 8);
-	memcpy(cpio->destdir, destdir, destdir_len);
-	if (destdir_len == 0 || destdir[destdir_len - 1] != '/')
-		cpio->destdir[destdir_len++] = '/';
-	cpio->destdir[destdir_len++] = '\0';
+	cpio->destdir_len = strlen(destdir);
+	cpio->destdir = malloc(cpio->destdir_len + 8);
+	memcpy(cpio->destdir, destdir, cpio->destdir_len);
+	if (cpio->destdir_len == 0 || destdir[cpio->destdir_len - 1] != '/')
+		cpio->destdir[cpio->destdir_len++] = '/';
+	cpio->destdir[cpio->destdir_len] = '\0';
 
 	cpio->archive = archive_write_disk_new();
 	if (cpio->archive == NULL)

Modified: stable/12/contrib/libarchive/cpio/cpio.h
==============================================================================
--- stable/12/contrib/libarchive/cpio/cpio.h	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/cpio/cpio.h	Fri Mar 13 01:05:40 2020	(r358925)
@@ -64,6 +64,7 @@ struct cpio {
 	int		  option_numeric_uid_gid; /* -n */
 	int		  option_rename; /* -r */
 	char		 *destdir;
+	size_t		  destdir_len;
 	size_t		  pass_destpath_alloc;
 	char		 *pass_destpath;
 	int		  uid_override;

Modified: stable/12/contrib/libarchive/cpio/test/test_format_newc.c
==============================================================================
--- stable/12/contrib/libarchive/cpio/test/test_format_newc.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/cpio/test/test_format_newc.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -49,10 +49,11 @@ is_hex(const char *p, size_t l)
 	return (1);
 }
 
-static int
+/* Convert up to 8 hex characters to unsigned 32-bit decimal integer */
+static uint32_t
 from_hex(const char *p, size_t l)
 {
-	int r = 0;
+	uint32_t r = 0;
 
 	while (l > 0) {
 		r *= 16;
@@ -82,11 +83,11 @@ DEFINE_TEST(test_format_newc)
 {
 	FILE *list;
 	int r;
-	int devmajor, devminor, ino, gid;
-	int uid = -1;
+	uint32_t devmajor, devminor, ino, gid, uid;
 	time_t t, t2, now;
 	char *p, *e;
-	size_t s, fs, ns;
+	size_t s;
+	uint64_t fs, ns;
 	char result[1024];
 
 	assertUmask(0);
@@ -199,9 +200,11 @@ DEFINE_TEST(test_format_newc)
 #else
 	assertEqualInt(0x81a4, from_hex(e + 14, 8)); /* Mode */
 #endif	
-	if (uid < 0)
-		uid = from_hex(e + 22, 8);
+#if defined(_WIN32)
+	uid = from_hex(e + 22, 8);
+#else
 	assertEqualInt(from_hex(e + 22, 8), uid); /* uid */
+#endif
 	gid = from_hex(e + 30, 8); /* gid */
 	assertEqualMem(e + 38, "00000003", 8); /* nlink */
 	t = from_hex(e + 46, 8); /* mtime */
@@ -215,14 +218,14 @@ DEFINE_TEST(test_format_newc)
 	    "       first appearance should be empty, so this file size\n"
 	    "       field should be zero");
 	assertEqualInt(0, from_hex(e + 54, 8)); /* File size */
-	fs = from_hex(e + 54, 8);
+	fs = (uint64_t)from_hex(e + 54, 8);
 	fs += PAD(fs, 4);
 	devmajor = from_hex(e + 62, 8); /* devmajor */
 	devminor = from_hex(e + 70, 8); /* devminor */
 	assert(is_hex(e + 78, 8)); /* rdevmajor */
 	assert(is_hex(e + 86, 8)); /* rdevminor */
 	assertEqualMem(e + 94, "00000006", 8); /* Name size */
-	ns = from_hex(e + 94, 8);
+	ns = (uint64_t)from_hex(e + 94, 8);
 	ns += PAD(ns + 2, 4);
 	assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
 	assertEqualMem(e + 110, "file1\0", 6); /* Name contents */
@@ -249,14 +252,14 @@ DEFINE_TEST(test_format_newc)
 		    " at t2=%#08jx", (intmax_t)t, (intmax_t)t2);
 		assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
 		assertEqualMem(e + 54, "00000005", 8); /* File size */
-		fs = from_hex(e + 54, 8);
+		fs = (uint64_t)from_hex(e + 54, 8);
 		fs += PAD(fs, 4);
 		assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
 		assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
 		assert(is_hex(e + 78, 8)); /* rdevmajor */
 		assert(is_hex(e + 86, 8)); /* rdevminor */
 		assertEqualMem(e + 94, "00000008", 8); /* Name size */
-		ns = from_hex(e + 94, 8);
+		ns = (uint64_t)from_hex(e + 94, 8);
 		ns += PAD(ns + 2, 4);
 		assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
 		assertEqualMem(e + 110, "symlink\0\0\0", 10); /* Name contents */
@@ -285,14 +288,14 @@ DEFINE_TEST(test_format_newc)
 	    "t2=%#08jx", (intmax_t)t, (intmax_t)t2);
 	assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
 	assertEqualMem(e + 54, "00000000", 8); /* File size */
-	fs = from_hex(e + 54, 8);
+	fs = (uint64_t)from_hex(e + 54, 8);
 	fs += PAD(fs, 4);
 	assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
 	assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
 	assert(is_hex(e + 78, 8)); /* rdevmajor */
 	assert(is_hex(e + 86, 8)); /* rdevminor */
 	assertEqualMem(e + 94, "00000004", 8); /* Name size */
-	ns = from_hex(e + 94, 8);
+	ns = (uint64_t)from_hex(e + 94, 8);
 	ns += PAD(ns + 2, 4);
 	assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
 	assertEqualMem(e + 110, "dir\0\0\0", 6); /* Name contents */
@@ -319,14 +322,14 @@ DEFINE_TEST(test_format_newc)
 	    "t2=%#08jx", (intmax_t)t, (intmax_t)t2);
 	assert(t2 == t || t2 == t + 1); /* Almost same as first entry. */
 	assertEqualInt(10, from_hex(e + 54, 8)); /* File size */
-	fs = from_hex(e + 54, 8);
+	fs = (uint64_t)from_hex(e + 54, 8);
 	fs += PAD(fs, 4);
 	assertEqualInt(devmajor, from_hex(e + 62, 8)); /* devmajor */
 	assertEqualInt(devminor, from_hex(e + 70, 8)); /* devminor */
 	assert(is_hex(e + 78, 8)); /* rdevmajor */
 	assert(is_hex(e + 86, 8)); /* rdevminor */
 	assertEqualMem(e + 94, "00000009", 8); /* Name size */
-	ns = from_hex(e + 94, 8);
+	ns = (uint64_t)from_hex(e + 94, 8);
 	ns += PAD(ns + 2, 4);
 	assertEqualInt(0, from_hex(e + 102, 8)); /* check field */
 	assertEqualMem(e + 110, "hardlink\0\0", 10); /* Name contents */

Modified: stable/12/contrib/libarchive/libarchive/archive_read.c
==============================================================================
--- stable/12/contrib/libarchive/libarchive/archive_read.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/libarchive/archive_read.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -892,15 +892,16 @@ archive_read_data(struct archive *_a, void *buff, size
 			len = a->read_data_remaining;
 			if (len > s)
 				len = s;
-			if (len)
+			if (len) {
 				memcpy(dest, a->read_data_block, len);
-			s -= len;
-			a->read_data_block += len;
-			a->read_data_remaining -= len;
-			a->read_data_output_offset += len;
-			a->read_data_offset += len;
-			dest += len;
-			bytes_read += len;
+				s -= len;
+				a->read_data_block += len;
+				a->read_data_remaining -= len;
+				a->read_data_output_offset += len;
+				a->read_data_offset += len;
+				dest += len;
+				bytes_read += len;
+			}
 		}
 	}
 	a->read_data_is_posix_read = 0;

Modified: stable/12/contrib/libarchive/libarchive/archive_read_open_filename.c
==============================================================================
--- stable/12/contrib/libarchive/libarchive/archive_read_open_filename.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/libarchive/archive_read_open_filename.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -221,7 +221,9 @@ file_open(struct archive *a, void *client_data)
 	struct read_file_data *mine = (struct read_file_data *)client_data;
 	void *buffer;
 	const char *filename = NULL;
+#if defined(_WIN32) && !defined(__CYGWIN__)
 	const wchar_t *wfilename = NULL;
+#endif
 	int fd = -1;
 	int is_disk_like = 0;
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -281,10 +283,12 @@ file_open(struct archive *a, void *client_data)
 #endif
 	}
 	if (fstat(fd, &st) != 0) {
+#if defined(_WIN32) && !defined(__CYGWIN__)
 		if (mine->filename_type == FNT_WCS)
 			archive_set_error(a, errno, "Can't stat '%S'",
 			    wfilename);
 		else
+#endif
 			archive_set_error(a, errno, "Can't stat '%s'",
 			    filename);
 		goto fail;

Modified: stable/12/contrib/libarchive/libarchive/archive_read_support_format_xar.c
==============================================================================
--- stable/12/contrib/libarchive/libarchive/archive_read_support_format_xar.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/libarchive/archive_read_support_format_xar.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -458,6 +458,11 @@ archive_read_support_format_xar(struct archive *_a)
 		return (ARCHIVE_FATAL);
 	}
 
+	/* initialize xar->file_queue */
+	xar->file_queue.allocated = 0;
+	xar->file_queue.used = 0;
+	xar->file_queue.files = NULL;
+
 	r = __archive_read_register_format(a,
 	    xar,
 	    "xar",
@@ -1221,10 +1226,12 @@ heap_add_entry(struct archive_read *a,
 	/* Expand our pending files list as necessary. */
 	if (heap->used >= heap->allocated) {
 		struct xar_file **new_pending_files;
-		int new_size = heap->allocated * 2;
+		int new_size;
 
 		if (heap->allocated < 1024)
 			new_size = 1024;
+		else
+			new_size = heap->allocated * 2;
 		/* Overflow might keep us from growing the list. */
 		if (new_size <= heap->allocated) {
 			archive_set_error(&a->archive,
@@ -1238,9 +1245,11 @@ heap_add_entry(struct archive_read *a,
 			    ENOMEM, "Out of memory");
 			return (ARCHIVE_FATAL);
 		}
-		memcpy(new_pending_files, heap->files,
-		    heap->allocated * sizeof(new_pending_files[0]));
-		free(heap->files);
+		if (heap->allocated) {
+			memcpy(new_pending_files, heap->files,
+			    heap->allocated * sizeof(new_pending_files[0]));
+			free(heap->files);
+		}
 		heap->files = new_pending_files;
 		heap->allocated = new_size;
 	}

Modified: stable/12/contrib/libarchive/libarchive/archive_util.c
==============================================================================
--- stable/12/contrib/libarchive/libarchive/archive_util.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/libarchive/archive_util.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -365,6 +365,7 @@ __archive_mktempx(const char *tmpdir, wchar_t *templat
 		}
 		fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
 		if (fd == -1) {
+			la_dosmaperr(GetLastError());
 			CloseHandle(h);
 			goto exit_tmpfile;
 		} else

Modified: stable/12/contrib/libarchive/libarchive/archive_write_disk_posix.c
==============================================================================
--- stable/12/contrib/libarchive/libarchive/archive_write_disk_posix.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/libarchive/archive_write_disk_posix.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -1856,8 +1856,9 @@ finish_metadata:
 		if (a->tmpname) {
 			if (rename(a->tmpname, a->name) == -1) {
 				archive_set_error(&a->archive, errno,
-				    "rename failed");
-				ret = ARCHIVE_FATAL;
+				    "Failed to rename temporary file");
+				ret = ARCHIVE_FAILED;
+				unlink(a->tmpname);
 			}
 			a->tmpname = NULL;
 		}
@@ -2144,8 +2145,11 @@ restore_entry(struct archive_write_disk *a)
 			if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) &&
 			    S_ISREG(a->st.st_mode)) {
 				/* Use a temporary file to extract */
-				if ((a->fd = la_mktemp(a)) == -1)
+				if ((a->fd = la_mktemp(a)) == -1) {
+					archive_set_error(&a->archive, errno,
+					    "Can't create temporary file");
 					return ARCHIVE_FAILED;
+				}
 				a->pst = NULL;
 				en = 0;
 			} else {

Modified: stable/12/contrib/libarchive/libarchive/archive_write_set_format_xar.c
==============================================================================
--- stable/12/contrib/libarchive/libarchive/archive_write_set_format_xar.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/libarchive/archive_write_set_format_xar.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -681,7 +681,8 @@ xar_write_data(struct archive_write *a, const void *bu
 {
 	struct xar *xar;
 	enum la_zaction run;
-	size_t size, rsize;
+	size_t size = 0;
+	size_t rsize;
 	int r;
 
 	xar = (struct xar *)a->format_data;

Modified: stable/12/contrib/libarchive/libarchive/cpio.5
==============================================================================
--- stable/12/contrib/libarchive/libarchive/cpio.5	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/libarchive/cpio.5	Fri Mar 13 01:05:40 2020	(r358925)
@@ -244,7 +244,7 @@ Note that this format supports only 4 gigabyte files (
 older ASCII format, which supports 8 gigabyte files).
 .Pp
 In this format, hardlinked files are handled by setting the
-filesize to zero for each entry except the last one that
+filesize to zero for each entry except the first one that
 appears in the archive.
 .Ss New CRC Format
 The CRC format is identical to the new ASCII format described

Modified: stable/12/contrib/libarchive/libarchive/test/test_read_format_zip.c
==============================================================================
--- stable/12/contrib/libarchive/libarchive/test/test_read_format_zip.c	Fri Mar 13 00:12:15 2020	(r358924)
+++ stable/12/contrib/libarchive/libarchive/test/test_read_format_zip.c	Fri Mar 13 01:05:40 2020	(r358925)
@@ -916,3 +916,53 @@ DEFINE_TEST(test_read_format_zip_lzma_alone_leak)
 	 * suite under Valgrind or ASan, the test runner won't return with
 	 * exit code 0 in case if a memory leak. */
 }
+
+DEFINE_TEST(test_read_format_zip_lzma_stream_end)
+{
+	const char *refname = "test_read_format_zip_lzma_stream_end.zipx";
+	struct archive *a;
+	struct archive_entry *ae;
+
+	assert((a = archive_read_new()) != NULL);
+		if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
+				skipping("lzma reading not fully supported on this platform");
+				assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+				return;
+		}
+	extract_reference_file(refname);
+
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+	assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a));
+	assertEqualString("vimrc", archive_entry_pathname(ae));
+	assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA));
+	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));
+}
+
+DEFINE_TEST(test_read_format_zip_lzma_stream_end_blockread)
+{
+	const char *refname = "test_read_format_zip_lzma_stream_end.zipx";
+	struct archive *a;
+	struct archive_entry *ae;
+
+	assert((a = archive_read_new()) != NULL);
+	if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
+			skipping("lzma reading not fully supported on this platform");
+			assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+			return;
+	}
+	extract_reference_file(refname);
+
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37));
+	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+	assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a));
+	assertEqualString("vimrc", archive_entry_pathname(ae));
+	assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA));
+	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));
+}

Copied: stable/12/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu (from r358533, head/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/12/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu	Fri Mar 13 01:05:40 2020	(r358925, copy of r358533, head/contrib/libarchive/libarchive/test/test_read_format_zip_lzma_stream_end.zipx.uu)
@@ -0,0 +1,19 @@
+begin 664 test_read_format_zip_lzma_stream_end.zipx
+M4$L#!#\``@`.`#TQD4VJ.XZZ/@(``)`#```%````=FEM<F,)!`4`70``@```
+M$0@$J,)\D;(#4L%<^$P5TO^CM0KI0HWG08B&_].4<,CJ")TW/L>)82Q1PWAL
+M+U`,N0L_$]^&650C/X$D6#4QFD$\A/"_![4!O/5O/!KH`WCQ*4?T2*]4P#/D
+M0'9I?EZG=N69Z0V;H0I=C<!C<J6O^834W097PY1$%=-++.YUA'!>P*$?".I\
+MGMG/80.A'^W>R4J'S/CZ%P`8`>F=R>R&R$2T@EM#X)"OQH1?A7,`:4IU9WV!
+M#2W*DXT',;.4YIN4A:-X)O=IREL201ZSOC=YSAU[C4-::/YV8\)%"L17+>VC
+M%/'B]ZCQN$2(Q*9*\KJZ`Y131`]5C&G';@1S-QES_RZF!2OX45@58+??ES%(
+MUJ<(\`11M$NO)HK#/MK-9RT"15.2I:IZN8<TJR>VTM1_?$G\L#BH67]$S%[4
+M%C-$\Q<+./&HV](4,7)OL-@C^M0F"2O!0N$OHOW54H87^QLBQVH*D%A<#SI%
+M/#+-5U(W';:KC)RE>0Y^5YI!RECQNR"R4.UW9IR!@:B!UB8?_D5$FT8YCJHJ
+M2[2"-&-_D2BJ6#XK[6G=%K"%;'^-+0]FHCY4ER#`^<I-M<!"D:-0H@);U"P"
+MPYX+4#8!&$7\M.+%%MZ:KQ2GX0<]$"P7F^HT)J5JM<$VO9/D[#7KZ\'FITL/
+MYIF"=GO+-L?F[8QS4KC7+=A)1`")V<.8DX629Q;;Y4XA\M-%O&MWC)^)`NO<
+M.J6(5V2UY9"I(C*QKA[Z-GJ<5/_O%<=P4$L!`C\#/P`"``X`/3&13:H[CKH^
+M`@``D`,```4``````````````+2!`````'9I;7)C4$L%!@`````!``$`,P``
+'`&$"````````
+`
+end



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202003130105.02D15eu0033405>