[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