s3:g_lock: remove an unreached code path.
[amitay/samba.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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &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(talloc_tos(), &src_w, src, &converted_size)) {
1356                 DEBUG(0,("strstr_m: src malloc fail\n"));
1357                 return NULL;
1358         }
1359
1360         if (!push_ucs2_talloc(talloc_tos(), &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(talloc_tos(), &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(TALLOC_CTX *mem_ctx, const uint8_t *buf, int len)
1533 {
1534         char *s;
1535         int i, j;
1536         const char *hex = "0123456789ABCDEF";
1537         s = talloc_array(mem_ctx, char, len * 3 + 1);
1538         if (s == NULL) {
1539                 return NULL;
1540         }
1541         for (j=i=0;i<len;i++) {
1542                 s[j] = '\\';
1543                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1544                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1545                 j += 3;
1546         }
1547         s[j] = 0;
1548         return s;
1549 }
1550
1551 char *binary_string(char *buf, int len)
1552 {
1553         char *s;
1554         int i, j;
1555         const char *hex = "0123456789ABCDEF";
1556         s = (char *)SMB_MALLOC(len * 2 + 1);
1557         if (!s)
1558                 return NULL;
1559         for (j=i=0;i<len;i++) {
1560                 s[j]   = hex[((unsigned char)buf[i]) >> 4];
1561                 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1562                 j += 2;
1563         }
1564         s[j] = 0;
1565         return s;
1566 }
1567
1568 /**
1569  Just a typesafety wrapper for snprintf into a fstring.
1570 **/
1571
1572 int fstr_sprintf(fstring s, const char *fmt, ...)
1573 {
1574         va_list ap;
1575         int ret;
1576
1577         va_start(ap, fmt);
1578         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1579         va_end(ap);
1580         return ret;
1581 }
1582
1583 /**
1584  List of Strings manipulation functions
1585 **/
1586
1587 #define S_LIST_ABS 16 /* List Allocation Block Size */
1588
1589 /******************************************************************************
1590  version of standard_sub_basic() for string lists; uses talloc_sub_basic()
1591  for the work
1592  *****************************************************************************/
1593
1594 bool str_list_sub_basic( char **list, const char *smb_name,
1595                          const char *domain_name )
1596 {
1597         TALLOC_CTX *ctx = list;
1598         char *s, *tmpstr;
1599
1600         while ( *list ) {
1601                 s = *list;
1602                 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
1603                 if ( !tmpstr ) {
1604                         DEBUG(0,("str_list_sub_basic: "
1605                                 "alloc_sub_basic() return NULL!\n"));
1606                         return false;
1607                 }
1608
1609                 TALLOC_FREE(*list);
1610                 *list = tmpstr;
1611
1612                 list++;
1613         }
1614
1615         return true;
1616 }
1617
1618 /******************************************************************************
1619  substitute a specific pattern in a string list
1620  *****************************************************************************/
1621
1622 bool str_list_substitute(char **list, const char *pattern, const char *insert)
1623 {
1624         TALLOC_CTX *ctx = list;
1625         char *p, *s, *t;
1626         ssize_t ls, lp, li, ld, i, d;
1627
1628         if (!list)
1629                 return false;
1630         if (!pattern)
1631                 return false;
1632         if (!insert)
1633                 return false;
1634
1635         lp = (ssize_t)strlen(pattern);
1636         li = (ssize_t)strlen(insert);
1637         ld = li -lp;
1638
1639         while (*list) {
1640                 s = *list;
1641                 ls = (ssize_t)strlen(s);
1642
1643                 while ((p = strstr_m(s, pattern))) {
1644                         t = *list;
1645                         d = p -t;
1646                         if (ld) {
1647                                 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
1648                                 if (!t) {
1649                                         DEBUG(0,("str_list_substitute: "
1650                                                 "Unable to allocate memory"));
1651                                         return false;
1652                                 }
1653                                 memcpy(t, *list, d);
1654                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1655                                 TALLOC_FREE(*list);
1656                                 *list = t;
1657                                 ls += ld;
1658                                 s = t +d +li;
1659                         }
1660
1661                         for (i = 0; i < li; i++) {
1662                                 switch (insert[i]) {
1663                                         case '`':
1664                                         case '"':
1665                                         case '\'':
1666                                         case ';':
1667                                         case '$':
1668                                         case '%':
1669                                         case '\r':
1670                                         case '\n':
1671                                                 t[d +i] = '_';
1672                                                 break;
1673                                         default:
1674                                                 t[d +i] = insert[i];
1675                                 }
1676                         }
1677                 }
1678
1679                 list++;
1680         }
1681
1682         return true;
1683 }
1684
1685
1686 #define IPSTR_LIST_SEP  ","
1687 #define IPSTR_LIST_CHAR ','
1688
1689 /**
1690  * Add ip string representation to ipstr list. Used also
1691  * as part of @function ipstr_list_make
1692  *
1693  * @param ipstr_list pointer to string containing ip list;
1694  *        MUST BE already allocated and IS reallocated if necessary
1695  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1696  *        as a result of reallocation)
1697  * @param ip IP address which is to be added to list
1698  * @return pointer to string appended with new ip and possibly
1699  *         reallocated to new length
1700  **/
1701
1702 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
1703 {
1704         char *new_ipstr = NULL;
1705         char addr_buf[INET6_ADDRSTRLEN];
1706         int ret;
1707
1708         /* arguments checking */
1709         if (!ipstr_list || !service) {
1710                 return NULL;
1711         }
1712
1713         print_sockaddr(addr_buf,
1714                         sizeof(addr_buf),
1715                         &service->ss);
1716
1717         /* attempt to convert ip to a string and append colon separator to it */
1718         if (*ipstr_list) {
1719                 if (service->ss.ss_family == AF_INET) {
1720                         /* IPv4 */
1721                         ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
1722                                        IPSTR_LIST_SEP, addr_buf,
1723                                        service->port);
1724                 } else {
1725                         /* IPv6 */
1726                         ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
1727                                        IPSTR_LIST_SEP, addr_buf,
1728                                        service->port);
1729                 }
1730                 SAFE_FREE(*ipstr_list);
1731         } else {
1732                 if (service->ss.ss_family == AF_INET) {
1733                         /* IPv4 */
1734                         ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
1735                                        service->port);
1736                 } else {
1737                         /* IPv6 */
1738                         ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
1739                                        service->port);
1740                 }
1741         }
1742         if (ret == -1) {
1743                 return NULL;
1744         }
1745         *ipstr_list = new_ipstr;
1746         return *ipstr_list;
1747 }
1748
1749 /**
1750  * Allocate and initialise an ipstr list using ip adresses
1751  * passed as arguments.
1752  *
1753  * @param ipstr_list pointer to string meant to be allocated and set
1754  * @param ip_list array of ip addresses to place in the list
1755  * @param ip_count number of addresses stored in ip_list
1756  * @return pointer to allocated ip string
1757  **/
1758
1759 char *ipstr_list_make(char **ipstr_list,
1760                         const struct ip_service *ip_list,
1761                         int ip_count)
1762 {
1763         int i;
1764
1765         /* arguments checking */
1766         if (!ip_list || !ipstr_list) {
1767                 return 0;
1768         }
1769
1770         *ipstr_list = NULL;
1771
1772         /* process ip addresses given as arguments */
1773         for (i = 0; i < ip_count; i++) {
1774                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1775         }
1776
1777         return (*ipstr_list);
1778 }
1779
1780
1781 /**
1782  * Parse given ip string list into array of ip addresses
1783  * (as ip_service structures)
1784  *    e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1785  *
1786  * @param ipstr ip string list to be parsed
1787  * @param ip_list pointer to array of ip addresses which is
1788  *        allocated by this function and must be freed by caller
1789  * @return number of successfully parsed addresses
1790  **/
1791
1792 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1793 {
1794         TALLOC_CTX *frame;
1795         char *token_str = NULL;
1796         size_t count;
1797         int i;
1798
1799         if (!ipstr_list || !ip_list)
1800                 return 0;
1801
1802         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1803         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1804                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1805                                         (unsigned long)count));
1806                 return 0;
1807         }
1808
1809         frame = talloc_stackframe();
1810         for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1811                                 IPSTR_LIST_SEP) && i<count; i++ ) {
1812                 char *s = token_str;
1813                 char *p = strrchr(token_str, ':');
1814
1815                 if (p) {
1816                         *p = 0;
1817                         (*ip_list)[i].port = atoi(p+1);
1818                 }
1819
1820                 /* convert single token to ip address */
1821                 if (token_str[0] == '[') {
1822                         /* IPv6 address. */
1823                         s++;
1824                         p = strchr(token_str, ']');
1825                         if (!p) {
1826                                 continue;
1827                         }
1828                         *p = '\0';
1829                 }
1830                 if (!interpret_string_addr(&(*ip_list)[i].ss,
1831                                         s,
1832                                         AI_NUMERICHOST)) {
1833                         continue;
1834                 }
1835         }
1836         TALLOC_FREE(frame);
1837         return count;
1838 }
1839
1840 /**
1841  * Safely free ip string list
1842  *
1843  * @param ipstr_list ip string list to be freed
1844  **/
1845
1846 void ipstr_list_free(char* ipstr_list)
1847 {
1848         SAFE_FREE(ipstr_list);
1849 }
1850
1851 static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1852
1853 /**
1854  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1855  **/
1856 DATA_BLOB base64_decode_data_blob(const char *s)
1857 {
1858         int bit_offset, byte_offset, idx, i, n;
1859         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1860         unsigned char *d = decoded.data;
1861         char *p;
1862
1863         n=i=0;
1864
1865         while (*s && (p=strchr_m(b64,*s))) {
1866                 idx = (int)(p - b64);
1867                 byte_offset = (i*6)/8;
1868                 bit_offset = (i*6)%8;
1869                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1870                 if (bit_offset < 3) {
1871                         d[byte_offset] |= (idx << (2-bit_offset));
1872                         n = byte_offset+1;
1873                 } else {
1874                         d[byte_offset] |= (idx >> (bit_offset-2));
1875                         d[byte_offset+1] = 0;
1876                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1877                         n = byte_offset+2;
1878                 }
1879                 s++; i++;
1880         }
1881
1882         if ((n > 0) && (*s == '=')) {
1883                 n -= 1;
1884         }
1885
1886         /* fix up length */
1887         decoded.length = n;
1888         return decoded;
1889 }
1890
1891 /**
1892  * Decode a base64 string in-place - wrapper for the above
1893  **/
1894 void base64_decode_inplace(char *s)
1895 {
1896         DATA_BLOB decoded = base64_decode_data_blob(s);
1897
1898         if ( decoded.length != 0 ) {
1899                 memcpy(s, decoded.data, decoded.length);
1900
1901                 /* null terminate */
1902                 s[decoded.length] = '\0';
1903         } else {
1904                 *s = '\0';
1905         }
1906
1907         data_blob_free(&decoded);
1908 }
1909
1910 /**
1911  * Encode a base64 string into a talloc()ed string caller to free.
1912  *
1913  * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
1914  * with adjustments
1915  **/
1916
1917 char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
1918 {
1919         int bits = 0;
1920         int char_count = 0;
1921         size_t out_cnt, len, output_len;
1922         char *result;
1923
1924         if (!data.length || !data.data)
1925                 return NULL;
1926
1927         out_cnt = 0;
1928         len = data.length;
1929         output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
1930                                            * random but should be enough for
1931                                            * the = and \0 */
1932         result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
1933         SMB_ASSERT(result != NULL);
1934
1935         while (len--) {
1936                 int c = (unsigned char) *(data.data++);
1937                 bits += c;
1938                 char_count++;
1939                 if (char_count == 3) {
1940                         result[out_cnt++] = b64[bits >> 18];
1941                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1942                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1943                         result[out_cnt++] = b64[bits & 0x3f];
1944                         bits = 0;
1945                         char_count = 0;
1946                 } else {
1947                         bits <<= 8;
1948                 }
1949         }
1950         if (char_count != 0) {
1951                 bits <<= 16 - (8 * char_count);
1952                 result[out_cnt++] = b64[bits >> 18];
1953                 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1954                 if (char_count == 1) {
1955                         result[out_cnt++] = '=';
1956                         result[out_cnt++] = '=';
1957                 } else {
1958                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1959                         result[out_cnt++] = '=';
1960                 }
1961         }
1962         result[out_cnt] = '\0'; /* terminate */
1963         return result;
1964 }
1965
1966 /* read a SMB_BIG_UINT from a string */
1967 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
1968 {
1969
1970         uint64_t val = -1;
1971         const char *p = nptr;
1972
1973         if (!p) {
1974                 if (entptr) {
1975                         *entptr = p;
1976                 }
1977                 return val;
1978         }
1979
1980         while (*p && isspace(*p))
1981                 p++;
1982
1983         sscanf(p,"%"PRIu64,&val);
1984         if (entptr) {
1985                 while (*p && isdigit(*p))
1986                         p++;
1987                 *entptr = p;
1988         }
1989
1990         return val;
1991 }
1992
1993 /* Convert a size specification to a count of bytes. We accept the following
1994  * suffixes:
1995  *          bytes if there is no suffix
1996  *      kK  kibibytes
1997  *      mM  mebibytes
1998  *      gG  gibibytes
1999  *      tT  tibibytes
2000  *      pP  whatever the ISO name for petabytes is
2001  *
2002  *  Returns 0 if the string can't be converted.
2003  */
2004 SMB_OFF_T conv_str_size(const char * str)
2005 {
2006         SMB_OFF_T lval;
2007         char * end;
2008
2009         if (str == NULL || *str == '\0') {
2010                 return 0;
2011         }
2012
2013 #ifdef HAVE_STRTOULL
2014         if (sizeof(SMB_OFF_T) == 8) {
2015             lval = strtoull(str, &end, 10 /* base */);
2016         } else {
2017             lval = strtoul(str, &end, 10 /* base */);
2018         }
2019 #else
2020         lval = strtoul(str, &end, 10 /* base */);
2021 #endif
2022
2023         if (end == NULL || end == str) {
2024                 return 0;
2025         }
2026
2027         if (*end) {
2028                 SMB_OFF_T lval_orig = lval;
2029
2030                 if (strwicmp(end, "K") == 0) {
2031                         lval *= (SMB_OFF_T)1024;
2032                 } else if (strwicmp(end, "M") == 0) {
2033                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2034                 } else if (strwicmp(end, "G") == 0) {
2035                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2036                                 (SMB_OFF_T)1024);
2037                 } else if (strwicmp(end, "T") == 0) {
2038                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2039                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2040                 } else if (strwicmp(end, "P") == 0) {
2041                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2042                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2043                                 (SMB_OFF_T)1024);
2044                 } else {
2045                         return 0;
2046                 }
2047
2048                 /* Primitive attempt to detect wrapping on platforms with
2049                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2050                  * a failure than some random number.
2051                  */
2052                 if (lval_orig <= lval) {
2053                         return 0;
2054                 }
2055         }
2056
2057         return lval;
2058 }
2059
2060 void string_append(char **left, const char *right)
2061 {
2062         int new_len = strlen(right) + 1;
2063
2064         if (*left == NULL) {
2065                 *left = (char *)SMB_MALLOC(new_len);
2066                 *left[0] = '\0';
2067         } else {
2068                 new_len += strlen(*left);
2069                 *left = (char *)SMB_REALLOC(*left, new_len);
2070         }
2071
2072         if (*left == NULL) {
2073                 return;
2074         }
2075
2076         safe_strcat(*left, right, new_len-1);
2077 }
2078
2079 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2080                          const char *str, const char ***strings,
2081                          int *num)
2082 {
2083         char *dup_str = talloc_strdup(mem_ctx, str);
2084
2085         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2086                         const char *, (*num)+1);
2087
2088         if ((*strings == NULL) || (dup_str == NULL)) {
2089                 *num = 0;
2090                 return false;
2091         }
2092
2093         (*strings)[*num] = dup_str;
2094         *num += 1;
2095         return true;
2096 }
2097
2098 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2099  * error checking in between. The indiation that something weird happened is
2100  * string==NULL */
2101
2102 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2103                     size_t *bufsize, const char *fmt, ...)
2104 {
2105         va_list ap;
2106         char *newstr;
2107         int ret;
2108         bool increased;
2109
2110         /* len<0 is an internal marker that something failed */
2111         if (*len < 0)
2112                 goto error;
2113
2114         if (*string == NULL) {
2115                 if (*bufsize == 0)
2116                         *bufsize = 128;
2117
2118                 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2119                 if (*string == NULL)
2120                         goto error;
2121         }
2122
2123         va_start(ap, fmt);
2124         ret = vasprintf(&newstr, fmt, ap);
2125         va_end(ap);
2126
2127         if (ret < 0)
2128                 goto error;
2129
2130         increased = false;
2131
2132         while ((*len)+ret >= *bufsize) {
2133                 increased = true;
2134                 *bufsize *= 2;
2135                 if (*bufsize >= (1024*1024*256))
2136                         goto error;
2137         }
2138
2139         if (increased) {
2140                 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2141                                                *bufsize);
2142                 if (*string == NULL) {
2143                         goto error;
2144                 }
2145         }
2146
2147         StrnCpy((*string)+(*len), newstr, ret);
2148         (*len) += ret;
2149         free(newstr);
2150         return;
2151
2152  error:
2153         *len = -1;
2154         *string = NULL;
2155 }
2156
2157 /*
2158  * asprintf into a string and strupper_m it after that.
2159  */
2160
2161 int asprintf_strupper_m(char **strp, const char *fmt, ...)
2162 {
2163         va_list ap;
2164         char *result;
2165         int ret;
2166
2167         va_start(ap, fmt);
2168         ret = vasprintf(&result, fmt, ap);
2169         va_end(ap);
2170
2171         if (ret == -1)
2172                 return -1;
2173
2174         strupper_m(result);
2175         *strp = result;
2176         return ret;
2177 }
2178
2179 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
2180 {
2181         va_list ap;
2182         char *ret;
2183
2184         va_start(ap, fmt);
2185         ret = talloc_vasprintf(t, fmt, ap);
2186         va_end(ap);
2187
2188         if (ret == NULL) {
2189                 return NULL;
2190         }
2191         strupper_m(ret);
2192         return ret;
2193 }
2194
2195 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
2196 {
2197         va_list ap;
2198         char *ret;
2199
2200         va_start(ap, fmt);
2201         ret = talloc_vasprintf(t, fmt, ap);
2202         va_end(ap);
2203
2204         if (ret == NULL) {
2205                 return NULL;
2206         }
2207         strlower_m(ret);
2208         return ret;
2209 }
2210
2211
2212 /*
2213    Returns the substring from src between the first occurrence of
2214    the char "front" and the first occurence of the char "back".
2215    Mallocs the return string which must be freed.  Not for use
2216    with wide character strings.
2217 */
2218 char *sstring_sub(const char *src, char front, char back)
2219 {
2220         char *temp1, *temp2, *temp3;
2221         ptrdiff_t len;
2222
2223         temp1 = strchr(src, front);
2224         if (temp1 == NULL) return NULL;
2225         temp2 = strchr(src, back);
2226         if (temp2 == NULL) return NULL;
2227         len = temp2 - temp1;
2228         if (len <= 0) return NULL;
2229         temp3 = (char*)SMB_MALLOC(len);
2230         if (temp3 == NULL) {
2231                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2232                 return NULL;
2233         }
2234         memcpy(temp3, temp1+1, len-1);
2235         temp3[len-1] = '\0';
2236         return temp3;
2237 }
2238
2239 /********************************************************************
2240  Check a string for any occurrences of a specified list of invalid
2241  characters.
2242 ********************************************************************/
2243
2244 bool validate_net_name( const char *name,
2245                 const char *invalid_chars,
2246                 int max_len)
2247 {
2248         int i;
2249
2250         for ( i=0; i<max_len && name[i]; i++ ) {
2251                 /* fail if strchr_m() finds one of the invalid characters */
2252                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2253                         return false;
2254                 }
2255         }
2256
2257         return true;
2258 }
2259
2260
2261 /*******************************************************************
2262  Add a shell escape character '\' to any character not in a known list
2263  of characters. UNIX charset format.
2264 *******************************************************************/
2265
2266 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2267 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2268
2269 char *escape_shell_string(const char *src)
2270 {
2271         size_t srclen = strlen(src);
2272         char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2273         char *dest = ret;
2274         bool in_s_quote = false;
2275         bool in_d_quote = false;
2276         bool next_escaped = false;
2277
2278         if (!ret) {
2279                 return NULL;
2280         }
2281
2282         while (*src) {
2283                 size_t c_size;
2284                 codepoint_t c = next_codepoint(src, &c_size);
2285
2286                 if (c == INVALID_CODEPOINT) {
2287                         SAFE_FREE(ret);
2288                         return NULL;
2289                 }
2290
2291                 if (c_size > 1) {
2292                         memcpy(dest, src, c_size);
2293                         src += c_size;
2294                         dest += c_size;
2295                         next_escaped = false;
2296                         continue;
2297                 }
2298
2299                 /*
2300                  * Deal with backslash escaped state.
2301                  * This only lasts for one character.
2302                  */
2303
2304                 if (next_escaped) {
2305                         *dest++ = *src++;
2306                         next_escaped = false;
2307                         continue;
2308                 }
2309
2310                 /*
2311                  * Deal with single quote state. The
2312                  * only thing we care about is exiting
2313                  * this state.
2314                  */
2315
2316                 if (in_s_quote) {
2317                         if (*src == '\'') {
2318                                 in_s_quote = false;
2319                         }
2320                         *dest++ = *src++;
2321                         continue;
2322                 }
2323
2324                 /*
2325                  * Deal with double quote state. The most
2326                  * complex state. We must cope with \, meaning
2327                  * possibly escape next char (depending what it
2328                  * is), ", meaning exit this state, and possibly
2329                  * add an \ escape to any unprotected character
2330                  * (listed in INSIDE_DQUOTE_LIST).
2331                  */
2332
2333                 if (in_d_quote) {
2334                         if (*src == '\\') {
2335                                 /*
2336                                  * Next character might be escaped.
2337                                  * We have to peek. Inside double
2338                                  * quotes only INSIDE_DQUOTE_LIST
2339                                  * characters are escaped by a \.
2340                                  */
2341
2342                                 char nextchar;
2343
2344                                 c = next_codepoint(&src[1], &c_size);
2345                                 if (c == INVALID_CODEPOINT) {
2346                                         SAFE_FREE(ret);
2347                                         return NULL;
2348                                 }
2349                                 if (c_size > 1) {
2350                                         /*
2351                                          * Don't escape the next char.
2352                                          * Just copy the \.
2353                                          */
2354                                         *dest++ = *src++;
2355                                         continue;
2356                                 }
2357
2358                                 nextchar = src[1];
2359
2360                                 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2361                                                         (int)nextchar)) {
2362                                         next_escaped = true;
2363                                 }
2364                                 *dest++ = *src++;
2365                                 continue;
2366                         }
2367
2368                         if (*src == '\"') {
2369                                 /* Exit double quote state. */
2370                                 in_d_quote = false;
2371                                 *dest++ = *src++;
2372                                 continue;
2373                         }
2374
2375                         /*
2376                          * We know the character isn't \ or ",
2377                          * so escape it if it's any of the other
2378                          * possible unprotected characters.
2379                          */
2380
2381                         if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2382                                 *dest++ = '\\';
2383                         }
2384                         *dest++ = *src++;
2385                         continue;
2386                 }
2387
2388                 /*
2389                  * From here to the end of the loop we're
2390                  * not in the single or double quote state.
2391                  */
2392
2393                 if (*src == '\\') {
2394                         /* Next character must be escaped. */
2395                         next_escaped = true;
2396                         *dest++ = *src++;
2397                         continue;
2398                 }
2399
2400                 if (*src == '\'') {
2401                         /* Go into single quote state. */
2402                         in_s_quote = true;
2403                         *dest++ = *src++;
2404                         continue;
2405                 }
2406
2407                 if (*src == '\"') {
2408                         /* Go into double quote state. */
2409                         in_d_quote = true;
2410                         *dest++ = *src++;
2411                         continue;
2412                 }
2413
2414                 /* Check if we need to escape the character. */
2415
2416                 if (!strchr(INCLUDE_LIST, (int)*src)) {
2417                         *dest++ = '\\';
2418                 }
2419                 *dest++ = *src++;
2420         }
2421         *dest++ = '\0';
2422         return ret;
2423 }
2424
2425 /***************************************************
2426  str_list_make, v3 version. The v4 version does not
2427  look at quoted strings with embedded blanks, so
2428  do NOT merge this function please!
2429 ***************************************************/
2430
2431 #define S_LIST_ABS 16 /* List Allocation Block Size */
2432
2433 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
2434         const char *sep)
2435 {
2436         char **list;
2437         const char *str;
2438         char *s, *tok;
2439         int num, lsize;
2440
2441         if (!string || !*string)
2442                 return NULL;
2443
2444         list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
2445         if (list == NULL) {
2446                 return NULL;
2447         }
2448         lsize = S_LIST_ABS;
2449
2450         s = talloc_strdup(list, string);
2451         if (s == NULL) {
2452                 DEBUG(0,("str_list_make: Unable to allocate memory"));
2453                 TALLOC_FREE(list);
2454                 return NULL;
2455         }
2456         if (!sep) sep = LIST_SEP;
2457
2458         num = 0;
2459         str = s;
2460
2461         while (next_token_talloc(list, &str, &tok, sep)) {
2462
2463                 if (num == lsize) {
2464                         char **tmp;
2465
2466                         lsize += S_LIST_ABS;
2467
2468                         tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
2469                                                    lsize + 1);
2470                         if (tmp == NULL) {
2471                                 DEBUG(0,("str_list_make: "
2472                                         "Unable to allocate memory"));
2473                                 TALLOC_FREE(list);
2474                                 return NULL;
2475                         }
2476
2477                         list = tmp;
2478
2479                         memset (&list[num], 0,
2480                                 ((sizeof(char**)) * (S_LIST_ABS +1)));
2481                 }
2482
2483                 list[num] = tok;
2484                 num += 1;
2485         }
2486
2487         list[num] = NULL;
2488
2489         TALLOC_FREE(s);
2490         return list;
2491 }