Revert "Fix bug #7781 (Samba transforms "ShareName" to lowercase when adding new...
[samba.git] / source3 / lib / util_str.c
index c2eeb12544e2f12db06b502ca51754822479fc5f..d86963702e03ebc73365d327f08f5f090e098e16 100644 (file)
-/* 
+/*
    Unix SMB/CIFS implementation.
    Samba utility functions
    Unix SMB/CIFS implementation.
    Samba utility functions
-   
+
    Copyright (C) Andrew Tridgell 1992-2001
    Copyright (C) Simo Sorce      2001-2002
    Copyright (C) Martin Pool     2003
    Copyright (C) James Peach    2006
    Copyright (C) Jeremy Allison  1992-2007
    Copyright (C) Andrew Tridgell 1992-2001
    Copyright (C) Simo Sorce      2001-2002
    Copyright (C) Martin Pool     2003
    Copyright (C) James Peach    2006
    Copyright (C) Jeremy Allison  1992-2007
-   
+
    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
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    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
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 
-/**
- * @file
- * @brief String utilities.
- **/
-
-/**
- * Internal function to get the next token from a string, return False if none
- * found.  Handles double-quotes.  This is the work horse function called by
- * next_token() and next_token_no_ltrim().
- *
- * Based on a routine by GJC@VILLAGE.COM. 
- * Extensively modified by Andrew.Tridgell@anu.edu.au
- */
-static BOOL next_token_internal(const char **ptr,
-                                char *buff,
-                                const char *sep,
-                                size_t bufsize,
-                                BOOL ltrim)
-{
-       char *s;
-       char *pbuf;
-       BOOL quoted;
-       size_t len=1;
-
-       if (!ptr)
-               return(False);
-
-       s = (char *)*ptr;
-
-       /* default to simple separators */
-       if (!sep)
-               sep = " \t\n\r";
-
-       /* find the first non sep char, if left-trimming is requested */
-       if (ltrim) {
-               while (*s && strchr_m(sep,*s))
-                       s++;
-       }
-       
-       /* nothing left? */
-       if (! *s)
-               return(False);
-       
-       /* copy over the token */
-       pbuf = buff;
-       for (quoted = False; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
-               if ( *s == '\"' ) {
-                       quoted = !quoted;
-               } else {
-                       len++;
-                       *pbuf++ = *s;
-               }
-       }
-       
-       *ptr = (*s) ? s+1 : s;  
-       *pbuf = 0;
-       
-       return(True);
-}
-
-/*
- * Get the next token from a string, return False if none found.  Handles
- * double-quotes.  This version trims leading separator characters before
- * looking for a token.
- */
-BOOL next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
-{
-    return next_token_internal(ptr, buff, sep, bufsize, True);
-}
-
-/*
- * Get the next token from a string, return False if none found.  Handles
- * double-quotes.  This version does not trim leading separator characters
- * before looking for a token.
- */
-BOOL next_token_no_ltrim(const char **ptr,
-                         char *buff,
-                         const char *sep,
-                         size_t bufsize)
-{
-    return next_token_internal(ptr, buff, sep, bufsize, False);
-}
-
-/**
-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 const char *last_ptr=NULL;
-
-BOOL next_token_nr(const char **ptr,char *buff, const char *sep, size_t bufsize)
-{
-       BOOL ret;
-       if (!ptr)
-               ptr = &last_ptr;
-
-       ret = next_token(ptr, buff, sep, bufsize);
-       last_ptr = *ptr;
-       return ret;     
-}
-
-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, const char *sep)
-{
-       char *s=(char *)last_ptr;
-       int ictok=0;
-       char **ret, **iret;
-
-       if (!sep)
-               sep = " \t\n\r";
-
-       while(*s && strchr_m(sep,*s))
-               s++;
-
-       /* nothing left? */
-       if (!*s)
-               return(NULL);
-
-       do {
-               ictok++;
-               while(*s && (!strchr_m(sep,*s)))
-                       s++;
-               while(*s && strchr_m(sep,*s))
-                       *s++=0;
-       } while(*s);
-       
-       *ctok=ictok;
-       s=(char *)last_ptr;
-       
-       if (!(ret=iret=SMB_MALLOC_ARRAY(char *,ictok+1)))
-               return NULL;
-       
-       while(ictok--) {    
-               *iret++=s;
-               if (ictok > 0) {
-                       while(*s++)
-                               ;
-                       while(!*s)
-                               s++;
-               }
-       }
-
-       ret[*ctok] = NULL;
-       return ret;
-}
+const char toupper_ascii_fast_table[128] = {
+       0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
+       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+       0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+       0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+       0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+       0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
+};
 
 /**
  * Case insensitive string compararison.
 
 /**
  * Case insensitive string compararison.
@@ -207,7 +62,7 @@ char **toktocliplist(int *ctok, const char *sep)
  * different, we'd need to restart the whole thing.
  *
  * Even better is to implement strcasecmp for each encoding and use a
  * different, we'd need to restart the whole thing.
  *
  * Even better is to implement strcasecmp for each encoding and use a
- * function pointer. 
+ * function pointer.
  **/
 int StrCaseCmp(const char *s, const char *t)
 {
  **/
 int StrCaseCmp(const char *s, const char *t)
 {
@@ -227,11 +82,12 @@ int StrCaseCmp(const char *s, const char *t)
                else if (!*pt)
                        return +1; /* t is a prefix */
                else if ((*ps & 0x80) || (*pt & 0x80))
                else if (!*pt)
                        return +1; /* t is a prefix */
                else if ((*ps & 0x80) || (*pt & 0x80))
-                       /* not ascii anymore, do it the hard way from here on in */
+                       /* not ascii anymore, do it the hard way
+                        * from here on in */
                        break;
 
                        break;
 
-               us = toupper_ascii(*ps);
-               ut = toupper_ascii(*pt);
+               us = toupper_ascii_fast(*ps);
+               ut = toupper_ascii_fast(*pt);
                if (us == ut)
                        continue;
                else if (us < ut)
                if (us == ut)
                        continue;
                else if (us < ut)
@@ -240,24 +96,24 @@ int StrCaseCmp(const char *s, const char *t)
                        return +1;
        }
 
                        return +1;
        }
 
-       size = push_ucs2_allocate(&buffer_s, ps);
-       if (size == (size_t)-1) {
-               return strcmp(ps, pt); 
+       if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
+               return strcmp(ps, pt);
                /* Not quite the right answer, but finding the right one
                /* Not quite the right answer, but finding the right one
-                  under this failure case is expensive, and it's pretty close */
+                  under this failure case is expensive, and it's pretty
+                  close */
        }
        }
-       
-       size = push_ucs2_allocate(&buffer_t, pt);
-       if (size == (size_t)-1) {
-               SAFE_FREE(buffer_s);
-               return strcmp(ps, pt); 
+
+       if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
+               TALLOC_FREE(buffer_s);
+               return strcmp(ps, pt);
                /* Not quite the right answer, but finding the right one
                /* Not quite the right answer, but finding the right one
-                  under this failure case is expensive, and it's pretty close */
+                  under this failure case is expensive, and it's pretty
+                  close */
        }
        }
-       
+
        ret = strcasecmp_w(buffer_s, buffer_t);
        ret = strcasecmp_w(buffer_s, buffer_t);
-       SAFE_FREE(buffer_s);
-       SAFE_FREE(buffer_t);
+       TALLOC_FREE(buffer_s);
+       TALLOC_FREE(buffer_t);
        return ret;
 }
 
        return ret;
 }
 
@@ -287,8 +143,8 @@ int StrnCaseCmp(const char *s, const char *t, size_t len)
                         * hard way from here on in */
                        break;
 
                         * hard way from here on in */
                        break;
 
-               us = toupper_ascii(*ps);
-               ut = toupper_ascii(*pt);
+               us = toupper_ascii_fast(*ps);
+               ut = toupper_ascii_fast(*pt);
                if (us == ut)
                        continue;
                else if (us < ut)
                if (us == ut)
                        continue;
                else if (us < ut)
@@ -301,17 +157,15 @@ int StrnCaseCmp(const char *s, const char *t, size_t len)
                return 0;
        }
 
                return 0;
        }
 
-       size = push_ucs2_allocate(&buffer_s, ps);
-       if (size == (size_t)-1) {
+       if (!push_ucs2_talloc(talloc_tos(), &buffer_s, ps, &size)) {
                return strncmp(ps, pt, len-n);
                /* Not quite the right answer, but finding the right one
                   under this failure case is expensive,
                   and it's pretty close */
        }
 
                return strncmp(ps, pt, len-n);
                /* Not quite the right answer, but finding the right one
                   under this failure case is expensive,
                   and it's pretty close */
        }
 
-       size = push_ucs2_allocate(&buffer_t, pt);
-       if (size == (size_t)-1) {
-               SAFE_FREE(buffer_s);
+       if (!push_ucs2_talloc(talloc_tos(), &buffer_t, pt, &size)) {
+               TALLOC_FREE(buffer_s);
                return strncmp(ps, pt, len-n);
                /* Not quite the right answer, but finding the right one
                   under this failure case is expensive,
                return strncmp(ps, pt, len-n);
                /* Not quite the right answer, but finding the right one
                   under this failure case is expensive,
@@ -319,8 +173,8 @@ int StrnCaseCmp(const char *s, const char *t, size_t len)
        }
 
        ret = strncasecmp_w(buffer_s, buffer_t, len-n);
        }
 
        ret = strncasecmp_w(buffer_s, buffer_t, len-n);
-       SAFE_FREE(buffer_s);
-       SAFE_FREE(buffer_t);
+       TALLOC_FREE(buffer_s);
+       TALLOC_FREE(buffer_t);
        return ret;
 }
 
        return ret;
 }
 
@@ -329,12 +183,12 @@ int StrnCaseCmp(const char *s, const char *t, size_t len)
  *
  * @note The comparison is case-insensitive.
  **/
  *
  * @note The comparison is case-insensitive.
  **/
-BOOL strequal(const char *s1, const char *s2)
+bool strequal(const char *s1, const char *s2)
 {
        if (s1 == s2)
 {
        if (s1 == s2)
-               return(True);
+               return(true);
        if (!s1 || !s2)
        if (!s1 || !s2)
-               return(False);
+               return(false);
 
        return(StrCaseCmp(s1,s2)==0);
 }
 
        return(StrCaseCmp(s1,s2)==0);
 }
@@ -344,12 +198,12 @@ BOOL strequal(const char *s1, const char *s2)
  *
  * @note The comparison is case-insensitive.
  **/
  *
  * @note The comparison is case-insensitive.
  **/
-BOOL strnequal(const char *s1,const char *s2,size_t n)
+bool strnequal(const char *s1,const char *s2,size_t n)
 {
        if (s1 == s2)
 {
        if (s1 == s2)
-               return(True);
+               return(true);
        if (!s1 || !s2 || !n)
        if (!s1 || !s2 || !n)
-               return(False);
+               return(false);
 
        return(StrnCaseCmp(s1,s2,n)==0);
 }
 
        return(StrnCaseCmp(s1,s2,n)==0);
 }
@@ -358,13 +212,13 @@ BOOL strnequal(const char *s1,const char *s2,size_t n)
  Compare 2 strings (case sensitive).
 **/
 
  Compare 2 strings (case sensitive).
 **/
 
-BOOL strcsequal(const char *s1,const char *s2)
+bool strcsequal(const char *s1,const char *s2)
 {
        if (s1 == s2)
 {
        if (s1 == s2)
-               return(True);
+               return(true);
        if (!s1 || !s2)
        if (!s1 || !s2)
-               return(False);
-  
+               return(false);
+
        return(strcmp(s1,s2)==0);
 }
 
        return(strcmp(s1,s2)==0);
 }
 
@@ -389,8 +243,8 @@ int strwicmp(const char *psz1, const char *psz2)
                        psz1++;
                while (isspace((int)*psz2))
                        psz2++;
                        psz1++;
                while (isspace((int)*psz2))
                        psz2++;
-               if (toupper_ascii(*psz1) != toupper_ascii(*psz2) || *psz1 == '\0'
-                   || *psz2 == '\0')
+               if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
+                               *psz1 == '\0' || *psz2 == '\0')
                        break;
                psz1++;
                psz2++;
                        break;
                psz1++;
                psz2++;
@@ -398,26 +252,6 @@ int strwicmp(const char *psz1, const char *psz2)
        return (*psz1 - *psz2);
 }
 
        return (*psz1 - *psz2);
 }
 
