Only in samba-3.0.7/source: build-samba
Only in samba-3.0.7/source/include: build_env.h
Only in samba-3.0.7/source/include: stamp-h
diff -uBbr --exclude-from=../../../samba-cvs/diff.excludes samba-3.0.7-orig/source/lib/ms_fnmatch.c samba-3.0.7/source/lib/ms_fnmatch.c
--- samba-3.0.7-orig/source/lib/ms_fnmatch.c	2004-04-04 01:37:34.000000000 -0600
+++ samba-3.0.7/source/lib/ms_fnmatch.c	2004-10-25 16:04:59.000000000 -0500
@@ -1,7 +1,7 @@
 /* 
    Unix SMB/CIFS implementation.
    filename matching routine
-   Copyright (C) Andrew Tridgell 1992-1998 
+   Copyright (C) Andrew Tridgell 1992-2004
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -15,229 +15,197 @@
    
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+*/
 
 /*
    This module was originally based on fnmatch.c copyright by the Free
-   Software Foundation. It bears little resemblence to that code now 
+   Software Foundation. It bears little (if any) resemblence to that
+   code now
 */  
 
 
-#if FNMATCH_TEST
-#include <stdio.h>
-#include <stdlib.h>
-#else
 #include "includes.h"
-#endif
+
+static int null_match(const smb_ucs2_t *p)
+{
+	for (;*p;p++) {
+		if (*p != UCS2_CHAR('*') &&
+		    *p != UCS2_CHAR('<') &&
+		    *p != UCS2_CHAR('"') &&
+		    *p != UCS2_CHAR('>')) return -1;
+	}
+	return 0;
+}
+
+/*
+  the max_n structure is purely for efficiency, it doesn't contribute
+  to the matching algorithm except by ensuring that the algorithm does
+  not grow exponentially
+*/
+struct max_n {
+	const smb_ucs2_t *predot;
+	const smb_ucs2_t *postdot;
+};
+
 
 /* 
-   bugger. we need a separate wildcard routine for older versions
-   of the protocol. This is not yet perfect, but its a lot
-   better than what we had */
-static int ms_fnmatch_lanman_core(const smb_ucs2_t *pattern, 
-				  const smb_ucs2_t *string,
-				  BOOL case_sensitive)
+  p and n are the pattern and string being matched. The max_n array is
+  an optimisation only. The ldot pointer is NULL if the string does
+  not contain a '.', otherwise it points at the last dot in 'n'.
+*/
+static int ms_fnmatch_core(const smb_ucs2_t *p, const smb_ucs2_t *n, 
+			   struct max_n *max_n, const smb_ucs2_t *ldot,
+			   BOOL is_case_sensitive)
 {
-	const smb_ucs2_t *p = pattern, *n = string;
 	smb_ucs2_t c;
-
-	if (strcmp_wa(p, "?")==0 && strcmp_wa(n, ".")) goto match;
+	int i;
 
 	while ((c = *p++)) {
 		switch (c) {
-		case UCS2_CHAR('.'):
-			if (! *n) goto next;
-			if (*n != UCS2_CHAR('.')) goto nomatch;
-			n++;
-			break;
-
-		case UCS2_CHAR('?'):
-			if (! *n) goto next;
-			if ((*n == UCS2_CHAR('.') && 
-			     n[1] != UCS2_CHAR('.')) || ! *n) 
-				goto next;
-			n++;
-			break;
-
-		case UCS2_CHAR('>'):
-			if (! *n) goto next;
-			if (n[0] == UCS2_CHAR('.')) {
-				if (! n[1] && ms_fnmatch_lanman_core(p, n+1, case_sensitive) == 0) goto match;
-				if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
-				goto nomatch;
-			}
-			n++;
-			break;
-
+			/* a '*' matches zero or more characters of any type */
 		case UCS2_CHAR('*'):
-			if (! *n) goto next;
-			if (! *p) goto match;
-			for (; *n; n++) {
-				if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
+			if (max_n->predot && max_n->predot <= n) {
+				return null_match(p);
 			}
-			break;
-
-		case UCS2_CHAR('<'):
-			for (; *n; n++) {
-				if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
-				if (*n == UCS2_CHAR('.') && 
-				    !strchr_w(n+1,UCS2_CHAR('.'))) {
-					n++;
-					break;
+			for (i=0; n[i]; i++) {
+				if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) {
+					return 0;
 				}
 			}
-			break;
-
-		case UCS2_CHAR('"'):
-			if (*n == 0 && ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
-			if (*n != UCS2_CHAR('.')) goto nomatch;
-			n++;
-			break;
+			if (!max_n->predot || max_n->predot > n) max_n->predot = n;
+			return null_match(p);
 
-		default:
-			if (case_sensitive) {
-				if (c != *n) goto nomatch;
-			} else {
-				if (tolower_w(c) != tolower_w(*n)) goto nomatch;
-			}
-			n++;
-		}
+			/* a '<' matches zero or more characters of
+			   any type, but stops matching at the last
+			   '.' in the string. */
+		case UCS2_CHAR('<'):
+			if (max_n->predot && max_n->predot <= n) {
+				return null_match(p);
 	}
-	
-	if (! *n) goto match;
-	
- nomatch:
-	/*
-	if (verbose) printf("NOMATCH pattern=[%s] string=[%s]\n", pattern, string);
-	*/
+			if (max_n->postdot && max_n->postdot <= n && n <= ldot) {
 	return -1;
-
-next:
-	if (ms_fnmatch_lanman_core(p, n, case_sensitive) == 0) goto match;
-        goto nomatch;
-
- match:
-	/*
-	if (verbose) printf("MATCH   pattern=[%s] string=[%s]\n", pattern, string);
-	*/
-	return 0;
-}
-
-static int ms_fnmatch_lanman1(const smb_ucs2_t *pattern, 
-			      const smb_ucs2_t *string, BOOL case_sensitive)
-{
-	if (!strpbrk_wa(pattern, "?*<>\"")) {
-		smb_ucs2_t s[] = {UCS2_CHAR('.'), 0};
-		if (strcmp_wa(string,"..") == 0) string = s;
-		return strcasecmp_w(pattern, string);
 	}
-
-	if (strcmp_wa(string,"..") == 0 || strcmp_wa(string,".") == 0) {
-		smb_ucs2_t dot[] = {UCS2_CHAR('.'), 0};
-		smb_ucs2_t dotdot[] = {UCS2_CHAR('.'), UCS2_CHAR('.'), 0};
-		return ms_fnmatch_lanman_core(pattern, dotdot, case_sensitive) &&
-			ms_fnmatch_lanman_core(pattern, dot, case_sensitive);
+			for (i=0; n[i]; i++) {
+				if (ms_fnmatch_core(p, n+i, max_n+1, ldot, is_case_sensitive) == 0) return 0;
+				if (n+i == ldot) {
+					if (ms_fnmatch_core(p, n+i+1, max_n+1, ldot, is_case_sensitive) == 0) return 0;
+					if (!max_n->postdot || max_n->postdot > n) max_n->postdot = n;
+					return -1;
 	}
-
-	return ms_fnmatch_lanman_core(pattern, string, case_sensitive);
-}
-
-
-/* the following function was derived using the masktest utility -
-   after years of effort we finally have a perfect MS wildcard
-   matching routine! 
-
-   NOTE: this matches only filenames with no directory component
-
-   Returns 0 on match, -1 on fail.
-*/
-static int ms_fnmatch_w(const smb_ucs2_t *pattern, const smb_ucs2_t *string, 
-			int protocol, BOOL case_sensitive)
-{
-	const smb_ucs2_t *p = pattern, *n = string;
-	smb_ucs2_t c;
-
-	if (protocol <= PROTOCOL_LANMAN2) {
-		return ms_fnmatch_lanman1(pattern, string, case_sensitive);
 	}
+			if (!max_n->predot || max_n->predot > n) max_n->predot = n;
+			return null_match(p);
 
-	while ((c = *p++)) {
-		switch (c) {
+			/* a '?' matches any single character */
 		case UCS2_CHAR('?'):
-			if (! *n) return -1;
+			if (! *n) {
+				return -1;
+			}
 			n++;
 			break;
 
+			/* a '?' matches any single character */
 		case UCS2_CHAR('>'):
 			if (n[0] == UCS2_CHAR('.')) {
-				if (! n[1] && ms_fnmatch_w(p, n+1, protocol, case_sensitive) == 0) return 0;
-				if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
-				return -1;
+				if (! n[1] && null_match(p) == 0) {
+					return 0;
 			}
-			if (! *n) return ms_fnmatch_w(p, n, protocol, case_sensitive);
-			n++;
 			break;
-
-		case UCS2_CHAR('*'):
-			for (; *n; n++) {
-				if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
 			}
-			break;
-
-		case UCS2_CHAR('<'):
-			for (; *n; n++) {
-				if (ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
-				if (*n == UCS2_CHAR('.') && !strchr_wa(n+1,'.')) {
+			if (! *n) return null_match(p);
 					n++;
 					break;
-				}
-			}
-			break;
 
 		case UCS2_CHAR('"'):
-			if (*n == 0 && ms_fnmatch_w(p, n, protocol, case_sensitive) == 0) return 0;
+			if (*n == 0 && null_match(p) == 0) {
+				return 0;
+			}
 			if (*n != UCS2_CHAR('.')) return -1;
 			n++;
 			break;
 
 		default:
-			if (case_sensitive) {
-				if (c != *n) return -1;
-			} else {
-				if (tolower_w(c) != tolower_w(*n)) return -1;
+			if (c != *n) {
+				if (is_case_sensitive) {
+					return -1;
+				}
+				if (toupper_w(c) != toupper_w(*n)) {
+					return -1;
+				}
 			}
 			n++;
+			break;
 		}
 	}
 	
-	if (! *n) return 0;
+	if (! *n) {
+		return 0;
+	}
 	
 	return -1;
 }
 
-int ms_fnmatch(const char *pattern, const char *string, int protocol, 
-	       BOOL case_senstive)
+int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol, 
+	       BOOL is_case_sensitive)
 {
-	wpstring buffer_pattern, buffer_string;
-	int ret;
-	size_t size;
+	wpstring p, s;
+	int ret, count, i;
+	struct max_n *max_n = NULL;
+
+	if (strcmp(string, "..") == 0) {
+		string = ".";
+	}
 
-	size = push_ucs2(NULL, buffer_pattern, pattern, sizeof(buffer_pattern), STR_TERMINATE);
-	if (size == (size_t)-1) {
-		return -1;
-		/* Not quite the right answer, but finding the right one
-		   under this failure case is expensive, and it's pretty close */
+	if (strpbrk(pattern, "<>*?\"") == NULL) {
+		/* this is not just an optmisation - it is essential
+		   for LANMAN1 correctness */
+		if (is_case_sensitive) {
+			return strcmp(pattern, string);
+		} else {
+			return StrCaseCmp(pattern, string);
+		}
 	}
 	
-	size = push_ucs2(NULL, buffer_string, string, sizeof(buffer_string), STR_TERMINATE);
-	if (size == (size_t)-1) {
+	pstrcpy_wa(p, pattern);
+	pstrcpy_wa(s, string);
+
+	if (protocol <= PROTOCOL_LANMAN2) {
+		/*
+		  for older negotiated protocols it is possible to
+		  translate the pattern to produce a "new style"
+		  pattern that exactly matches w2k behaviour
+		*/
+		for (i=0;p[i];i++) {
+			if (p[i] == UCS2_CHAR('?')) {
+				p[i] = UCS2_CHAR('>');
+			} else if (p[i] == UCS2_CHAR('.') && 
+				   (p[i+1] == UCS2_CHAR('?') || 
+				    p[i+1] == UCS2_CHAR('*') ||
+				    p[i+1] == 0)) {
+				p[i] = UCS2_CHAR('"');
+			} else if (p[i] == UCS2_CHAR('*') && p[i+1] == UCS2_CHAR('.')) {
+				p[i] = UCS2_CHAR('<');
+			}
+		}
+	}
+
+	for (count=i=0;p[i];i++) {
+		if (p[i] == UCS2_CHAR('*') || p[i] == UCS2_CHAR('<')) count++;
+	}
+
+	if (count != 0) {
+		max_n = calloc(sizeof(struct max_n), count);
+		if (!max_n) {
 		return -1;
-		/* Not quite the right answer, but finding the right one
-		   under this failure case is expensive, and it's pretty close */
+		}
 	}
 
-	ret = ms_fnmatch_w(buffer_pattern, buffer_string, protocol, case_senstive);
- 	DEBUG(10,("ms_fnmatch(%s,%s) -> %d\n", pattern, string, ret));
+	ret = ms_fnmatch_core(p, s, max_n, strrchr_w(s, UCS2_CHAR('.')), is_case_sensitive);
+
+	if (max_n) {
+		free(max_n);
+	}
 
 	return ret;
 }
@@ -245,5 +214,5 @@
 /* a generic fnmatch function - uses for non-CIFS pattern matching */
 int gen_fnmatch(const char *pattern, const char *string)
 {
-	return ms_fnmatch(pattern, string, PROTOCOL_NT1, True);
+	return ms_fnmatch(pattern, string, PROTOCOL_NT1, False);
 }
Only in samba-3.0.7/source/script: gen-8bit-gap.sh
Only in samba-3.0.7/source: smbadduser