[PATCH] Re: stat_cache and strupper_m()

Andrew Bartlett abartlet at samba.org
Fri Jul 18 10:36:21 GMT 2003


On Thu, Jul 17, 2003 at 10:14:29AM +0000, Andrew Bartlett wrote:
> Jeremy,
> 
> I was looking over our strupper code users again, and in particular
> your changes to the stat cache, to cope with expanding and 
> contracting strings.
> 
> This patch reimplements strdup_upper() to always use 
> convert_string_allocate(), and therefore always expand
> and contract as required.
> 
> (rather than just contractions)
> 
> I've not tested this with anything by ascii, but I wanted to put 
> the idea out for others to look at.  Also, I would note that 
> stat_cache_add() currently asserts that the length of the two
> strings is equal - I think it might need similar work to that
> in stat_cache_lookup().

Thanks to Tim for reminding me to attache it this time...

Andrew Bartlett
-------------- next part --------------
? lib/become_root_dummy.c
Index: smbd/statcache.c
===================================================================
RCS file: /home/cvs/samba/source/smbd/statcache.c,v
retrieving revision 1.13.2.9
diff -u -r1.13.2.9 statcache.c
--- smbd/statcache.c	7 Jul 2003 20:22:35 -0000	1.13.2.9
+++ smbd/statcache.c	17 Jul 2003 09:12:18 -0000
@@ -98,7 +98,12 @@
 		translated_path_length--;
 	}
 
-	original_path = strdup(full_orig_name);
+	if(case_sensitive) {
+		original_path = strdup(full_orig_name);
+	} else {
+		original_path = strdup_upper(full_orig_name);
+	}
+
 	if (!original_path) {
 		SAFE_FREE(translated_path);
 		return;
@@ -111,9 +116,6 @@
 		original_path_length--;
 	}
 
-	if(!case_sensitive)
-		strupper_m(original_path);
-
 	if (original_path_length != translated_path_length) {
 		if (original_path_length < translated_path_length) {
 			DEBUG(0, ("OOPS - tried to store stat cache entry for werid length paths [%s] %u and [%s] %u)!\n",
@@ -161,6 +163,7 @@
 	}
 
 	scp->original_path = scp->names;
+	/* pointer into the structure... */
 	scp->translated_path = scp->names + original_path_length + 1;
 	safe_strcpy(scp->original_path, original_path, original_path_length);
 	safe_strcpy(scp->translated_path, translated_path, translated_path_length);
@@ -194,7 +197,7 @@
 		       char **start, SMB_STRUCT_STAT *pst)
 {
 	stat_cache_entry *scp;
-	pstring chk_name;
+	char *chk_name;
 	size_t namelen;
 	hash_element *hash_elem;
 	char *sp;
@@ -218,10 +221,20 @@
 		return False;
 	}
 
-	pstrcpy(chk_name, name);
+	if (case_sensitive) {
+		chk_name = strdup(name);
+		if (!chk_name) {
+			DEBUG(0, ("stat_cache_lookup: strdup failed!\n"));
+			return False;
+		}
+
+	} else {
+		chk_name = strdup_upper(name);
+		if (!chk_name) {
+			DEBUG(0, ("stat_cache_lookup: strdup_upper failed!\n"));
+			return False;
+		}
 
-	if(!case_sensitive) {
-		strupper_m( chk_name );
 		/*
 		 * In some language encodings the length changes
 		 * if we uppercase. We need to treat this differently
@@ -252,11 +265,13 @@
 				 * We reached the end of the name - no match.
 				 */
 				DO_PROFILE_INC(statcache_misses);
+				SAFE_FREE(chk_name);
 				return False;
 			}
 			if((*chk_name == '\0') || (strcmp(chk_name, ".") == 0)
 					|| (strcmp(chk_name, "..") == 0)) {
 				DO_PROFILE_INC(statcache_misses);
+				SAFE_FREE(chk_name);
 				return False;
 			}
 		} else {
@@ -265,6 +280,7 @@
 			if(SMB_VFS_STAT(conn,scp->translated_path, pst) != 0) {
 				/* Discard this entry - it doesn't exist in the filesystem.  */
 				hash_remove(&stat_cache, hash_elem);
+				SAFE_FREE(chk_name);
 				return False;
 			}
 
@@ -290,6 +306,7 @@
 				++*start;
 
 			pstrcpy(dirpath, scp->translated_path);
+			SAFE_FREE(chk_name);
 			return (namelen == scp->translated_path_length);
 		}
 	}
Index: lib/charcnv.c
===================================================================
RCS file: /home/cvs/samba/source/lib/charcnv.c,v
retrieving revision 1.55.2.28
diff -u -r1.55.2.28 charcnv.c
--- lib/charcnv.c	3 Jul 2003 19:11:28 -0000	1.55.2.28
+++ lib/charcnv.c	17 Jul 2003 09:12:21 -0000
@@ -334,6 +334,35 @@
 	return size;
 }
 
