diff options
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/charcnv.c | 8 | ||||
-rw-r--r-- | source3/lib/util.c | 68 | ||||
-rw-r--r-- | source3/lib/util_str.c | 67 | ||||
-rw-r--r-- | source3/lib/util_unistr.c | 205 |
4 files changed, 319 insertions, 29 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c index e55de729c2a..ebf316d9dd3 100644 --- a/source3/lib/charcnv.c +++ b/source3/lib/charcnv.c @@ -123,7 +123,13 @@ size_t convert_string(charset_t from, charset_t to, { case EINVAL: reason="Incomplete multibyte sequence"; break; case E2BIG: reason="No more room"; DEBUG(0, ("Required %d, available %d\n", - srclen, destlen)); + srclen, destlen)); + /* we are not sure we need srclen bytes, + may be more, may be less. + We only know we need more than destlen + bytes ---simo */ + + break; case EILSEQ: reason="Illegal myltibyte sequence"; break; } diff --git a/source3/lib/util.c b/source3/lib/util.c index c833707d62c..e2a5fe10d0e 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -418,6 +418,58 @@ void unix_clean_name(char *s) trim_string(s,NULL,"/.."); } +/******************************************************************* +convert '\' to '/' +reduce a file name, removing or reducing /../ , /./ , // elements. +remove also any trailing . and / +return a new allocated string. +********************************************************************/ +smb_ucs2_t *unix_clean_path(const smb_ucs2_t *s) +{ + smb_ucs2_t *ns; + smb_ucs2_t *p, *r, *t; + + DEBUG(3, ("unix_clean_name_w\n")); /* [%unicode]\n")); */ + + /* convert '\' to '/' */ + ns = strdup_w(s); + if (!ns) return NULL; + unix_format_w(ns); + + /* remove all double slashes */ + p = ns; + ns = all_string_sub_wa(p, "//", "/"); + SAFE_FREE(p); + if (!ns) return NULL; + + /* remove any /./ */ + p = ns; + ns = all_string_sub_wa(p, "/./", "/"); + SAFE_FREE(p); + if (!ns) return NULL; + + /* reduce any /../ */ + t = ns; + while ((r = strstr_wa(t, "/..")) != NULL) { + t = &(r[3]); + if (*t == UCS2_CHAR('/') || *t == 0) { + *r = 0; + p = strrchr_w(ns, UCS2_CHAR('/')); + if (!p) p = ns; + memmove(p, t, (strlen_w(t) + 1) * sizeof(smb_ucs2_t)); + t = p; + } + } + + /* remove any trailing /. */ + trim_string_wa(ns, NULL, "/."); + + /* remove any leading and trailing / */ + trim_string_wa(ns, "/", "/"); + + return ns; +} + /**************************************************************************** make a dir struct ****************************************************************************/ @@ -1783,6 +1835,22 @@ BOOL ms_has_wild(char *s) return False; } +BOOL ms_has_wild_w(const smb_ucs2_t *s) +{ + smb_ucs2_t c; + while ((c = *s++)) { + switch (c) { + case UCS2_CHAR('*'): + case UCS2_CHAR('?'): + case UCS2_CHAR('<'): + case UCS2_CHAR('>'): + case UCS2_CHAR('"'): + return True; + } + } + return False; +} + /******************************************************************* a wrapper that handles case sensitivity and the special handling of the ".." name diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index e97885ae054..dc9dbd8ed7c 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -245,9 +245,7 @@ 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); - } + string_replace_w(tmpbuf, UCS2_CHAR(oldc), UCS2_CHAR(newc)); pull_ucs2(NULL, s, tmpbuf, -1, sizeof(tmpbuf), STR_TERMINATE); } @@ -744,6 +742,65 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len) } /**************************************************************************** +similar to all_string_sub but for unicode strings. +return a new allocate unicode string. +len is the number of bytes, not chars + similar to string_sub() but allows for any character to be substituted. + Use with caution! + if len==0 then no length check is performed +****************************************************************************/ + +smb_ucs2_t *all_string_sub_w(smb_ucs2_t *s, const smb_ucs2_t *pattern, + const smb_ucs2_t *insert) +{ + smb_ucs2_t *r, *rp, *sp; + size_t ls, lp, li, lt; + + if (!insert || !pattern || !*pattern || !s) return NULL; + + ls = lt = (size_t)strlen_w(s) * sizeof(smb_ucs2_t); + lp = (size_t)strlen_w(pattern) * sizeof(smb_ucs2_t); + li = (size_t)strlen_w(insert) * sizeof(smb_ucs2_t); + + if (li > lp) { + smb_ucs2_t *st = s; + int ld = li - lp; + while (sp = strstr_w(st, pattern)) { + st = sp + lp; + lt += ld; + } + } + + r = rp = (smb_ucs2_t *)malloc((lt + 1)*(sizeof(smb_ucs2_t))); + if (!r) { + DEBUG(0, ("all_string_sub_w: out of memory!\n")); + return NULL; + } + + while (sp = strstr_w(s, pattern)) { + memcpy(rp, s, sp - s); + rp += (sp - s); + memcpy(rp, insert, li); + s = sp + lp; + rp += li; + } + *rp = 0; + + return r; +} + +smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern, + const char *insert) +{ + wpstring p, i; + + if (!insert || !pattern || !s) return NULL; + push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE); + push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE); + return all_string_sub_w(s, p, i); +} + +/**************************************************************************** splits out the front and back at a separator. ****************************************************************************/ void split_at_last_component(char *path, char *front, char sep, char *back) @@ -813,7 +870,7 @@ char *strchr_m(const char *s, char c) smb_ucs2_t *p; push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); - p = strchr_wa(ws, c); + p = strchr_w(ws, UCS2_CHAR(c)); if (!p) return NULL; *p = 0; pull_ucs2_pstring(s2, ws); @@ -827,7 +884,7 @@ char *strrchr_m(const char *s, char c) smb_ucs2_t *p; push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE); - p = strrchr_wa(ws, c); + p = strrchr_w(ws, UCS2_CHAR(c)); if (!p) return NULL; *p = 0; pull_ucs2_pstring(s2, ws); diff --git a/source3/lib/util_unistr.c b/source3/lib/util_unistr.c index d0e2a119b85..287472ad65e 100644 --- a/source3/lib/util_unistr.c +++ b/source3/lib/util_unistr.c @@ -242,6 +242,52 @@ smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c) return NULL; } +smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c) +{ + const smb_ucs2_t *p = s; + int len = strlen_w(s); + if (len == 0) return NULL; + p += (len - 1); + do { + if (c == *p) return (smb_ucs2_t *)p; + } while (p-- != s); + return NULL; +} + +/******************************************************************* +wide strstr() +********************************************************************/ +smb_ucs2_t *strstr_w(const smb_ucs2_t *s, const smb_ucs2_t *ins) +{ + smb_ucs2_t *r; + size_t slen, inslen; + + if (!s || !*s || !ins || !*ins) return NULL; + slen = strlen_w(s); + inslen = strlen_w(ins); + r = (smb_ucs2_t *)s; + while (r = strchr_w(r, *ins)) { + if (strncmp_w(r, ins, inslen) == 0) return r; + r++; + } + return NULL; +} + +smb_ucs2_t *strstr_wa(const smb_ucs2_t *s, const char *ins) +{ + smb_ucs2_t *r; + size_t slen, inslen; + + if (!s || !*s || !ins || !*ins) return NULL; + slen = strlen_w(s); + inslen = strlen(ins); + r = (smb_ucs2_t *)s; + while (r = strchr_w(r, UCS2_CHAR(*ins))) { + if (strncmp_wa(r, ins, inslen) == 0) return r; + r++; + } + return NULL; +} /******************************************************************* Convert a string to lower case. @@ -280,6 +326,18 @@ BOOL strupper_w(smb_ucs2_t *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); +} + +/******************************************************************* case insensitive string comparison ********************************************************************/ int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b) @@ -288,23 +346,60 @@ int strcasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b) return (tolower_w(*a) - tolower_w(*b)); } +/******************************************************************* +case insensitive string comparison, lenght limited +********************************************************************/ +int strncasecmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len) +{ + size_t n = 0; + while ((n < len) && *b && (toupper_w(*a) == toupper_w(*b))) { a++; b++; n++; } + return (len - n)?(tolower_w(*a) - tolower_w(*b)):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); +} /******************************************************************* duplicate string ********************************************************************/ smb_ucs2_t *strdup_w(const smb_ucs2_t *src) { + return strndup_w(src, 0); +} + +/* if len == 0 then duplicate the whole string */ +smb_ucs2_t *strndup_w(const smb_ucs2_t *src, size_t len) +{ smb_ucs2_t *dest; - uint32 len; - len = strlen_w(src) + 1; - dest = (smb_ucs2_t *)malloc(len*sizeof(smb_ucs2_t)); + if (!len) len = strlen_w(src); + dest = (smb_ucs2_t *)malloc((len + 1) * sizeof(smb_ucs2_t)); if (!dest) { DEBUG(0,("strdup_w: out of memory!\n")); return NULL; } - memcpy(dest, src, len*sizeof(smb_ucs2_t)); + memcpy(dest, src, len * sizeof(smb_ucs2_t)); + dest[len] = 0; return dest; } @@ -368,33 +463,33 @@ void pstrcpy_wa(smb_ucs2_t *dest, const char *src) } } -int strcmp_wa(const smb_ucs2_t *a, const char *b) +int strcmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b) { - while (*b && *a == UCS2_CHAR(*b)) { a++; b++; } - return (*a - UCS2_CHAR(*b)); + while (*b && *a == *b) { a++; b++; } + return (*a - *b); + /* warning: if *a != *b and both are not 0 we retrun a random + greater or lesser than 0 number not realted to which + string is longer */ } +int strncmp_w(const smb_ucs2_t *a, const smb_ucs2_t *b, size_t len) +{ + size_t n = 0; + while ((n < len) && *b && *a == *b) { a++; b++; n++;} + return (len - n)?(*a - *b):0; +} - -smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c) +int strcmp_wa(const smb_ucs2_t *a, const char *b) { - while (*s != 0) { - if (UCS2_CHAR(c) == *s) return (smb_ucs2_t *)s; - s++; - } - return NULL; + while (*b && *a == UCS2_CHAR(*b)) { a++; b++; } + return (*a - UCS2_CHAR(*b)); } -smb_ucs2_t *strrchr_wa(const smb_ucs2_t *s, char c) +int strncmp_wa(const smb_ucs2_t *a, const char *b, size_t len) { - const smb_ucs2_t *p = s; - int len = strlen_w(s); - if (len == 0) return NULL; - p += (len-1); - do { - if (UCS2_CHAR(c) == *p) return (smb_ucs2_t *)p; - } while (p-- != s); - return NULL; + size_t n = 0; + while ((n < len) && *b && *a == UCS2_CHAR(*b)) { a++; b++; n++;} + return (len - n)?(*a - UCS2_CHAR(*b)):0; } smb_ucs2_t *strpbrk_wa(const smb_ucs2_t *s, const char *p) @@ -452,3 +547,67 @@ smb_ucs2_t *strncat_wa(smb_ucs2_t *dest, const char *src, const size_t max) SAFE_FREE(ucs2_src); return dest; } + +/******************************************************************* +replace any occurence of oldc with newc in unicode string +********************************************************************/ + +void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc) +{ + for(;*s;s++) { + if(*s==oldc) *s=newc; + } +} + +/******************************************************************* +trim unicode string +********************************************************************/ + +BOOL trim_string_w(smb_ucs2_t *s, const smb_ucs2_t *front, + const smb_ucs2_t *back) +{ + BOOL ret = False; + size_t len, lw, front_len, flw, back_len, blw; + + if (!s || !*s) return False; + + len = strlen_w(s); + + if (front && *front) { + front_len = strlen_w(front); + flw = front_len * sizeof(smb_ucs2_t); + lw = (len + 1) * sizeof(smb_ucs2_t); + while (len && strncmp_w(s, front, front_len) == 0) { + memcpy(s, s + flw, lw - flw); + len -= front_len; + lw -= flw; + ret = True; + } + } + + if (back && *back) { + back_len = strlen_w(back); + blw = back_len * sizeof(smb_ucs2_t); + lw = len * sizeof(smb_ucs2_t); + while (len && strncmp_w(s + lw - blw, back, back_len) == 0) { + s[len - back_len] = 0; + len -= back_len; + lw -= blw; + ret = True; + } + } + + return ret; +} + +BOOL trim_string_wa(smb_ucs2_t *s, const char *front, + const char *back) +{ + wpstring f, b; + + if (front) push_ucs2(NULL, f, front, sizeof(wpstring) - 1, STR_TERMINATE); + else *f = 0; + if (back) push_ucs2(NULL, b, back, sizeof(wpstring) - 1, STR_TERMINATE); + else *b = 0; + return trim_string_w(s, f, b); +} |