-
-/**
- Convert a string to upper case, but don't modify it.
-**/
-
-char *strupper_static(const char *s)
-{
-       static char *str = NULL;
-
-       if (str) {
-               SAFE_FREE(str);
-       }
-       str = SMB_STRDUP(s);
-       if (!str) {
-               return CONST_DISCARD(char *,s);
-       }
-       strupper_m(str);
-       return str;
-}
-
 /**
  Convert a string to "normal" form.
 **/
 /**
  Convert a string to "normal" form.
 **/
@@ -434,7 +268,7 @@ void strnorm(char *s, int case_default)
  Check if a string is in "normal" case.
 **/
 
  Check if a string is in "normal" case.
 **/
 
-BOOL strisnormal(const char *s, int case_default)
+bool strisnormal(const char *s, int case_default)
 {
        if (case_default == CASE_UPPER)
                return(!strhaslower(s));
 {
        if (case_default == CASE_UPPER)
                return(!strhaslower(s));
@@ -447,7 +281,6 @@ BOOL strisnormal(const char *s, int case_default)
  String replace.
  NOTE: oldc and newc must be 7 bit characters
 **/
  String replace.
  NOTE: oldc and newc must be 7 bit characters
 **/
-
 void string_replace( char *s, char oldc, char newc )
 {
        char *p;
 void string_replace( char *s, char oldc, char newc )
 {
        char *p;
@@ -531,13 +364,13 @@ char *skip_string(const char *base, size_t len, char *buf)
 
 size_t str_charnum(const char *s)
 {
 
 size_t str_charnum(const char *s)
 {
-       size_t ret;
+       size_t ret, converted_size;
        smb_ucs2_t *tmpbuf2 = NULL;
        smb_ucs2_t *tmpbuf2 = NULL;
-       if (push_ucs2_allocate(&tmpbuf2, s) == (size_t)-1) {
+       if (!push_ucs2_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
                return 0;
        }
        ret = strlen_w(tmpbuf2);
                return 0;
        }
        ret = strlen_w(tmpbuf2);
-       SAFE_FREE(tmpbuf2);
+       TALLOC_FREE(tmpbuf2);
        return ret;
 }
 
        return ret;
 }
 
@@ -549,25 +382,25 @@ size_t str_charnum(const char *s)
 
 size_t str_ascii_charnum(const char *s)
 {
 
 size_t str_ascii_charnum(const char *s)
 {
-       size_t ret;
+       size_t ret, converted_size;
        char *tmpbuf2 = NULL;
        char *tmpbuf2 = NULL;
-       if (push_ascii_allocate(&tmpbuf2, s) == (size_t)-1) {
+       if (!push_ascii_talloc(talloc_tos(), &tmpbuf2, s, &converted_size)) {
                return 0;
        }
        ret = strlen(tmpbuf2);
                return 0;
        }
        ret = strlen(tmpbuf2);
-       SAFE_FREE(tmpbuf2);
+       TALLOC_FREE(tmpbuf2);
        return ret;
 }
 
        return ret;
 }
 
-BOOL trim_char(char *s,char cfront,char cback)
+bool trim_char(char *s,char cfront,char cback)
 {
 {
-       BOOL ret = False;
+       bool ret = false;
        char *ep;
        char *fp = s;
 
        /* Ignore null or empty strings. */
        if (!s || (s[0] == '\0'))
        char *ep;
        char *fp = s;
 
        /* Ignore null or empty strings. */
        if (!s || (s[0] == '\0'))
-               return False;
+               return false;
 
        if (cfront) {
                while (*fp && *fp == cfront)
 
        if (cfront) {
                while (*fp && *fp == cfront)
@@ -575,17 +408,17 @@ BOOL trim_char(char *s,char cfront,char cback)
                if (!*fp) {
                        /* We ate the string. */
                        s[0] = '\0';
                if (!*fp) {
                        /* We ate the string. */
                        s[0] = '\0';
-                       return True;
+                       return true;
                }
                if (fp != s)
                }
                if (fp != s)
-                       ret = True;
+                       ret = true;
        }
 
        ep = fp + strlen(fp) - 1;
        if (cback) {
                /* Attempt ascii only. Bail for mb strings. */
                while ((ep >= fp) && (*ep == cback)) {
        }
 
        ep = fp + strlen(fp) - 1;
        if (cback) {
                /* Attempt ascii only. Bail for mb strings. */
                while ((ep >= fp) && (*ep == cback)) {
-                       ret = True;
+                       ret = true;
                        if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
                                /* Could be mb... bail back to tim_string. */
                                char fs[2], bs[2];
                        if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
                                /* Could be mb... bail back to tim_string. */
                                char fs[2], bs[2];
@@ -603,7 +436,7 @@ BOOL trim_char(char *s,char cfront,char cback)
                if (ep < fp) {
                        /* We ate the string. */
                        s[0] = '\0';
                if (ep < fp) {
                        /* We ate the string. */
                        s[0] = '\0';
-                       return True;
+                       return true;
                }
        }
 
                }
        }
 
@@ -612,57 +445,18 @@ BOOL trim_char(char *s,char cfront,char cback)
        return ret;
 }
 
        return ret;
 }
 
-/**
- Trim the specified elements off the front and back of a string.
-**/
-
-BOOL trim_string(char *s,const char *front,const char *back)
-{
-       BOOL ret = False;
-       size_t front_len;
-       size_t back_len;
-       size_t len;
-
-       /* Ignore null or empty strings. */
-       if (!s || (s[0] == '\0'))
-               return False;
-
-       front_len       = front? strlen(front) : 0;
-       back_len        = back? strlen(back) : 0;
-
-       len = strlen(s);
-
-       if (front_len) {
-               while (len && strncmp(s, front, front_len)==0) {
-                       /* Must use memmove here as src & dest can
-                        * easily overlap. Found by valgrind. JRA. */
-                       memmove(s, s+front_len, (len-front_len)+1);
-                       len -= front_len;
-                       ret=True;
-               }
-       }
-       
-       if (back_len) {
-               while ((len >= back_len) && strncmp(s+len-back_len,back,back_len)==0) {
-                       s[len-back_len]='\0';
-                       len -= back_len;
-                       ret=True;
-               }
-       }
-       return ret;
-}
-
 /**
  Does a string have any uppercase chars in it?
 **/
 
 /**
  Does a string have any uppercase chars in it?
 **/
 
-BOOL strhasupper(const char *s)
+bool strhasupper(const char *s)
 {
        smb_ucs2_t *tmp, *p;
 {
        smb_ucs2_t *tmp, *p;
-       BOOL ret;
+       bool ret;
+       size_t converted_size;
 
 
-       if (push_ucs2_allocate(&tmp, s) == -1) {
-               return False;
+       if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
+               return false;
        }
 
        for(p = tmp; *p != 0; p++) {
        }
 
        for(p = tmp; *p != 0; p++) {
@@ -672,7 +466,7 @@ BOOL strhasupper(const char *s)
        }
 
        ret = (*p != 0);
        }
 
        ret = (*p != 0);
-       SAFE_FREE(tmp);
+       TALLOC_FREE(tmp);
        return ret;
 }
 
        return ret;
 }
 
@@ -680,13 +474,14 @@ BOOL strhasupper(const char *s)
  Does a string have any lowercase chars in it?
 **/
 
  Does a string have any lowercase chars in it?
 **/
 
-BOOL strhaslower(const char *s)
+bool strhaslower(const char *s)
 {
        smb_ucs2_t *tmp, *p;
 {
        smb_ucs2_t *tmp, *p;
-       BOOL ret;
+       bool ret;
+       size_t converted_size;
 
 
-       if (push_ucs2_allocate(&tmp, s) == -1) {
-               return False;
+       if (!push_ucs2_talloc(talloc_tos(), &tmp, s, &converted_size)) {
+               return false;
        }
 
        for(p = tmp; *p != 0; p++) {
        }
 
        for(p = tmp; *p != 0; p++) {
@@ -696,43 +491,26 @@ BOOL strhaslower(const char *s)
        }
 
        ret = (*p != 0);
        }
 
        ret = (*p != 0);
-       SAFE_FREE(tmp);
+       TALLOC_FREE(tmp);
        return ret;
 }
 
        return ret;
 }
 
-/**
- Find the number of 'c' chars in a string
-**/
-
-size_t count_chars(const char *s,char c)
-{
-       smb_ucs2_t *ptr;
-       int count;
-       smb_ucs2_t *alloc_tmpbuf = NULL;
-
-       if (push_ucs2_allocate(&alloc_tmpbuf, s) == (size_t)-1) {
-               return 0;
-       }
-
-       for(count=0,ptr=alloc_tmpbuf;*ptr;ptr++)
-               if(*ptr==UCS2_CHAR(c))
-                       count++;
-
-       SAFE_FREE(alloc_tmpbuf);
-       return(count);
-}
-
 /**
  Safe string copy into a known length string. maxlength does not
  include the terminating zero.
 **/
 
 /**
  Safe string copy into a known length string. maxlength does not
  include the terminating zero.
 **/
 
-char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_t maxlength)
+char *safe_strcpy_fn(const char *fn,
+               int line,
+               char *dest,
+               const char *src,
+               size_t maxlength)
 {
        size_t len;
 
        if (!dest) {
 {
        size_t len;
 
        if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in safe_strcpy, called from [%s][%d]\n", fn, line));
+               DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
+                       "called from [%s][%d]\n", fn, line));
                return NULL;
        }
 
                return NULL;
        }
 
@@ -743,38 +521,44 @@ char *safe_strcpy_fn(const char *fn, int line, char *dest,const char *src, size_
        if (!src) {
                *dest = 0;
                return dest;
        if (!src) {
                *dest = 0;
                return dest;
-       }  
+       }
 
        len = strnlen(src, maxlength+1);
 
        if (len > maxlength) {
 
        len = strnlen(src, maxlength+1);
 
        if (len > maxlength) {
-               DEBUG(0,("ERROR: string overflow by %lu (%lu - %lu) in safe_strcpy [%.50s]\n",
-                        (unsigned long)(len-maxlength), (unsigned long)len, 
+               DEBUG(0,("ERROR: string overflow by "
+                       "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
+                        (unsigned long)(len-maxlength), (unsigned long)len,
                         (unsigned long)maxlength, src));
                len = maxlength;
        }
                         (unsigned long)maxlength, src));
                len = maxlength;
        }
-      
+
        memmove(dest, src, len);
        dest[len] = 0;
        return dest;
        memmove(dest, src, len);
        dest[len] = 0;
        return dest;
-}  
+}
 
 /**
  Safe string cat into a string. maxlength does not
  include the terminating zero.
 **/
 
 /**
  Safe string cat into a string. maxlength does not
  include the terminating zero.
 **/
-char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size_t maxlength)
+char *safe_strcat_fn(const char *fn,
+               int line,
+               char *dest,
+               const char *src,
+               size_t maxlength)
 {
        size_t src_len, dest_len;
 
        if (!dest) {
 {
        size_t src_len, dest_len;
 
        if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in safe_strcat, called from [%s][%d]\n", fn, line));
+               DEBUG(0,("ERROR: NULL dest in safe_strcat, "
+                       "called from [%s][%d]\n", fn, line));
                return NULL;
        }
 
        if (!src)
                return dest;
                return NULL;
        }
 
        if (!src)
                return dest;
-       
+
        src_len = strnlen(src, maxlength + 1);
        dest_len = strnlen(dest, maxlength + 1);
 
        src_len = strnlen(src, maxlength + 1);
        dest_len = strnlen(dest, maxlength + 1);
 
@@ -783,7 +567,8 @@ char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size
 #endif
 
        if (src_len + dest_len > maxlength) {
 #endif
 
        if (src_len + dest_len > maxlength) {
-               DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
+               DEBUG(0,("ERROR: string overflow by %d "
+                       "in safe_strcat [%.50s]\n",
                         (int)(src_len + dest_len - maxlength), src));
                if (maxlength > dest_len) {
                        memcpy(&dest[dest_len], src, maxlength - dest_len);
                         (int)(src_len + dest_len - maxlength), src));
                if (maxlength > dest_len) {
                        memcpy(&dest[dest_len], src, maxlength - dest_len);
@@ -801,9 +586,17 @@ char *safe_strcat_fn(const char *fn, int line, char *dest, const char *src, size
  Paranoid strcpy into a buffer of given length (includes terminating
  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
  and replaces with '_'. Deliberately does *NOT* check for multibyte
  Paranoid strcpy into a buffer of given length (includes terminating
  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 !
+ characters. Treats src as an array of bytes, not as a multibyte
+ string. Any byte >0x7f is automatically converted to '_'.
+ other_safe_chars must also contain an ascii string (bytes<0x7f).
 **/
 **/
-char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, const char *other_safe_chars, size_t maxlength)
+
+char *alpha_strcpy_fn(const char *fn,
+               int line,
+               char *dest,
+               const char *src,
+               const char *other_safe_chars,
+               size_t maxlength)
 {
        size_t len, i;
 
 {
        size_t len, i;
 
@@ -812,14 +605,15 @@ char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, con
 #endif
 
        if (!dest) {
 #endif
 
        if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in alpha_strcpy, called from [%s][%d]\n", fn, line));
+               DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
+                       "called from [%s][%d]\n", fn, line));
                return NULL;
        }
 
        if (!src) {
                *dest = 0;
                return dest;
                return NULL;
        }
 
        if (!src) {
                *dest = 0;
                return dest;
-       }  
+       }
 
        len = strlen(src);
        if (len >= maxlength)
 
        len = strlen(src);
        if (len >= maxlength)
@@ -830,7 +624,12 @@ char *alpha_strcpy_fn(const char *fn, int line, char *dest, const char *src, con
 
        for(i = 0; i < len; i++) {
                int val = (src[i] & 0xff);
 
        for(i = 0; i < len; i++) {
                int val = (src[i] & 0xff);
-               if (isupper_ascii(val) || islower_ascii(val) || isdigit(val) || strchr_m(other_safe_chars, val))
+               if (val > 0x7f) {
+                       dest[i] = '_';
+                       continue;
+               }
+               if (isupper(val) || islower(val) ||
+                               isdigit(val) || strchr(other_safe_chars, val))
                        dest[i] = src[i];
                else
                        dest[i] = '_';
                        dest[i] = src[i];
                else
                        dest[i] = '_';
@@ -854,7 +653,8 @@ char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
 #endif
 
        if (!dest) {
 #endif
 
        if (!dest) {
-               DEBUG(0,("ERROR: NULL dest in StrnCpy, called from [%s][%d]\n", fn, line));
+               DEBUG(0,("ERROR: NULL dest in StrnCpy, "
+                       "called from [%s][%d]\n", fn, line));
                return(NULL);
        }
 
                return(NULL);
        }
 
@@ -862,7 +662,7 @@ char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
                *dest = 0;
                return(dest);
        }
                *dest = 0;
                return(dest);
        }
-       
+
        while (n-- && (*d = *src)) {
                d++;
                src++;
        while (n-- && (*d = *src)) {
                d++;
                src++;
@@ -900,136 +700,50 @@ static char *strncpyn(char *dest, const char *src, size_t n, char c)
 }
 #endif
 
 }
 #endif
 
-/**
- Routine to get hex characters and turn them into a 16 byte array.
- the array can be variable length, and any non-hex-numeric
- characters are skipped.  "0xnn" or "0Xnn" is specially catered
- for.
-
- valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
-
-**/
-
-size_t strhex_to_str(char *p, size_t len, const char *strhex)
-{
-       size_t i;
-       size_t num_chars = 0;
-       unsigned char   lonybble, hinybble;
-       const char     *hexchars = "0123456789ABCDEF";
-       char           *p1 = NULL, *p2 = NULL;
-
-       for (i = 0; i < len && strhex[i] != 0; i++) {
-               if (strnequal(hexchars, "0x", 2)) {
-                       i++; /* skip two chars */
-                       continue;
-               }
-
-               if (!(p1 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
-                       break;
-
-               i++; /* next hex digit */
-
-               if (!(p2 = strchr_m(hexchars, toupper_ascii(strhex[i]))))
-                       break;
-
-               /* get the two nybbles */
-               hinybble = PTR_DIFF(p1, hexchars);
-               lonybble = PTR_DIFF(p2, hexchars);
-
-               p[num_chars] = (hinybble << 4) | lonybble;
-               num_chars++;
-
-               p1 = NULL;
-               p2 = NULL;
-       }
-       return num_chars;
-}
-
-DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex) 
-{
-       DATA_BLOB ret_blob;
-
-       if (mem_ctx != NULL)
-               ret_blob = data_blob_talloc(mem_ctx, NULL, strlen(strhex)/2+1);
-       else
-               ret_blob = data_blob(NULL, strlen(strhex)/2+1);
-
-       ret_blob.length = strhex_to_str((char*)ret_blob.data,   
-                                       strlen(strhex), 
-                                       strhex);
-
-       return ret_blob;
-}
-
-/**
- * Routine to print a buffer as HEX digits, into an allocated string.
- */
-
-char *hex_encode(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len)
-{
-       int i;
-       char *hex_buffer;
-
-       hex_buffer = TALLOC_ARRAY(mem_ctx, char, (len*2)+1);
-
-       for (i = 0; i < len; i++)
-               slprintf(&hex_buffer[i*2], 3, "%02X", buff_in[i]);
-
-       return hex_buffer;
-}
-
 /**
  Check if a string is part of a list.
 **/
 
 /**
  Check if a string is part of a list.
 **/
 
-BOOL in_list(const char *s, const char *list, BOOL casesensitive)
+bool in_list(const char *s, const char *list, bool casesensitive)
 {
 {
-       char *tok;
-       const char *p=list;
-       size_t bufsize = strlen(list);
-       BOOL ret = False;
-
-       if (!list)
-               return(False);
-
-       /* We know a token can't be larger
-        * than the entire list. */
+       char *tok = NULL;
+       bool ret = false;
+       TALLOC_CTX *frame;
 
 
-       tok = SMB_MALLOC(bufsize+1);
-       if (!tok) {
-               return False;
+       if (!list) {
+               return false;
        }
 
        }
 
-       while (next_token(&p,tok,LIST_SEP,bufsize+1)) {
+       frame = talloc_stackframe();
+       while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
                if (casesensitive) {
                        if (strcmp(tok,s) == 0) {
                if (casesensitive) {
                        if (strcmp(tok,s) == 0) {
-                               ret = True;
+                               ret = true;
                                break;
                        }
                } else {
                        if (StrCaseCmp(tok,s) == 0) {
                                break;
                        }
                } else {
                        if (StrCaseCmp(tok,s) == 0) {
-                               ret = True;
+                               ret = true;
                                break;
                        }
                }
        }
                                break;
                        }
                }
        }
-
-       SAFE_FREE(tok);
+       TALLOC_FREE(frame);
        return ret;
 }
 
 /* this is used to prevent lots of mallocs of size 1 */
        return ret;
 }
 
 /* this is used to prevent lots of mallocs of size 1 */
-static const char *null_string = "";
+static const char null_string[] = "";
 
 /**
  Set a string value, allocing the space for the string
 **/
 
 
 /**
  Set a string value, allocing the space for the string
 **/
 
-static BOOL string_init(char **dest,const char *src)
+static bool string_init(char **dest,const char *src)
 {
        size_t l;
 
 {
        size_t l;
 
-       if (!src)     
+       if (!src)
                src = "";
 
        l = strlen(src);
                src = "";
 
        l = strlen(src);
@@ -1040,10 +754,10 @@ static BOOL string_init(char **dest,const char *src)
                (*dest) = SMB_STRDUP(src);
                if ((*dest) == NULL) {
                        DEBUG(0,("Out of memory in string_init\n"));
                (*dest) = SMB_STRDUP(src);
                if ((*dest) == NULL) {
                        DEBUG(0,("Out of memory in string_init\n"));
-                       return False;
+                       return false;
                }
        }
                }
        }
-       return(True);
+       return(true);
 }
 
 /**
 }
 
 /**
@@ -1064,17 +778,17 @@ void string_free(char **s)
  for the string
 **/
 
  for the string
 **/
 
-BOOL string_set(char **dest,const char *src)
+bool string_set(char **dest,const char *src)
 {
        string_free(dest);
        return(string_init(dest,src));
 }
 
 /**
 {
        string_free(dest);
        return(string_init(dest,src));
 }
 
 /**
- Substitute a string for a pattern in another string. Make sure there is 
+ Substitute a string for a pattern in another string. Make sure there is
  enough room!
 
  enough room!
 
- This routine looks for pattern in s and replaces it with 
+ This routine looks for pattern in s and replaces it with
  insert. It may do multiple replacements or just one.
 
  Any of " ; ' $ or ` in the insert string are replaced with _
  insert. It may do multiple replacements or just one.
 
  Any of " ; ' $ or ` in the insert string are replaced with _
@@ -1082,8 +796,9 @@ BOOL string_set(char **dest,const char *src)
  use of len==0 which was for no length checks to be done.
 **/
 
  use of len==0 which was for no length checks to be done.
 **/
 
-void string_sub2(char *s,const char *pattern, const char *insert, size_t len, 
-                BOOL remove_unsafe_characters, BOOL replace_once, BOOL allow_trailing_dollar)
+void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
+                bool remove_unsafe_characters, bool replace_once,
+                bool allow_trailing_dollar)
 {
        char *p;
        ssize_t ls,lp,li, i;
 {
        char *p;
        ssize_t ls,lp,li, i;
@@ -1100,7 +815,8 @@ void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
 
        while (lp <= ls && (p = strstr_m(s,pattern))) {
                if (ls + (li-lp) >= len) {
 
        while (lp <= ls && (p = strstr_m(s,pattern))) {
                if (ls + (li-lp) >= len) {
-                       DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
+                       DEBUG(0,("ERROR: string overflow by "
+                               "%d in string_sub(%.50s, %d)\n",
                                 (int)(ls + (li-lp) - len),
                                 pattern, (int)len));
                        break;
                                 (int)(ls + (li-lp) - len),
                                 pattern, (int)len));
                        break;
@@ -1115,7 +831,8 @@ void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
                        case '\'':
                        case ';':
                        case '$':
                        case '\'':
                        case ';':
                        case '$':
-                               /* allow a trailing $ (as in machine accounts) */
+                               /* allow a trailing $
+                                * (as in machine accounts) */
                                if (allow_trailing_dollar && (i == li - 1 )) {
                                        p[i] = insert[i];
                                        break;
                                if (allow_trailing_dollar && (i == li - 1 )) {
                                        p[i] = insert[i];
                                        break;
@@ -1125,8 +842,9 @@ void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
                        case '\n':
                                if ( remove_unsafe_characters ) {
                                        p[i] = '_';
                        case '\n':
                                if ( remove_unsafe_characters ) {
                                        p[i] = '_';
-                                       /* yes this break should be here since we want to 
-                                          fall throw if not replacing unsafe chars */
+                                       /* yes this break should be here
+                                        * since we want to fall throw if
+                                        * not replacing unsafe chars */
                                        break;
                                }
                        default:
                                        break;
                                }
                        default:
@@ -1141,14 +859,15 @@ void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
        }
 }
 
        }
 }
 
-void string_sub_once(char *s, const char *pattern, const char *insert, size_t len)
+void string_sub_once(char *s, const char *pattern,
+               const char *insert, size_t len)
 {
 {
-       string_sub2( s, pattern, insert, len, True, True, False );
+       string_sub2( s, pattern, insert, len, true, true, false );
 }
 
 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
 {
 }
 
 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
 {
-       string_sub2( s, pattern, insert, len, True, False, False );
+       string_sub2( s, pattern, insert, len, true, false, false );
 }
 
 void fstring_sub(char *s,const char *pattern,const char *insert)
 }
 
 void fstring_sub(char *s,const char *pattern,const char *insert)
@@ -1156,20 +875,18 @@ void fstring_sub(char *s,const char *pattern,const char *insert)
        string_sub(s, pattern, insert, sizeof(fstring));
 }
 
        string_sub(s, pattern, insert, sizeof(fstring));
 }
 
-void pstring_sub(char *s,const char *pattern,const char *insert)
-{
-       string_sub(s, pattern, insert, sizeof(pstring));
-}
-
 /**
 /**
- Similar to string_sub, but it will accept only allocated strings
+ Similar to string_sub2, but it will accept only allocated strings
  and may realloc them so pay attention at what you pass on no
  and may realloc them so pay attention at what you pass on no
- pointers inside strings, no pstrings or const may be passed
+ pointers inside strings, no const may be passed
  as string.
 **/
 
  as string.
 **/
 
-char *realloc_string_sub(char *string, const char *pattern,
-                        const char *insert)
+char *realloc_string_sub2(char *string,
+                       const char *pattern,
+                       const char *insert,
+                       bool remove_unsafe_characters,
+                       bool allow_trailing_dollar)
 {
        char *p, *in;
        char *s;
 {
        char *p, *in;
        char *s;
@@ -1196,22 +913,31 @@ char *realloc_string_sub(char *string, const char *pattern,
                        case '\'':
                        case ';':
                        case '$':
                        case '\'':
                        case ';':
                        case '$':
+                               /* allow a trailing $
+                                * (as in machine accounts) */
+                               if (allow_trailing_dollar && (i == li - 1 )) {
+                                       break;
+                               }
                        case '%':
                        case '\r':
                        case '\n':
                        case '%':
                        case '\r':
                        case '\n':
-                               in[i] = '_';
+                               if ( remove_unsafe_characters ) {
+                                       in[i] = '_';
+                                       break;
+                               }
                        default:
                                /* ok */
                                break;
                }
        }
                        default:
                                /* ok */
                                break;
                }
        }
-       
+
        while ((p = strstr_m(s,pattern))) {
                if (ld > 0) {
                        int offset = PTR_DIFF(s,string);
                        string = (char *)SMB_REALLOC(string, ls + ld + 1);
                        if (!string) {
        while ((p = strstr_m(s,pattern))) {
                if (ld > 0) {
                        int offset = PTR_DIFF(s,string);
                        string = (char *)SMB_REALLOC(string, ls + ld + 1);
                        if (!string) {
-                               DEBUG(0, ("realloc_string_sub: out of memory!\n"));
+                               DEBUG(0, ("realloc_string_sub: "
+                                       "out of memory!\n"));
                                SAFE_FREE(in);
                                return NULL;
                        }
                                SAFE_FREE(in);
                                return NULL;
                        }
@@ -1228,22 +954,38 @@ char *realloc_string_sub(char *string, const char *pattern,
        return string;
 }
 
        return string;
 }
 
-/* Same as string_sub, but returns a talloc'ed string */
+char *realloc_string_sub(char *string,
+                       const char *pattern,
+                       const char *insert)
+{
+       return realloc_string_sub2(string, pattern, insert, true, false);
+}
+
+/*
+ * Internal guts of talloc_string_sub and talloc_all_string_sub.
+ * talloc version of string_sub2.
+ */
 
 
-char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
-                       const char *pattern, const char *insert)
+char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
+                       const char *pattern,
+                       const char *insert,
+                       bool remove_unsafe_characters,
+                       bool replace_once,
+                       bool allow_trailing_dollar)
 {
        char *p, *in;
        char *s;
        char *string;
        ssize_t ls,lp,li,ld, i;
 
 {
        char *p, *in;
        char *s;
        char *string;
        ssize_t ls,lp,li,ld, i;
 
-       if (!insert || !pattern || !*pattern || !src || !*src)
+       if (!insert || !pattern || !*pattern || !src) {
                return NULL;
                return NULL;
+       }
 
        string = talloc_strdup(mem_ctx, src);
        if (string == NULL) {
 
        string = talloc_strdup(mem_ctx, src);
        if (string == NULL) {
-               DEBUG(0, ("talloc_strdup failed\n"));
+               DEBUG(0, ("talloc_string_sub2: "
+                       "talloc_strdup failed\n"));
                return NULL;
        }
 
                return NULL;
        }
 
@@ -1251,13 +993,14 @@ char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
 
        in = SMB_STRDUP(insert);
        if (!in) {
 
        in = SMB_STRDUP(insert);
        if (!in) {
-               DEBUG(0, ("talloc_string_sub: out of memory!\n"));
+               DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
                return NULL;
        }
        ls = (ssize_t)strlen(s);
        lp = (ssize_t)strlen(pattern);
        li = (ssize_t)strlen(insert);
        ld = li - lp;
                return NULL;
        }
        ls = (ssize_t)strlen(s);
        lp = (ssize_t)strlen(pattern);
        li = (ssize_t)strlen(insert);
        ld = li - lp;
+
        for (i=0;i<li;i++) {
                switch (in[i]) {
                        case '`':
        for (i=0;i<li;i++) {
                switch (in[i]) {
                        case '`':
@@ -1265,16 +1008,24 @@ char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
                        case '\'':
                        case ';':
                        case '$':
                        case '\'':
                        case ';':
                        case '$':
+                               /* allow a trailing $
+                                * (as in machine accounts) */
+                               if (allow_trailing_dollar && (i == li - 1 )) {
+                                       break;
+                               }
                        case '%':
                        case '\r':
                        case '\n':
                        case '%':
                        case '\r':
                        case '\n':
-                               in[i] = '_';
+                               if (remove_unsafe_characters) {
+                                       in[i] = '_';
+                                       break;
+                               }
                        default:
                                /* ok */
                                break;
                }
        }
                        default:
                                /* ok */
                                break;
                }
        }
-       
+
        while ((p = strstr_m(s,pattern))) {
                if (ld > 0) {
                        int offset = PTR_DIFF(s,string);
        while ((p = strstr_m(s,pattern))) {
                if (ld > 0) {
                        int offset = PTR_DIFF(s,string);
@@ -1294,13 +1045,28 @@ char *talloc_string_sub(TALLOC_CTX *mem_ctx, const char *src,
                memcpy(p, in, li);
                s = p + li;
                ls += ld;
                memcpy(p, in, li);
                s = p + li;
                ls += ld;
+
+               if (replace_once) {
+                       break;
+               }
        }
        SAFE_FREE(in);
        return string;
 }
 
        }
        SAFE_FREE(in);
        return string;
 }
 
+/* Same as string_sub, but returns a talloc'ed string */
+
+char *talloc_string_sub(TALLOC_CTX *mem_ctx,
+                       const char *src,
+                       const char *pattern,
+                       const char *insert)
+{
+       return talloc_string_sub2(mem_ctx, src, pattern, insert,
+                       true, false, false);
+}
+
 /**
 /**
- Similar to string_sub() but allows for any character to be substituted. 
+ Similar to string_sub() but allows for any character to be substituted.
  Use with caution!
  if len==0 then the string cannot be extended. This is different from the old
  use of len==0 which was for no length checks to be done.
  Use with caution!
  if len==0 then the string cannot be extended. This is different from the old
  use of len==0 which was for no length checks to be done.
@@ -1320,13 +1086,14 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
 
        if (!*pattern)
                return;
 
        if (!*pattern)
                return;
-       
+
        if (len == 0)
                len = ls + 1; /* len is number of *bytes* */
        if (len == 0)
                len = ls + 1; /* len is number of *bytes* */
-       
+
        while (lp <= ls && (p = strstr_m(s,pattern))) {
                if (ls + (li-lp) >= len) {
        while (lp <= ls && (p = strstr_m(s,pattern))) {
                if (ls + (li-lp) >= len) {
-                       DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
+                       DEBUG(0,("ERROR: string overflow by "
+                               "%d in all_string_sub(%.50s, %d)\n",
                                 (int)(ls + (li-lp) - len),
                                 pattern, (int)len));
                        break;
                                 (int)(ls + (li-lp) - len),
                                 pattern, (int)len));
                        break;
@@ -1340,108 +1107,30 @@ 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 allocated unicode string.
- similar to string_sub() but allows for any character to be substituted.
- Use with caution!
-**/
-
-static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
-                               const smb_ucs2_t *insert)
-{
-       smb_ucs2_t *r, *rp;
-       const smb_ucs2_t *sp;
-       size_t  lr, lp, li, lt;
-
-       if (!insert || !pattern || !*pattern || !s)
-               return NULL;
-
-       lt = (size_t)strlen_w(s);
-       lp = (size_t)strlen_w(pattern);
-       li = (size_t)strlen_w(insert);
-
-       if (li > lp) {
-               const smb_ucs2_t *st = s;
-               int ld = li - lp;
-               while ((sp = strstr_w(st, pattern))) {
-                       st = sp + lp;
-                       lt += ld;
-               }
-       }
-
-       r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
-       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) / sizeof(smb_ucs2_t));
-               memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
-               s = sp + lp;
-               rp += li;
-       }
-       lr = ((rp - r) / sizeof(smb_ucs2_t));
-       if (lr < lt) {
-               memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
-               rp += (lt - lr);
-       }
-       *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);
-}
-
-#if 0
-/**
- Splits out the front and back at a separator.
-**/
-
-static void split_at_last_component(char *path, char *front, char sep, char *back)
+char *talloc_all_string_sub(TALLOC_CTX *ctx,
+                               const char *src,
+                               const char *pattern,
+                               const char *insert)
 {
 {
-       char *p = strrchr_m(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;
-       }
+       return talloc_string_sub2(ctx, src, pattern, insert,
+                       false, false, false);
 }
 }
-#endif
 
 /**
  Write an octal as a string.
 **/
 
 
 /**
  Write an octal as a string.
 **/
 
-const char *octal_string(int i)
+char *octal_string(int i)
 {
 {
-       static char ret[64];
-       if (i == -1)
-               return "-1";
-       slprintf(ret, sizeof(ret)-1, "0%o", i);
-       return ret;
+       char *result;
+       if (i == -1) {
+               result = talloc_strdup(talloc_tos(), "-1");
+       }
+       else {
+               result = talloc_asprintf(talloc_tos(), "0%o", i);
+       }
+       SMB_ASSERT(result != NULL);
+       return result;
 }
 
 
 }
 
 
@@ -1457,7 +1146,7 @@ char *string_truncate(char *s, unsigned int length)
 }
 
 /**
 }
 
 /**
- Strchr and strrchr_m are very hard to do on general multi-byte strings. 
+ Strchr and strrchr_m are very hard to do on general multi-byte strings.
  We convert via ucs2 for now.
 **/
 
  We convert via ucs2 for now.
 **/
 
@@ -1468,6 +1157,7 @@ char *strchr_m(const char *src, char c)
        smb_ucs2_t *p;
        const char *s;
        char *ret;
        smb_ucs2_t *p;
        const char *s;
        char *ret;
+       size_t converted_size;
 
        /* characters below 0x3F are guaranteed to not appear in
           non-initial position in multi-byte charsets */
 
        /* characters below 0x3F are guaranteed to not appear in
           non-initial position in multi-byte charsets */
@@ -1493,24 +1183,24 @@ char *strchr_m(const char *src, char c)
        s = src;
 #endif
 
        s = src;
 #endif
 
-       if (push_ucs2_allocate(&ws, s)==(size_t)-1) {
+       if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
                /* Wrong answer, but what can we do... */
                return strchr(src, c);
        }
        p = strchr_w(ws, UCS2_CHAR(c));
        if (!p) {
                /* Wrong answer, but what can we do... */
                return strchr(src, c);
        }
        p = strchr_w(ws, UCS2_CHAR(c));
        if (!p) {
-               SAFE_FREE(ws);
+               TALLOC_FREE(ws);
                return NULL;
        }
        *p = 0;
                return NULL;
        }
        *p = 0;
-       if (pull_ucs2_allocate(&s2, ws)==(size_t)-1) {
+       if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
                SAFE_FREE(ws);
                /* Wrong answer, but what can we do... */
                return strchr(src, c);
        }
        ret = (char *)(s+strlen(s2));
                SAFE_FREE(ws);
                /* Wrong answer, but what can we do... */
                return strchr(src, c);
        }
        ret = (char *)(s+strlen(s2));
-       SAFE_FREE(ws);
-       SAFE_FREE(s2);
+       TALLOC_FREE(ws);
+       TALLOC_FREE(s2);
        return ret;
 }
 
        return ret;
 }
 
