summaryrefslogtreecommitdiffstats
path: root/source/lib/util_str.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/lib/util_str.c')
-rw-r--r--source/lib/util_str.c957
1 files changed, 696 insertions, 261 deletions
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index 3a77098e09c..32e2c40a7b4 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -1,8 +1,8 @@
/*
Unix SMB/Netbios implementation.
- Version 3.0
+ Version 1.9.
Samba utility functions
- Copyright (C) Andrew Tridgell 1992-2001
+ Copyright (C) Andrew Tridgell 1992-1998
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
@@ -21,6 +21,15 @@
#include "includes.h"
+extern int DEBUGLEVEL;
+
+static char *last_ptr=NULL;
+
+void set_first_token(char *ptr)
+{
+ last_ptr = ptr;
+}
+
/****************************************************************************
Get the next token from a string, return False if none found
handles double-quotes.
@@ -29,112 +38,151 @@ Extensively modified by Andrew.Tridgell@anu.edu.au
****************************************************************************/
BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
{
- char *s;
- BOOL quoted;
- size_t len=1;
-
- if (!ptr) return(False);
-
- s = *ptr;
-
- /* default to simple separators */
- if (!sep) sep = " \t\n\r";
+ char *s;
+ BOOL quoted;
+ size_t len=1;
- /* find the first non sep char */
- while (*s && strchr_m(sep,*s)) s++;
-
- /* nothing left? */
- if (! *s) return(False);
-
- /* copy over the token */
- for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
- if (*s == '\"') {
- quoted = !quoted;
- } else {
- len++;
- *buff++ = *s;
- }
- }
-
- *ptr = (*s) ? s+1 : s;
- *buff = 0;
-
- return(True);
-}
+ if (!ptr) ptr = &last_ptr;
+ if (!ptr) return(False);
+ s = *ptr;
+ /* default to simple separators */
+ if (!sep) sep = " \t\n\r";
-/****************************************************************************
-This is like next_token but is not re-entrant and "remembers" the first
-parameter so you can pass NULL. This is useful for user interface code
-but beware the fact that it is not re-entrant!
-****************************************************************************/
-static char *last_ptr=NULL;
+ /* find the first non sep char */
+ while(*s && strchr(sep,*s)) s++;
-BOOL next_token_nr(char **ptr,char *buff,char *sep, size_t bufsize)
-{
- BOOL ret;
- if (!ptr) ptr = &last_ptr;
+ /* nothing left? */
+ if (! *s) return(False);
- ret = next_token(ptr, buff, sep, bufsize);
- last_ptr = *ptr;
- return ret;
-}
+ /* copy over the token */
+ for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
+ {
+ if (*s == '\"') {
+ quoted = !quoted;
+ } else {
+ len++;
+ *buff++ = *s;
+ }
+ }
-static uint16 tmpbuf[sizeof(pstring)];
+ *ptr = (*s) ? s+1 : s;
+ *buff = 0;
+ last_ptr = *ptr;
-void set_first_token(char *ptr)
-{
- last_ptr = ptr;
+ return(True);
}
-
/****************************************************************************
Convert list of tokens to array; dependent on above routine.
Uses last_ptr from above - bit of a hack.
****************************************************************************/
char **toktocliplist(int *ctok, char *sep)
{
- char *s=last_ptr;
- int ictok=0;
- char **ret, **iret;
+ char *s=last_ptr;
+ int ictok=0;
+ char **ret, **iret;
- if (!sep) sep = " \t\n\r";
+ if (!sep) sep = " \t\n\r";
- while(*s && strchr_m(sep,*s)) s++;
+ while(*s && strchr(sep,*s)) s++;
- /* nothing left? */
- if (!*s) return(NULL);
+ /* nothing left? */
+ if (!*s) return(NULL);
- do {
- ictok++;
- while(*s && (!strchr_m(sep,*s))) s++;
- while(*s && strchr_m(sep,*s)) *s++=0;
- } while(*s);
-
- *ctok=ictok;
- s=last_ptr;
-
- if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
-
- while(ictok--) {
- *iret++=s;
- while(*s++);
- while(!*s) s++;
- }
+ do {
+ ictok++;
+ while(*s && (!strchr(sep,*s))) s++;
+ while(*s && strchr(sep,*s)) *s++=0;
+ } while(*s);
- return ret;
+ *ctok=ictok;
+ s=last_ptr;
+
+ if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
+
+ while(ictok--) {
+ *iret++=s;
+ while(*s++);
+ while(!*s) s++;
+ }
+
+ return ret;
}
+
/*******************************************************************
case insensitive string compararison
********************************************************************/
int StrCaseCmp(const char *s, const char *t)
{
- pstring buf1, buf2;
- unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
- unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
- return strcmp(buf1,buf2);
+ /* compare until we run out of string, either t or s, or find a difference */
+ /* We *must* use toupper rather than tolower here due to the
+ asynchronous upper to lower mapping.
+ */
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ int diff;
+ for (;;)
+ {
+ if (!*s || !*t)
+ return toupper (*s) - toupper (*t);
+ else if (is_sj_alph (*s) && is_sj_alph (*t))
+ {
+ diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
+ if (diff)
+ return diff;
+ s += 2;
+ t += 2;
+ }
+ else if (is_shift_jis (*s) && is_shift_jis (*t))
+ {
+ diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
+ if (diff)
+ return diff;
+ diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
+ if (diff)
+ return diff;
+ s += 2;
+ t += 2;
+ }
+ else if (is_shift_jis (*s))
+ return 1;
+ else if (is_shift_jis (*t))
+ return -1;
+ else
+ {
+ diff = toupper (*s) - toupper (*t);
+ if (diff)
+ return diff;
+ s++;
+ t++;
+ }
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (*s && *t && toupper(*s) == toupper(*t))
+ {
+ s++;
+ t++;
+ }
+
+ return(toupper(*s) - toupper(*t));
+ }
}
/*******************************************************************
@@ -142,10 +190,83 @@ int StrCaseCmp(const char *s, const char *t)
********************************************************************/
int StrnCaseCmp(const char *s, const char *t, size_t n)
{
- pstring buf1, buf2;
- unix_strupper(s, strlen(s)+1, buf1, sizeof(buf1));
- unix_strupper(t, strlen(t)+1, buf2, sizeof(buf2));
- return strncmp(buf1,buf2,n);
+ /* compare until we run out of string, either t or s, or chars */
+ /* We *must* use toupper rather than tolower here due to the
+ asynchronous upper to lower mapping.
+ */
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ int diff;
+ for (;n > 0;)
+ {
+ if (!*s || !*t)
+ return toupper (*s) - toupper (*t);
+ else if (is_sj_alph (*s) && is_sj_alph (*t))
+ {
+ diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
+ if (diff)
+ return diff;
+ s += 2;
+ t += 2;
+ n -= 2;
+ }
+ else if (is_shift_jis (*s) && is_shift_jis (*t))
+ {
+ diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
+ if (diff)
+ return diff;
+ diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
+ if (diff)
+ return diff;
+ s += 2;
+ t += 2;
+ n -= 2;
+ }
+ else if (is_shift_jis (*s))
+ return 1;
+ else if (is_shift_jis (*t))
+ return -1;
+ else
+ {
+ diff = toupper (*s) - toupper (*t);
+ if (diff)
+ return diff;
+ s++;
+ t++;
+ n--;
+ }
+ }
+ return 0;
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (n && *s && *t && toupper(*s) == toupper(*t))
+ {
+ s++;
+ t++;
+ n--;
+ }
+
+ /* not run out of chars - strings are different lengths */
+ if (n)
+ return(toupper(*s) - toupper(*t));
+
+ /* identical up to where we run out of chars,
+ and strings are same length */
+ return(0);
+ }
}
/*******************************************************************
@@ -153,10 +274,10 @@ int StrnCaseCmp(const char *s, const char *t, size_t n)
********************************************************************/
BOOL strequal(const char *s1, const char *s2)
{
- if (s1 == s2) return(True);
- if (!s1 || !s2) return(False);
+ if (s1 == s2) return(True);
+ if (!s1 || !s2) return(False);
- return(StrCaseCmp(s1,s2)==0);
+ return(StrCaseCmp(s1,s2)==0);
}
/*******************************************************************
@@ -213,6 +334,112 @@ int strwicmp(char *psz1, char *psz2)
/*******************************************************************
+ convert a string to lower case
+********************************************************************/
+void strlower(char *s)
+{
+ while (*s)
+ {
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ if (is_shift_jis (*s))
+ {
+ if (is_sj_upper (s[0], s[1]))
+ s[1] = sj_tolower2 (s[1]);
+ s += 2;
+ }
+ else if (is_kana (*s))
+ {
+ s++;
+ }
+ else
+ {
+ if (isupper(*s))
+ *s = tolower(*s);
+ s++;
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else
+ {
+ if (isupper(*s))
+ *s = tolower(*s);
+ s++;
+ }
+ }
+ }
+}
+
+/*******************************************************************
+ convert a string to upper case
+********************************************************************/
+void strupper(char *s)
+{
+ while (*s)
+ {
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ if (is_shift_jis (*s))
+ {
+ if (is_sj_lower (s[0], s[1]))
+ s[1] = sj_toupper2 (s[1]);
+ s += 2;
+ }
+ else if (is_kana (*s))
+ {
+ s++;
+ }
+ else
+ {
+ if (islower(*s))
+ *s = toupper(*s);
+ s++;
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else
+ {
+ if (islower(*s))
+ *s = toupper(*s);
+ s++;
+ }
+ }
+ }
+}
+
+/*******************************************************************
convert a string to "normal" form
********************************************************************/
void strnorm(char *s)
@@ -229,26 +456,44 @@ check if a string is in "normal" case
********************************************************************/
BOOL strisnormal(char *s)
{
- extern int case_default;
- if (case_default == CASE_UPPER)
- return(!strhaslower(s));
-
- return(!strhasupper(s));
+ extern int case_default;
+ if (case_default == CASE_UPPER)
+ return(!strhaslower(s));
+
+ return(!strhasupper(s));
}
/****************************************************************************
string replace
- NOTE: oldc and newc must be 7 bit characters
****************************************************************************/
void string_replace(char *s,char oldc,char newc)
{
- smb_ucs2_t *ptr;
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- for(ptr=tmpbuf;*ptr;ptr++) {
- if(*ptr==UCS2_CHAR(oldc)) *ptr = UCS2_CHAR(newc);
- }
- pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE);
+ size_t skip;
+
+ /*
+ * sbcs optimization.
+ */
+ if(!global_is_multibyte_codepage) {
+ while (*s) {
+ if (oldc == *s)
+ *s = newc;
+ s++;
+ }
+ } else {
+ while (*s)
+ {
+ skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else
+ {
+ if (oldc == *s)
+ *s = newc;
+ s++;
+ }
+ }
+ }
}
@@ -257,20 +502,35 @@ skip past some strings in a buffer
********************************************************************/
char *skip_string(char *buf,size_t n)
{
- while (n--)
- buf += strlen(buf) + 1;
- return(buf);
+ while (n--)
+ buf += strlen(buf) + 1;
+ return(buf);
}
/*******************************************************************
Count the number of characters in a string. Normally this will
be the same as the number of bytes in a string for single byte strings,
but will be different for multibyte.
+ 16.oct.98, jdblair@cobaltnet.com.
********************************************************************/
+
size_t str_charnum(const char *s)
{
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- return strlen_w(tmpbuf);
+ size_t len = 0;
+
+ /*
+ * sbcs optimization.
+ */
+ if(!global_is_multibyte_codepage) {
+ return strlen(s);
+ } else {
+ while (*s != '\0') {
+ int skip = get_character_len(*s);
+ s += (skip ? skip : 1);
+ len++;
+ }
+ }
+ return len;
}
/*******************************************************************
@@ -279,36 +539,110 @@ trim the specified elements off the front and back of a string
BOOL trim_string(char *s,const char *front,const char *back)
{
- BOOL ret = False;
- size_t front_len;
- size_t back_len;
- size_t len;
+ BOOL ret = False;
+ size_t s_len;
+ size_t front_len;
+ size_t back_len;
+ char *sP;
/* Ignore null or empty strings. */
- if (!s || (s[0] == '\0'))
- return False;
- front_len = front? strlen(front) : 0;
- back_len = back? strlen(back) : 0;
+ if ( !s || (s[0] == '\0'))
+ return False;
+
+ sP = s;
+ s_len = strlen( s ) + 1;
+ front_len = (front) ? strlen( front ) + 1 : 0;
+ back_len = (back) ? strlen( back ) + 1 : 0;
+
+ /*
+ * remove "front" string from given "s", if it matches front part,
+ * repeatedly.
+ */
+ if ( front && front_len > 1 ) {
+ while (( s_len >= front_len )&&
+ ( memcmp( sP, front, front_len - 1 )) == 0 ) {
+ ret = True;
+ sP += ( front_len - 1 );
+ s_len -= ( front_len - 1 );
+ }
+ }
- len = strlen(s);
+ /*
+ * we'll memmove sP to s later, after we're done with
+ * back part removal, for minimizing copy.
+ */
+
+
+ /*
+ * We split out the multibyte code page
+ * case here for speed purposes. Under a
+ * multibyte code page we need to walk the
+ * string forwards only and multiple times.
+ * Thanks to John Blair for finding this
+ * one. JRA.
+ */
+ /*
+ * This JRA's comment is partly correct, but partly wrong.
+ * You can always check from "end" part, and if it did not match,
+ * it means there is no possibility of finding one.
+ * If you found matching point, mark them, then look from front
+ * if marking point suits multi-byte string rule.
+ * Kenichi Okuyama.
+ */
+
+ if ( back && back_len > 1 && s_len >= back_len) {
+ char *bP = sP + s_len - back_len;
+ long b_len = s_len;
+
+ while (( b_len >= back_len )&&
+ ( memcmp( bP, back, back_len - 1 ) == 0 )) {
+ bP -= ( back_len - 1 );
+ b_len -= ( back_len - 1 );
+ }
- if (front_len) {
- while (len && strncmp(s, front, front_len)==0) {
- memcpy(s, s+front_len, (len-front_len)+1);
- len -= front_len;
- ret=True;
- }
- }
-
- if (back_len) {
- while (strncmp(s+len-back_len,back,back_len)==0) {
- s[len-back_len]='\0';
- len -= back_len;
- ret=True;
- }
- }
- return ret;
+ /*
+ * You're here, means you ether have found match multiple times,
+ * or you found none. If you've found match, then bP should be
+ * moving.
+ */
+ if ( bP != sP + s_len - back_len ) {
+ bP += ( back_len - 1 ); /* slide bP to first matching point. */
+
+ if( !global_is_multibyte_codepage ) {
+ /* simply terminate */
+ (*bP) = '\0';
+ s_len = b_len;
+ ret = True;
+ } else {
+ /* trace string from start. */
+ char *cP = sP;
+ while ( cP < sP + s_len - back_len ) {
+ size_t skip;
+ skip = skip_multibyte_char( *cP );
+ cP += ( skip ? skip : 1 );
+ if ( cP == bP ) {
+ /* you found the match */
+ (*bP) = '\0';
+ ret = True;
+ s_len = b_len;
+ break;
+ }
+ while (( cP > bP )&&( bP < sP + s_len - back_len )) {
+ bP += ( back_len - 1 );
+ b_len += ( back_len - 1 );
+ }
+ }
+ }
+ }
+ }
+
+ /* if front found matching point */
+ if ( sP != s ) {
+ /* slide string to buffer top */
+ memmove( s, sP, s_len );
+ }
+ return ret;
}
@@ -317,11 +651,46 @@ does a string have any uppercase chars in it?
****************************************************************************/
BOOL strhasupper(const char *s)
{
- smb_ucs2_t *ptr;
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- for(ptr=tmpbuf;*ptr;ptr++)
- if(isupper_w(*ptr)) return True;
- return(False);
+ while (*s)
+ {
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ if (is_shift_jis (*s))
+ s += 2;
+ else if (is_kana (*s))
+ s++;
+ else
+ {
+ if (isupper(*s))
+ return(True);
+ s++;
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (isupper(*s))
+ return(True);
+ s++;
+ }
+ }
+ }
+ return(False);
}
/****************************************************************************
@@ -329,23 +698,104 @@ does a string have any lowercase chars in it?
****************************************************************************/
BOOL strhaslower(const char *s)
{
- smb_ucs2_t *ptr;
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- for(ptr=tmpbuf;*ptr;ptr++)
- if(islower_w(*ptr)) return True;
- return(False);
+ while (*s)
+ {
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ if (is_shift_jis (*s))
+ {
+ if (is_sj_upper (s[0], s[1]))
+ return(True);
+ if (is_sj_lower (s[0], s[1]))
+ return (True);
+ s += 2;
+ }
+ else if (is_kana (*s))
+ {
+ s++;
+ }
+ else
+ {
+ if (islower(*s))
+ return(True);
+ s++;
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (islower(*s))
+ return(True);
+ s++;
+ }
+ }
+ }
+ return(False);
}
/****************************************************************************
-find the number of 'c' chars in a string
+find the number of chars in a string
****************************************************************************/
size_t count_chars(const char *s,char c)
{
- smb_ucs2_t *ptr;
- int count;
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- for(count=0,ptr=tmpbuf;*ptr;ptr++) if(*ptr==UCS2_CHAR(c)) count++;
- return(count);
+ size_t count=0;
+
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ while (*s)
+ {
+ if (is_shift_jis (*s))
+ s += 2;
+ else
+ {
+ if (*s == c)
+ count++;
+ s++;
+ }
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (*s)
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (*s == c)
+ count++;
+ s++;
+ }
+ }
+ }
+ return(count);
}
/*******************************************************************
@@ -354,15 +804,52 @@ Return True if a string consists only of one particular character.
BOOL str_is_all(const char *s,char c)
{
- smb_ucs2_t *ptr;
-
- if(s == NULL) return False;
- if(!*s) return False;
-
- push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
- for(ptr=tmpbuf;*ptr;ptr++) if(*ptr!=UCS2_CHAR(c)) return False;
-
- return True;
+ if(s == NULL)
+ return False;
+ if(!*s)
+ return False;
+
+#if !defined(KANJI_WIN95_COMPATIBILITY)
+ /*
+ * For completeness we should put in equivalent code for code pages
+ * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
+ * doubt anyone wants Samba to behave differently from Win95 and WinNT
+ * here. They both treat full width ascii characters as case senstive
+ * filenames (ie. they don't do the work we do here).
+ * JRA.
+ */
+
+ if(lp_client_code_page() == KANJI_CODEPAGE)
+ {
+ /* Win95 treats full width ascii characters as case sensitive. */
+ while (*s)
+ {
+ if (is_shift_jis (*s))
+ s += 2;
+ else
+ {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ }
+ }
+ else
+#endif /* KANJI_WIN95_COMPATIBILITY */
+ {
+ while (*s)
+ {
+ size_t skip = get_character_len( *s );
+ if( skip != 0 )
+ s += skip;
+ else {
+ if (*s != c)
+ return False;
+ s++;
+ }
+ }
+ }
+ return True;
}
/*******************************************************************
@@ -372,29 +859,29 @@ include the terminating zero.
char *safe_strcpy(char *dest,const char *src, size_t maxlength)
{
- size_t len;
+ size_t len;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
- return NULL;
- }
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
+ return NULL;
+ }
- if (!src) {
- *dest = 0;
- return dest;
- }
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
- len = strlen(src);
+ len = strlen(src);
- if (len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
- (int)(len-maxlength), src));
- len = maxlength;
- }
+ if (len > maxlength) {
+ DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
+ (int)(len-maxlength), src));
+ len = maxlength;
+ }
- memmove(dest, src, len);
- dest[len] = 0;
- return dest;
+ memcpy(dest, src, len);
+ dest[len] = 0;
+ return dest;
}
/*******************************************************************
@@ -404,29 +891,29 @@ include the terminating zero.
char *safe_strcat(char *dest, const char *src, size_t maxlength)
{
- size_t src_len, dest_len;
+ size_t src_len, dest_len;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
- return NULL;
- }
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
+ return NULL;
+ }
- if (!src) {
- return dest;
- }
-
- src_len = strlen(src);
- dest_len = strlen(dest);
-
- if (src_len + dest_len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
- (int)(src_len + dest_len - maxlength), src));
- src_len = maxlength - dest_len;
- }
-
- memcpy(&dest[dest_len], src, src_len);
- dest[dest_len + src_len] = 0;
- return dest;
+ if (!src) {
+ return dest;
+ }
+
+ src_len = strlen(src);
+ dest_len = strlen(dest);
+
+ if (src_len + dest_len > maxlength) {
+ DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
+ (int)(src_len + dest_len - maxlength), src));
+ src_len = maxlength - dest_len;
+ }
+
+ memcpy(&dest[dest_len], src, src_len);
+ dest[dest_len + src_len] = 0;
+ return dest;
}
/*******************************************************************
@@ -459,7 +946,7 @@ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, si
for(i = 0; i < len; i++) {
int val = (src[i] & 0xff);
- if(isupper(val) || islower(val) || isdigit(val) || strchr_m(other_safe_chars, val))
+ if(isupper(val) || islower(val) || isdigit(val) || strchr(other_safe_chars, val))
dest[i] = src[i];
else
dest[i] = '_';
@@ -477,15 +964,15 @@ char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, si
char *StrnCpy(char *dest,const char *src,size_t n)
{
- char *d = dest;
- if (!dest) return(NULL);
- if (!src) {
- *dest = 0;
- return(dest);
- }
- while (n-- && (*d++ = *src++)) ;
- *d = 0;
- return(dest);
+ char *d = dest;
+ if (!dest) return(NULL);
+ if (!src) {
+ *dest = 0;
+ return(dest);
+ }
+ while (n-- && (*d++ = *src++)) ;
+ *d = 0;
+ return(dest);
}
/****************************************************************************
@@ -497,7 +984,7 @@ char *strncpyn(char *dest, const char *src,size_t n, char c)
char *p;
size_t str_len;
- p = strchr_m(src, c);
+ p = strchr(src, c);
if (p == NULL)
{
DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
@@ -537,14 +1024,14 @@ size_t strhex_to_str(char *p, size_t len, const char *strhex)
continue;
}
- if (!(p1 = strchr_m(hexchars, toupper(strhex[i]))))
+ if (!(p1 = strchr(hexchars, toupper(strhex[i]))))
{
break;
}
i++; /* next hex digit */
- if (!(p2 = strchr_m(hexchars, toupper(strhex[i]))))
+ if (!(p2 = strchr(hexchars, toupper(strhex[i]))))
{
break;
}
@@ -630,7 +1117,8 @@ void string_free(char **s)
if (!s || !(*s)) return;
if (*s == null_string)
*s = NULL;
- SAFE_FREE(*s);
+ if (*s) free(*s);
+ *s = NULL;
}
/****************************************************************************
@@ -748,7 +1236,7 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
****************************************************************************/
void split_at_last_component(char *path, char *front, char sep, char *back)
{
- char *p = strrchr_m(path, sep);
+ char *p = strrchr(path, sep);
if (p != NULL)
{
@@ -800,56 +1288,3 @@ char *string_truncate(char *s, int length)
}
return s;
}
-
-
-/****************************************************************************
-strchr and strrchr_m are very hard to do on general multi-byte strings.
-we convert via ucs2 for now
-****************************************************************************/
-char *strchr_m(const char *s, char c)
-{
- wpstring ws;
- pstring s2;
- smb_ucs2_t *p;
-
- push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
- p = strchr_wa(ws, c);
- if (!p) return NULL;
- *p = 0;
- pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
-}
-
-char *strrchr_m(const char *s, char c)
-{
- wpstring ws;
- pstring s2;
- smb_ucs2_t *p;
-
- push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
- p = strrchr_wa(ws, c);
- if (!p) return NULL;
- *p = 0;
- pull_ucs2_pstring(s2, ws);
- return (char *)(s+strlen(s2));
-}
-
-/*******************************************************************
- convert a string to lower case
-********************************************************************/
-void strlower_m(char *s)
-{
- /* I assume that lowercased string takes the same number of bytes
- * as source string even in UTF-8 encoding. (VIV) */
- unix_strlower(s,strlen(s)+1,s,strlen(s)+1);
-}
-
-/*******************************************************************
- convert a string to upper case
-********************************************************************/
-void strupper_m(char *s)
-{
- /* 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);
-}