Convert Samba3 to use the common lib/util/charset API
[ira/wip.git] / source3 / lib / util_str.c
1 /*
2    Unix SMB/CIFS implementation.
3    Samba utility functions
4
5    Copyright (C) Andrew Tridgell 1992-2001
6    Copyright (C) Simo Sorce      2001-2002
7    Copyright (C) Martin Pool     2003
8    Copyright (C) James Peach     2006
9    Copyright (C) Jeremy Allison  1992-2007
10
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3 of the License, or
14    (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 */
24
25 #include "includes.h"
26
27 const char toupper_ascii_fast_table[128] = {
28         0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
29         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
30         0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
31         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
32         0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
33         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
34         0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
35         0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
36 };
37
38 /**
39  * Case insensitive string compararison.
40  *
41  * iconv does not directly give us a way to compare strings in
42  * arbitrary unix character sets -- all we can is convert and then
43  * compare.  This is expensive.
44  *
45  * As an optimization, we do a first pass that considers only the
46  * prefix of the strings that is entirely 7-bit.  Within this, we
47  * check whether they have the same value.
48  *
49  * Hopefully this will often give the answer without needing to copy.
50  * In particular it should speed comparisons to literal ascii strings
51  * or comparisons of strings that are "obviously" different.
52  *
53  * If we find a non-ascii character we fall back to converting via
54  * iconv.
55  *
56  * This should never be slower than convering the whole thing, and
57  * often faster.
58  *
59  * A different optimization would be to compare for bitwise equality
60  * in the binary encoding.  (It would be possible thought hairy to do
61  * both simultaneously.)  But in that case if they turn out to be
62  * different, we'd need to restart the whole thing.
63  *
64  * Even better is to implement strcasecmp for each encoding and use a
65  * function pointer.
66  **/
67 int StrCaseCmp(const char *s, const char *t)
68 {
69
70         const char *ps, *pt;
71         size_t size;
72         smb_ucs2_t *buffer_s, *buffer_t;
73         int ret;
74
75         for (ps = s, pt = t; ; ps++, pt++) {
76                 char us, ut;
77
78                 if (!*ps && !*pt)
79                         return 0; /* both ended */
80                 else if (!*ps)
81                         return -1; /* s is a prefix */
82                 else if (!*pt)
83                         return +1; /* t is a prefix */
84                 else if ((*ps & 0x80) || (*pt & 0x80))
85                         /* not ascii anymore, do it the hard way
86                          * from here on in */
87                         break;
88
89                 us = toupper_ascii_fast(*ps);
90                 ut = toupper_ascii_fast(*pt);
91                 if (us == ut)
92                         continue;
93                 else if (us < ut)
94                         return -1;
95                 else if (us > ut)
96                         return +1;
97         }
98
99         if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) {
100                 return strcmp(ps, pt);
101                 /* Not quite the right answer, but finding the right one
102                    under this failure case is expensive, and it's pretty
103                    close */
104         }
105
106         if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) {
107                 TALLOC_FREE(buffer_s);
108                 return strcmp(ps, pt);
109                 /* Not quite the right answer, but finding the right one
110                    under this failure case is expensive, and it's pretty
111                    close */
112         }
113
114         ret = strcasecmp_w(buffer_s, buffer_t);
115         TALLOC_FREE(buffer_s);
116         TALLOC_FREE(buffer_t);
117         return ret;
118 }
119
120
121 /**
122  Case insensitive string compararison, length limited.
123 **/
124 int StrnCaseCmp(const char *s, const char *t, size_t len)
125 {
126         size_t n = 0;
127         const char *ps, *pt;
128         size_t size;
129         smb_ucs2_t *buffer_s, *buffer_t;
130         int ret;
131
132         for (ps = s, pt = t; n < len ; ps++, pt++, n++) {
133                 char us, ut;
134
135                 if (!*ps && !*pt)
136                         return 0; /* both ended */
137                 else if (!*ps)
138                         return -1; /* s is a prefix */
139                 else if (!*pt)
140                         return +1; /* t is a prefix */
141                 else if ((*ps & 0x80) || (*pt & 0x80))
142                         /* not ascii anymore, do it the
143                          * hard way from here on in */
144                         break;
145
146                 us = toupper_ascii_fast(*ps);
147                 ut = toupper_ascii_fast(*pt);
148                 if (us == ut)
149                         continue;
150                 else if (us < ut)
151                         return -1;
152                 else if (us > ut)
153                         return +1;
154         }
155
156         if (n == len) {
157                 return 0;
158         }
159
160         if (!push_ucs2_talloc(NULL, &buffer_s, ps, &size)) {
161                 return strncmp(ps, pt, len-n);
162                 /* Not quite the right answer, but finding the right one
163                    under this failure case is expensive,
164                    and it's pretty close */
165         }
166
167         if (!push_ucs2_talloc(NULL, &buffer_t, pt, &size)) {
168                 TALLOC_FREE(buffer_s);
169                 return strncmp(ps, pt, len-n);
170                 /* Not quite the right answer, but finding the right one
171                    under this failure case is expensive,
172                    and it's pretty close */
173         }
174
175         ret = strncasecmp_w(buffer_s, buffer_t, len-n);
176         TALLOC_FREE(buffer_s);
177         TALLOC_FREE(buffer_t);
178         return ret;
179 }
180
181 /**
182  * Compare 2 strings.
183  *
184  * @note The comparison is case-insensitive.
185  **/
186 bool strequal(const char *s1, const char *s2)
187 {
188         if (s1 == s2)
189                 return(true);
190         if (!s1 || !s2)
191                 return(false);
192
193         return(StrCaseCmp(s1,s2)==0);
194 }
195
196 /**
197  * Compare 2 strings up to and including the nth char.
198  *
199  * @note The comparison is case-insensitive.
200  **/
201 bool strnequal(const char *s1,const char *s2,size_t n)
202 {
203         if (s1 == s2)
204                 return(true);
205         if (!s1 || !s2 || !n)
206                 return(false);
207
208         return(StrnCaseCmp(s1,s2,n)==0);
209 }
210
211 /**
212  Compare 2 strings (case sensitive).
213 **/
214
215 bool strcsequal(const char *s1,const char *s2)
216 {
217         if (s1 == s2)
218                 return(true);
219         if (!s1 || !s2)
220                 return(false);
221
222         return(strcmp(s1,s2)==0);
223 }
224
225 /**
226 Do a case-insensitive, whitespace-ignoring string compare.
227 **/
228
229 int strwicmp(const char *psz1, const char *psz2)
230 {
231         /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
232         /* appropriate value. */
233         if (psz1 == psz2)
234                 return (0);
235         else if (psz1 == NULL)
236                 return (-1);
237         else if (psz2 == NULL)
238                 return (1);
239
240         /* sync the strings on first non-whitespace */
241         while (1) {
242                 while (isspace((int)*psz1))
243                         psz1++;
244                 while (isspace((int)*psz2))
245                         psz2++;
246                 if (toupper_ascii(*psz1) != toupper_ascii(*psz2) ||
247                                 *psz1 == '\0' || *psz2 == '\0')
248                         break;
249                 psz1++;
250                 psz2++;
251         }
252         return (*psz1 - *psz2);
253 }
254
255 /**
256  Convert a string to "normal" form.
257 **/
258
259 void strnorm(char *s, int case_default)
260 {
261         if (case_default == CASE_UPPER)
262                 strupper_m(s);
263         else
264                 strlower_m(s);
265 }
266
267 /**
268  Check if a string is in "normal" case.
269 **/
270
271 bool strisnormal(const char *s, int case_default)
272 {
273         if (case_default == CASE_UPPER)
274                 return(!strhaslower(s));
275
276         return(!strhasupper(s));
277 }
278
279
280 /**
281  String replace.
282  NOTE: oldc and newc must be 7 bit characters
283 **/
284 void string_replace( char *s, char oldc, char newc )
285 {
286         char *p;
287
288         /* this is quite a common operation, so we want it to be
289            fast. We optimise for the ascii case, knowing that all our
290            supported multi-byte character sets are ascii-compatible
291            (ie. they match for the first 128 chars) */
292
293         for (p = s; *p; p++) {
294                 if (*p & 0x80) /* mb string - slow path. */
295                         break;
296                 if (*p == oldc) {
297                         *p = newc;
298                 }
299         }
300
301         if (!*p)
302                 return;
303
304         /* Slow (mb) path. */
305 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
306         /* With compose characters we must restart from the beginning. JRA. */
307         p = s;
308 #endif
309
310         while (*p) {
311                 size_t c_size;
312                 next_codepoint(p, &c_size);
313
314                 if (c_size == 1) {
315                         if (*p == oldc) {
316                                 *p = newc;
317                         }
318                 }
319                 p += c_size;
320         }
321 }
322
323 /**
324  *  Skip past some strings in a buffer - old version - no checks.
325  *  **/
326
327 char *push_skip_string(char *buf)
328 {
329         buf += strlen(buf) + 1;
330         return(buf);
331 }
332
333 /**
334  Skip past a string in a buffer. Buffer may not be
335  null terminated. end_ptr points to the first byte after
336  then end of the buffer.
337 **/
338
339 char *skip_string(const char *base, size_t len, char *buf)
340 {
341         const char *end_ptr = base + len;
342
343         if (end_ptr < base || !base || !buf || buf >= end_ptr) {
344                 return NULL;
345         }
346
347         /* Skip the string */
348         while (*buf) {
349                 buf++;
350                 if (buf >= end_ptr) {
351                         return NULL;
352                 }
353         }
354         /* Skip the '\0' */
355         buf++;
356         return buf;
357 }
358
359 /**
360  Count the number of characters in a string. Normally this will
361  be the same as the number of bytes in a string for single byte strings,
362  but will be different for multibyte.
363 **/
364
365 size_t str_charnum(const char *s)
366 {
367         size_t ret, converted_size;
368         smb_ucs2_t *tmpbuf2 = NULL;
369         if (!push_ucs2_talloc(NULL, &tmpbuf2, s, &converted_size)) {
370                 return 0;
371         }
372         ret = strlen_w(tmpbuf2);
373         TALLOC_FREE(tmpbuf2);
374         return ret;
375 }
376
377 /**
378  Count the number of characters in a string. Normally this will
379  be the same as the number of bytes in a string for single byte strings,
380  but will be different for multibyte.
381 **/
382
383 size_t str_ascii_charnum(const char *s)
384 {
385         size_t ret, converted_size;
386         char *tmpbuf2 = NULL;
387         if (!push_ascii_talloc(NULL, &tmpbuf2, s, &converted_size)) {
388                 return 0;
389         }
390         ret = strlen(tmpbuf2);
391         TALLOC_FREE(tmpbuf2);
392         return ret;
393 }
394
395 bool trim_char(char *s,char cfront,char cback)
396 {
397         bool ret = false;
398         char *ep;
399         char *fp = s;
400
401         /* Ignore null or empty strings. */
402         if (!s || (s[0] == '\0'))
403                 return false;
404
405         if (cfront) {
406                 while (*fp && *fp == cfront)
407                         fp++;
408                 if (!*fp) {
409                         /* We ate the string. */
410                         s[0] = '\0';
411                         return true;
412                 }
413                 if (fp != s)
414                         ret = true;
415         }
416
417         ep = fp + strlen(fp) - 1;
418         if (cback) {
419                 /* Attempt ascii only. Bail for mb strings. */
420                 while ((ep >= fp) && (*ep == cback)) {
421                         ret = true;
422                         if ((ep > fp) && (((unsigned char)ep[-1]) & 0x80)) {
423                                 /* Could be mb... bail back to tim_string. */
424                                 char fs[2], bs[2];
425                                 if (cfront) {
426                                         fs[0] = cfront;
427                                         fs[1] = '\0';
428                                 }
429                                 bs[0] = cback;
430                                 bs[1] = '\0';
431                                 return trim_string(s, cfront ? fs : NULL, bs);
432                         } else {
433                                 ep--;
434                         }
435                 }
436                 if (ep < fp) {
437                         /* We ate the string. */
438                         s[0] = '\0';
439                         return true;
440                 }
441         }
442
443         ep[1] = '\0';
444         memmove(s, fp, ep-fp+2);
445         return ret;
446 }
447
448 /**
449  Does a string have any uppercase chars in it?
450 **/
451
452 bool strhasupper(const char *s)
453 {
454         smb_ucs2_t *tmp, *p;
455         bool ret;
456         size_t converted_size;
457
458         if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) {
459                 return false;
460         }
461
462         for(p = tmp; *p != 0; p++) {
463                 if(isupper_w(*p)) {
464                         break;
465                 }
466         }
467
468         ret = (*p != 0);
469         TALLOC_FREE(tmp);
470         return ret;
471 }
472
473 /**
474  Does a string have any lowercase chars in it?
475 **/
476
477 bool strhaslower(const char *s)
478 {
479         smb_ucs2_t *tmp, *p;
480         bool ret;
481         size_t converted_size;
482
483         if (!push_ucs2_talloc(NULL, &tmp, s, &converted_size)) {
484                 return false;
485         }
486
487         for(p = tmp; *p != 0; p++) {
488                 if(islower_w(*p)) {
489                         break;
490                 }
491         }
492
493         ret = (*p != 0);
494         TALLOC_FREE(tmp);
495         return ret;
496 }
497
498 /**
499  Safe string copy into a known length string. maxlength does not
500  include the terminating zero.
501 **/
502
503 char *safe_strcpy_fn(const char *fn,
504                 int line,
505                 char *dest,
506                 const char *src,
507                 size_t maxlength)
508 {
509         size_t len;
510
511         if (!dest) {
512                 DEBUG(0,("ERROR: NULL dest in safe_strcpy, "
513                         "called from [%s][%d]\n", fn, line));
514                 return NULL;
515         }
516
517 #ifdef DEVELOPER
518         clobber_region(fn,line,dest, maxlength+1);
519 #endif
520
521         if (!src) {
522                 *dest = 0;
523                 return dest;
524         }
525
526         len = strnlen(src, maxlength+1);
527
528         if (len > maxlength) {
529                 DEBUG(0,("ERROR: string overflow by "
530                         "%lu (%lu - %lu) in safe_strcpy [%.50s]\n",
531                          (unsigned long)(len-maxlength), (unsigned long)len,
532                          (unsigned long)maxlength, src));
533                 len = maxlength;
534         }
535
536         memmove(dest, src, len);
537         dest[len] = 0;
538         return dest;
539 }
540
541 /**
542  Safe string cat into a string. maxlength does not
543  include the terminating zero.
544 **/
545 char *safe_strcat_fn(const char *fn,
546                 int line,
547                 char *dest,
548                 const char *src,
549                 size_t maxlength)
550 {
551         size_t src_len, dest_len;
552
553         if (!dest) {
554                 DEBUG(0,("ERROR: NULL dest in safe_strcat, "
555                         "called from [%s][%d]\n", fn, line));
556                 return NULL;
557         }
558
559         if (!src)
560                 return dest;
561
562         src_len = strnlen(src, maxlength + 1);
563         dest_len = strnlen(dest, maxlength + 1);
564
565 #ifdef DEVELOPER
566         clobber_region(fn, line, dest + dest_len, maxlength + 1 - dest_len);
567 #endif
568
569         if (src_len + dest_len > maxlength) {
570                 DEBUG(0,("ERROR: string overflow by %d "
571                         "in safe_strcat [%.50s]\n",
572                          (int)(src_len + dest_len - maxlength), src));
573                 if (maxlength > dest_len) {
574                         memcpy(&dest[dest_len], src, maxlength - dest_len);
575                 }
576                 dest[maxlength] = 0;
577                 return NULL;
578         }
579
580         memcpy(&dest[dest_len], src, src_len);
581         dest[dest_len + src_len] = 0;
582         return dest;
583 }
584
585 /**
586  Paranoid strcpy into a buffer of given length (includes terminating
587  zero. Strips out all but 'a-Z0-9' and the character in other_safe_chars
588  and replaces with '_'. Deliberately does *NOT* check for multibyte
589  characters. Don't change it !
590 **/
591
592 char *alpha_strcpy_fn(const char *fn,
593                 int line,
594                 char *dest,
595                 const char *src,
596                 const char *other_safe_chars,
597                 size_t maxlength)
598 {
599         size_t len, i;
600
601 #ifdef DEVELOPER
602         clobber_region(fn, line, dest, maxlength);
603 #endif
604
605         if (!dest) {
606                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
607                         "called from [%s][%d]\n", fn, line));
608                 return NULL;
609         }
610
611         if (!src) {
612                 *dest = 0;
613                 return dest;
614         }
615
616         len = strlen(src);
617         if (len >= maxlength)
618                 len = maxlength - 1;
619
620         if (!other_safe_chars)
621                 other_safe_chars = "";
622
623         for(i = 0; i < len; i++) {
624                 int val = (src[i] & 0xff);
625                 if (isupper_ascii(val) || islower_ascii(val) ||
626                                 isdigit(val) || strchr_m(other_safe_chars, val))
627                         dest[i] = src[i];
628                 else
629                         dest[i] = '_';
630         }
631
632         dest[i] = '\0';
633
634         return dest;
635 }
636
637 /**
638  Like strncpy but always null terminates. Make sure there is room!
639  The variable n should always be one less than the available size.
640 **/
641 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
642 {
643         char *d = dest;
644
645 #ifdef DEVELOPER
646         clobber_region(fn, line, dest, n+1);
647 #endif
648
649         if (!dest) {
650                 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
651                         "called from [%s][%d]\n", fn, line));
652                 return(NULL);
653         }
654
655         if (!src) {
656                 *dest = 0;
657                 return(dest);
658         }
659
660         while (n-- && (*d = *src)) {
661                 d++;
662                 src++;
663         }
664
665         *d = 0;
666         return(dest);
667 }
668
669 #if 0
670 /**
671  Like strncpy but copies up to the character marker.  always null terminates.
672  returns a pointer to the character marker in the source string (src).
673 **/
674
675 static char *strncpyn(char *dest, const char *src, size_t n, char c)
676 {
677         char *p;
678         size_t str_len;
679
680 #ifdef DEVELOPER
681         clobber_region(dest, n+1);
682 #endif
683         p = strchr_m(src, c);
684         if (p == NULL) {
685                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
686                 return NULL;
687         }
688
689         str_len = PTR_DIFF(p, src);
690         strncpy(dest, src, MIN(n, str_len));
691         dest[str_len] = '\0';
692
693         return p;
694 }
695 #endif
696
697 /**
698  Check if a string is part of a list.
699 **/
700
701 bool in_list(const char *s, const char *list, bool casesensitive)
702 {
703         char *tok = NULL;
704         bool ret = false;
705         TALLOC_CTX *frame;
706
707         if (!list) {
708                 return false;
709         }
710
711         frame = talloc_stackframe();
712         while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
713                 if (casesensitive) {
714                         if (strcmp(tok,s) == 0) {
715                                 ret = true;
716                                 break;
717                         }
718                 } else {
719                         if (StrCaseCmp(tok,s) == 0) {
720                                 ret = true;
721                                 break;
722                         }
723                 }
724         }
725         TALLOC_FREE(frame);
726         return ret;
727 }
728
729 /* this is used to prevent lots of mallocs of size 1 */
730 static const char null_string[] = "";
731
732 /**
733  Set a string value, allocing the space for the string
734 **/
735
736 static bool string_init(char **dest,const char *src)
737 {
738         size_t l;
739
740         if (!src)
741                 src = "";
742
743         l = strlen(src);
744
745         if (l == 0) {
746                 *dest = CONST_DISCARD(char*, null_string);
747         } else {
748                 (*dest) = SMB_STRDUP(src);
749                 if ((*dest) == NULL) {
750                         DEBUG(0,("Out of memory in string_init\n"));
751                         return false;
752                 }
753         }
754         return(true);
755 }
756
757 /**
758  Free a string value.
759 **/
760
761 void string_free(char **s)
762 {
763         if (!s || !(*s))
764                 return;
765         if (*s == null_string)
766                 *s = NULL;
767         SAFE_FREE(*s);
768 }
769
770 /**
771  Set a string value, deallocating any existing space, and allocing the space
772  for the string
773 **/
774
775 bool string_set(char **dest,const char *src)
776 {
777         string_free(dest);
778         return(string_init(dest,src));
779 }
780
781 /**
782  Substitute a string for a pattern in another string. Make sure there is
783  enough room!
784
785  This routine looks for pattern in s and replaces it with
786  insert. It may do multiple replacements or just one.
787
788  Any of " ; ' $ or ` in the insert string are replaced with _
789  if len==0 then the string cannot be extended. This is different from the old
790  use of len==0 which was for no length checks to be done.
791 **/
792
793 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
794                  bool remove_unsafe_characters, bool replace_once,
795                  bool allow_trailing_dollar)
796 {
797         char *p;
798         ssize_t ls,lp,li, i;
799
800         if (!insert || !pattern || !*pattern || !s)
801                 return;
802
803         ls = (ssize_t)strlen(s);
804         lp = (ssize_t)strlen(pattern);
805         li = (ssize_t)strlen(insert);
806
807         if (len == 0)
808                 len = ls + 1; /* len is number of *bytes* */
809
810         while (lp <= ls && (p = strstr_m(s,pattern))) {
811                 if (ls + (li-lp) >= len) {
812                         DEBUG(0,("ERROR: string overflow by "
813                                 "%d in string_sub(%.50s, %d)\n",
814                                  (int)(ls + (li-lp) - len),
815                                  pattern, (int)len));
816                         break;
817                 }
818                 if (li != lp) {
819                         memmove(p+li,p+lp,strlen(p+lp)+1);
820                 }
821                 for (i=0;i<li;i++) {
822                         switch (insert[i]) {
823                         case '`':
824                         case '"':
825                         case '\'':
826                         case ';':
827                         case '$':
828                                 /* allow a trailing $
829                                  * (as in machine accounts) */
830                                 if (allow_trailing_dollar && (i == li - 1 )) {
831                                         p[i] = insert[i];
832                                         break;
833                                 }
834                         case '%':
835                         case '\r':
836                         case '\n':
837                                 if ( remove_unsafe_characters ) {
838                                         p[i] = '_';
839                                         /* yes this break should be here
840                                          * since we want to fall throw if
841                                          * not replacing unsafe chars */
842                                         break;
843                                 }
844                         default:
845                                 p[i] = insert[i];
846                         }
847                 }
848                 s = p + li;
849                 ls += (li-lp);
850
851                 if (replace_once)
852                         break;
853         }
854 }
855
856 void string_sub_once(char *s, const char *pattern,
857                 const char *insert, size_t len)
858 {
859         string_sub2( s, pattern, insert, len, true, true, false );
860 }
861
862 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
863 {
864         string_sub2( s, pattern, insert, len, true, false, false );
865 }
866
867 void fstring_sub(char *s,const char *pattern,const char *insert)
868 {
869         string_sub(s, pattern, insert, sizeof(fstring));
870 }
871
872 /**
873  Similar to string_sub2, but it will accept only allocated strings
874  and may realloc them so pay attention at what you pass on no
875  pointers inside strings, no const may be passed
876  as string.
877 **/
878
879 char *realloc_string_sub2(char *string,
880                         const char *pattern,
881                         const char *insert,
882                         bool remove_unsafe_characters,
883                         bool allow_trailing_dollar)
884 {
885         char *p, *in;
886         char *s;
887         ssize_t ls,lp,li,ld, i;
888
889         if (!insert || !pattern || !*pattern || !string || !*string)
890                 return NULL;
891
892         s = string;
893
894         in = SMB_STRDUP(insert);
895         if (!in) {
896                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
897                 return NULL;
898         }
899         ls = (ssize_t)strlen(s);
900         lp = (ssize_t)strlen(pattern);
901         li = (ssize_t)strlen(insert);
902         ld = li - lp;
903         for (i=0;i<li;i++) {
904                 switch (in[i]) {
905                         case '`':
906                         case '"':
907                         case '\'':
908                         case ';':
909                         case '$':
910                                 /* allow a trailing $
911                                  * (as in machine accounts) */
912                                 if (allow_trailing_dollar && (i == li - 1 )) {
913                                         break;
914                                 }
915                         case '%':
916                         case '\r':
917                         case '\n':
918                                 if ( remove_unsafe_characters ) {
919                                         in[i] = '_';
920                                         break;
921                                 }
922                         default:
923                                 /* ok */
924                                 break;
925                 }
926         }
927
928         while ((p = strstr_m(s,pattern))) {
929                 if (ld > 0) {
930                         int offset = PTR_DIFF(s,string);
931                         string = (char *)SMB_REALLOC(string, ls + ld + 1);
932                         if (!string) {
933                                 DEBUG(0, ("realloc_string_sub: "
934                                         "out of memory!\n"));
935                                 SAFE_FREE(in);
936                                 return NULL;
937                         }
938                         p = string + offset + (p - s);
939                 }
940                 if (li != lp) {
941                         memmove(p+li,p+lp,strlen(p+lp)+1);
942                 }
943                 memcpy(p, in, li);
944                 s = p + li;
945                 ls += ld;
946         }
947         SAFE_FREE(in);
948         return string;
949 }
950
951 char *realloc_string_sub(char *string,
952                         const char *pattern,
953                         const char *insert)
954 {
955         return realloc_string_sub2(string, pattern, insert, true, false);
956 }
957
958 /*
959  * Internal guts of talloc_string_sub and talloc_all_string_sub.
960  * talloc version of string_sub2.
961  */
962
963 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
964                         const char *pattern,
965                         const char *insert,
966                         bool remove_unsafe_characters,
967                         bool replace_once,
968                         bool allow_trailing_dollar)
969 {
970         char *p, *in;
971         char *s;
972         char *string;
973         ssize_t ls,lp,li,ld, i;
974
975         if (!insert || !pattern || !*pattern || !src) {
976                 return NULL;
977         }
978
979         string = talloc_strdup(mem_ctx, src);
980         if (string == NULL) {
981                 DEBUG(0, ("talloc_string_sub2: "
982                         "talloc_strdup failed\n"));
983                 return NULL;
984         }
985
986         s = string;
987
988         in = SMB_STRDUP(insert);
989         if (!in) {
990                 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
991                 return NULL;
992         }
993         ls = (ssize_t)strlen(s);
994         lp = (ssize_t)strlen(pattern);
995         li = (ssize_t)strlen(insert);
996         ld = li - lp;
997
998         for (i=0;i<li;i++) {
999                 switch (in[i]) {
1000                         case '`':
1001                         case '"':
1002                         case '\'':
1003                         case ';':
1004                         case '$':
1005                                 /* allow a trailing $
1006                                  * (as in machine accounts) */
1007                                 if (allow_trailing_dollar && (i == li - 1 )) {
1008                                         break;
1009                                 }
1010                         case '%':
1011                         case '\r':
1012                         case '\n':
1013                                 if (remove_unsafe_characters) {
1014                                         in[i] = '_';
1015                                         break;
1016                                 }
1017                         default:
1018                                 /* ok */
1019                                 break;
1020                 }
1021         }
1022
1023         while ((p = strstr_m(s,pattern))) {
1024                 if (ld > 0) {
1025                         int offset = PTR_DIFF(s,string);
1026                         string = (char *)TALLOC_REALLOC(mem_ctx, string,
1027                                                         ls + ld + 1);
1028                         if (!string) {
1029                                 DEBUG(0, ("talloc_string_sub: out of "
1030                                           "memory!\n"));
1031                                 SAFE_FREE(in);
1032                                 return NULL;
1033                         }
1034                         p = string + offset + (p - s);
1035                 }
1036                 if (li != lp) {
1037                         memmove(p+li,p+lp,strlen(p+lp)+1);
1038                 }
1039                 memcpy(p, in, li);
1040                 s = p + li;
1041                 ls += ld;
1042
1043                 if (replace_once) {
1044                         break;
1045                 }
1046         }
1047         SAFE_FREE(in);
1048         return string;
1049 }
1050
1051 /* Same as string_sub, but returns a talloc'ed string */
1052
1053 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
1054                         const char *src,
1055                         const char *pattern,
1056                         const char *insert)
1057 {
1058         return talloc_string_sub2(mem_ctx, src, pattern, insert,
1059                         true, false, false);
1060 }
1061
1062 /**
1063  Similar to string_sub() but allows for any character to be substituted.
1064  Use with caution!
1065  if len==0 then the string cannot be extended. This is different from the old
1066  use of len==0 which was for no length checks to be done.
1067 **/
1068
1069 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1070 {
1071         char *p;
1072         ssize_t ls,lp,li;
1073
1074         if (!insert || !pattern || !s)
1075                 return;
1076
1077         ls = (ssize_t)strlen(s);
1078         lp = (ssize_t)strlen(pattern);
1079         li = (ssize_t)strlen(insert);
1080
1081         if (!*pattern)
1082                 return;
1083
1084         if (len == 0)
1085                 len = ls + 1; /* len is number of *bytes* */
1086
1087         while (lp <= ls && (p = strstr_m(s,pattern))) {
1088                 if (ls + (li-lp) >= len) {
1089                         DEBUG(0,("ERROR: string overflow by "
1090                                 "%d in all_string_sub(%.50s, %d)\n",
1091                                  (int)(ls + (li-lp) - len),
1092                                  pattern, (int)len));
1093                         break;
1094                 }
1095                 if (li != lp) {
1096                         memmove(p+li,p+lp,strlen(p+lp)+1);
1097                 }
1098                 memcpy(p, insert, li);
1099                 s = p + li;
1100                 ls += (li-lp);
1101         }
1102 }
1103
1104 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1105                                 const char *src,
1106                                 const char *pattern,
1107                                 const char *insert)
1108 {
1109         return talloc_string_sub2(ctx, src, pattern, insert,
1110                         false, false, false);
1111 }
1112
1113 /**
1114  Write an octal as a string.
1115 **/
1116
1117 char *octal_string(int i)
1118 {
1119         char *result;
1120         if (i == -1) {
1121                 result = talloc_strdup(talloc_tos(), "-1");
1122         }
1123         else {
1124                 result = talloc_asprintf(talloc_tos(), "0%o", i);
1125         }
1126         SMB_ASSERT(result != NULL);
1127         return result;
1128 }
1129
1130
1131 /**
1132  Truncate a string at a specified length.
1133 **/
1134
1135 char *string_truncate(char *s, unsigned int length)
1136 {
1137         if (s && strlen(s) > length)
1138                 s[length] = 0;
1139         return s;
1140 }
1141
1142 /**
1143  Strchr and strrchr_m are very hard to do on general multi-byte strings.
1144  We convert via ucs2 for now.
1145 **/
1146
1147 char *strchr_m(const char *src, char c)
1148 {
1149         smb_ucs2_t *ws = NULL;
1150         char *s2 = NULL;
1151         smb_ucs2_t *p;
1152         const char *s;
1153         char *ret;
1154         size_t converted_size;
1155
1156         /* characters below 0x3F are guaranteed to not appear in
1157            non-initial position in multi-byte charsets */
1158         if ((c & 0xC0) == 0) {
1159                 return strchr(src, c);
1160         }
1161
1162         /* this is quite a common operation, so we want it to be
1163            fast. We optimise for the ascii case, knowing that all our
1164            supported multi-byte character sets are ascii-compatible
1165            (ie. they match for the first 128 chars) */
1166
1167         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1168                 if (*s == c)
1169                         return (char *)s;
1170         }
1171
1172         if (!*s)
1173                 return NULL;
1174
1175 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1176         /* With compose characters we must restart from the beginning. JRA. */
1177         s = src;
1178 #endif
1179
1180         if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
1181                 /* Wrong answer, but what can we do... */
1182                 return strchr(src, c);
1183         }
1184         p = strchr_w(ws, UCS2_CHAR(c));
1185         if (!p) {
1186                 TALLOC_FREE(ws);
1187                 return NULL;
1188         }
1189         *p = 0;
1190         if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
1191                 SAFE_FREE(ws);
1192                 /* Wrong answer, but what can we do... */
1193                 return strchr(src, c);
1194         }
1195         ret = (char *)(s+strlen(s2));
1196         TALLOC_FREE(ws);
1197         TALLOC_FREE(s2);
1198         return ret;
1199 }
1200
1201 char *strrchr_m(const char *s, char c)
1202 {
1203         /* characters below 0x3F are guaranteed to not appear in
1204            non-initial position in multi-byte charsets */
1205         if ((c & 0xC0) == 0) {
1206                 return strrchr(s, c);
1207         }
1208
1209         /* this is quite a common operation, so we want it to be
1210            fast. We optimise for the ascii case, knowing that all our
1211            supported multi-byte character sets are ascii-compatible
1212            (ie. they match for the first 128 chars). Also, in Samba
1213            we only search for ascii characters in 'c' and that
1214            in all mb character sets with a compound character
1215            containing c, if 'c' is not a match at position
1216            p, then p[-1] > 0x7f. JRA. */
1217
1218         {
1219                 size_t len = strlen(s);
1220                 const char *cp = s;
1221                 bool got_mb = false;
1222
1223                 if (len == 0)
1224                         return NULL;
1225                 cp += (len - 1);
1226                 do {
1227                         if (c == *cp) {
1228                                 /* Could be a match. Part of a multibyte ? */
1229                                 if ((cp > s) &&
1230                                         (((unsigned char)cp[-1]) & 0x80)) {
1231                                         /* Yep - go slow :-( */
1232                                         got_mb = true;
1233                                         break;
1234                                 }
1235                                 /* No - we have a match ! */
1236                                 return (char *)cp;
1237                         }
1238                 } while (cp-- != s);
1239                 if (!got_mb)
1240                         return NULL;
1241         }
1242
1243         /* String contained a non-ascii char. Slow path. */
1244         {
1245                 smb_ucs2_t *ws = NULL;
1246                 char *s2 = NULL;
1247                 smb_ucs2_t *p;
1248                 char *ret;
1249                 size_t converted_size;
1250
1251                 if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
1252                         /* Wrong answer, but what can we do. */
1253                         return strrchr(s, c);
1254                 }
1255                 p = strrchr_w(ws, UCS2_CHAR(c));
1256                 if (!p) {
1257                         TALLOC_FREE(ws);
1258                         return NULL;
1259                 }
1260                 *p = 0;
1261                 if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
1262                         TALLOC_FREE(ws);
1263                         /* Wrong answer, but what can we do. */
1264                         return strrchr(s, c);
1265                 }
1266                 ret = (char *)(s+strlen(s2));
1267                 TALLOC_FREE(ws);
1268                 TALLOC_FREE(s2);
1269                 return ret;
1270         }
1271 }
1272
1273 /***********************************************************************
1274  Return the equivalent of doing strrchr 'n' times - always going
1275  backwards.
1276 ***********************************************************************/
1277
1278 char *strnrchr_m(const char *s, char c, unsigned int n)
1279 {
1280         smb_ucs2_t *ws = NULL;
1281         char *s2 = NULL;
1282         smb_ucs2_t *p;
1283         char *ret;
1284         size_t converted_size;
1285
1286         if (!push_ucs2_talloc(NULL, &ws, s, &converted_size)) {
1287                 /* Too hard to try and get right. */
1288                 return NULL;
1289         }
1290         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1291         if (!p) {
1292                 TALLOC_FREE(ws);
1293                 return NULL;
1294         }
1295         *p = 0;
1296         if (!pull_ucs2_talloc(NULL, &s2, ws, &converted_size)) {
1297                 TALLOC_FREE(ws);
1298                 /* Too hard to try and get right. */
1299                 return NULL;
1300         }
1301         ret = (char *)(s+strlen(s2));
1302         TALLOC_FREE(ws);
1303         TALLOC_FREE(s2);
1304         return ret;
1305 }
1306
1307 /***********************************************************************
1308  strstr_m - We convert via ucs2 for now.
1309 ***********************************************************************/
1310
1311 char *strstr_m(const char *src, const char *findstr)
1312 {
1313         smb_ucs2_t *p;
1314         smb_ucs2_t *src_w, *find_w;
1315         const char *s;
1316         char *s2;
1317         char *retp;
1318
1319         size_t converted_size, findstr_len = 0;
1320
1321         /* for correctness */
1322         if (!findstr[0]) {
1323                 return (char*)src;
1324         }
1325
1326         /* Samba does single character findstr calls a *lot*. */
1327         if (findstr[1] == '\0')
1328                 return strchr_m(src, *findstr);
1329
1330         /* We optimise for the ascii case, knowing that all our
1331            supported multi-byte character sets are ascii-compatible
1332            (ie. they match for the first 128 chars) */
1333
1334         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1335                 if (*s == *findstr) {
1336                         if (!findstr_len)
1337                                 findstr_len = strlen(findstr);
1338
1339                         if (strncmp(s, findstr, findstr_len) == 0) {
1340                                 return (char *)s;
1341                         }
1342                 }
1343         }
1344
1345         if (!*s)
1346                 return NULL;
1347
1348 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1349         /* 'make check' fails unless we do this */
1350
1351         /* With compose characters we must restart from the beginning. JRA. */
1352         s = src;
1353 #endif
1354
1355         if (!push_ucs2_talloc(NULL, &src_w, src, &converted_size)) {
1356                 DEBUG(0,("strstr_m: src malloc fail\n"));
1357                 return NULL;
1358         }
1359
1360         if (!push_ucs2_talloc(NULL, &find_w, findstr, &converted_size)) {
1361                 TALLOC_FREE(src_w);
1362                 DEBUG(0,("strstr_m: find malloc fail\n"));
1363                 return NULL;
1364         }
1365
1366         p = strstr_w(src_w, find_w);
1367
1368         if (!p) {
1369                 TALLOC_FREE(src_w);
1370                 TALLOC_FREE(find_w);
1371                 return NULL;
1372         }
1373
1374         *p = 0;
1375         if (!pull_ucs2_talloc(NULL, &s2, src_w, &converted_size)) {
1376                 TALLOC_FREE(src_w);
1377                 TALLOC_FREE(find_w);
1378                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1379                 return NULL;
1380         }
1381         retp = (char *)(s+strlen(s2));
1382         TALLOC_FREE(src_w);
1383         TALLOC_FREE(find_w);
1384         TALLOC_FREE(s2);
1385         return retp;
1386 }
1387
1388 /**
1389  Convert a string to lower case.
1390 **/
1391
1392 void strlower_m(char *s)
1393 {
1394         size_t len;
1395         int errno_save;
1396
1397         /* this is quite a common operation, so we want it to be
1398            fast. We optimise for the ascii case, knowing that all our
1399            supported multi-byte character sets are ascii-compatible
1400            (ie. they match for the first 128 chars) */
1401
1402         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1403                 *s = tolower_ascii((unsigned char)*s);
1404                 s++;
1405         }
1406
1407         if (!*s)
1408                 return;
1409
1410         /* I assume that lowercased string takes the same number of bytes
1411          * as source string even in UTF-8 encoding. (VIV) */
1412         len = strlen(s) + 1;
1413         errno_save = errno;
1414         errno = 0;
1415         unix_strlower(s,len,s,len);
1416         /* Catch mb conversion errors that may not terminate. */
1417         if (errno)
1418                 s[len-1] = '\0';
1419         errno = errno_save;
1420 }
1421
1422 /**
1423  Convert a string to upper case.
1424 **/
1425
1426 void strupper_m(char *s)
1427 {
1428         size_t len;
1429         int errno_save;
1430
1431         /* this is quite a common operation, so we want it to be
1432            fast. We optimise for the ascii case, knowing that all our
1433            supported multi-byte character sets are ascii-compatible
1434            (ie. they match for the first 128 chars) */
1435
1436         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1437                 *s = toupper_ascii_fast((unsigned char)*s);
1438                 s++;
1439         }
1440
1441         if (!*s)
1442                 return;
1443
1444         /* I assume that lowercased string takes the same number of bytes
1445          * as source string even in multibyte encoding. (VIV) */
1446         len = strlen(s) + 1;
1447         errno_save = errno;
1448         errno = 0;
1449         unix_strupper(s,len,s,len);
1450         /* Catch mb conversion errors that may not terminate. */
1451         if (errno)
1452                 s[len-1] = '\0';
1453         errno = errno_save;
1454 }
1455
1456 /**
1457  Count the number of UCS2 characters in a string. Normally this will
1458  be the same as the number of bytes in a string for single byte strings,
1459  but will be different for multibyte.
1460 **/
1461
1462 size_t strlen_m(const char *s)
1463 {
1464         size_t count = 0;
1465
1466         if (!s) {
1467                 return 0;
1468         }
1469
1470         while (*s && !(((uint8_t)*s) & 0x80)) {
1471                 s++;
1472                 count++;
1473         }
1474
1475         if (!*s) {
1476                 return count;
1477         }
1478
1479         while (*s) {
1480                 size_t c_size;
1481                 codepoint_t c = next_codepoint(s, &c_size);
1482                 if (c < 0x10000) {
1483                         /* Unicode char fits into 16 bits. */
1484                         count += 1;
1485                 } else {
1486                         /* Double-width unicode char - 32 bits. */
1487                         count += 2;
1488                 }
1489                 s += c_size;
1490         }
1491
1492         return count;
1493 }
1494
1495 /**
1496  Count the number of UCS2 characters in a string including the null
1497  terminator.
1498 **/
1499
1500 size_t strlen_m_term(const char *s)
1501 {
1502         if (!s) {
1503                 return 0;
1504         }
1505         return strlen_m(s) + 1;
1506 }
1507
1508 /*
1509  * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1510  * if a string is there, include the terminator.
1511  */
1512
1513 size_t strlen_m_term_null(const char *s)
1514 {
1515         size_t len;
1516         if (!s) {
1517                 return 0;
1518         }
1519         len = strlen_m(s);
1520         if (len == 0) {
1521                 return 0;
1522         }
1523
1524         return len+1;
1525 }
1526 /**
1527  Return a RFC2254 binary string representation of a buffer.
1528  Used in LDAP filters.
1529  Caller must free.
1530 **/
1531
1532 char *binary_string_rfc2254(char *buf, int len)
1533 {
1534         char *s;
1535         int i, j;
1536         const char *hex = "0123456789ABCDEF";
1537         s = (char *)SMB_MALLOC(len * 3 + 1);
1538         if (!s)
1539                 return NULL;
1540         for (j=i=0;i<len;i++) {
1541                 s[j] = '\\';
1542                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1543                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1544                 j += 3;
1545         }
1546         s[j] = 0;
1547         return s;
1548 }
1549
1550 char *binary_string(char *buf, int len)
1551 {
1552         char *s;
1553         int i, j;
1554         const char *hex = "0123456789ABCDEF";
1555         s = (char *)SMB_MALLOC(len * 2 + 1);
1556         if (!s)
1557                 return NULL;
1558         for (j=i=0;i<len;i++) {
1559                 s[j]   = hex[((unsigned char)buf[i]) >> 4];
1560                 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1561                 j += 2;
1562         }
1563         s[j] = 0;
1564         return s;
1565 }
1566
1567 /**
1568  Just a typesafety wrapper for snprintf into a fstring.
1569 **/
1570
1571 int fstr_sprintf(fstring s, const char *fmt, ...)
1572 {
1573         va_list ap;
1574         int ret;
1575
1576         va_start(ap, fmt);
1577         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1578         va_end(ap);
1579         return ret;
1580 }
1581
1582 /**
1583  List of Strings manipulation functions
1584 **/
1585
1586 #define S_LIST_ABS 16 /* List Allocation Block Size */
1587
1588 /******************************************************************************
1589  version of standard_sub_basic() for string lists; uses talloc_sub_basic()
1590  for the work
1591  *****************************************************************************/
1592
1593 bool str_list_sub_basic( char **list, const char *smb_name,
1594                          const char *domain_name )
1595 {
1596         TALLOC_CTX *ctx = list;
1597         char *s, *tmpstr;
1598
1599         while ( *list ) {
1600                 s = *list;
1601                 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
1602                 if ( !tmpstr ) {
1603                         DEBUG(0,("str_list_sub_basic: "
1604                                 "alloc_sub_basic() return NULL!\n"));
1605                         return false;
1606                 }
1607
1608                 TALLOC_FREE(*list);
1609                 *list = tmpstr;
1610
1611                 list++;
1612         }
1613
1614         return true;
1615 }
1616
1617 /******************************************************************************
1618  substritute a specific pattern in a string list
1619  *****************************************************************************/
1620
1621 bool str_list_substitute(char **list, const char *pattern, const char *insert)
1622 {
1623         TALLOC_CTX *ctx = list;
1624         char *p, *s, *t;
1625         ssize_t ls, lp, li, ld, i, d;
1626
1627         if (!list)
1628                 return false;
1629         if (!pattern)
1630                 return false;
1631         if (!insert)
1632                 return false;
1633
1634         lp = (ssize_t)strlen(pattern);
1635         li = (ssize_t)strlen(insert);
1636         ld = li -lp;
1637
1638         while (*list) {
1639                 s = *list;
1640                 ls = (ssize_t)strlen(s);
1641
1642                 while ((p = strstr_m(s, pattern))) {
1643                         t = *list;
1644                         d = p -t;
1645                         if (ld) {
1646                                 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
1647                                 if (!t) {
1648                                         DEBUG(0,("str_list_substitute: "
1649                                                 "Unable to allocate memory"));
1650                                         return false;
1651                                 }
1652                                 memcpy(t, *list, d);
1653                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1654                                 TALLOC_FREE(*list);
1655                                 *list = t;
1656                                 ls += ld;
1657                                 s = t +d +li;
1658                         }
1659
1660                         for (i = 0; i < li; i++) {
1661                                 switch (insert[i]) {
1662                                         case '`':
1663                                         case '"':
1664                                         case '\'':
1665                                         case ';':
1666                                         case '$':
1667                                         case '%':
1668                                         case '\r':
1669                                         case '\n':
1670                                                 t[d +i] = '_';
1671                                                 break;
1672                                         default:
1673                                                 t[d +i] = insert[i];
1674                                 }
1675                         }
1676                 }
1677
1678                 list++;
1679         }
1680
1681         return true;
1682 }
1683
1684
1685 #define IPSTR_LIST_SEP  ","
1686 #define IPSTR_LIST_CHAR ','
1687
1688 /**
1689  * Add ip string representation to ipstr list. Used also
1690  * as part of @function ipstr_list_make
1691  *
1692  * @param ipstr_list pointer to string containing ip list;
1693  *        MUST BE already allocated and IS reallocated if necessary
1694  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1695  *        as a result of reallocation)
1696  * @param ip IP address which is to be added to list
1697  * @return pointer to string appended with new ip and possibly
1698  *         reallocated to new length
1699  **/
1700
1701 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
1702 {
1703         char *new_ipstr = NULL;
1704         char addr_buf[INET6_ADDRSTRLEN];
1705         int ret;
1706
1707         /* arguments checking */
1708         if (!ipstr_list || !service) {
1709                 return NULL;
1710         }
1711
1712         print_sockaddr(addr_buf,
1713                         sizeof(addr_buf),
1714                         &service->ss);
1715
1716         /* attempt to convert ip to a string and append colon separator to it */
1717         if (*ipstr_list) {
1718                 if (service->ss.ss_family == AF_INET) {
1719                         /* IPv4 */
1720                         ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
1721                                        IPSTR_LIST_SEP, addr_buf,
1722                                        service->port);
1723                 } else {
1724                         /* IPv6 */
1725                         ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
1726                                        IPSTR_LIST_SEP, addr_buf,
1727                                        service->port);
1728                 }
1729                 SAFE_FREE(*ipstr_list);
1730         } else {
1731                 if (service->ss.ss_family == AF_INET) {
1732                         /* IPv4 */
1733                         ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
1734                                        service->port);
1735                 } else {
1736                         /* IPv6 */
1737                         ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
1738                                        service->port);
1739                 }
1740         }
1741         if (ret == -1) {
1742                 return NULL;
1743         }
1744         *ipstr_list = new_ipstr;
1745         return *ipstr_list;
1746 }
1747
1748 /**
1749  * Allocate and initialise an ipstr list using ip adresses
1750  * passed as arguments.
1751  *
1752  * @param ipstr_list pointer to string meant to be allocated and set
1753  * @param ip_list array of ip addresses to place in the list
1754  * @param ip_count number of addresses stored in ip_list
1755  * @return pointer to allocated ip string
1756  **/
1757
1758 char *ipstr_list_make(char **ipstr_list,
1759                         const struct ip_service *ip_list,
1760                         int ip_count)
1761 {
1762         int i;
1763
1764         /* arguments checking */
1765         if (!ip_list || !ipstr_list) {
1766                 return 0;
1767         }
1768
1769         *ipstr_list = NULL;
1770
1771         /* process ip addresses given as arguments */
1772         for (i = 0; i < ip_count; i++) {
1773                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1774         }
1775
1776         return (*ipstr_list);
1777 }
1778
1779
1780 /**
1781  * Parse given ip string list into array of ip addresses
1782  * (as ip_service structures)
1783  *    e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1784  *
1785  * @param ipstr ip string list to be parsed
1786  * @param ip_list pointer to array of ip addresses which is
1787  *        allocated by this function and must be freed by caller
1788  * @return number of successfully parsed addresses
1789  **/
1790
1791 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1792 {
1793         TALLOC_CTX *frame;
1794         char *token_str = NULL;
1795         size_t count;
1796         int i;
1797
1798         if (!ipstr_list || !ip_list)
1799                 return 0;
1800
1801         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1802         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1803                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1804                                         (unsigned long)count));
1805                 return 0;
1806         }
1807
1808         frame = talloc_stackframe();
1809         for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1810                                 IPSTR_LIST_SEP) && i<count; i++ ) {
1811                 char *s = token_str;
1812                 char *p = strrchr(token_str, ':');
1813
1814                 if (p) {
1815                         *p = 0;
1816                         (*ip_list)[i].port = atoi(p+1);
1817                 }
1818
1819                 /* convert single token to ip address */
1820                 if (token_str[0] == '[') {
1821                         /* IPv6 address. */
1822                         s++;
1823                         p = strchr(token_str, ']');
1824                         if (!p) {
1825                                 continue;
1826                         }
1827                         *p = '\0';
1828                 }
1829                 if (!interpret_string_addr(&(*ip_list)[i].ss,
1830                                         s,
1831                                         AI_NUMERICHOST)) {
1832                         continue;
1833                 }
1834         }
1835         TALLOC_FREE(frame);
1836         return count;
1837 }
1838
1839 /**
1840  * Safely free ip string list
1841  *
1842  * @param ipstr_list ip string list to be freed
1843  **/
1844
1845 void ipstr_list_free(char* ipstr_list)
1846 {
1847         SAFE_FREE(ipstr_list);
1848 }
1849
1850 static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1851
1852 /**
1853  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1854  **/
1855 DATA_BLOB base64_decode_data_blob(const char *s)
1856 {
1857         int bit_offset, byte_offset, idx, i, n;
1858         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1859         unsigned char *d = decoded.data;
1860         char *p;
1861
1862         n=i=0;
1863
1864         while (*s && (p=strchr_m(b64,*s))) {
1865                 idx = (int)(p - b64);
1866                 byte_offset = (i*6)/8;
1867                 bit_offset = (i*6)%8;
1868                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1869                 if (bit_offset < 3) {
1870                         d[byte_offset] |= (idx << (2-bit_offset));
1871                         n = byte_offset+1;
1872                 } else {
1873                         d[byte_offset] |= (idx >> (bit_offset-2));
1874                         d[byte_offset+1] = 0;
1875                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1876                         n = byte_offset+2;
1877                 }
1878                 s++; i++;
1879         }
1880
1881         if ((n > 0) && (*s == '=')) {
1882                 n -= 1;
1883         }
1884
1885         /* fix up length */
1886         decoded.length = n;
1887         return decoded;
1888 }
1889
1890 /**
1891  * Decode a base64 string in-place - wrapper for the above
1892  **/
1893 void base64_decode_inplace(char *s)
1894 {
1895         DATA_BLOB decoded = base64_decode_data_blob(s);
1896
1897         if ( decoded.length != 0 ) {
1898                 memcpy(s, decoded.data, decoded.length);
1899
1900                 /* null terminate */
1901                 s[decoded.length] = '\0';
1902         } else {
1903                 *s = '\0';
1904         }
1905
1906         data_blob_free(&decoded);
1907 }
1908
1909 /**
1910  * Encode a base64 string into a talloc()ed string caller to free.
1911  *
1912  * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
1913  * with adjustments
1914  **/
1915
1916 char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
1917 {
1918         int bits = 0;
1919         int char_count = 0;
1920         size_t out_cnt, len, output_len;
1921         char *result;
1922
1923         if (!data.length || !data.data)
1924                 return NULL;
1925
1926         out_cnt = 0;
1927         len = data.length;
1928         output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
1929                                            * random but should be enough for
1930                                            * the = and \0 */
1931         result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
1932         SMB_ASSERT(result != NULL);
1933
1934         while (len-- && out_cnt < (data.length * 2) - 5) {
1935                 int c = (unsigned char) *(data.data++);
1936                 bits += c;
1937                 char_count++;
1938                 if (char_count == 3) {
1939                         result[out_cnt++] = b64[bits >> 18];
1940                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1941                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1942                         result[out_cnt++] = b64[bits & 0x3f];
1943                         bits = 0;
1944                         char_count = 0;
1945                 } else {
1946                         bits <<= 8;
1947                 }
1948         }
1949         if (char_count != 0) {
1950                 bits <<= 16 - (8 * char_count);
1951                 result[out_cnt++] = b64[bits >> 18];
1952                 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1953                 if (char_count == 1) {
1954                         result[out_cnt++] = '=';
1955                         result[out_cnt++] = '=';
1956                 } else {
1957                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1958                         result[out_cnt++] = '=';
1959                 }
1960         }
1961         result[out_cnt] = '\0'; /* terminate */
1962         return result;
1963 }
1964
1965 /* read a SMB_BIG_UINT from a string */
1966 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1967 {
1968
1969         uint64_t val = -1;
1970         const char *p = nptr;
1971
1972         if (!p) {
1973                 if (entptr) {
1974                         *entptr = p;
1975                 }
1976                 return val;
1977         }
1978
1979         while (*p && isspace(*p))
1980                 p++;
1981
1982         sscanf(p,"%"PRIu64,&val);
1983         if (entptr) {
1984                 while (*p && isdigit(*p))
1985                         p++;
1986                 *entptr = p;
1987         }
1988
1989         return val;
1990 }
1991
1992 /* Convert a size specification to a count of bytes. We accept the following
1993  * suffixes:
1994  *          bytes if there is no suffix
1995  *      kK  kibibytes
1996  *      mM  mebibytes
1997  *      gG  gibibytes
1998  *      tT  tibibytes
1999  *      pP  whatever the ISO name for petabytes is
2000  *
2001  *  Returns 0 if the string can't be converted.
2002  */
2003 SMB_OFF_T conv_str_size(const char * str)
2004 {
2005         SMB_OFF_T lval;
2006         char * end;
2007
2008         if (str == NULL || *str == '\0') {
2009                 return 0;
2010         }
2011
2012 #ifdef HAVE_STRTOULL
2013         if (sizeof(SMB_OFF_T) == 8) {
2014             lval = strtoull(str, &end, 10 /* base */);
2015         } else {
2016             lval = strtoul(str, &end, 10 /* base */);
2017         }
2018 #else
2019         lval = strtoul(str, &end, 10 /* base */);
2020 #endif
2021
2022         if (end == NULL || end == str) {
2023                 return 0;
2024         }
2025
2026         if (*end) {
2027                 SMB_OFF_T lval_orig = lval;
2028
2029                 if (strwicmp(end, "K") == 0) {
2030                         lval *= (SMB_OFF_T)1024;
2031                 } else if (strwicmp(end, "M") == 0) {
2032                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2033                 } else if (strwicmp(end, "G") == 0) {
2034                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2035                                 (SMB_OFF_T)1024);
2036                 } else if (strwicmp(end, "T") == 0) {
2037                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2038                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2039                 } else if (strwicmp(end, "P") == 0) {
2040                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2041                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2042                                 (SMB_OFF_T)1024);
2043                 } else {
2044                         return 0;
2045                 }
2046
2047                 /* Primitive attempt to detect wrapping on platforms with
2048                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2049                  * a failure than some random number.
2050                  */
2051                 if (lval_orig <= lval) {
2052                         return 0;
2053                 }
2054         }
2055
2056         return lval;
2057 }
2058
2059 void string_append(char **left, const char *right)
2060 {
2061         int new_len = strlen(right) + 1;
2062
2063         if (*left == NULL) {
2064                 *left = (char *)SMB_MALLOC(new_len);
2065                 *left[0] = '\0';
2066         } else {
2067                 new_len += strlen(*left);
2068                 *left = (char *)SMB_REALLOC(*left, new_len);
2069         }
2070
2071         if (*left == NULL) {
2072                 return;
2073         }
2074
2075         safe_strcat(*left, right, new_len-1);
2076 }
2077
2078 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2079                          const char *str, const char ***strings,
2080                          int *num)
2081 {
2082         char *dup_str = talloc_strdup(mem_ctx, str);
2083
2084         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2085                         const char *, (*num)+1);
2086
2087         if ((*strings == NULL) || (dup_str == NULL)) {
2088                 *num = 0;
2089                 return false;
2090         }
2091
2092         (*strings)[*num] = dup_str;
2093         *num += 1;
2094         return true;
2095 }
2096
2097 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2098  * error checking in between. The indiation that something weird happened is
2099  * string==NULL */
2100
2101 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2102                     size_t *bufsize, const char *fmt, ...)
2103 {
2104         va_list ap;
2105         char *newstr;
2106         int ret;
2107         bool increased;
2108
2109         /* len<0 is an internal marker that something failed */
2110         if (*len < 0)
2111                 goto error;
2112
2113         if (*string == NULL) {
2114                 if (*bufsize == 0)
2115                         *bufsize = 128;
2116
2117                 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2118                 if (*string == NULL)
2119                         goto error;
2120         }
2121
2122         va_start(ap, fmt);
2123         ret = vasprintf(&newstr, fmt, ap);
2124         va_end(ap);
2125
2126         if (ret < 0)
2127                 goto error;
2128
2129         increased = false;
2130
2131         while ((*len)+ret >= *bufsize) {
2132                 increased = true;
2133                 *bufsize *= 2;
2134                 if (*bufsize >= (1024*1024*256))
2135                         goto error;
2136         }
2137
2138         if (increased) {
2139                 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2140                                                *bufsize);
2141                 if (*string == NULL) {
2142                         goto error;
2143                 }
2144         }
2145
2146         StrnCpy((*string)+(*len), newstr, ret);
2147         (*len) += ret;
2148         free(newstr);
2149         return;
2150
2151  error:
2152         *len = -1;
2153         *string = NULL;
2154 }
2155
2156 /*
2157  * asprintf into a string and strupper_m it after that.
2158  */
2159
2160 int asprintf_strupper_m(char **strp, const char *fmt, ...)
2161 {
2162         va_list ap;
2163         char *result;
2164         int ret;
2165
2166         va_start(ap, fmt);
2167         ret = vasprintf(&result, fmt, ap);
2168         va_end(ap);
2169
2170         if (ret == -1)
2171                 return -1;
2172
2173         strupper_m(result);
2174         *strp = result;
2175         return ret;
2176 }
2177
2178 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
2179 {
2180         va_list ap;
2181         char *ret;
2182
2183         va_start(ap, fmt);
2184         ret = talloc_vasprintf(t, fmt, ap);
2185         va_end(ap);
2186
2187         if (ret == NULL) {
2188                 return NULL;
2189         }
2190         strupper_m(ret);
2191         return ret;
2192 }
2193
2194 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
2195 {
2196         va_list ap;
2197         char *ret;
2198
2199         va_start(ap, fmt);
2200         ret = talloc_vasprintf(t, fmt, ap);
2201         va_end(ap);
2202
2203         if (ret == NULL) {
2204                 return NULL;
2205         }
2206         strlower_m(ret);
2207         return ret;
2208 }
2209
2210
2211 /*
2212    Returns the substring from src between the first occurrence of
2213    the char "front" and the first occurence of the char "back".
2214    Mallocs the return string which must be freed.  Not for use
2215    with wide character strings.
2216 */
2217 char *sstring_sub(const char *src, char front, char back)
2218 {
2219         char *temp1, *temp2, *temp3;
2220         ptrdiff_t len;
2221
2222         temp1 = strchr(src, front);
2223         if (temp1 == NULL) return NULL;
2224         temp2 = strchr(src, back);
2225         if (temp2 == NULL) return NULL;
2226         len = temp2 - temp1;
2227         if (len <= 0) return NULL;
2228         temp3 = (char*)SMB_MALLOC(len);
2229         if (temp3 == NULL) {
2230                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2231                 return NULL;
2232         }
2233         memcpy(temp3, temp1+1, len-1);
2234         temp3[len-1] = '\0';
2235         return temp3;
2236 }
2237
2238 /********************************************************************
2239  Check a string for any occurrences of a specified list of invalid
2240  characters.
2241 ********************************************************************/
2242
2243 bool validate_net_name( const char *name,
2244                 const char *invalid_chars,
2245                 int max_len)
2246 {
2247         int i;
2248
2249         for ( i=0; i<max_len && name[i]; i++ ) {
2250                 /* fail if strchr_m() finds one of the invalid characters */
2251                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2252                         return false;
2253                 }
2254         }
2255
2256         return true;
2257 }
2258
2259
2260 /*******************************************************************
2261  Add a shell escape character '\' to any character not in a known list
2262  of characters. UNIX charset format.
2263 *******************************************************************/
2264
2265 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2266 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2267
2268 char *escape_shell_string(const char *src)
2269 {
2270         size_t srclen = strlen(src);
2271         char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2272         char *dest = ret;
2273         bool in_s_quote = false;
2274         bool in_d_quote = false;
2275         bool next_escaped = false;
2276
2277         if (!ret) {
2278                 return NULL;
2279         }
2280
2281         while (*src) {
2282                 size_t c_size;
2283                 codepoint_t c = next_codepoint(src, &c_size);
2284
2285                 if (c == INVALID_CODEPOINT) {
2286                         SAFE_FREE(ret);
2287                         return NULL;
2288                 }
2289
2290                 if (c_size > 1) {
2291                         memcpy(dest, src, c_size);
2292                         src += c_size;
2293                         dest += c_size;
2294                         next_escaped = false;
2295                         continue;
2296                 }
2297
2298                 /*
2299                  * Deal with backslash escaped state.
2300                  * This only lasts for one character.
2301                  */
2302
2303                 if (next_escaped) {
2304                         *dest++ = *src++;
2305                         next_escaped = false;
2306                         continue;
2307                 }
2308
2309                 /*
2310                  * Deal with single quote state. The
2311                  * only thing we care about is exiting
2312                  * this state.
2313                  */
2314
2315                 if (in_s_quote) {
2316                         if (*src == '\'') {
2317                                 in_s_quote = false;
2318                         }
2319                         *dest++ = *src++;
2320                         continue;
2321                 }
2322
2323                 /*
2324                  * Deal with double quote state. The most
2325                  * complex state. We must cope with \, meaning
2326                  * possibly escape next char (depending what it
2327                  * is), ", meaning exit this state, and possibly
2328                  * add an \ escape to any unprotected character
2329                  * (listed in INSIDE_DQUOTE_LIST).
2330                  */
2331
2332                 if (in_d_quote) {
2333                         if (*src == '\\') {
2334                                 /*
2335                                  * Next character might be escaped.
2336                                  * We have to peek. Inside double
2337                                  * quotes only INSIDE_DQUOTE_LIST
2338                                  * characters are escaped by a \.
2339                                  */
2340
2341                                 char nextchar;
2342
2343                                 c = next_codepoint(&src[1], &c_size);
2344                                 if (c == INVALID_CODEPOINT) {
2345                                         SAFE_FREE(ret);
2346                                         return NULL;
2347                                 }
2348                                 if (c_size > 1) {
2349                                         /*
2350                                          * Don't escape the next char.
2351                                          * Just copy the \.
2352                                          */
2353                                         *dest++ = *src++;
2354                                         continue;
2355                                 }
2356
2357                                 nextchar = src[1];
2358
2359                                 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2360                                                         (int)nextchar)) {
2361                                         next_escaped = true;
2362                                 }
2363                                 *dest++ = *src++;
2364                                 continue;
2365                         }
2366
2367                         if (*src == '\"') {
2368                                 /* Exit double quote state. */
2369                                 in_d_quote = false;
2370                                 *dest++ = *src++;
2371                                 continue;
2372                         }
2373
2374                         /*
2375                          * We know the character isn't \ or ",
2376                          * so escape it if it's any of the other
2377                          * possible unprotected characters.
2378                          */
2379
2380                         if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2381                                 *dest++ = '\\';
2382                         }
2383                         *dest++ = *src++;
2384                         continue;
2385                 }
2386
2387                 /*
2388                  * From here to the end of the loop we're
2389                  * not in the single or double quote state.
2390                  */
2391
2392                 if (*src == '\\') {
2393                         /* Next character must be escaped. */
2394                         next_escaped = true;
2395                         *dest++ = *src++;
2396                         continue;
2397                 }
2398
2399                 if (*src == '\'') {
2400                         /* Go into single quote state. */
2401                         in_s_quote = true;
2402                         *dest++ = *src++;
2403                         continue;
2404                 }
2405
2406                 if (*src == '\"') {
2407                         /* Go into double quote state. */
2408                         in_d_quote = true;
2409                         *dest++ = *src++;
2410                         continue;
2411                 }
2412
2413                 /* Check if we need to escape the character. */
2414
2415                 if (!strchr(INCLUDE_LIST, (int)*src)) {
2416                         *dest++ = '\\';
2417                 }
2418                 *dest++ = *src++;
2419         }
2420         *dest++ = '\0';
2421         return ret;
2422 }
2423
2424 /***************************************************
2425  Wrapper for str_list_make() to restore the s3 behavior.
2426  In samba 3.2 passing NULL or an empty string returned NULL.
2427
2428  In master, it now returns a list of length 1 with the first string set
2429  to NULL (an empty list)
2430 ***************************************************/
2431
2432 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
2433 {
2434         if (!string || !*string) {
2435                 return NULL;
2436         }
2437         return str_list_make(mem_ctx, string, sep);
2438 }