@@ -1534,7 +1224,7 @@ char *strrchr_m(const char *s, char c)
        {
                size_t len = strlen(s);
                const char *cp = s;
        {
                size_t len = strlen(s);
                const char *cp = s;
-               BOOL got_mb = False;
+               bool got_mb = false;
 
                if (len == 0)
                        return NULL;
 
                if (len == 0)
                        return NULL;
@@ -1542,9 +1232,10 @@ char *strrchr_m(const char *s, char c)
                do {
                        if (c == *cp) {
                                /* Could be a match. Part of a multibyte ? */
                do {
                        if (c == *cp) {
                                /* Could be a match. Part of a multibyte ? */
-                               if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
+                               if ((cp > s) &&
+                                       (((unsigned char)cp[-1]) & 0x80)) {
                                        /* Yep - go slow :-( */
                                        /* Yep - go slow :-( */
-                                       got_mb = True;
+                                       got_mb = true;
                                        break;
                                }
                                /* No - we have a match ! */
                                        break;
                                }
                                /* No - we have a match ! */
@@ -1561,25 +1252,26 @@ char *strrchr_m(const char *s, char c)
                char *s2 = NULL;
                smb_ucs2_t *p;
                char *ret;
                char *s2 = NULL;
                smb_ucs2_t *p;
                char *ret;
+               size_t converted_size;
 
 
-               if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
+               if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
                        /* Wrong answer, but what can we do. */
                        return strrchr(s, c);
                }
                p = strrchr_w(ws, UCS2_CHAR(c));
                if (!p) {
                        /* Wrong answer, but what can we do. */
                        return strrchr(s, c);
                }
                p = strrchr_w(ws, UCS2_CHAR(c));
                if (!p) {
-                       SAFE_FREE(ws);
+                       TALLOC_FREE(ws);
                        return NULL;
                }
                *p = 0;
                        return NULL;
                }
                *p = 0;
-               if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
-                       SAFE_FREE(ws);
+               if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
+                       TALLOC_FREE(ws);
                        /* Wrong answer, but what can we do. */
                        return strrchr(s, c);
                }
                ret = (char *)(s+strlen(s2));
                        /* Wrong answer, but what can we do. */
                        return strrchr(s, c);
                }
                ret = (char *)(s+strlen(s2));
-               SAFE_FREE(ws);
-               SAFE_FREE(s2);
+               TALLOC_FREE(ws);
+               TALLOC_FREE(s2);
                return ret;
        }
 }
                return ret;
        }
 }
