summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2001-11-04 18:26:53 +0000
committerSimo Sorce <idra@samba.org>2001-11-04 18:26:53 +0000
commit740d6f5dd60bef72037ed5fcd7b2192af22c2e41 (patch)
treeec2831f8ab9ad97aeb5af792634249fb898addb9 /source3/lib
parentc3f21fc360b220b4547c43c03ac60f20ecb30654 (diff)
downloadsamba-740d6f5dd60bef72037ed5fcd7b2192af22c2e41.tar.gz
samba-740d6f5dd60bef72037ed5fcd7b2192af22c2e41.tar.bz2
samba-740d6f5dd60bef72037ed5fcd7b2192af22c2e41.zip
a big one:
- old mangle code has gone, the new one based on tdb seem resonably ok probably the valid.dat table need to be updated to treat wild chars as invalid ones (work ok without it) - a LOT of new string manipulation function for unicode, they are somewhat tested but a review would not be bad - some new function I will need for the new unix_convert function I'm writing, this will be renamed filename_convert and use only unicode strings. - charconv, I attached a comment, if someone wnat to look if I'm right or just was hacking to late in the night to make a sane one :) of course any bug is my responsibility an will be pleased to see patches if you find any. :-) Simo. (This used to be commit ee19f7efb6ea9216fc91cf112ac1afa691983e9d)
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/charcnv.c8
-rw-r--r--source3/lib/util.c68
-rw-r--r--source3/lib/util_str.c67
-rw-r--r--source3/lib/util_unistr.c205
4 files changed, 319 insertions, 29 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index e55de729c2..ebf316d9dd 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 c833707d62..e2a5fe10d0 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 e97885ae05..dc9dbd8ed7 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 d0e2a119b8..287472ad65 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);
+}