]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
IFC
authorTim Kientzle <kientzle@gmail.com>
Tue, 19 Aug 2008 22:33:06 +0000 (18:33 -0400)
committerTim Kientzle <kientzle@gmail.com>
Tue, 19 Aug 2008 22:33:06 +0000 (18:33 -0400)
SVN-Revision: 182

tar/matching.c
tar/test/test_copy.c
tar/test/test_option_T.c
tar/test/test_patterns.c
tar/test/test_patterns.tgz.err.uu [new file with mode: 0644]
tar/test/test_patterns.tgz.out.uu [new file with mode: 0644]
tar/test/test_patterns.tgz.uu [new file with mode: 0644]

index 952055fe8a234e567ee6fdb863b1a0aa9126a245..b1031f2878b33ba04c45529ec399584a19e381d9 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "bsdtar_platform.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/matching.c,v 1.13 2008/05/26 17:10:10 kientzle Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/tar/matching.c,v 1.16 2008/08/18 18:13:40 kientzle Exp $");
 
 #ifdef HAVE_ERRNO_H
 #include <errno.h>
@@ -59,6 +59,7 @@ static int    bsdtar_fnmatch(const char *p, const char *s);
 static void    initialize_matching(struct bsdtar *);
 static int     match_exclusion(struct match *, const char *pathname);
 static int     match_inclusion(struct match *, const char *pathname);
+static int     pathmatch(const char *p, const char *s);
 
 /*
  * The matching logic here needs to be re-thought.  I started out to
@@ -118,8 +119,6 @@ add_pattern(struct bsdtar *bsdtar, struct match **list, const char *pattern)
        match = malloc(sizeof(*match) + strlen(pattern) + 1);
        if (match == NULL)
                bsdtar_errc(bsdtar, 1, errno, "Out of memory");
-       if (pattern[0] == '/')
-               pattern++;
        strcpy(match->pattern, pattern);
        /* Both "foo/" and "foo" should match "foo/bar". */
        if (match->pattern[strlen(match->pattern)-1] == '/')
@@ -195,12 +194,12 @@ match_exclusion(struct match *match, const char *pathname)
        const char *p;
 
        if (*match->pattern == '*' || *match->pattern == '/')
-               return (bsdtar_fnmatch(match->pattern, pathname) == 0);
+               return (pathmatch(match->pattern, pathname) == 0);
 
        for (p = pathname; p != NULL; p = strchr(p, '/')) {
                if (*p == '/')
                        p++;
-               if (bsdtar_fnmatch(match->pattern, p) == 0)
+               if (pathmatch(match->pattern, p) == 0)
                        return (1);
        }
        return (0);
@@ -213,7 +212,7 @@ match_exclusion(struct match *match, const char *pathname)
 int
 match_inclusion(struct match *match, const char *pathname)
 {
-       return (bsdtar_fnmatch(match->pattern, pathname) == 0);
+       return (pathmatch(match->pattern, pathname) == 0);
 }
 
 void
@@ -281,6 +280,41 @@ unmatched_inclusions_warn(struct bsdtar *bsdtar, const char *msg)
        return (matching->inclusions_unmatched_count);
 }
 
+/*
+ * TODO: Extend this so that the following matches work:
+ *     "foo//bar" == "foo/bar"
+ *     "foo/./bar" == "foo/bar"
+ *     "./foo" == "foo"
+ *
+ * The POSIX fnmatch() function doesn't handle any of these, but
+ * all are common situations that arise when paths are generated within
+ * large scripts.  E.g., the following is quite common:
+ *      MYPATH=foo/  TARGET=$MYPATH/bar
+ * It may be worthwhile to edit such paths at write time as well,
+ * especially when such editing may avoid the need for long pathname
+ * extensions.
+ */
+static int
+pathmatch(const char *pattern, const char *string)
+{
+       /*
+        * Strip leading "./" or ".//" so that, e.g.,
+        * "foo" matches "./foo".  In particular, this
+        * opens up an optimization for the writer to
+        * elide leading "./".
+        */
+       if (pattern[0] == '.' && pattern[1] == '/') {
+               pattern += 2;
+               while (pattern[0] == '/')
+                       ++pattern;
+       }
+       if (string[0] == '.' && string[1] == '/') {
+               string += 2;
+               while (string[0] == '/')
+                       ++string;
+       }
+       return (bsdtar_fnmatch(pattern, string));
+}
 
 
 #if defined(HAVE_FNMATCH) && defined(HAVE_FNM_LEADING_DIR)
index b2eef8cf791e36e15f772d54641ea6efcb8fee2e..a64f2c88671fb70feef2225c827c1a75d1fac1f9 100644 (file)
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_copy.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_copy.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $");
 
 static void
 create_tree(void)
@@ -196,6 +196,9 @@ verify_tree(int limit)
                char dir[2];
                dir[0] = *dp; dir[1] = '\0';
                d = opendir(dir);