@@ -1595,25 +1287,26 @@ char *strnrchr_m(const char *s, char c, unsigned int n)
        char *s2 = NULL;
        smb_ucs2_t *p;
        char *ret;
        char *s2 = NULL;
        smb_ucs2_t *p;
        char *ret;
+       size_t converted_size;
 
 
-       if (push_ucs2_allocate(&ws,s)==(size_t)-1) {
+       if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
                /* Too hard to try and get right. */
                return NULL;
        }
        p = strnrchr_w(ws, UCS2_CHAR(c), n);
        if (!p) {
                /* Too hard to try and get right. */
                return NULL;
        }
        p = strnrchr_w(ws, UCS2_CHAR(c), n);
        if (!p) {
-               SAFE_FREE(ws);
+               TALLOC_FREE(ws);
                return NULL;
        }
        *p = 0;
                return NULL;
        }
        *p = 0;
-       if (pull_ucs2_allocate(&s2,ws)==(size_t)-1) {
-               SAFE_FREE(ws);
+       if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
+               TALLOC_FREE(ws);
                /* Too hard to try and get right. */
                return NULL;
        }
        ret = (char *)(s+strlen(s2));
                /* Too hard to try and get right. */
                return NULL;
        }
        ret = (char *)(s+strlen(s2));
-       SAFE_FREE(ws);
-       SAFE_FREE(s2);
+       TALLOC_FREE(ws);
+       TALLOC_FREE(s2);
        return ret;
 }
 
        return ret;
 }
 
