1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-26 18:50:30 +03:00

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)
This commit is contained in:
Simo Sorce 2001-11-04 18:26:53 +00:00
parent c3f21fc360
commit 740d6f5dd6
7 changed files with 583 additions and 1117 deletions

View File

@ -383,6 +383,16 @@ typedef struct write_cache
char *data;
} write_cache;
typedef struct
{
smb_ucs2_t *path;
smb_ucs2_t *name;
smb_ucs2_t *unixname;
smb_ucs2_t *dosname;
SMB_STRUCT_STAT *statinfo;
} smb_filename;
typedef struct files_struct
{
struct files_struct *next, *prev;

View File

@ -216,6 +216,7 @@ copy an IP address from one buffer to another
****************************************************************************/
#define unix_format(fname) string_replace(fname,'\\','/')
#define unix_format_w(fname) string_replace_w(fname, UCS2_CHAR('\\'), UCS2_CHAR('/'))
/****************************************************************************
Make a file into DOS format.

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
@ -743,6 +741,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.
****************************************************************************/
@ -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);

View File

@ -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.
@ -279,6 +325,18 @@ BOOL strupper_w(smb_ucs2_t *s)
return ret;
}
/*******************************************************************
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
********************************************************************/
@ -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_w(const smb_ucs2_t *a, const smb_ucs2_t *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;
}
int strcmp_wa(const smb_ucs2_t *a, const char *b)
{
while (*b && *a == UCS2_CHAR(*b)) { a++; b++; }
return (*a - UCS2_CHAR(*b));
}
smb_ucs2_t *strchr_wa(const smb_ucs2_t *s, char c)
int strncmp_wa(const smb_ucs2_t *a, const char *b, size_t len)
{
while (*s != 0) {
if (UCS2_CHAR(c) == *s) return (smb_ucs2_t *)s;
s++;
}
return NULL;
}
smb_ucs2_t *strrchr_wa(const smb_ucs2_t *s, char c)
{
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);
}

File diff suppressed because it is too large Load Diff