Re: bsdtar breakage on 5.3-BETA2

From: Tim Kientzle <kientzle_at_freebsd.org>
Date: Sat, 04 Sep 2004 14:22:25 -0700
Will Froning wrote:
> 
> On a FBSD4.10 box I have created a tar file of a users home directory
> and then copied it over to a 5.3-BETA2 box (MD5 checksums match).
>
 > [ ... file with long name gets reported as a dir instead of regular 
file ....]
 >

Good catch!  The code for handling certain
very old tar archives was getting confused
by the long filename extensions.

The attached patch fixes it for me.
If you have a chance, apply it to
src/lib/libarchive and then rebuild
both libarchive and src/usr.bin/tar and
let me know if this fixes it for you as well.

Tim

--- libarchive-current/archive_read_support_format_tar.c	Wed Aug 25 20:25:58 2004
+++ libarchive/archive_read_support_format_tar.c	Sat Sep  4 13:59:40 2004
_at__at_ -351,12 +351,33 _at__at_
 {
 	struct stat st;
 	struct tar *tar;
+	const char *p;
+	int r;
+	size_t l;
 
 	memset(&st, 0, sizeof(st));
 	tar = *(a->pformat_data);
 	tar->entry_offset = 0;
 
-	return (tar_read_header(a, tar, entry, &st));
+	r = tar_read_header(a, tar, entry, &st);
+
+	if (r == ARCHIVE_OK) {
+		/*
+		 * "Regular" entry with trailing '/' is really
+		 * directory: This is needed for certain old tar
+		 * variants and even for some broken newer ones.
+		 */
+		p = archive_entry_pathname(entry);
+		l = strlen(p);
+		if (S_ISREG(st.st_mode) && p[l-1] == '/') {
+			st.st_mode &= ~S_IFMT;
+			st.st_mode |= S_IFDIR;
+		}
+
+		/* Copy the final stat data into the entry. */
+		archive_entry_copy_stat(entry, &st);
+	}
+	return (r);
 }
 
 static int
_at__at_ -421,8 +442,6 _at__at_
 	ssize_t bytes;
 	int err;
 	const void *h;
-	const char *p;
-	size_t l;
 	const struct archive_entry_header_ustar *header;
 
 	/* Read 512-byte header record */
_at__at_ -513,17 +532,9 _at__at_
 			a->archive_format_name = "tar (non-POSIX)";
 			err = header_old_tar(a, tar, entry, st, h);
 		}
-
-		/* "Regular" entry with trailing '/' is really directory. */
-		p = archive_entry_pathname(entry);
-		l = strlen(p);
-		if (S_ISREG(st->st_mode) && p[l-1] == '/') {
-			st->st_mode &= ~S_IFMT;
-			st->st_mode |= S_IFDIR;
-		}
 	}
-	archive_entry_copy_stat(entry, st);
 	--tar->header_recursion_depth;
+
 	return (err);
 }
 
Received on Sat Sep 04 2004 - 19:22:29 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:10 UTC