@@ -1629,7 +1322,7 @@ char *strstr_m(const char *src, const char *findstr)
        char *s2;
        char *retp;
 
        char *s2;
        char *retp;
 
-       size_t findstr_len = 0;
+       size_t converted_size, findstr_len = 0;
 
        /* for correctness */
        if (!findstr[0]) {
 
        /* for correctness */
        if (!findstr[0]) {
@@ -1646,7 +1339,7 @@ char *strstr_m(const char *src, const char *findstr)
 
        for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
                if (*s == *findstr) {
 
        for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
                if (*s == *findstr) {
-                       if (!findstr_len) 
+                       if (!findstr_len)
                                findstr_len = strlen(findstr);
 
                        if (strncmp(s, findstr, findstr_len) == 0) {
                                findstr_len = strlen(findstr);
 
                        if (strncmp(s, findstr, findstr_len) == 0) {
@@ -1665,13 +1358,13 @@ char *strstr_m(const char *src, const char *findstr)
        s = src;
 #endif
 
        s = src;
 #endif
 
-       if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
+       if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) {
                DEBUG(0,("strstr_m: src malloc fail\n"));
                return NULL;
        }
                DEBUG(0,("strstr_m: src malloc fail\n"));
                return NULL;
        }
-       
-       if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
-               SAFE_FREE(src_w);
+
+       if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) {
+               TALLOC_FREE(src_w);
                DEBUG(0,("strstr_m: find malloc fail\n"));
                return NULL;
        }
                DEBUG(0,("strstr_m: find malloc fail\n"));
                return NULL;
        }
@@ -1679,22 +1372,22 @@ char *strstr_m(const char *src, const char *findstr)
        p = strstr_w(src_w, find_w);
 
        if (!p) {
        p = strstr_w(src_w, find_w);
 
        if (!p) {
-               SAFE_FREE(src_w);
-               SAFE_FREE(find_w);
+               TALLOC_FREE(src_w);
+               TALLOC_FREE(find_w);
                return NULL;
        }
                return NULL;
        }
-       
+
        *p = 0;
        *p = 0;
-       if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
-               SAFE_FREE(src_w);
-               SAFE_FREE(find_w);
+       if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) {
+               TALLOC_FREE(src_w);
+               TALLOC_FREE(find_w);
                DEBUG(0,("strstr_m: dest malloc fail\n"));
                return NULL;
        }
        retp = (char *)(s+strlen(s2));
                DEBUG(0,("strstr_m: dest malloc fail\n"));
                return NULL;
        }
        retp = (char *)(s+strlen(s2));
-       SAFE_FREE(src_w);
-       SAFE_FREE(find_w);
-       SAFE_FREE(s2);
+       TALLOC_FREE(src_w);
+       TALLOC_FREE(find_w);
+       TALLOC_FREE(s2);
        return retp;
 }
 
        return retp;
 }
 
@@ -1725,7 +1418,7 @@ void strlower_m(char *s)
        len = strlen(s) + 1;
        errno_save = errno;
        errno = 0;
        len = strlen(s) + 1;
        errno_save = errno;
        errno = 0;
-       unix_strlower(s,len,s,len);     
+       unix_strlower(s,len,s,len);
        /* Catch mb conversion errors that may not terminate. */
        if (errno)
                s[len-1] = '\0';
        /* Catch mb conversion errors that may not terminate. */
        if (errno)
                s[len-1] = '\0';
@@ -1747,7 +1440,7 @@ void strupper_m(char *s)
           (ie. they match for the first 128 chars) */
 
        while (*s && !(((unsigned char)s[0]) & 0x80)) {
           (ie. they match for the first 128 chars) */
 
        while (*s && !(((unsigned char)s[0]) & 0x80)) {
-               *s = toupper_ascii((unsigned char)*s);
+               *s = toupper_ascii_fast((unsigned char)*s);
                s++;
        }
 
                s++;
        }
 
@@ -1759,7 +1452,7 @@ void strupper_m(char *s)
        len = strlen(s) + 1;
        errno_save = errno;
        errno = 0;
        len = strlen(s) + 1;
        errno_save = errno;
        errno = 0;
-       unix_strupper(s,len,s,len);     
+       unix_strupper(s,len,s,len);
        /* Catch mb conversion errors that may not terminate. */
        if (errno)
                s[len-1] = '\0';
        /* Catch mb conversion errors that may not terminate. */
        if (errno)
                s[len-1] = '\0';