+/**
+ strdup() a unix string to upper case.
+**/
+
+char *strdup_upper(const char *s)
+{
+	size_t size;
+	smb_ucs2_t *buffer;
+	char *out_buffer;
+	
+	size = convert_string_allocate(CH_UNIX, CH_UCS2, s, strlen(s)+1,
+				       (void **) &buffer);
+	if (size == -1) {
+		return NULL;
+	}
+
+	strupper_w(buffer);
+	
+	size = convert_string_allocate(CH_UCS2, CH_UNIX, buffer, size, 
+				       (void **) &out_buffer);
+	SAFE_FREE(buffer);
+
+	if (size == -1) {
+		return NULL;
+	}
+	
+	return out_buffer;
+}
+
 size_t unix_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
 {
 	size_t size;
@@ -353,6 +382,34 @@
 	return size;
 }
 
+/**
+ strdup() a unix string to lower case.
+**/
+
+char *strdup_lower(const char *s)
+{
+	size_t size;
+	smb_ucs2_t *buffer;
+	char *out_buffer;
+	
+	size = convert_string_allocate(CH_UNIX, CH_UCS2, s, strlen(s),
+				       (void **) &buffer);
+	if (size == -1) {
+		return NULL;
+	}
+
+	strlower_w(buffer);
+	
+	size = convert_string_allocate(CH_UCS2, CH_UNIX, buffer, size, 
+				       (void **) &out_buffer);
+	SAFE_FREE(buffer);
+
+	if (size == -1) {
+		return NULL;
+	}
+	
+	return out_buffer;
+}
 
 static size_t ucs2_align(const void *base_ptr, const void *p, int flags)
 {
Index: lib/util_str.c
===================================================================
RCS file: /home/cvs/samba/source/lib/util_str.c,v
retrieving revision 1.47.2.28
diff -u -r1.47.2.28 util_str.c
--- lib/util_str.c	3 Jul 2003 19:11:28 -0000	1.47.2.28
+++ lib/util_str.c	17 Jul 2003 09:12:23 -0000
@@ -1156,21 +1167,6 @@
 }
 
 /**
- Duplicate convert a string to lower case.
-**/
-
-char *strdup_lower(const char *s)
-{
-	char *t = strdup(s);
-	if (t == NULL) {
-		DEBUG(0, ("strdup_lower: Out of memory!\n"));
-		return NULL;
-	}
-	strlower_m(t);
-	return t;
-}
-
-/**
  Convert a string to upper case.
 **/
 
@@ -1192,21 +1188,6 @@
 	/* I assume that lowercased string takes the same number of bytes
 	 * as source string even in multibyte encoding. (VIV) */
 	unix_strupper(s,strlen(s)+1,s,strlen(s)+1);	
-}
-
-/**
- Convert a string to upper case.
-**/
-
-char *strdup_upper(const char *s)
-{
-	char *t = strdup(s);
-	if (t == NULL) {
-		DEBUG(0, ("strdup_upper: Out of memory!\n"));
-		return NULL;
-	}
-	strupper_m(t);
-	return t;
 }
 
 /**


More information about the samba-technical mailing list