/*
Unix SMB/Netbios implementation.
- Version 1.9.
+ Version 3.0
Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Andrew Tridgell 1992-2001
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
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.
****************************************************************************/
BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
{
- char *s;
- BOOL quoted;
- size_t len=1;
+ char *s;
+ BOOL quoted;
+ size_t len=1;
- if (!ptr) ptr = &last_ptr;
- if (!ptr) return(False);
+ if (!ptr) return(False);
+
+ s = *ptr;
+
+ /* default to simple separators */
+ if (!sep) sep = " \t\n\r";
+
+ /* find the first non sep char */
+ while (*s && strchr(sep,*s)) s++;
+
+ /* nothing left? */
+ if (! *s) return(False);
+
+ /* copy over the token */
+ for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) {
+ if (*s == '\"') {
+ quoted = !quoted;
+ } else {
+ len++;
+ *buff++ = *s;
+ }
+ }
+
+ *ptr = (*s) ? s+1 : s;
+ *buff = 0;
+
+ return(True);
+}
- s = *ptr;
- /* default to simple separators */
- if (!sep) sep = " \t\n\r";
- /* find the first non sep char */
- while(*s && strchr(sep,*s)) s++;
+/****************************************************************************
+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;
- /* nothing left? */
- if (! *s) return(False);
+BOOL next_token_nr(char **ptr,char *buff,char *sep, size_t bufsize)
+{
+ BOOL ret;
+ if (!ptr) ptr = &last_ptr;
- /* copy over the token */
- for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++)
- {
- if (*s == '\"') {
- quoted = !quoted;
- } else {
- len++;
- *buff++ = *s;
- }
- }
+ ret = next_token(ptr, buff, sep, bufsize);
+ last_ptr = *ptr;
+ return ret;
+}
- *ptr = (*s) ? s+1 : s;
- *buff = 0;
- last_ptr = *ptr;
+static uint16 tmpbuf[sizeof(pstring)];
- return(True);
+void set_first_token(char *ptr)
+{
+ last_ptr = ptr;
}
+
/****************************************************************************
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;
-
- if (!sep) sep = " \t\n\r";
+ char *s=last_ptr;
+ int ictok=0;
+ char **ret, **iret;
- while(*s && strchr(sep,*s)) s++;
+ if (!sep) sep = " \t\n\r";
- /* nothing left? */
- if (!*s) return(NULL);
+ while(*s && strchr(sep,*s)) s++;
- do {
- ictok++;
- while(*s && (!strchr(sep,*s))) s++;
- while(*s && strchr(sep,*s)) *s++=0;
- } while(*s);
+ /* nothing left? */
+ if (!*s) return(NULL);
- *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);
+
+ *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;
+ return ret;
}
-
/*******************************************************************
case insensitive string compararison
********************************************************************/
int StrCaseCmp(const char *s, const char *t)
{
- /* 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));
- }
+ pstring buf1, buf2;
+ unix_strlower(s, strlen(s)+1, buf1, sizeof(buf1));
+ unix_strlower(t, strlen(t)+1, buf2, sizeof(buf2));
+ return strcmp(buf1,buf2);
}
/*******************************************************************
********************************************************************/
int StrnCaseCmp(const char *s, const char *t, size_t 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);
- }
+ pstring buf1, buf2;
+ unix_strlower(s, strlen(s)+1, buf1, sizeof(buf1));
+ unix_strlower(t, strlen(t)+1, buf2, sizeof(buf2));
+ return strncmp(buf1,buf2,n);
}
/*******************************************************************
}
-/*******************************************************************
- 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
********************************************************************/
********************************************************************/
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)
{
- 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++;
- }
- }
- }
+ 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);
}
********************************************************************/
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)
{
- 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;
+ push_ucs2(NULL, tmpbuf,s, sizeof(tmpbuf), STR_TERMINATE);
+ return strlen_w(tmpbuf);
}
/*******************************************************************
BOOL trim_string(char *s,const char *front,const char *back)
{
- BOOL ret = False;
- size_t front_len = (front && *front) ? strlen(front) : 0;
- size_t back_len = (back && *back) ? strlen(back) : 0;
- size_t s_len;
-
- while (front_len && strncmp(s, front, front_len) == 0)
- {
- char *p = s;
- ret = True;
- while (1)
- {
- if (!(*p = p[front_len]))
- break;
- p++;
- }
- }
+ BOOL ret = False;
+ size_t front_len;
+ size_t back_len;
+ size_t len;
- /*
- * 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.
- */
-
- if(back_len)
- {
- if(!global_is_multibyte_codepage)
- {
- s_len = strlen(s);
- while ((s_len >= back_len) &&
- (strncmp(s + s_len - back_len, back, back_len)==0))
- {
- ret = True;
- s[s_len - back_len] = '\0';
- s_len = strlen(s);
- }
- }
- else
- {
+ /* Ignore null or empty strings. */
+ if (!s || (s[0] == '\0'))
+ return False;
- /*
- * Multibyte code page case.
- * Keep going through the string, trying
- * to match the 'back' string with the end
- * of the string. If we get a match, truncate
- * 'back' off the end of the string and
- * go through the string again from the
- * start. Keep doing this until we have
- * gone through the string with no match
- * at the string end.
- */
-
- size_t mb_back_len = str_charnum(back);
- size_t mb_s_len = str_charnum(s);
-
- while(mb_s_len >= mb_back_len)
- {
- size_t charcount = 0;
- char *mbp = s;
-
- /*
- * sbcs optimization.
- */
- if(!global_is_multibyte_codepage) {
- while(charcount < (mb_s_len - mb_back_len)) {
- mbp += 1;
- charcount++;
- }
- } else {
- while(charcount < (mb_s_len - mb_back_len)) {
- size_t skip = skip_multibyte_char(*mbp);
- mbp += (skip ? skip : 1);
- charcount++;
- }
- }
+ front_len = front? strlen(front) : 0;
+ back_len = back? strlen(back) : 0;
- /*
- * mbp now points at mb_back_len multibyte
- * characters from the end of s.
- */
-
- if(strcmp(mbp, back) == 0)
- {
- ret = True;
- *mbp = '\0';
- mb_s_len = str_charnum(s);
- mbp = s;
- }
- else
- break;
- } /* end while mb_s_len... */
- } /* end else .. */
- } /* end if back_len .. */
+ len = strlen(s);
- return(ret);
+ 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;
}
****************************************************************************/
BOOL strhasupper(const 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))
- 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);
+ 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);
}
/****************************************************************************
****************************************************************************/
BOOL strhaslower(const 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]))
- 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);
+ 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);
}
/****************************************************************************
-find the number of chars in a string
+find the number of 'c' chars in a string
****************************************************************************/
size_t count_chars(const char *s,char c)
{
- 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);
+ 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);
}
/*******************************************************************
BOOL str_is_all(const char *s,char c)
{
- 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;
+ 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;
}
/*******************************************************************
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;
+ }
- memcpy(dest, src, len);
- dest[len] = 0;
- return dest;
+ memmove(dest, src, len);
+ dest[len] = 0;
+ return dest;
}
/*******************************************************************
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 (!src) {
- return dest;
- }
-
- src_len = strlen(src);
- dest_len = strlen(dest);
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
+ return NULL;
+ }
- 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;
}
/*******************************************************************
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 !
+ zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
+ and replaces with '_'. Deliberately does *NOT* check for multibyte
+ characters. Don't change it !
********************************************************************/
-char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
+char *alpha_strcpy(char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
{
size_t len, i;
if (len >= maxlength)
len = maxlength - 1;
+ if (!other_safe_chars)
+ other_safe_chars = "";
+
for(i = 0; i < len; i++) {
int val = (src[i] & 0xff);
- if(isupper(val) ||islower(val) || isdigit(val))
+ if(isupper(val) || islower(val) || isdigit(val) || strchr(other_safe_chars, val))
dest[i] = src[i];
else
dest[i] = '_';
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);
}
/****************************************************************************
if (i == -1) {
return "-1";
}
- slprintf(ret, sizeof(ret), "0%o", i);
+ slprintf(ret, sizeof(ret)-1, "0%o", i);
return ret;
}
return s;
}
-/* Parse a string of the form DOMAIN/user into a domain and a user */
-void parse_domain_user(char *domuser, fstring domain, fstring user)
+/****************************************************************************
+strchr and strrchr are very hard to do on general multi-byte strings.
+we convert via ucs2 for now
+****************************************************************************/
+char *strchr_m(const char *s, char c)
{
- char *p;
- char *sep = lp_winbind_separator();
- if (!sep) sep = "\\";
- p = strchr(domuser,*sep);
- if (!p) p = strchr(domuser,'\\');
- if (!p) {
- fstrcpy(domain,"");
- fstrcpy(user, domuser);
- return;
- }
-
- fstrcpy(user, p+1);
- fstrcpy(domain, domuser);
- domain[PTR_DIFF(p, domuser)] = 0;
+ 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);
+}
+