@@ -1767,12 +1460,12 @@ void strupper_m(char *s)
 }
 
 /**
 }
 
 /**
- Count the number of UCS2 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.
-**/
-
-size_t strlen_m(const char *s)
+ * Calculate the number of units (8 or 16-bit, depending on the
+ * destination charset), that would be needed to convert the input
+ * string which is expected to be in in CH_UNIX encoding to the
+ * destination charset (which should be a unicode charset).
+ */
+size_t strlen_m_ext(const char *s, const charset_t dst_charset)
 {
        size_t count = 0;
 
 {
        size_t count = 0;
 
@@ -1792,21 +1485,69 @@ size_t strlen_m(const char *s)
        while (*s) {
                size_t c_size;
                codepoint_t c = next_codepoint(s, &c_size);
        while (*s) {
                size_t c_size;
                codepoint_t c = next_codepoint(s, &c_size);
-               if (c < 0x10000) {
-                       /* Unicode char fits into 16 bits. */
-                       count += 1;
-               } else {
-                       /* Double-width unicode char - 32 bits. */
-                       count += 2;
-               }
                s += c_size;
                s += c_size;
-       }
-
-       return count;
-}
 
 
-/**
- Count the number of UCS2 characters in a string including the null
+               switch(dst_charset) {
+               case CH_UTF16LE:
+               case CH_UTF16BE:
+               case CH_UTF16MUNGED:
+                       if (c < 0x10000) {
+                               /* Unicode char fits into 16 bits. */
+                               count += 1;
+                       } else {
+                               /* Double-width unicode char - 32 bits. */
+                               count += 2;
+                       }
+                       break;
+               case CH_UTF8:
+                       /*
+                        * this only checks ranges, and does not
+                        * check for invalid codepoints
+                        */
+                       if (c < 0x80) {
+                               count += 1;
+                       } else if (c < 0x800) {
+                               count += 2;
+                       } else if (c < 0x1000) {
+                               count += 3;
+                       } else {
+                               count += 4;
+                       }
+                       break;
+               default:
+                       /*
+                        * non-unicode encoding:
+                        * assume that each codepoint fits into
+                        * one unit in the destination encoding.
+                        */
+                       count += 1;
+               }
+       }
+
+       return count;
+}
+
+size_t strlen_m_ext_term(const char *s, const charset_t dst_charset)
+{
+       if (!s) {
+               return 0;
+       }
+       return strlen_m_ext(s, dst_charset) + 1;
+}
+
+/**
+ Count the number of UCS2 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.
+**/
+
+size_t strlen_m(const char *s)
+{
+       return strlen_m_ext(s, CH_UTF16LE);
+}
+
+/**
+ Count the number of UCS2 characters in a string including the null
  terminator.
 **/
 
  terminator.
 **/
 
@@ -1842,14 +1583,15 @@ size_t strlen_m_term_null(const char *s)
  Caller must free.
 **/
 
  Caller must free.
 **/
 
-char *binary_string_rfc2254(char *buf, int len)
+char *binary_string_rfc2254(TALLOC_CTX *mem_ctx, const uint8_t *buf, int len)
 {
        char *s;
        int i, j;
        const char *hex = "0123456789ABCDEF";
 {
        char *s;
        int i, j;
        const char *hex = "0123456789ABCDEF";
-       s = (char *)SMB_MALLOC(len * 3 + 1);
-       if (!s)
+       s = talloc_array(mem_ctx, char, len * 3 + 1);
+       if (s == NULL) {
                return NULL;
                return NULL;
+       }
        for (j=i=0;i<len;i++) {
                s[j] = '\\';
                s[j+1] = hex[((unsigned char)buf[i]) >> 4];
        for (j=i=0;i<len;i++) {
                s[j] = '\\';
                s[j+1] = hex[((unsigned char)buf[i]) >> 4];
@@ -1876,21 +1618,6 @@ char *binary_string(char *buf, int len)
        s[j] = 0;
        return s;
 }
        s[j] = 0;
        return s;
 }
-/**
- Just a typesafety wrapper for snprintf into a pstring.
-**/
-
- int pstr_sprintf(pstring s, const char *fmt, ...)
-{
-       va_list ap;
-       int ret;
-
-       va_start(ap, fmt);
-       ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
-       va_end(ap);
-       return ret;
-}
-
 
 /**
  Just a typesafety wrapper for snprintf into a fstring.
 
 /**
  Just a typesafety wrapper for snprintf into a fstring.
@@ -1913,252 +1640,56 @@ int fstr_sprintf(fstring s, const char *fmt, ...)
 
 #define S_LIST_ABS 16 /* List Allocation Block Size */
 
 
 #define S_LIST_ABS 16 /* List Allocation Block Size */
 
-static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
-{
-       char **list, **rlist;
-       const char *str;
-       char *s;
-       int num, lsize;
-       pstring tok;
-
-       if (!string || !*string)
-               return NULL;
-       if (mem_ctx) {
-               s = talloc_strdup(mem_ctx, string);
-       } else {
-               s = SMB_STRDUP(string);
-       }
-       if (!s) {
-               DEBUG(0,("str_list_make: Unable to allocate memory"));
-               return NULL;
-       }
-       if (!sep) sep = LIST_SEP;
-
-       num = lsize = 0;
-       list = NULL;
-
-       str = s;
-       while (next_token(&str, tok, sep, sizeof(tok))) {
-               if (num == lsize) {
-                       lsize += S_LIST_ABS;
-                       if (mem_ctx) {
-                               rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
-                       } else {
-                               /* We need to keep the old list on error so we can free the elements
-                                  if the realloc fails. */
-                               rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
-                       }
-                       if (!rlist) {
-                               DEBUG(0,("str_list_make: Unable to allocate memory"));
-                               str_list_free(&list);
-                               if (mem_ctx) {
-                                       TALLOC_FREE(s);
-                               } else {
-                                       SAFE_FREE(s);
-                               }
-                               return NULL;
-                       } else {
-                               list = rlist;
-                       }
-                       memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
-               }
-
-               if (mem_ctx) {
-                       list[num] = talloc_strdup(mem_ctx, tok);
-               } else {
-                       list[num] = SMB_STRDUP(tok);
-               }
-
-               if (!list[num]) {
-                       DEBUG(0,("str_list_make: Unable to allocate memory"));
-                       str_list_free(&list);
-                       if (mem_ctx) {
-                               TALLOC_FREE(s);
-                       } else {
-                               SAFE_FREE(s);
-                       }
-                       return NULL;
-               }
-       
-               num++;  
-       }
-
-       if (mem_ctx) {
-               TALLOC_FREE(s);
-       } else {
-               SAFE_FREE(s);
-       }
-
-       return list;
-}
-
-char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
-{
-       return str_list_make_internal(mem_ctx, string, sep);
-}
-
-char **str_list_make(const char *string, const char *sep)
-{
-       return str_list_make_internal(NULL, string, sep);
-}
-
-BOOL str_list_copy(char ***dest, const char **src)
-{
-       char **list, **rlist;
-       int num, lsize;
-       
-       *dest = NULL;
-       if (!src)
-               return False;
-       
-       num = lsize = 0;
-       list = NULL;
-               
-       while (src[num]) {
-               if (num == lsize) {
-                       lsize += S_LIST_ABS;
-                       rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
-                       if (!rlist) {
-                               DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
-                               str_list_free(&list);
-                               return False;
-                       } else {
-                               list = rlist;
-                       }
-                       memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
-               }
-               
-               list[num] = SMB_STRDUP(src[num]);
-               if (!list[num]) {
-                       DEBUG(0,("str_list_copy: Unable to allocate memory"));
-                       str_list_free(&list);
-                       return False;
-               }
-
-               num++;
-       }
-       
-       *dest = list;
-       return True;    
-}
-
-/**
- * Return true if all the elements of the list match exactly.
- **/
-BOOL str_list_compare(char **list1, char **list2)
-{
-       int num;
-       
-       if (!list1 || !list2)
-               return (list1 == list2); 
-       
-       for (num = 0; list1[num]; num++) {
-               if (!list2[num])
-                       return False;
-               if (!strcsequal(list1[num], list2[num]))
-                       return False;
-       }
-       if (list2[num])
-               return False; /* if list2 has more elements than list1 fail */
-       
-       return True;
-}
-
-static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
-{
-       char **tlist;
-       
-       if (!list || !*list)
-               return;
-       tlist = *list;
-       for(; *tlist; tlist++) {
-               if (mem_ctx) {
-                       TALLOC_FREE(*tlist);
-               } else {
-                       SAFE_FREE(*tlist);
-               }
-       }
-       if (mem_ctx) {
-               TALLOC_FREE(*tlist);
-       } else {
-               SAFE_FREE(*list);
-       }
-}
-
-void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
-{
-       str_list_free_internal(mem_ctx, list);
-}
-
-void str_list_free(char ***list)
-{
-       str_list_free_internal(NULL, list);
-}
-
 /******************************************************************************
 /******************************************************************************
- *****************************************************************************/
-
-int str_list_count( const char **list )
-{
-       int i = 0;
-
-       if ( ! list )
-               return 0;
-
-       /* count the number of list members */
-       
-       for ( i=0; *list; i++, list++ );
-       
-       return i;
-}
-
-/******************************************************************************
- version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
+ version of standard_sub_basic() for string lists; uses talloc_sub_basic()
  for the work
  *****************************************************************************/
  for the work
  *****************************************************************************/
-BOOL str_list_sub_basic( char **list, const char *smb_name,
+
+bool str_list_sub_basic( char **list, const char *smb_name,
                         const char *domain_name )
 {
                         const char *domain_name )
 {
+       TALLOC_CTX *ctx = list;
        char *s, *tmpstr;
        char *s, *tmpstr;
-       
+
        while ( *list ) {
                s = *list;
        while ( *list ) {
                s = *list;
-               tmpstr = alloc_sub_basic(smb_name, domain_name, s);
+               tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
                if ( !tmpstr ) {
                if ( !tmpstr ) {
-                       DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
-                       return False;
+                       DEBUG(0,("str_list_sub_basic: "
+                               "alloc_sub_basic() return NULL!\n"));
+                       return false;
                }
 
                }
 
-               SAFE_FREE(*list);
+               TALLOC_FREE(*list);
                *list = tmpstr;
                *list = tmpstr;
-                       
+
                list++;
        }
 
                list++;
        }
 
-       return True;
+       return true;
 }
 
 /******************************************************************************
 }
 
 /******************************************************************************
- substritute a specific pattern in a string list
+ substitute a specific pattern in a string list
  *****************************************************************************/
  *****************************************************************************/
-BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
+
+bool str_list_substitute(char **list, const char *pattern, const char *insert)
 {
 {
+       TALLOC_CTX *ctx = list;
        char *p, *s, *t;
        ssize_t ls, lp, li, ld, i, d;
 
        if (!list)
        char *p, *s, *t;
        ssize_t ls, lp, li, ld, i, d;
 
        if (!list)
-               return False;
+               return false;
        if (!pattern)
        if (!pattern)
-               return False;
+               return false;
        if (!insert)
        if (!insert)
-               return False;
+               return false;
 
        lp = (ssize_t)strlen(pattern);
        li = (ssize_t)strlen(insert);
        ld = li -lp;
 
        lp = (ssize_t)strlen(pattern);
        li = (ssize_t)strlen(insert);
        ld = li -lp;
-                       
+
        while (*list) {
                s = *list;
                ls = (ssize_t)strlen(s);
        while (*list) {
                s = *list;
                ls = (ssize_t)strlen(s);
@@ -2167,19 +1698,20 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
                        t = *list;
                        d = p -t;
                        if (ld) {
                        t = *list;
                        d = p -t;
                        if (ld) {
-                               t = (char *) SMB_MALLOC(ls +ld +1);
+                               t = TALLOC_ARRAY(ctx, char, ls +ld +1);
                                if (!t) {
                                if (!t) {
-                                       DEBUG(0,("str_list_substitute: Unable to allocate memory"));
-                                       return False;
+                                       DEBUG(0,("str_list_substitute: "
+                                               "Unable to allocate memory"));
+                                       return false;
                                }
                                memcpy(t, *list, d);
                                memcpy(t +d +li, p +lp, ls -d -lp +1);
                                }
                                memcpy(t, *list, d);
                                memcpy(t +d +li, p +lp, ls -d -lp +1);
-                               SAFE_FREE(*list);
+                               TALLOC_FREE(*list);
                                *list = t;
                                ls += ld;
                                s = t +d +li;
                        }
                                *list = t;
                                ls += ld;
                                s = t +d +li;
                        }
-                       
+
                        for (i = 0; i < li; i++) {
                                switch (insert[i]) {
                                        case '`':
                        for (i = 0; i < li; i++) {
                                switch (insert[i]) {
                                        case '`':
@@ -2195,14 +1727,13 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
                                        default:
                                                t[d +i] = insert[i];
                                }
                                        default:
                                                t[d +i] = insert[i];
                                }
-                       }       
+                       }
                }
                }
-               
-               
+
                list++;
        }
                list++;
        }
-       
-       return True;
+
+       return true;
 }
 
 
 }
 
 
@@ -2222,26 +1753,53 @@ BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
  *         reallocated to new length
  **/
 
  *         reallocated to new length
  **/
 
-char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
+static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
 {
 {
-       char* new_ipstr = NULL;
-       
+       char *new_ipstr = NULL;
+       char addr_buf[INET6_ADDRSTRLEN];
+       int ret;
+
        /* arguments checking */
        /* arguments checking */
-       if (!ipstr_list || !service) return NULL;
+       if (!ipstr_list || !service) {
+               return NULL;
+       }
+
+       print_sockaddr(addr_buf,
+                       sizeof(addr_buf),
+                       &service->ss);
 
        /* attempt to convert ip to a string and append colon separator to it */
        if (*ipstr_list) {
 
        /* attempt to convert ip to a string and append colon separator to it */
        if (*ipstr_list) {
-               asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
-                       inet_ntoa(service->ip), service->port);
+               if (service->ss.ss_family == AF_INET) {
+                       /* IPv4 */
+                       ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
+                                      IPSTR_LIST_SEP, addr_buf,
+                                      service->port);
+               } else {
+                       /* IPv6 */
+                       ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
+                                      IPSTR_LIST_SEP, addr_buf,
+                                      service->port);
+               }
                SAFE_FREE(*ipstr_list);
        } else {
                SAFE_FREE(*ipstr_list);
        } else {
-               asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
+               if (service->ss.ss_family == AF_INET) {
+                       /* IPv4 */
+                       ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
+                                      service->port);
+               } else {
+                       /* IPv6 */
+                       ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
+                                      service->port);
+               }
+       }
+       if (ret == -1) {
+               return NULL;
        }
        *ipstr_list = new_ipstr;
        return *ipstr_list;
 }
 
        }
        *ipstr_list = new_ipstr;
        return *ipstr_list;
 }
 