+               failure("Unable to open dir '%s'", dir);
+               if (!assert(d != NULL))
+                       continue;
                while ((de = readdir(d)) != NULL) {
                        p = de->d_name;
                        switch(dp[0]) {
index 6c9007b24a90e32fb993d3ed61768f7f016d0ef2..e0a220b0522c9f6da45dee2ef8212dc75dd5ecfa 100644 (file)
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_option_T.c,v 1.2 2008/05/26 17:10:10 kientzle Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_option_T.c,v 1.3 2008/08/15 06:12:02 kientzle Exp $");
 
 static int
 touch(const char *fn)
@@ -40,6 +40,7 @@ touch(const char *fn)
 DEFINE_TEST(test_option_T)
 {
        FILE *f;
+       int r;
 
        /* Create a simple dir heirarchy; bail if anything fails. */
        if (!assertEqualInt(0, mkdir("d1", 0755))) return;
@@ -67,8 +68,10 @@ DEFINE_TEST(test_option_T)
        fclose(f);
 
        /* Use -c -T to archive up the files. */
-       systemf("%s -c -f test1.tar -T filelist > test1.out 2> test1.err",
+       r = systemf("%s -c -f test1.tar -T filelist > test1.out 2> test1.err",
            testprog);
+       failure("Failure here probably means that tar can't archive zero-length files without reading them");
+       assert(r == 0);
        assertEmptyFile("test1.out");
        assertEmptyFile("test1.err");
 
index e7b1679fd9d0372da2d606efd58503e38a742a17..b3e61d75ab7fb53fc09c0952e3475d528846113d 100644 (file)
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include "test.h"
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: src/usr.bin/tar/test/test_patterns.c,v 1.2 2008/08/15 06:12:02 kientzle Exp $");
 
 DEFINE_TEST(test_patterns)
 {
        int fd, r;
+       const char *reffile1 = "test_patterns.tgz";
+       const char *reffile1_out = "test_patterns.tgz.out";
+       const char *reffile1_err = "test_patterns.tgz.err";
 
        /*
         * Test basic command-line pattern handling.
@@ -44,4 +47,14 @@ DEFINE_TEST(test_patterns)
        r = systemf("%s zxfv tar1.tgz foo bar > tar1b.out 2> tar1b.err", testprog);
        failure("tar should return non-zero because a file was given on the command line that's not in the archive");
        assert(r != 0);
+
+       extract_reference_file(reffile1);
+       extract_reference_file(reffile1_out);
+       extract_reference_file(reffile1_err);
+
+       r = systemf("%s tf %s /tmp/foo/bar > tar2a.out 2> tar2a.err",
+           testprog, reffile1);
+       assertEqualInt(r, 0);
+       assertEqualFile("tar2a.out", reffile1_out);
+       assertEqualFile("tar2a.err", reffile1_err);
 }
diff --git a/tar/test/test_patterns.tgz.err.uu b/tar/test/test_patterns.tgz.err.uu
new file mode 100644 (file)
index 0000000..258082a
--- /dev/null
@@ -0,0 +1,6 @@
+$FreeBSD: src/usr.bin/tar/test/test_patterns.tgz.err.uu,v 1.1 2008/08/15 06:12:02 kientzle Exp $
+begin 644 test_patterns.tgz.err
+M8G-D=&%R.B!296UO=FEN9R!L96%D:6YG("<O)R!F<F]M(&UE;6)E<B!N86UE
+"<PH`
+`
+end
diff --git a/tar/test/test_patterns.tgz.out.uu b/tar/test/test_patterns.tgz.out.uu
new file mode 100644 (file)
index 0000000..07cc1a5
--- /dev/null
@@ -0,0 +1,5 @@
+$FreeBSD: src/usr.bin/tar/test/test_patterns.tgz.out.uu,v 1.1 2008/08/15 06:12:02 kientzle Exp $
+begin 644 test_patterns.tgz.out
+==&UP+V9O;R]B87(O"G1M<"]F;V\O8F%R+V)A>@H`
+`
+end
diff --git a/tar/test/test_patterns.tgz.uu b/tar/test/test_patterns.tgz.uu
new file mode 100644 (file)
index 0000000..1171e58
--- /dev/null
@@ -0,0 +1,9 @@
+$FreeBSD: src/usr.bin/tar/test/test_patterns.tgz.uu,v 1.1 2008/08/15 06:12:02 kientzle Exp $
+begin 644 test_patterns.tgz
+M'XL(`,P5I4@``^W3T0J",!3&<1]E;[!SYC:?Q\`H2`PS@IZ^F5AV(PFMJ__O
+MYB@;>.:W8X?V;/==9XM\1*0*P:2J59"QCN8ZO:A*4*<NAFA$G?=:F)"QIY?K
+M9:C[U,IP;%?WW0Y-<UI9_SR4^6F/&=DY_UW=Y[H#V_(O4_ZE$T?^_[#(_Y[K
+M&^E_1.^WS'^9'@HCN1I:(O_W_&>Z`]OR?\Y_C!7Y`P``````````````?.,!
+(*>E$>P`H````
+`
+end