Based on a routine by GJC@VILLAGE.COM.
Extensively modified by Andrew.Tridgell@anu.edu.au
****************************************************************************/
-BOOL next_token(char **ptr,char *buff,char *sep, int bufsize)
+BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
{
char *s;
BOOL quoted;
- int len=1;
+ size_t len=1;
if (!ptr) ptr = &last_ptr;
if (!ptr) return(False);
/*******************************************************************
case insensitive string compararison
********************************************************************/
-int StrCaseCmp(char *s, char *t)
+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
/*******************************************************************
case insensitive string compararison, length limited
********************************************************************/
-int StrnCaseCmp(char *s, char *t, int n)
+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
/*******************************************************************
compare 2 strings
********************************************************************/
-BOOL strequal(char *s1, char *s2)
+BOOL strequal(const char *s1, const char *s2)
{
if (s1 == s2) return(True);
if (!s1 || !s2) return(False);
/*******************************************************************
compare 2 strings up to and including the nth char.
******************************************************************/
-BOOL strnequal(char *s1,char *s2,int n)
+BOOL strnequal(const char *s1,const char *s2,size_t n)
{
if (s1 == s2) return(True);
if (!s1 || !s2 || !n) return(False);
/*******************************************************************
compare 2 strings (case sensitive)
********************************************************************/
-BOOL strcsequal(char *s1,char *s2)
+BOOL strcsequal(const char *s1,const char *s2)
{
if (s1 == s2) return(True);
if (!s1 || !s2) return(False);
return(strcmp(s1,s2)==0);
}
+/***************************************************************************
+Do a case-insensitive, whitespace-ignoring string compare.
+***************************************************************************/
+int strwicmp(char *psz1, char *psz2)
+{
+ /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
+ /* appropriate value. */
+ if (psz1 == psz2)
+ return (0);
+ else if (psz1 == NULL)
+ return (-1);
+ else if (psz2 == NULL)
+ return (1);
+
+ /* sync the strings on first non-whitespace */
+ while (1)
+ {
+ while (isspace(*psz1))
+ psz1++;
+ while (isspace(*psz2))
+ psz2++;
+ if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0'
+ || *psz2 == '\0')
+ break;
+ psz1++;
+ psz2++;
+ }
+ return (*psz1 - *psz2);
+}
+
/*******************************************************************
convert a string to lower case
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- int skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- int skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else
****************************************************************************/
void string_replace(char *s,char oldc,char newc)
{
- int skip;
- while (*s)
- {
- skip = skip_multibyte_char( *s );
- if( skip != 0 )
- s += skip;
- else
- {
+ 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++;
+ }
+ }
}
}
/*******************************************************************
skip past some strings in a buffer
********************************************************************/
-char *skip_string(char *buf,int n)
+char *skip_string(char *buf,size_t n)
{
while (n--)
buf += strlen(buf) + 1;
16.oct.98, jdblair@cobaltnet.com.
********************************************************************/
-size_t str_charnum(char *s)
+size_t str_charnum(const char *s)
{
size_t len = 0;
- while (*s != '\0') {
- int skip = skip_multibyte_char(*s);
- s += (skip ? skip : 1);
- len++;
+ /*
+ * 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;
}
trim the specified elements off the front and back of a string
********************************************************************/
-BOOL trim_string(char *s,char *front,char *back)
+BOOL trim_string(char *s,const char *front,const char *back)
{
BOOL ret = False;
size_t front_len = (front && *front) ? strlen(front) : 0;
if(back_len)
{
- if(!is_multibyte_codepage())
+ if(!global_is_multibyte_codepage)
{
s_len = strlen(s);
while ((s_len >= back_len) &&
size_t charcount = 0;
char *mbp = s;
- while(charcount < (mb_s_len - mb_back_len))
- {
- size_t skip = skip_multibyte_char(*mbp);
- mbp += (skip ? skip : 1);
- charcount++;
+ /*
+ * 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++;
+ }
}
/*
/****************************************************************************
does a string have any uppercase chars in it?
****************************************************************************/
-BOOL strhasupper(char *s)
+BOOL strhasupper(const char *s)
{
while (*s)
{
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- int skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else {
/****************************************************************************
does a string have any lowercase chars in it?
****************************************************************************/
-BOOL strhaslower(char *s)
+BOOL strhaslower(const char *s)
{
while (*s)
{
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- int skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else {
/****************************************************************************
find the number of chars in a string
****************************************************************************/
-int count_chars(char *s,char c)
+size_t count_chars(const char *s,char c)
{
- int count=0;
+ size_t count=0;
#if !defined(KANJI_WIN95_COMPATIBILITY)
/*
{
while (*s)
{
- int skip = skip_multibyte_char( *s );
+ size_t skip = get_character_len( *s );
if( skip != 0 )
s += skip;
else {
return(count);
}
+/*******************************************************************
+Return True if a string consists only of one particular character.
+********************************************************************/
+
+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;
+}
/*******************************************************************
safe string copy into a known length string. maxlength does not
include the terminating zero.
********************************************************************/
-char *safe_strcpy(char *dest,const char *src, int maxlength)
+
+char *safe_strcpy(char *dest,const char *src, size_t maxlength)
{
- int len;
+ size_t len;
if (!dest) {
DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
if (len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
- len-maxlength, src));
+ (int)(len-maxlength), src));
len = maxlength;
}
safe string cat into a string. maxlength does not
include the terminating zero.
********************************************************************/
-char *safe_strcat(char *dest, char *src, int maxlength)
+
+char *safe_strcat(char *dest, const char *src, size_t maxlength)
{
- int src_len, dest_len;
+ size_t src_len, dest_len;
if (!dest) {
DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
if (src_len + dest_len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
- src_len + dest_len - maxlength, src));
+ (int)(src_len + dest_len - maxlength), src));
src_len = maxlength - dest_len;
}
return dest;
}
-/****************************************************************************
-this is a safer strcpy(), meant to prevent core dumps when nasty things happen
-****************************************************************************/
-char *StrCpy(char *dest,char *src)
+/*******************************************************************
+ 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 !
+********************************************************************/
+
+char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
{
- char *d = dest;
+ size_t len, i;
- /* I don't want to get lazy with these ... */
- SMB_ASSERT(dest && src);
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
+ return NULL;
+ }
- if (!dest) return(NULL);
- if (!src) {
- *dest = 0;
- return(dest);
- }
- while ((*d++ = *src++)) ;
- return(dest);
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
+
+ len = strlen(src);
+ if (len >= maxlength)
+ len = maxlength - 1;
+
+ for(i = 0; i < len; i++) {
+ int val = (src[i] & 0xff);
+ if(isupper(val) ||islower(val) || isdigit(val))
+ dest[i] = src[i];
+ else
+ dest[i] = '_';
+ }
+
+ dest[i] = '\0';
+
+ return dest;
}
/****************************************************************************
-like strncpy but always null terminates. Make sure there is room!
+ Like strncpy but always null terminates. Make sure there is room!
+ The variable n should always be one less than the available size.
****************************************************************************/
-char *StrnCpy(char *dest,char *src,int n)
+
+char *StrnCpy(char *dest,const char *src,size_t n)
{
char *d = dest;
if (!dest) return(NULL);
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).
****************************************************************************/
-char *strncpyn(char *dest, char *src,int n, char c)
+char *strncpyn(char *dest, const char *src,size_t n, char c)
{
char *p;
- int str_len;
+ size_t str_len;
p = strchr(src, c);
if (p == NULL)
valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
**************************************************************/
-int strhex_to_str(char *p, int len, const char *strhex)
+size_t strhex_to_str(char *p, size_t len, const char *strhex)
{
- int i;
- int num_chars = 0;
+ size_t i;
+ size_t num_chars = 0;
unsigned char lonybble, hinybble;
char *hexchars = "0123456789ABCDEF";
char *p1 = NULL, *p2 = NULL;
continue;
}
- while (!(p1 = strchr(hexchars, toupper(strhex[i]))))
+ if (!(p1 = strchr(hexchars, toupper(strhex[i]))))
{
- continue;
+ break;
}
i++; /* next hex digit */
- while (!(p2 = strchr(hexchars, toupper(strhex[i]))))
+ if (!(p2 = strchr(hexchars, toupper(strhex[i]))))
{
- continue;
+ break;
}
/* get the two nybbles */
/****************************************************************************
set a string value, allocing the space for the string
****************************************************************************/
-BOOL string_init(char **dest,char *src)
+static BOOL string_init(char **dest,const char *src)
{
- int l;
+ size_t l;
if (!src)
src = "";
set a string value, allocing the space for the string, and deallocating any
existing space
****************************************************************************/
-BOOL string_set(char **dest,char *src)
+BOOL string_set(char **dest,const char *src)
{
string_free(dest);
return(string_init(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.
-return True if a substitution was done.
+any of " ; ' $ or ` in the insert string are replaced with _
+if len==0 then no length check is performed
****************************************************************************/
-BOOL string_sub(char *s,char *pattern,char *insert)
+void string_sub(char *s,const char *pattern,const char *insert, size_t len)
{
- BOOL ret = False;
- char *p;
- int ls,lp,li;
+ char *p;
+ ssize_t ls,lp,li, i;
+
+ if (!insert || !pattern || !s) return;
+
+ ls = (ssize_t)strlen(s);
+ lp = (ssize_t)strlen(pattern);
+ li = (ssize_t)strlen(insert);
+
+ if (!*pattern) return;
+
+ while (lp <= ls && (p = strstr(s,pattern))) {
+ if (len && (ls + (li-lp) >= len)) {
+ DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
+ (int)(ls + (li-lp) - len),
+ pattern, (int)len));
+ break;
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
+ for (i=0;i<li;i++) {
+ switch (insert[i]) {
+ case '`':
+ case '"':
+ case '\'':
+ case ';':
+ case '$':
+ case '%':
+ case '\r':
+ case '\n':
+ p[i] = '_';
+ break;
+ default:
+ p[i] = insert[i];
+ }
+ }
+ s = p + li;
+ ls += (li-lp);
+ }
+}
- if (!insert || !pattern || !s) return(False);
+void fstring_sub(char *s,const char *pattern,const char *insert)
+{
+ string_sub(s, pattern, insert, sizeof(fstring));
+}
- ls = strlen(s);
- lp = strlen(pattern);
- li = strlen(insert);
+void pstring_sub(char *s,const char *pattern,const char *insert)
+{
+ string_sub(s, pattern, insert, sizeof(pstring));
+}
- if (!*pattern) return(False);
+/****************************************************************************
+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(char *s,const char *pattern,const char *insert, size_t len)
+{
+ char *p;
+ ssize_t ls,lp,li;
+
+ if (!insert || !pattern || !s) return;
+
+ ls = (ssize_t)strlen(s);
+ lp = (ssize_t)strlen(pattern);
+ li = (ssize_t)strlen(insert);
+
+ if (!*pattern) return;
+
+ while (lp <= ls && (p = strstr(s,pattern))) {
+ if (len && (ls + (li-lp) >= len)) {
+ DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n",
+ (int)(ls + (li-lp) - len),
+ pattern, (int)len));
+ break;
+ }
+ if (li != lp) {
+ memmove(p+li,p+lp,strlen(p+lp)+1);
+ }
+ memcpy(p, insert, li);
+ s = p + li;
+ ls += (li-lp);
+ }
+}
- while (lp <= ls && (p = strstr(s,pattern)))
- {
- ret = True;
- memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
- memcpy(p,insert,li);
- s = p + li;
- ls = strlen(s);
- }
- return(ret);
+/****************************************************************************
+ splits out the front and back at a separator.
+****************************************************************************/
+void split_at_last_component(char *path, char *front, char sep, char *back)
+{
+ char *p = strrchr(path, sep);
+
+ if (p != NULL)
+ {
+ *p = 0;
+ }
+ if (front != NULL)
+ {
+ pstrcpy(front, path);
+ }
+ if (p != NULL)
+ {
+ if (back != NULL)
+ {
+ pstrcpy(back, p+1);
+ }
+ *p = '\\';
+ }
+ else
+ {
+ if (back != NULL)
+ {
+ back[0] = 0;
+ }
+ }
+}
+
+
+/****************************************************************************
+write an octal as a string
+****************************************************************************/
+char *octal_string(int i)
+{
+ static char ret[64];
+ if (i == -1) {
+ return "-1";
+ }
+ slprintf(ret, sizeof(ret), "0%o", i);
+ return ret;
+}
+
+
+/****************************************************************************
+truncate a string at a specified length
+****************************************************************************/
+char *string_truncate(char *s, int length)
+{
+ if (s && strlen(s) > length) {
+ s[length] = 0;
+ }
+ 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)
+{
+ 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;
+ strupper(domain);
+}