-
 /**
  * Allocate and initialise an ipstr list using ip adresses
  * passed as arguments.
 /**
  * Allocate and initialise an ipstr list using ip adresses
  * passed as arguments.
@@ -2251,75 +1809,88 @@ char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
  * @param ip_count number of addresses stored in ip_list
  * @return pointer to allocated ip string
  **/
  * @param ip_count number of addresses stored in ip_list
  * @return pointer to allocated ip string
  **/
-char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
+
+char *ipstr_list_make(char **ipstr_list,
+                       const struct ip_service *ip_list,
+                       int ip_count)
 {
        int i;
 {
        int i;
-       
+
        /* arguments checking */
        /* arguments checking */
-       if (!ip_list || !ipstr_list) return 0;
+       if (!ip_list || !ipstr_list) {
+               return 0;
+       }
 
        *ipstr_list = NULL;
 
        *ipstr_list = NULL;
-       
+
        /* process ip addresses given as arguments */
        /* process ip addresses given as arguments */
-       for (i = 0; i < ip_count; i++)
+       for (i = 0; i < ip_count; i++) {
                *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
                *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
-       
+       }
+
        return (*ipstr_list);
 }
 
 
 /**
  * Parse given ip string list into array of ip addresses
        return (*ipstr_list);
 }
 
 
 /**
  * Parse given ip string list into array of ip addresses
- * (as ip_service structures)  
- *    e.g. 192.168.1.100:389,192.168.1.78, ...
+ * (as ip_service structures)
+ *    e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
  *
  *
- * @param ipstr ip string list to be parsed 
+ * @param ipstr ip string list to be parsed
  * @param ip_list pointer to array of ip addresses which is
  *        allocated by this function and must be freed by caller
  * @param ip_list pointer to array of ip addresses which is
  *        allocated by this function and must be freed by caller
- * @return number of succesfully parsed addresses
+ * @return number of successfully parsed addresses
  **/
  **/
-int ipstr_list_parse(const charipstr_list, struct ip_service **ip_list)
+
+int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
 {
 {
-       fstring token_str;
+       TALLOC_CTX *frame;
+       char *token_str = NULL;
        size_t count;
        int i;
 
        size_t count;
        int i;
 
-       if (!ipstr_list || !ip_list) 
+       if (!ipstr_list || !ip_list)
                return 0;
                return 0;
-       
+
        count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
        if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
        count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
        if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
-               DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
+               DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
+                                       (unsigned long)count));
                return 0;
        }
                return 0;
        }
-       
-       for ( i=0; 
-               next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
-               i++ ) 
-       {
-               struct in_addr addr;
-               unsigned port = 0;      
-               char *p = strchr(token_str, ':');
-               
+
+       frame = talloc_stackframe();
+       for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
+                               IPSTR_LIST_SEP) && i<count; i++ ) {
+               char *s = token_str;
+               char *p = strrchr(token_str, ':');
+
                if (p) {
                        *p = 0;
                if (p) {
                        *p = 0;
-                       port = atoi(p+1);
+                       (*ip_list)[i].port = atoi(p+1);
                }
 
                /* convert single token to ip address */
                }
 
                /* convert single token to ip address */
-               if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
-                       break;
-                               
-               (*ip_list)[i].ip = addr;
-               (*ip_list)[i].port = port;
+               if (token_str[0] == '[') {
+                       /* IPv6 address. */
+                       s++;
+                       p = strchr(token_str, ']');
+                       if (!p) {
+                               continue;
+                       }
+                       *p = '\0';
+               }
+               if (!interpret_string_addr(&(*ip_list)[i].ss,
+                                       s,
+                                       AI_NUMERICHOST)) {
+                       continue;
+               }
        }
        }
-       
+       TALLOC_FREE(frame);
        return count;
 }
 
        return count;
 }
 
-
 /**
  * Safely free ip string list
  *
 /**
  * Safely free ip string list
  *
@@ -2331,43 +1902,7 @@ void ipstr_list_free(char* ipstr_list)
        SAFE_FREE(ipstr_list);
 }
 
        SAFE_FREE(ipstr_list);
 }
 
-
-/**
- Unescape a URL encoded string, in place.
-**/
-
-void rfc1738_unescape(char *buf)
-{
-       char *p=buf;
-
-       while (p && *p && (p=strchr_m(p,'%'))) {
-               int c1 = p[1];
-               int c2 = p[2];
-
-               if (c1 >= '0' && c1 <= '9')
-                       c1 = c1 - '0';
-               else if (c1 >= 'A' && c1 <= 'F')
-                       c1 = 10 + c1 - 'A';
-               else if (c1 >= 'a' && c1 <= 'f')
-                       c1 = 10 + c1 - 'a';
-               else {p++; continue;}
-
-               if (c2 >= '0' && c2 <= '9')
-                       c2 = c2 - '0';
-               else if (c2 >= 'A' && c2 <= 'F')
-                       c2 = 10 + c2 - 'A';
-               else if (c2 >= 'a' && c2 <= 'f')
-                       c2 = 10 + c2 - 'a';
-               else {p++; continue;}
-                       
-               *p = (c1<<4) | c2;
-
-               memmove(p+1, p+3, strlen(p+3)+1);
-               p++;
-       }
-}
-
-static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 /**
  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
 
 /**
  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
@@ -2427,11 +1962,13 @@ void base64_decode_inplace(char *s)
 }
 
 /**
 }
 
 /**
- * Encode a base64 string into a malloc()ed string caller to free.
+ * Encode a base64 string into a talloc()ed string caller to free.
  *
  *
- *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
+ * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
+ * with adjustments
  **/
  **/
-char * base64_encode_data_blob(DATA_BLOB data)
+
+char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
 {
        int bits = 0;
        int char_count = 0;
 {
        int bits = 0;
        int char_count = 0;
@@ -2443,10 +1980,13 @@ char * base64_encode_data_blob(DATA_BLOB data)
 
        out_cnt = 0;
        len = data.length;
 
        out_cnt = 0;
        len = data.length;
-       output_len = data.length * 2;
-       result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
+       output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
+                                          * random but should be enough for
+                                          * the = and \0 */
+       result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
+       SMB_ASSERT(result != NULL);
 
 
-       while (len-- && out_cnt < (data.length * 2) - 5) {
+       while (len--) {
                int c = (unsigned char) *(data.data++);
                bits += c;
                char_count++;
                int c = (unsigned char) *(data.data++);
                bits += c;
                char_count++;
@@ -2454,36 +1994,36 @@ char * base64_encode_data_blob(DATA_BLOB data)
                        result[out_cnt++] = b64[bits >> 18];
                        result[out_cnt++] = b64[(bits >> 12) & 0x3f];
                        result[out_cnt++] = b64[(bits >> 6) & 0x3f];
                        result[out_cnt++] = b64[bits >> 18];
                        result[out_cnt++] = b64[(bits >> 12) & 0x3f];
                        result[out_cnt++] = b64[(bits >> 6) & 0x3f];
-           result[out_cnt++] = b64[bits & 0x3f];
-           bits = 0;
-           char_count = 0;
-       } else {
-           bits <<= 8;
-       }
-    }
-    if (char_count != 0) {
-       bits <<= 16 - (8 * char_count);
-       result[out_cnt++] = b64[bits >> 18];
-       result[out_cnt++] = b64[(bits >> 12) & 0x3f];
-       if (char_count == 1) {
-           result[out_cnt++] = '=';
-           result[out_cnt++] = '=';
-       } else {
-           result[out_cnt++] = b64[(bits >> 6) & 0x3f];
-           result[out_cnt++] = '=';
+                       result[out_cnt++] = b64[bits & 0x3f];
+                       bits = 0;
+                       char_count = 0;
+               } else {
+                       bits <<= 8;
+               }
+       }
+       if (char_count != 0) {
+               bits <<= 16 - (8 * char_count);
+               result[out_cnt++] = b64[bits >> 18];
+               result[out_cnt++] = b64[(bits >> 12) & 0x3f];
+               if (char_count == 1) {
+                       result[out_cnt++] = '=';
+                       result[out_cnt++] = '=';
+               } else {
+                       result[out_cnt++] = b64[(bits >> 6) & 0x3f];
+                       result[out_cnt++] = '=';
+               }
        }
        }
-    }
-    result[out_cnt] = '\0';    /* terminate */
-    return result;
+       result[out_cnt] = '\0'; /* terminate */
+       return result;
 }
 
 /* read a SMB_BIG_UINT from a string */
 }
 
 /* read a SMB_BIG_UINT from a string */
-SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
+uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
 {
 
 {
 
-       SMB_BIG_UINT val = -1;
+       uint64_t val = -1;
        const char *p = nptr;
        const char *p = nptr;
-       
+
        if (!p) {
                if (entptr) {
                        *entptr = p;
        if (!p) {
                if (entptr) {
                        *entptr = p;
@@ -2494,11 +2034,7 @@ SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
        while (*p && isspace(*p))
                p++;
 
        while (*p && isspace(*p))
                p++;
 
-#ifdef LARGE_SMB_OFF_T
-       sscanf(p,"%llu",&val);  
-#else /* LARGE_SMB_OFF_T */
-       sscanf(p,"%lu",&val);
-#endif /* LARGE_SMB_OFF_T */
+       sscanf(p,"%"PRIu64,&val);
        if (entptr) {
                while (*p && isdigit(*p))
                        p++;
        if (entptr) {
                while (*p && isdigit(*p))
                        p++;
@@ -2594,22 +2130,23 @@ void string_append(char **left, const char *right)
        safe_strcat(*left, right, new_len-1);
 }
 
        safe_strcat(*left, right, new_len-1);
 }
 
-BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
+bool add_string_to_array(TALLOC_CTX *mem_ctx,
                         const char *str, const char ***strings,
                         int *num)
 {
        char *dup_str = talloc_strdup(mem_ctx, str);
 
                         const char *str, const char ***strings,
                         int *num)
 {
        char *dup_str = talloc_strdup(mem_ctx, str);
 
-       *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
+       *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
+                       const char *, (*num)+1);
 
        if ((*strings == NULL) || (dup_str == NULL)) {
                *num = 0;
 
        if ((*strings == NULL) || (dup_str == NULL)) {
                *num = 0;
-               return False;
+               return false;
        }
 
        (*strings)[*num] = dup_str;
        *num += 1;
        }
 
        (*strings)[*num] = dup_str;
        *num += 1;
-       return True;
+       return true;
 }
 
 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
 }
 
 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
@@ -2622,7 +2159,7 @@ void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
        va_list ap;
        char *newstr;
        int ret;
        va_list ap;
        char *newstr;
        int ret;
-       BOOL increased;
+       bool increased;
 
        /* len<0 is an internal marker that something failed */
        if (*len < 0)
 
        /* len<0 is an internal marker that something failed */
        if (*len < 0)
@@ -2644,10 +2181,10 @@ void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
        if (ret < 0)
                goto error;
 
        if (ret < 0)
                goto error;
 
-       increased = False;
+       increased = false;
 
        while ((*len)+ret >= *bufsize) {
 
        while ((*len)+ret >= *bufsize) {
-               increased = True;
+               increased = true;
                *bufsize *= 2;
                if (*bufsize >= (1024*1024*256))
                        goto error;
                *bufsize *= 2;
                if (*bufsize >= (1024*1024*256))
                        goto error;
@@ -2671,6 +2208,61 @@ void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
        *string = NULL;
 }
 
        *string = NULL;
 }
 
+/*
+ * asprintf into a string and strupper_m it after that.
+ */
+
+int asprintf_strupper_m(char **strp, const char *fmt, ...)
+{
+       va_list ap;
+       char *result;
+       int ret;
+
+       va_start(ap, fmt);
+       ret = vasprintf(&result, fmt, ap);
+       va_end(ap);
+
+       if (ret == -1)
+               return -1;
+
+       strupper_m(result);
+       *strp = result;
+       return ret;
+}
+
+char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
+{
+       va_list ap;
+       char *ret;
+
+       va_start(ap, fmt);
+       ret = talloc_vasprintf(t, fmt, ap);
+       va_end(ap);
+
+       if (ret == NULL) {
+               return NULL;
+       }
+       strupper_m(ret);
+       return ret;
+}
+
+char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
+{
+       va_list ap;
+       char *ret;
+
+       va_start(ap, fmt);
+       ret = talloc_vasprintf(t, fmt, ap);
+       va_end(ap);
+
+       if (ret == NULL) {
+               return NULL;
+       }
+       strlower_m(ret);
+       return ret;
+}
+
+
 /*
    Returns the substring from src between the first occurrence of
    the char "front" and the first occurence of the char "back".
 /*
    Returns the substring from src between the first occurrence of
    the char "front" and the first occurence of the char "back".
@@ -2703,68 +2295,22 @@ char *sstring_sub(const char *src, char front, char back)
  characters.
 ********************************************************************/
 
  characters.
 ********************************************************************/
 
-BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
+bool validate_net_name( const char *name,
+               const char *invalid_chars,
+               int max_len)
 {
        int i;
 
        for ( i=0; i<max_len && name[i]; i++ ) {
                /* fail if strchr_m() finds one of the invalid characters */
                if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
 {
        int i;
 
        for ( i=0; i<max_len && name[i]; i++ ) {
                /* fail if strchr_m() finds one of the invalid characters */
                if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
-                       return False;
+                       return false;
                }
        }
 
                }
        }
 
-       return True;
-}
-
-
-/**
-return the number of bytes occupied by a buffer in ASCII format
-the result includes the null termination
-limited by 'n' bytes
-**/
-size_t ascii_len_n(const char *src, size_t n)
-{
-       size_t len;
-
-       len = strnlen(src, n);
-       if (len+1 <= n) {
-               len += 1;
-       }
-
-       return len;
+       return true;
 }
 
 }
 
-/**
-return the number of bytes occupied by a buffer in CH_UTF16 format
-the result includes the null termination
-**/
-size_t utf16_len(const void *buf)
-{
-       size_t len;
-
-       for (len = 0; SVAL(buf,len); len += 2) ;
-
-       return len + 2;
-}
-
-/**
-return the number of bytes occupied by a buffer in CH_UTF16 format
-the result includes the null termination
-limited by 'n' bytes
-**/
-size_t utf16_len_n(const void *src, size_t n)
-{
-       size_t len;
-
-       for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
-
-       if (len+2 <= n) {
-               len += 2;
-       }
-
-       return len;
-}
 
 /*******************************************************************
  Add a shell escape character '\' to any character not in a known list
 
 /*******************************************************************
  Add a shell escape character '\' to any character not in a known list
@@ -2779,9 +2325,9 @@ char *escape_shell_string(const char *src)
        size_t srclen = strlen(src);
        char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
        char *dest = ret;
        size_t srclen = strlen(src);
        char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
        char *dest = ret;
-       BOOL in_s_quote = False;
-       BOOL in_d_quote = False;
-       BOOL next_escaped = False;
+       bool in_s_quote = false;
+       bool in_d_quote = false;
+       bool next_escaped = false;
 
        if (!ret) {
                return NULL;
 
        if (!ret) {
                return NULL;
@@ -2800,7 +2346,7 @@ char *escape_shell_string(const char *src)
                        memcpy(dest, src, c_size);
                        src += c_size;
                        dest += c_size;
                        memcpy(dest, src, c_size);
                        src += c_size;
                        dest += c_size;
-                       next_escaped = False;
+                       next_escaped = false;
                        continue;
                }
 
                        continue;
                }
 
@@ -2811,7 +2357,7 @@ char *escape_shell_string(const char *src)
 
                if (next_escaped) {
                        *dest++ = *src++;
 
                if (next_escaped) {
                        *dest++ = *src++;
-                       next_escaped = False;
+                       next_escaped = false;
                        continue;
                }
 
                        continue;
                }
 
@@ -2823,13 +2369,13 @@ char *escape_shell_string(const char *src)
 
                if (in_s_quote) {
                        if (*src == '\'') {
 
                if (in_s_quote) {
                        if (*src == '\'') {
-                               in_s_quote = False;
+                               in_s_quote = false;
                        }
                        *dest++ = *src++;
                        continue;
                }
 
                        }
                        *dest++ = *src++;
                        continue;
                }
 
-               /* 
+               /*
                 * Deal with double quote state. The most
                 * complex state. We must cope with \, meaning
                 * possibly escape next char (depending what it
                 * Deal with double quote state. The most
                 * complex state. We must cope with \, meaning
                 * possibly escape next char (depending what it
@@ -2840,7 +2386,7 @@ char *escape_shell_string(const char *src)
 
                if (in_d_quote) {
                        if (*src == '\\') {
 
                if (in_d_quote) {
                        if (*src == '\\') {
-                               /* 
+                               /*
                                 * Next character might be escaped.
                                 * We have to peek. Inside double
                                 * quotes only INSIDE_DQUOTE_LIST
                                 * Next character might be escaped.
                                 * We have to peek. Inside double
                                 * quotes only INSIDE_DQUOTE_LIST
@@ -2865,8 +2411,9 @@ char *escape_shell_string(const char *src)
 
                                nextchar = src[1];
 
 
                                nextchar = src[1];
 
-                               if (nextchar && strchr(INSIDE_DQUOTE_LIST, (int)nextchar)) {
-                                       next_escaped = True;
+                               if (nextchar && strchr(INSIDE_DQUOTE_LIST,
+                                                       (int)nextchar)) {
+                                       next_escaped = true;
                                }
                                *dest++ = *src++;
                                continue;
                                }
                                *dest++ = *src++;
                                continue;
@@ -2874,7 +2421,7 @@ char *escape_shell_string(const char *src)
 
                        if (*src == '\"') {
                                /* Exit double quote state. */
 
                        if (*src == '\"') {
                                /* Exit double quote state. */
-                               in_d_quote = False;
+                               in_d_quote = false;
                                *dest++ = *src++;
                                continue;
                        }
                                *dest++ = *src++;
                                continue;
                        }
@@ -2892,28 +2439,28 @@ char *escape_shell_string(const char *src)
                        continue;
                }
 
                        continue;
                }
 
-               /* 
+               /*
                 * From here to the end of the loop we're
                 * not in the single or double quote state.
                 */
 
                if (*src == '\\') {
                        /* Next character must be escaped. */
                 * From here to the end of the loop we're
                 * not in the single or double quote state.
                 */
 
                if (*src == '\\') {
                        /* Next character must be escaped. */
-                       next_escaped = True;
+                       next_escaped = true;
                        *dest++ = *src++;
                        continue;
                }
 
                if (*src == '\'') {
                        /* Go into single quote state. */
                        *dest++ = *src++;
                        continue;
                }
 
                if (*src == '\'') {
                        /* Go into single quote state. */
-                       in_s_quote = True;
+                       in_s_quote = true;
                        *dest++ = *src++;
                        continue;
                }
 
                if (*src == '\"') {
                        /* Go into double quote state. */
                        *dest++ = *src++;
                        continue;
                }
 
                if (*src == '\"') {
                        /* Go into double quote state. */
-                       in_d_quote = True;
+                       in_d_quote = true;
                        *dest++ = *src++;
                        continue;
                }
                        *dest++ = *src++;
                        continue;
                }
@@ -2928,3 +2475,71 @@ char *escape_shell_string(const char *src)
        *dest++ = '\0';
        return ret;
 }
        *dest++ = '\0';
        return ret;
 }
+
+/***************************************************
+ str_list_make, v3 version. The v4 version does not
+ look at quoted strings with embedded blanks, so
+ do NOT merge this function please!
+***************************************************/
+
+#define S_LIST_ABS 16 /* List Allocation Block Size */
+
+char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
+       const char *sep)
+{
+       char **list;
+       const char *str;
+       char *s, *tok;
+       int num, lsize;
+
+       if (!string || !*string)
+               return NULL;
+
+       list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
+       if (list == NULL) {
+               return NULL;
+       }
+       lsize = S_LIST_ABS;
+
+       s = talloc_strdup(list, string);
+       if (s == NULL) {
+               DEBUG(0,("str_list_make: Unable to allocate memory"));
+               TALLOC_FREE(list);
+               return NULL;
+       }
+       if (!sep) sep = LIST_SEP;
+
+       num = 0;
+       str = s;
+
+       while (next_token_talloc(list, &str, &tok, sep)) {
+
+               if (num == lsize) {
+                       char **tmp;
+
+                       lsize += S_LIST_ABS;
+
+                       tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
+                                                  lsize + 1);
+                       if (tmp == NULL) {
+                               DEBUG(0,("str_list_make: "
+                                       "Unable to allocate memory"));
+                               TALLOC_FREE(list);
+                               return NULL;
+                       }
+
+                       list = tmp;
+
+                       memset (&list[num], 0,
+                               ((sizeof(char**)) * (S_LIST_ABS +1)));
+               }
+
+               list[num] = tok;
+               num += 1;
+       }
+
+       list[num] = NULL;
+
+       TALLOC_FREE(s);
+       return list;
+}