diff options
Diffstat (limited to 'source/lib/util_str.c')
-rw-r--r-- | source/lib/util_str.c | 957 |
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); -} |