diff options
author | Jeremy Allison <jra@samba.org> | 1999-12-29 02:00:38 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 1999-12-29 02:00:38 +0000 |
commit | 211697ee6cbeb2bbe86b96e17b922dd16d45c0e9 (patch) | |
tree | a15631184583b5eb0d17d0bf0329eea0be59fefc /source3/lib | |
parent | 4a85b76daeb0ef0032e5ac442a123af32d7c2e9e (diff) | |
download | samba-211697ee6cbeb2bbe86b96e17b922dd16d45c0e9.tar.gz samba-211697ee6cbeb2bbe86b96e17b922dd16d45c0e9.tar.bz2 samba-211697ee6cbeb2bbe86b96e17b922dd16d45c0e9.zip |
Converted most of the functions in lib/util_str.c to smb_ucs2_t equivalents.
Jeremy.
(This used to be commit 1ba42aca2163c534f6be4e4a733604e3dffe0ed8)
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/util_unistr.c | 912 |
1 files changed, 875 insertions, 37 deletions
diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index ddcea26e38..5e7076d5df 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -23,6 +23,9 @@ extern int DEBUGLEVEL; + smb_ucs2_t wchar_list_sep[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)',', + (smb_ucs2_t)';', (smb_ucs2_t)':', (smb_ucs2_t)'\n', + (smb_ucs2_t)'\r', 0 }; /* * The following are the codepage to ucs2 and vica versa maps. * These are dynamically loaded from a unicode translation file. @@ -689,7 +692,7 @@ smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len) Count the number of characters in a smb_ucs2_t string. ********************************************************************/ -size_t wstrlen(const smb_ucs2_t *src) +size_t strlen_w(const smb_ucs2_t *src) { size_t len; @@ -704,12 +707,12 @@ size_t wstrlen(const smb_ucs2_t *src) the terminating zero. maxlength is in bytes. ********************************************************************/ -smb_ucs2_t *safe_wstrcpy(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength) +smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength) { size_t ucs2_len; if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_wstrcpy\n")); + DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n")); return NULL; } @@ -718,14 +721,20 @@ smb_ucs2_t *safe_wstrcpy(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlengt return dest; } - ucs2_len = wstrlen(src); + /* + * Convert maxlength to smb_ucs2_t units. + */ - if (ucs2_len >= (maxlength/sizeof(smb_ucs2_t))) { + maxlength /= sizeof(smb_ucs2_t); + + ucs2_len = strlen_w(src); + + if (ucs2_len >= maxlength) { fstring out; - DEBUG(0,("ERROR: string overflow by %u bytes in safe_wstrcpy [%.50s]\n", - (unsigned int)((ucs2_len*sizeof(smb_ucs2_t))-maxlength), + DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n", + (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)), unicode_to_unix(out,src,sizeof(out))) ); - ucs2_len = (maxlength/sizeof(smb_ucs2_t)) - 1; + ucs2_len = maxlength - 1; } memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t)); @@ -738,27 +747,32 @@ smb_ucs2_t *safe_wstrcpy(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlengt maxlength is in bytes. ********************************************************************/ -smb_ucs2_t *safe_wstrcat(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength) +smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength) { size_t ucs2_src_len, ucs2_dest_len; if (!dest) { - DEBUG(0,("ERROR: NULL dest in safe_wstrcat\n")); + DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n")); return NULL; } - if (!src) { + if (!src) return dest; - } - ucs2_src_len = wstrlen(src); - ucs2_dest_len = wstrlen(dest); + /* + * Convert maxlength to smb_ucs2_t units. + */ + + maxlength /= sizeof(smb_ucs2_t); - if (ucs2_src_len + ucs2_dest_len >= (maxlength/sizeof(smb_ucs2_t))) { + ucs2_src_len = strlen_w(src); + ucs2_dest_len = strlen_w(dest); + + if (ucs2_src_len + ucs2_dest_len >= maxlength) { fstring out; - int new_len = (maxlength/sizeof(smb_ucs2_t)) - ucs2_dest_len - 1; - DEBUG(0,("ERROR: string overflow by %u characters in safe_wstrcat [%.50s]\n", - (unsigned int)((sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len)) - maxlength), + int new_len = maxlength - ucs2_dest_len - 1; + DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n", + (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)), unicode_to_unix(out,src,sizeof(out))) ); ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0); } @@ -772,7 +786,7 @@ smb_ucs2_t *safe_wstrcat(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxleng Compare the two strings s1 and s2. len is in ucs2 units. ********************************************************************/ -int wstrcmp(const smb_ucs2_t *s1, const smb_ucs2_t *s2) +int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2) { smb_ucs2_t c1, c2; @@ -793,7 +807,7 @@ int wstrcmp(const smb_ucs2_t *s1, const smb_ucs2_t *s2) Compare the first n characters of s1 to s2. len is in ucs2 units. ********************************************************************/ -int wstrncmp(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len) +int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len) { smb_ucs2_t c1, c2; @@ -815,16 +829,16 @@ int wstrncmp(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len) Search string s2 from s1. ********************************************************************/ -smb_ucs2_t *wstrstr(const smb_ucs2_t *s1, const smb_ucs2_t *s2) +smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2) { - size_t len = wstrlen(s2); + size_t len = strlen_w(s2); if (!*s2) return (smb_ucs2_t *)s1; for(;*s1; s1++) { if (*s1 == *s2) { - if (wstrncmp(s1, s2, len) == 0) + if (strncmp_w(s1, s2, len) == 0) return (smb_ucs2_t *)s1; } } @@ -835,7 +849,7 @@ smb_ucs2_t *wstrstr(const smb_ucs2_t *s1, const smb_ucs2_t *s2) Search for ucs2 char c from the beginning of s. ********************************************************************/ -smb_ucs2_t *wstrchr(const smb_ucs2_t *s, smb_ucs2_t c) +smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c) { do { if (*s == c) @@ -849,7 +863,7 @@ smb_ucs2_t *wstrchr(const smb_ucs2_t *s, smb_ucs2_t c) Search for ucs2 char c from the end of s. ********************************************************************/ -smb_ucs2_t *wstrrchr(const smb_ucs2_t *s, smb_ucs2_t c) +smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c) { smb_ucs2_t *retval = 0; @@ -865,7 +879,7 @@ smb_ucs2_t *wstrrchr(const smb_ucs2_t *s, smb_ucs2_t c) Search token from s1 separated by any ucs2 char of s2. ********************************************************************/ -smb_ucs2_t *wstrtok(smb_ucs2_t *s1, const smb_ucs2_t *s2) +smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2) { static smb_ucs2_t *s = NULL; smb_ucs2_t *q; @@ -877,7 +891,7 @@ smb_ucs2_t *wstrtok(smb_ucs2_t *s1, const smb_ucs2_t *s2) } for (q = s1; *s1; s1++) { - smb_ucs2_t *p = wstrchr(s2, *s1); + smb_ucs2_t *p = strchr_w(s2, *s1); if (p) { if (s1 != q) { s = s1 + 1; @@ -899,13 +913,13 @@ smb_ucs2_t *wstrtok(smb_ucs2_t *s1, const smb_ucs2_t *s2) Duplicate a ucs2 string. ********************************************************************/ -smb_ucs2_t *wstrdup(const smb_ucs2_t *s) +smb_ucs2_t *strdup_w(const smb_ucs2_t *s) { - size_t newlen = (wstrlen(s)+1)*sizeof(smb_ucs2_t); + size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t); smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen); if (newstr == NULL) return NULL; - safe_wstrcpy(newstr, s, newlen); + safe_strcpy_w(newstr, s, newlen); return newstr; } @@ -928,7 +942,7 @@ static smb_unicode_table_t map_table[] = { Is an upper case wchar. ********************************************************************/ -int wisupper( smb_ucs2_t val) +int isupper_w( smb_ucs2_t val) { return (map_table[val].flags & UNI_UPPER); } @@ -937,7 +951,7 @@ int wisupper( smb_ucs2_t val) Is a lower case wchar. ********************************************************************/ -int wislower( smb_ucs2_t val) +int islower_w( smb_ucs2_t val) { return (map_table[val].flags & UNI_LOWER); } @@ -946,7 +960,7 @@ int wislower( smb_ucs2_t val) Is a digit wchar. ********************************************************************/ -int wisdigit( smb_ucs2_t val) +int isdigit_w( smb_ucs2_t val) { return (map_table[val].flags & UNI_DIGIT); } @@ -955,7 +969,7 @@ int wisdigit( smb_ucs2_t val) Is a hex digit wchar. ********************************************************************/ -int wisxdigit( smb_ucs2_t val) +int isxdigit_w( smb_ucs2_t val) { return (map_table[val].flags & UNI_XDIGIT); } @@ -964,7 +978,7 @@ int wisxdigit( smb_ucs2_t val) Is a space wchar. ********************************************************************/ -int wisspace( smb_ucs2_t val) +int isspace_w( smb_ucs2_t val) { return (map_table[val].flags & UNI_SPACE); } @@ -973,7 +987,7 @@ int wisspace( smb_ucs2_t val) Convert a wchar to upper case. ********************************************************************/ -smb_ucs2_t wtoupper( smb_ucs2_t val ) +smb_ucs2_t toupper_w( smb_ucs2_t val ) { return map_table[val].upper; } @@ -982,7 +996,831 @@ smb_ucs2_t wtoupper( smb_ucs2_t val ) Convert a wchar to lower case. ********************************************************************/ -smb_ucs2_t wtolowerr( smb_ucs2_t val ) +smb_ucs2_t tolower_w( smb_ucs2_t val ) { return map_table[val].lower; } + +static smb_ucs2_t *last_ptr = NULL; + +void set_first_token_w(smb_ucs2_t *ptr) +{ + last_ptr = ptr; +} + +/**************************************************************************** + Get the next token from a string, return False if none found + handles double-quotes. + Based on a routine by GJC@VILLAGE.COM. + Extensively modified by Andrew.Tridgell@anu.edu.au + bufsize is in bytes. +****************************************************************************/ + +static smb_ucs2_t sep_list[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)'\n', (smb_ucs2_t)'\r', 0}; +static smb_ucs2_t quotechar = (smb_ucs2_t)'\"'; + +BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize) +{ + smb_ucs2_t *s; + BOOL quoted; + size_t len=1; + + /* + * Convert bufsize to smb_ucs2_t units. + */ + + bufsize /= sizeof(smb_ucs2_t); + + if (!ptr) + ptr = &last_ptr; + if (!ptr) + return(False); + + s = *ptr; + + /* + * Default to simple separators. + */ + + if (!sep) + sep = sep_list; + + /* + * Find the first non sep char. + */ + + while(*s && strchr_w(sep,*s)) + s++; + + /* + * Nothing left ? + */ + + if (!*s) + return(False); + + /* + * Copy over the token. + */ + + for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) { + if (*s == quotechar) { + quoted = !quoted; + } else { + len++; + *buff++ = *s; + } + } + + *ptr = (*s) ? s+1 : s; + *buff = 0; + last_ptr = *ptr; + + return(True); +} + +/**************************************************************************** + Convert list of tokens to array; dependent on above routine. + Uses last_ptr from above - bit of a hack. +****************************************************************************/ + +smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep) +{ + smb_ucs2_t *s=last_ptr; + int ictok=0; + smb_ucs2_t **ret, **iret; + + if (!sep) + sep = sep_list; + + while(*s && strchr_w(sep,*s)) + s++; + + /* + * Nothing left ? + */ + + if (!*s) + return(NULL); + + do { + ictok++; + while(*s && (!strchr_w(sep,*s))) + s++; + while(*s && strchr_w(sep,*s)) + *s++=0; + } while(*s); + + *ctok = ictok; + s = last_ptr; + + if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *)))) + return NULL; + + while(ictok--) { + *iret++=s; + while(*s++) + ; + while(!*s) + s++; + } + + return ret; +} + +/******************************************************************* + Case insensitive string compararison. +********************************************************************/ + +int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t) +{ + /* + * Compare until we run out of string, either t or s, or find a difference. + */ + + while (*s && *t && toupper_w(*s) == toupper_w(*t)) { + s++; + t++; + } + + return(toupper_w(*s) - toupper_w(*t)); +} + +/******************************************************************* + Case insensitive string compararison, length limited. +********************************************************************/ + +int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n) +{ + /* + * Compare until we run out of string, either t or s, or chars. + */ + + while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) { + s++; + t++; + n--; + } + + /* + * Not run out of chars - strings are different lengths. + */ + + if (n) + return(toupper_w(*s) - toupper_w(*t)); + + /* + * Identical up to where we run out of chars, + * and strings are same length. + */ + + return(0); +} + +/******************************************************************* + Compare 2 strings. +********************************************************************/ + +BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2) +{ + if (s1 == s2) + return(True); + if (!s1 || !s2) + return(False); + + return(StrCaseCmp_w(s1,s2)==0); +} + +/******************************************************************* + Compare 2 strings up to and including the nth char. +******************************************************************/ + +BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n) +{ + if (s1 == s2) + return(True); + if (!s1 || !s2 || !n) + return(False); + + return(StrnCaseCmp_w(s1,s2,n)==0); +} + +/******************************************************************* + Compare 2 strings (case sensitive). +********************************************************************/ + +BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2) +{ + if (s1 == s2) + return(True); + if (!s1 || !s2) + return(False); + + return(strcmp_w(s1,s2)==0); +} + +/******************************************************************* + Convert a string to lower case. +********************************************************************/ + +void strlower_w(smb_ucs2_t *s) +{ + while (*s) { + if (isupper_w(*s)) + *s = tolower_w(*s); + s++; + } +} + +/******************************************************************* + Convert a string to upper case. +********************************************************************/ + +void strupper_w(smb_ucs2_t *s) +{ + while (*s) { + if (islower_w(*s)) + *s = toupper_w(*s); + s++; + } +} + +/******************************************************************* + Convert a string to "normal" form. +********************************************************************/ + +void strnorm_w(smb_ucs2_t *s) +{ + extern int case_default; + if (case_default == CASE_UPPER) + strupper_w(s); + else + strlower_w(s); +} + +/******************************************************************* + Check if a string is in "normal" case. +********************************************************************/ + +BOOL strisnormal_w(smb_ucs2_t *s) +{ + extern int case_default; + if (case_default == CASE_UPPER) + return(!strhaslower_w(s)); + + return(!strhasupper_w(s)); +} + +/**************************************************************************** + String replace. +****************************************************************************/ + +void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc) +{ + while (*s) { + if (oldc == *s) + *s = newc; + s++; + } +} + +/******************************************************************* + Skip past some strings in a buffer. n is in bytes. +********************************************************************/ + +smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n) +{ + while (n--) + buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1; + return(buf); +} + +/******************************************************************* + Count the number of characters in a string. Same as strlen_w in + smb_ucs2_t string units. +********************************************************************/ + +size_t str_charnum_w(const smb_ucs2_t *s) +{ + return strlen_w(s); +} + +/******************************************************************* + Trim the specified elements off the front and back of a string. +********************************************************************/ + +BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back) +{ + BOOL ret = False; + size_t front_len = (front && *front) ? strlen_w(front) : 0; + size_t back_len = (back && *back) ? strlen_w(back) : 0; + size_t s_len; + + while (front_len && strncmp_w(s, front, front_len) == 0) { + smb_ucs2_t *p = s; + ret = True; + + while (1) { + if (!(*p = p[front_len])) + break; + p++; + } + } + + if(back_len) { + s_len = strlen_w(s); + while ((s_len >= back_len) && + (strncmp_w(s + s_len - back_len, back, back_len)==0)) { + ret = True; + s[s_len - back_len] = 0; + s_len = strlen_w(s); + } + } + + return(ret); +} + +/**************************************************************************** + Does a string have any uppercase chars in it ? +****************************************************************************/ + +BOOL strhasupper_w(const smb_ucs2_t *s) +{ + while (*s) { + if (isupper_w(*s)) + return(True); + s++; + } + return(False); +} + +/**************************************************************************** + Does a string have any lowercase chars in it ? +****************************************************************************/ + +BOOL strhaslower_w(const smb_ucs2_t *s) +{ + while (*s) { + if (islower(*s)) + return(True); + s++; + } + return(False); +} + +/**************************************************************************** + Find the number of 'c' chars in a string. +****************************************************************************/ + +size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c) +{ + size_t count=0; + + while (*s) { + if (*s == c) + count++; + s++; + } + return(count); +} + +/******************************************************************* + Return True if a string consists only of one particular character. +********************************************************************/ + +BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c) +{ + if(s == NULL) + return False; + if(!*s) + return False; + + while (*s) { + if (*s != c) + return False; + s++; + } + return True; +} + +/******************************************************************* + Paranoid strcpy into a buffer of given length (includes terminating + zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately + does *NOT* check for multibyte characters. Don't change it ! + maxlength is in bytes. +********************************************************************/ + +smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength) +{ + size_t len, i; + + /* + * Convert to smb_ucs2_t units. + */ + + maxlength /= sizeof(smb_ucs2_t); + + if (!dest) { + DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n")); + return NULL; + } + + if (!src) { + *dest = 0; + return dest; + } + + len = strlen_w(src); + if (len >= maxlength) + len = maxlength - 1; + + for(i = 0; i < len; i++) { + smb_ucs2_t val = src[i]; + if(isupper_w(val) ||islower_w(val) || isdigit_w(val)) + dest[i] = src[i]; + else + dest[i] = (smb_ucs2_t)'_'; + } + + dest[i] = 0; + + return dest; +} + +/**************************************************************************** + Like strncpy but always null terminates. Make sure there is room ! + The variable n should always be one less than the available size and is in bytes. +****************************************************************************/ + +smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n) +{ + smb_ucs2_t *d = dest; + if (!dest) + return(NULL); + if (!src) { + *dest = 0; + return(dest); + } + + /* + * Convert to smb_ucs2_t units. + */ + + n /= sizeof(smb_ucs2_t); + + while (n-- && (*d++ = *src++)) + ; + *d = 0; + return(dest); +} + +/**************************************************************************** + Like strncpy but copies up to the character marker. Always null terminates. + returns a pointer to the character marker in the source string (src). + n is in bytes. +****************************************************************************/ + +smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c) +{ + smb_ucs2_t *p; + size_t str_len; + + p = strchr_w(src, c); + if (p == NULL) { + fstring cval; + smb_ucs2_t mbcval[2]; + mbcval[0] = c; + mbcval[1] = 0; + DEBUG(5, ("strncpyn_w: separator character (%s) not found\n", + unicode_to_unix(cval,mbcval,sizeof(cval)) )); + return NULL; + } + + str_len = PTR_DIFF(p, src) + sizeof(smb_ucs2_t); + safe_strcpy_w(dest, src, MIN(n, str_len)); + + return p; +} + +/************************************************************* + Routine to get hex characters and turn them into a 16 byte array. + The array can be variable length, and any non-hex-numeric + characters are skipped. "0xnn" or "0Xnn" is specially catered + for. len is in bytes. + Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n" +**************************************************************/ + +static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 }; +static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3', + (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7', + (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B', + (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 }; + +size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex) +{ + size_t i; + size_t num_chars = 0; + unsigned char lonybble, hinybble; + smb_ucs2_t *p1 = NULL, *p2 = NULL; + + /* + * Convert to smb_ucs2_t units. + */ + + len /= sizeof(smb_ucs2_t); + + for (i = 0; i < len && strhex[i] != 0; i++) { + if (strnequal_w(hexchars, hexprefix, 2)) { + i++; /* skip two chars */ + continue; + } + + if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i])))) + break; + + i++; /* next hex digit */ + + if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i])))) + break; + + /* get the two nybbles */ + hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t)); + lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t)); + + p[num_chars] = (hinybble << 4) | lonybble; + num_chars++; + + p1 = NULL; + p2 = NULL; + } + return num_chars; +} + +/**************************************************************************** + Check if a string is part of a list. +****************************************************************************/ + +BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive) +{ + wpstring tok; + smb_ucs2_t *p=list; + + if (!list) + return(False); + + while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) { + if (casesensitive) { + if (strcmp_w(tok,s) == 0) + return(True); + } else { + if (StrCaseCmp_w(tok,s) == 0) + return(True); + } + } + return(False); +} + +/* This is used to prevent lots of mallocs of size 2 */ +static smb_ucs2_t *null_string = NULL; + +/**************************************************************************** + Set a string value, allocing the space for the string. +****************************************************************************/ + +BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src) +{ + size_t l; + + if (!null_string) { + if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) { + DEBUG(0,("string_init_w: malloc fail for null_string.\n")); + return False; + } + *null_string = 0; + } + + if (!src) + src = null_string; + + l = strlen_w(src); + + if (l == 0) + *dest = null_string; + else { + (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1)); + if ((*dest) == NULL) { + DEBUG(0,("Out of memory in string_init_w\n")); + return False; + } + + wpstrcpy(*dest,src); + } + return(True); +} + +/**************************************************************************** + Free a string value. +****************************************************************************/ + +void string_free_w(smb_ucs2_t **s) +{ + if (!s || !(*s)) + return; + if (*s == null_string) + *s = NULL; + if (*s) + free((char *)*s); + *s = NULL; +} + +/**************************************************************************** + Set a string value, allocing the space for the string, and deallocating any + existing space. +****************************************************************************/ + +BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src) +{ + string_free_w(dest); + + return(string_init_w(dest,src)); +} + +/**************************************************************************** + Substitute a string for a pattern in another string. Make sure there is + enough room ! + + This routine looks for pattern in s and replaces it with + insert. It may do multiple replacements. + + Any of " ; ' $ or ` in the insert string are replaced with _ + if len==0 then no length check is performed + len is in bytes. +****************************************************************************/ + +void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len) +{ + smb_ucs2_t *p; + ssize_t ls,lp,li, i; + + /* + * Convert to smb_ucs2_t units. + */ + + len /= sizeof(smb_ucs2_t); + + if (!insert || !pattern || !s) + return; + + ls = (ssize_t)strlen_w(s); + lp = (ssize_t)strlen_w(pattern); + li = (ssize_t)strlen_w(insert); + + if (!*pattern) + return; + + while (lp <= ls && (p = strstr_w(s,pattern))) { + if (len && (ls + (li-lp) >= len)) { + fstring out; + DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n", + (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)), + unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t))); + break; + } + if (li != lp) + memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1)); + + for (i=0;i<li;i++) { + switch (insert[i]) { + case (smb_ucs2_t)'`': + case (smb_ucs2_t)'"': + case (smb_ucs2_t)'\'': + case (smb_ucs2_t)';': + case (smb_ucs2_t)'$': + case (smb_ucs2_t)'%': + case (smb_ucs2_t)'\r': + case (smb_ucs2_t)'\n': + p[i] = (smb_ucs2_t)'_'; + break; + default: + p[i] = insert[i]; + } + } + s = p + li; + ls += (li-lp); + } +} + +void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert) +{ + string_sub_w(s, pattern, insert, sizeof(wfstring)); +} + +void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert) +{ + string_sub_w(s, pattern, insert, sizeof(wpstring)); +} + +/**************************************************************************** + Similar to string_sub() but allows for any character to be substituted. + Use with caution ! + if len==0 then no length check is performed. +****************************************************************************/ + +void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len) +{ + smb_ucs2_t *p; + ssize_t ls,lp,li; + + /* + * Convert to smb_ucs2_t units. + */ + + len /= sizeof(smb_ucs2_t); + + if (!insert || !pattern || !s) + return; + + ls = (ssize_t)strlen_w(s); + lp = (ssize_t)strlen_w(pattern); + li = (ssize_t)strlen_w(insert); + + if (!*pattern) + return; + + while (lp <= ls && (p = strstr_w(s,pattern))) { + if (len && (ls + (li-lp) >= len)) { + fstring out; + DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n", + (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)), + unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t))); + break; + } + if (li != lp) + memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1)); + + memcpy(p, insert, li*sizeof(smb_ucs2_t)); + s = p + li; + ls += (li-lp); + } +} + +/**************************************************************************** + Splits out the front and back at a separator. +****************************************************************************/ + +void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back) +{ + smb_ucs2_t *p = strrchr_w(path, sep); + + if (p != NULL) + *p = 0; + + if (front != NULL) + wpstrcpy(front, path); + + if (p != NULL) { + if (back != NULL) + wpstrcpy(back, p+1); + *p = (smb_ucs2_t)'\\'; + } else { + if (back != NULL) + back[0] = 0; + } +} + + +/**************************************************************************** + Write an octal as a string. +****************************************************************************/ + +smb_ucs2_t *octal_string_w(int i) +{ + static smb_ucs2_t wret[64]; + char ret[64]; + + if (i == -1) + slprintf(ret, sizeof(ret), "-1"); + else + slprintf(ret, sizeof(ret), "0%o", i); + return unix_to_unicode(wret, ret, sizeof(wret)); +} + + +/**************************************************************************** + Truncate a string at a specified length. + length is in bytes. +****************************************************************************/ + +smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length) +{ + /* + * Convert to smb_ucs2_t units. + */ + + length /= sizeof(smb_ucs2_t); + + if (s && strlen_w(s) > length) + s[length] = 0; + + return s; +} |