Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Apr 2010 18:44:42 +0000 (UTC)
From:      Tim Kientzle <kientzle@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r206487 - head/usr.bin/tar
Message-ID:  <201004111844.o3BIigLU079853@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kientzle
Date: Sun Apr 11 18:44:42 2010
New Revision: 206487
URL: http://svn.freebsd.org/changeset/base/206487

Log:
  If a file is specifically both included and excluded, then:
   * It is not extracted (because it is excluded)
   * If it's not present in the archive, then an error is
     reported (because the file was requested and not found)
   * If it is present in the archive, no error is reported.
  Previously, this would always report an error because the
  exclusion prevented the entry from matching the inclusion.
  
  Also, tar is now more reluctant to report unmatched inclusions.
  Previously, "tar x file1 'file*'" against an archive that contained a
  single entry "file1" would match file1 and then report an error for
  the second pattern because it wasn't matched.  It now considers both
  inclusions to be matched and reports no error.

Modified:
  head/usr.bin/tar/matching.c

Modified: head/usr.bin/tar/matching.c
==============================================================================
--- head/usr.bin/tar/matching.c	Sun Apr 11 18:41:31 2010	(r206486)
+++ head/usr.bin/tar/matching.c	Sun Apr 11 18:44:42 2010	(r206487)
@@ -156,40 +156,41 @@ lafe_excluded(struct lafe_matching *matc
 	if (matching == NULL)
 		return (0);
 
+	/* Mark off any unmatched inclusions. */
+	/* In particular, if a filename does appear in the archive and
+	 * is explicitly included and excluded, then we don't report
+	 * it as missing even though we don't extract it.
+	 */
+	matched = NULL;
+	for (match = matching->inclusions; match != NULL; match = match->next){
+		if (match->matches == 0
+		    && match_inclusion(match, pathname)) {
+			matching->inclusions_unmatched_count--;
+			match->matches++;
+			matched = match;
+		}
+	}
+
 	/* Exclusions take priority */
 	for (match = matching->exclusions; match != NULL; match = match->next){
 		if (match_exclusion(match, pathname))
 			return (1);
 	}
 
-	/* Then check for inclusions */
-	matched = NULL;
+	/* It's not excluded and we found an inclusion above, so it's included. */
+	if (matched != NULL)
+		return (0);
+
+
+	/* We didn't find an unmatched inclusion, check the remaining ones. */
 	for (match = matching->inclusions; match != NULL; match = match->next){
-		if (match_inclusion(match, pathname)) {
-			/*
-			 * If this pattern has never been matched,
-			 * then we're done.
-			 */
-			if (match->matches == 0) {
-				match->matches++;
-				matching->inclusions_unmatched_count--;
-				return (0);
-			}
-			/*
-			 * Otherwise, remember the match but keep checking
-			 * in case we can tick off an unmatched pattern.
-			 */
-			matched = match;
+		/* We looked at previously-unmatched inclusions already. */
+		if (match->matches > 0
+		    && match_inclusion(match, pathname)) {
+			match->matches++;
+			return (0);
 		}
 	}
-	/*
-	 * We didn't find a pattern that had never been matched, but
-	 * we did find a match, so count it and exit.
-	 */
-	if (matched != NULL) {
-		matched->matches++;
-		return (0);
-	}
 
 	/* If there were inclusions, default is to exclude. */
 	if (matching->inclusions != NULL)



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