cifs-pattern-match-20040921
authorJeffrey Altman <jaltman@mit.edu>
Tue, 21 Sep 2004 21:05:14 +0000 (21:05 +0000)
committerJeffrey Altman <jaltman@secure-endpoints.com>
Tue, 21 Sep 2004 21:05:14 +0000 (21:05 +0000)
The pattern matching algorithm was failing to match strings when the
pattern terminated in a '*'.  The logic was also too complex because
it failed to simply the patterns prior to processing.  Any combination
of '*' and '?' == '*' according to the Windows file name pattern
matching rules.

====================
This delta was composed from multiple commits as part of the CVS->Git migration.
The checkin message with each commit was inconsistent.
The following are the additional commit messages.
====================
FIXES 15365

The pattern matching algorithm was failing to match strings when the
pattern terminated in a '*'.  The logic was also too complex because
it failed to simply the patterns prior to processing.  Any combination
of '*' and '?' == '*' according to the Windows file name pattern
matching rules.

doc/txt/winnotes/afs-changes-since-1.2.txt
doc/txt/winnotes/afs-issues.txt
src/WINNT/afsd/smb3.c

index 2dff4e8..1475bb9 100644 (file)
@@ -1,4 +1,7 @@
 Since 1.3.71:
+  * Fix the pattern matching algorithm to properly match patterns
+    ending with a '*'.
+
   * smb_ReceiveCoreRename() was factored to produce smb_Rename()
     which is used by both the original function and the new
     smb_ReceiveNTRename().  smb_ReceiveNTRename() supports the
index 44ce41f..0d54904 100644 (file)
@@ -196,10 +196,7 @@ List of unfunded projects:
       afsmap.exe <drive> /DELETE
   22. Write-through caching appears to be unsupported.   Files copied to AFS
       do not end up in the local cache.
-  23. The Win32 API CreateHardLink() is not properly supported by the SMB/CIFS
-      server.  It neither returns a valid error nor does it perform the 
-      operation.
-  24. Missing SMB/CIFS functions: 
+  23. Missing SMB/CIFS functions: 
         Find
         FindUnique
         FindClose
@@ -207,7 +204,8 @@ List of unfunded projects:
         WriteBulk       
         WriteBulkData
         Tran2::SessionSetup
+  24. StoreBehind mode is not implemented.  Or more correctly, all data is
+      written directly to the server and is not cached.  Writes invalidate
+      the local cache entries which are then read back from the server.
 
 
-        
-        
index 2468781..b70ae2b 100644 (file)
@@ -3283,40 +3283,41 @@ VOID initUpperCaseTable(VOID)
 // Return value
 // BOOL : TRUE/FALSE (match/mistmatch)
 
-BOOL szWildCardMatchFileName(PSZ pattern, PSZ name) {
-   PSZ pename;         // points to the last 'name' character
-   PSZ p;
-   pename = name + strlen(name) - 1;
-   while (*name) {
-      switch (*pattern) {
-         case '?':
-         case '>':
-            if (*(++pattern) != '<' || *(++pattern) != '*') {
-               if (*name == '.') 
-                   return FALSE;
-               ++name;
-               break;
-            } /* endif */
-         case '<':
+BOOL 
+szWildCardMatchFileName(PSZ pattern, PSZ name) 
+{
+    PSZ pename;         // points to the last 'name' character
+    PSZ p;
+    pename = name + strlen(name) - 1;
+    while (*name) {
+        switch (*pattern) {
+        case '?':
+            if (*name == '.') 
+                return FALSE;
+            ++pattern, ++name;
+            break;
          case '*':
-            while ((*pattern == '<') || (*pattern == '*') || (*pattern == '?') || (*pattern == '>')) 
-                ++pattern;
-            if (!*pattern) 
+            ++pattern;
+            if (*pattern == '\0')
                 return TRUE;
             for (p = pename; p >= name; --p) {
-               if ((mapCaseTable[*p] == mapCaseTable[*pattern]) &&
-                   szWildCardMatchFileName(pattern + 1, p + 1))
-                  return TRUE;
+                if ((mapCaseTable[*p] == mapCaseTable[*pattern]) &&
+                     szWildCardMatchFileName(pattern + 1, p + 1))
+                    return TRUE;
             } /* endfor */
             return FALSE;
-         default:
+        default:
             if (mapCaseTable[*name] != mapCaseTable[*pattern]) 
                 return FALSE;
             ++pattern, ++name;
             break;
       } /* endswitch */
    } /* endwhile */ 
-   return !*pattern;
+
+    if (*pattern == '\0' || *pattern == '*' && *(pattern+1) == '\0')
+        return TRUE;
+    else 
+        return FALSE;
 }
 
 /* do a case-folding search of the star name mask with the name in namep.
@@ -3324,11 +3325,53 @@ BOOL szWildCardMatchFileName(PSZ pattern, PSZ name) {
  */
 int smb_V3MatchMask(char *namep, char *maskp, int flags) 
 {
-       /* make sure we only match 8.3 names, if requested */
-       if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) 
+    char * newmask;
+    int    i, j, star, qmark, retval;
+
+    /* make sure we only match 8.3 names, if requested */
+    if ((flags & CM_FLAG_8DOT3) && !cm_Is8Dot3(namep)) 
         return 0;
-       
-       return szWildCardMatchFileName(maskp, namep) ? 1:0;
+    
+    /* optimize the pattern:
+     * if there is a mixture of '?' and '*',
+     * for example  the sequence "*?*?*?*"
+     * must be turned into the form "*"
+     */
+    newmask = (char *)malloc(strlen(maskp)+1);
+    for ( i=0, j=0, star=0, qmark=0; maskp[i]; i++) {
+        switch ( maskp[i] ) {
+        case '?':
+        case '>':
+            qmark++;
+            break;
+        case '<':
+        case '*':
+            star++;
+            break;
+        default:
+            if ( star ) {
+                newmask[j++] = '*';
+            } else if ( qmark ) {
+                while ( qmark-- )
+                    newmask[j++] = '?';
+            }
+            newmask[j++] = maskp[i];
+            star = 0;
+            qmark = 0;
+        }
+    }
+    if ( star ) {
+        newmask[j++] = '*';
+    } else if ( qmark ) {
+        while ( qmark-- )
+            newmask[j++] = '?';
+    }
+    newmask[j++] = '\0';
+
+    retval = szWildCardMatchFileName(newmask, namep) ? 1:0;
+
+    free(newmask);
+    return retval;
 }
 
 #else /* USE_OLD_MATCHING */