summaryrefslogtreecommitdiffstats
path: root/usr.bin/cpio/pathmatch.c
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2009-04-17 04:04:57 +0000
committerkientzle <kientzle@FreeBSD.org>2009-04-17 04:04:57 +0000
commit5853643ce6ecab17fd51492c41fe5a44599637b2 (patch)
tree71b1033c9249ea051e5e93acaad8389233a40909 /usr.bin/cpio/pathmatch.c
parent4e8cb50d8bef897f785cb884230eb42be06c0541 (diff)
downloadFreeBSD-src-5853643ce6ecab17fd51492c41fe5a44599637b2.zip
FreeBSD-src-5853643ce6ecab17fd51492c41fe5a44599637b2.tar.gz
Merge from libarchive.googlecode.com:
* Lots of new tests. * New -n / --numeric-uid-gid option * More sanity-checking of arguments * Various Windows portability improvements * Sync up version number to 2.7.0
Diffstat (limited to 'usr.bin/cpio/pathmatch.c')
-rw-r--r--usr.bin/cpio/pathmatch.c65
1 files changed, 32 insertions, 33 deletions
diff --git a/usr.bin/cpio/pathmatch.c b/usr.bin/cpio/pathmatch.c
index d33bd34..40fa836 100644
--- a/usr.bin/cpio/pathmatch.c
+++ b/usr.bin/cpio/pathmatch.c
@@ -101,11 +101,10 @@ pm_list(const char *start, const char *end, const char c, int flags)
*/
static const char *
pm_slashskip(const char *s) {
- while (*s == '.' || *s == '/') {
- if (s[0] != '/' && s[1] != '/')
- break;
+ while ((*s == '/')
+ || (s[0] == '.' && s[1] == '/')
+ || (s[0] == '.' && s[1] == '\0'))
++s;
- }
return (s);
}
@@ -130,8 +129,6 @@ pm(const char *p, const char *s, int flags)
return (1);
/* "dir" == "dir/" == "dir/." */
s = pm_slashskip(s);
- if (s[0] == '.' && s[1] == '\0')
- return (1);
}
return (*s == '\0');
break;
@@ -176,19 +173,6 @@ pm(const char *p, const char *s, int flags)
if (*p != *s)
return (0);
break;
- default:
- if (*p == *s)
- break;
- if ((*s == '\0') && (*p == '/')) {
- p = pm_slashskip(p);
- if (*p == '\0')
- return (1);
- if (p[0] == '.' && p[1] == '\0')
- return (1);
- return (0);
- }
- return (0);
- break;
case '\\':
/* Trailing '\\' matches itself. */
if (p[1] == '\0') {
@@ -200,19 +184,34 @@ pm(const char *p, const char *s, int flags)
return (0);
}
break;
- }
- /*
- * TODO: pattern of "\/\.\/" should not match plain "/",
- * it should only match explicit "/./".
- */
- if (*p == '/')
+ case '/':
+ if (*s != '/' && *s != '\0')
+ return (0);
+ /* Note: pattern "/\./" won't match "/";
+ * pm_slashskip() correctly stops at backslash. */
p = pm_slashskip(p);
- else
- ++p;
- if (*s == '/')
s = pm_slashskip(s);
- else
- ++s;
+ if (*p == '\0' && (flags & PATHMATCH_NO_ANCHOR_END))
+ return (1);
+ --p; /* Counteract the increment below. */
+ --s;
+ break;
+ case '$':
+ /* '$' is special only at end of pattern and only
+ * if PATHMATCH_NO_ANCHOR_END is specified. */
+ if (p[1] == '\0' && (flags & PATHMATCH_NO_ANCHOR_END)){
+ /* "dir" == "dir/" == "dir/." */
+ return (*pm_slashskip(s) == '\0');
+ }
+ /* Otherwise, '$' is not special. */
+ /* FALL THROUGH */
+ default:
+ if (*p != *s)
+ return (0);
+ break;
+ }
+ ++p;
+ ++s;
}
}
@@ -236,9 +235,9 @@ pathmatch(const char *p, const char *s, int flags)
/* If start is unanchored, try to match start of each path element. */
if (flags & PATHMATCH_NO_ANCHOR_START) {
- for ( ; p != NULL; p = strchr(p, '/')) {
- if (*p == '/')
- p++;
+ for ( ; s != NULL; s = strchr(s, '/')) {
+ if (*s == '/')
+ s++;
if (pm(p, s, flags))
return (1);
}
OpenPOWER on IntegriCloud