Revert "Fix bug #7781 (Samba transforms "ShareName" to lowercase when adding new...
[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. Treats src as an array of bytes, not as a multibyte
590  string. Any byte >0x7f is automatically converted to '_'.
591  other_safe_chars must also contain an ascii string (bytes<0x7f).
592 **/
593
594 char *alpha_strcpy_fn(const char *fn,
595                 int line,
596                 char *dest,
597                 const char *src,
598                 const char *other_safe_chars,
599                 size_t maxlength)
600 {
601         size_t len, i;
602
603 #ifdef DEVELOPER
604         clobber_region(fn, line, dest, maxlength);
605 #endif
606
607         if (!dest) {
608                 DEBUG(0,("ERROR: NULL dest in alpha_strcpy, "
609                         "called from [%s][%d]\n", fn, line));
610                 return NULL;
611         }
612
613         if (!src) {
614                 *dest = 0;
615                 return dest;
616         }
617
618         len = strlen(src);
619         if (len >= maxlength)
620                 len = maxlength - 1;
621
622         if (!other_safe_chars)
623                 other_safe_chars = "";
624
625         for(i = 0; i < len; i++) {
626                 int val = (src[i] & 0xff);
627                 if (val > 0x7f) {
628                         dest[i] = '_';
629                         continue;
630                 }
631                 if (isupper(val) || islower(val) ||
632                                 isdigit(val) || strchr(other_safe_chars, val))
633                         dest[i] = src[i];
634                 else
635                         dest[i] = '_';
636         }
637
638         dest[i] = '\0';
639
640         return dest;
641 }
642
643 /**
644  Like strncpy but always null terminates. Make sure there is room!
645  The variable n should always be one less than the available size.
646 **/
647 char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n)
648 {
649         char *d = dest;
650
651 #ifdef DEVELOPER
652         clobber_region(fn, line, dest, n+1);
653 #endif
654
655         if (!dest) {
656                 DEBUG(0,("ERROR: NULL dest in StrnCpy, "
657                         "called from [%s][%d]\n", fn, line));
658                 return(NULL);
659         }
660
661         if (!src) {
662                 *dest = 0;
663                 return(dest);
664         }
665
666         while (n-- && (*d = *src)) {
667                 d++;
668                 src++;
669         }
670
671         *d = 0;
672         return(dest);
673 }
674
675 #if 0
676 /**
677  Like strncpy but copies up to the character marker.  always null terminates.
678  returns a pointer to the character marker in the source string (src).
679 **/
680
681 static char *strncpyn(char *dest, const char *src, size_t n, char c)
682 {
683         char *p;
684         size_t str_len;
685
686 #ifdef DEVELOPER
687         clobber_region(dest, n+1);
688 #endif
689         p = strchr_m(src, c);
690         if (p == NULL) {
691                 DEBUG(5, ("strncpyn: separator character (%c) not found\n", c));
692                 return NULL;
693         }
694
695         str_len = PTR_DIFF(p, src);
696         strncpy(dest, src, MIN(n, str_len));
697         dest[str_len] = '\0';
698
699         return p;
700 }
701 #endif
702
703 /**
704  Check if a string is part of a list.
705 **/
706
707 bool in_list(const char *s, const char *list, bool casesensitive)
708 {
709         char *tok = NULL;
710         bool ret = false;
711         TALLOC_CTX *frame;
712
713         if (!list) {
714                 return false;
715         }
716
717         frame = talloc_stackframe();
718         while (next_token_talloc(frame, &list, &tok,LIST_SEP)) {
719                 if (casesensitive) {
720                         if (strcmp(tok,s) == 0) {
721                                 ret = true;
722                                 break;
723                         }
724                 } else {
725                         if (StrCaseCmp(tok,s) == 0) {
726                                 ret = true;
727                                 break;
728                         }
729                 }
730         }
731         TALLOC_FREE(frame);
732         return ret;
733 }
734
735 /* this is used to prevent lots of mallocs of size 1 */
736 static const char null_string[] = "";
737
738 /**
739  Set a string value, allocing the space for the string
740 **/
741
742 static bool string_init(char **dest,const char *src)
743 {
744         size_t l;
745
746         if (!src)
747                 src = "";
748
749         l = strlen(src);
750
751         if (l == 0) {
752                 *dest = CONST_DISCARD(char*, null_string);
753         } else {
754                 (*dest) = SMB_STRDUP(src);
755                 if ((*dest) == NULL) {
756                         DEBUG(0,("Out of memory in string_init\n"));
757                         return false;
758                 }
759         }
760         return(true);
761 }
762
763 /**
764  Free a string value.
765 **/
766
767 void string_free(char **s)
768 {
769         if (!s || !(*s))
770                 return;
771         if (*s == null_string)
772                 *s = NULL;
773         SAFE_FREE(*s);
774 }
775
776 /**
777  Set a string value, deallocating any existing space, and allocing the space
778  for the string
779 **/
780
781 bool string_set(char **dest,const char *src)
782 {
783         string_free(dest);
784         return(string_init(dest,src));
785 }
786
787 /**
788  Substitute a string for a pattern in another string. Make sure there is
789  enough room!
790
791  This routine looks for pattern in s and replaces it with
792  insert. It may do multiple replacements or just one.
793
794  Any of " ; ' $ or ` in the insert string are replaced with _
795  if len==0 then the string cannot be extended. This is different from the old
796  use of len==0 which was for no length checks to be done.
797 **/
798
799 void string_sub2(char *s,const char *pattern, const char *insert, size_t len,
800                  bool remove_unsafe_characters, bool replace_once,
801                  bool allow_trailing_dollar)
802 {
803         char *p;
804         ssize_t ls,lp,li, i;
805
806         if (!insert || !pattern || !*pattern || !s)
807                 return;
808
809         ls = (ssize_t)strlen(s);
810         lp = (ssize_t)strlen(pattern);
811         li = (ssize_t)strlen(insert);
812
813         if (len == 0)
814                 len = ls + 1; /* len is number of *bytes* */
815
816         while (lp <= ls && (p = strstr_m(s,pattern))) {
817                 if (ls + (li-lp) >= len) {
818                         DEBUG(0,("ERROR: string overflow by "
819                                 "%d in string_sub(%.50s, %d)\n",
820                                  (int)(ls + (li-lp) - len),
821                                  pattern, (int)len));
822                         break;
823                 }
824                 if (li != lp) {
825                         memmove(p+li,p+lp,strlen(p+lp)+1);
826                 }
827                 for (i=0;i<li;i++) {
828                         switch (insert[i]) {
829                         case '`':
830                         case '"':
831                         case '\'':
832                         case ';':
833                         case '$':
834                                 /* allow a trailing $
835                                  * (as in machine accounts) */
836                                 if (allow_trailing_dollar && (i == li - 1 )) {
837                                         p[i] = insert[i];
838                                         break;
839                                 }
840                         case '%':
841                         case '\r':
842                         case '\n':
843                                 if ( remove_unsafe_characters ) {
844                                         p[i] = '_';
845                                         /* yes this break should be here
846                                          * since we want to fall throw if
847                                          * not replacing unsafe chars */
848                                         break;
849                                 }
850                         default:
851                                 p[i] = insert[i];
852                         }
853                 }
854                 s = p + li;
855                 ls += (li-lp);
856
857                 if (replace_once)
858                         break;
859         }
860 }
861
862 void string_sub_once(char *s, const char *pattern,
863                 const char *insert, size_t len)
864 {
865         string_sub2( s, pattern, insert, len, true, true, false );
866 }
867
868 void string_sub(char *s,const char *pattern, const char *insert, size_t len)
869 {
870         string_sub2( s, pattern, insert, len, true, false, false );
871 }
872
873 void fstring_sub(char *s,const char *pattern,const char *insert)
874 {
875         string_sub(s, pattern, insert, sizeof(fstring));
876 }
877
878 /**
879  Similar to string_sub2, but it will accept only allocated strings
880  and may realloc them so pay attention at what you pass on no
881  pointers inside strings, no const may be passed
882  as string.
883 **/
884
885 char *realloc_string_sub2(char *string,
886                         const char *pattern,
887                         const char *insert,
888                         bool remove_unsafe_characters,
889                         bool allow_trailing_dollar)
890 {
891         char *p, *in;
892         char *s;
893         ssize_t ls,lp,li,ld, i;
894
895         if (!insert || !pattern || !*pattern || !string || !*string)
896                 return NULL;
897
898         s = string;
899
900         in = SMB_STRDUP(insert);
901         if (!in) {
902                 DEBUG(0, ("realloc_string_sub: out of memory!\n"));
903                 return NULL;
904         }
905         ls = (ssize_t)strlen(s);
906         lp = (ssize_t)strlen(pattern);
907         li = (ssize_t)strlen(insert);
908         ld = li - lp;
909         for (i=0;i<li;i++) {
910                 switch (in[i]) {
911                         case '`':
912                         case '"':
913                         case '\'':
914                         case ';':
915                         case '$':
916                                 /* allow a trailing $
917                                  * (as in machine accounts) */
918                                 if (allow_trailing_dollar && (i == li - 1 )) {
919                                         break;
920                                 }
921                         case '%':
922                         case '\r':
923                         case '\n':
924                                 if ( remove_unsafe_characters ) {
925                                         in[i] = '_';
926                                         break;
927                                 }
928                         default:
929                                 /* ok */
930                                 break;
931                 }
932         }
933
934         while ((p = strstr_m(s,pattern))) {
935                 if (ld > 0) {
936                         int offset = PTR_DIFF(s,string);
937                         string = (char *)SMB_REALLOC(string, ls + ld + 1);
938                         if (!string) {
939                                 DEBUG(0, ("realloc_string_sub: "
940                                         "out of memory!\n"));
941                                 SAFE_FREE(in);
942                                 return NULL;
943                         }
944                         p = string + offset + (p - s);
945                 }
946                 if (li != lp) {
947                         memmove(p+li,p+lp,strlen(p+lp)+1);
948                 }
949                 memcpy(p, in, li);
950                 s = p + li;
951                 ls += ld;
952         }
953         SAFE_FREE(in);
954         return string;
955 }
956
957 char *realloc_string_sub(char *string,
958                         const char *pattern,
959                         const char *insert)
960 {
961         return realloc_string_sub2(string, pattern, insert, true, false);
962 }
963
964 /*
965  * Internal guts of talloc_string_sub and talloc_all_string_sub.
966  * talloc version of string_sub2.
967  */
968
969 char *talloc_string_sub2(TALLOC_CTX *mem_ctx, const char *src,
970                         const char *pattern,
971                         const char *insert,
972                         bool remove_unsafe_characters,
973                         bool replace_once,
974                         bool allow_trailing_dollar)
975 {
976         char *p, *in;
977         char *s;
978         char *string;
979         ssize_t ls,lp,li,ld, i;
980
981         if (!insert || !pattern || !*pattern || !src) {
982                 return NULL;
983         }
984
985         string = talloc_strdup(mem_ctx, src);
986         if (string == NULL) {
987                 DEBUG(0, ("talloc_string_sub2: "
988                         "talloc_strdup failed\n"));
989                 return NULL;
990         }
991
992         s = string;
993
994         in = SMB_STRDUP(insert);
995         if (!in) {
996                 DEBUG(0, ("talloc_string_sub2: ENOMEM\n"));
997                 return NULL;
998         }
999         ls = (ssize_t)strlen(s);
1000         lp = (ssize_t)strlen(pattern);
1001         li = (ssize_t)strlen(insert);
1002         ld = li - lp;
1003
1004         for (i=0;i<li;i++) {
1005                 switch (in[i]) {
1006                         case '`':
1007                         case '"':
1008                         case '\'':
1009                         case ';':
1010                         case '$':
1011                                 /* allow a trailing $
1012                                  * (as in machine accounts) */
1013                                 if (allow_trailing_dollar && (i == li - 1 )) {
1014                                         break;
1015                                 }
1016                         case '%':
1017                         case '\r':
1018                         case '\n':
1019                                 if (remove_unsafe_characters) {
1020                                         in[i] = '_';
1021                                         break;
1022                                 }
1023                         default:
1024                                 /* ok */
1025                                 break;
1026                 }
1027         }
1028
1029         while ((p = strstr_m(s,pattern))) {
1030                 if (ld > 0) {
1031                         int offset = PTR_DIFF(s,string);
1032                         string = (char *)TALLOC_REALLOC(mem_ctx, string,
1033                                                         ls + ld + 1);
1034                         if (!string) {
1035                                 DEBUG(0, ("talloc_string_sub: out of "
1036                                           "memory!\n"));
1037                                 SAFE_FREE(in);
1038                                 return NULL;
1039                         }
1040                         p = string + offset + (p - s);
1041                 }
1042                 if (li != lp) {
1043                         memmove(p+li,p+lp,strlen(p+lp)+1);
1044                 }
1045                 memcpy(p, in, li);
1046                 s = p + li;
1047                 ls += ld;
1048
1049                 if (replace_once) {
1050                         break;
1051                 }
1052         }
1053         SAFE_FREE(in);
1054         return string;
1055 }
1056
1057 /* Same as string_sub, but returns a talloc'ed string */
1058
1059 char *talloc_string_sub(TALLOC_CTX *mem_ctx,
1060                         const char *src,
1061                         const char *pattern,
1062                         const char *insert)
1063 {
1064         return talloc_string_sub2(mem_ctx, src, pattern, insert,
1065                         true, false, false);
1066 }
1067
1068 /**
1069  Similar to string_sub() but allows for any character to be substituted.
1070  Use with caution!
1071  if len==0 then the string cannot be extended. This is different from the old
1072  use of len==0 which was for no length checks to be done.
1073 **/
1074
1075 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1076 {
1077         char *p;
1078         ssize_t ls,lp,li;
1079
1080         if (!insert || !pattern || !s)
1081                 return;
1082
1083         ls = (ssize_t)strlen(s);
1084         lp = (ssize_t)strlen(pattern);
1085         li = (ssize_t)strlen(insert);
1086
1087         if (!*pattern)
1088                 return;
1089
1090         if (len == 0)
1091                 len = ls + 1; /* len is number of *bytes* */
1092
1093         while (lp <= ls && (p = strstr_m(s,pattern))) {
1094                 if (ls + (li-lp) >= len) {
1095                         DEBUG(0,("ERROR: string overflow by "
1096                                 "%d in all_string_sub(%.50s, %d)\n",
1097                                  (int)(ls + (li-lp) - len),
1098                                  pattern, (int)len));
1099                         break;
1100                 }
1101                 if (li != lp) {
1102                         memmove(p+li,p+lp,strlen(p+lp)+1);
1103                 }
1104                 memcpy(p, insert, li);
1105                 s = p + li;
1106                 ls += (li-lp);
1107         }
1108 }
1109
1110 char *talloc_all_string_sub(TALLOC_CTX *ctx,
1111                                 const char *src,
1112                                 const char *pattern,
1113                                 const char *insert)
1114 {
1115         return talloc_string_sub2(ctx, src, pattern, insert,
1116                         false, false, false);
1117 }
1118
1119 /**
1120  Write an octal as a string.
1121 **/
1122
1123 char *octal_string(int i)
1124 {
1125         char *result;
1126         if (i == -1) {
1127                 result = talloc_strdup(talloc_tos(), "-1");
1128         }
1129         else {
1130                 result = talloc_asprintf(talloc_tos(), "0%o", i);
1131         }
1132         SMB_ASSERT(result != NULL);
1133         return result;
1134 }
1135
1136
1137 /**
1138  Truncate a string at a specified length.
1139 **/
1140
1141 char *string_truncate(char *s, unsigned int length)
1142 {
1143         if (s && strlen(s) > length)
1144                 s[length] = 0;
1145         return s;
1146 }
1147
1148 /**
1149  Strchr and strrchr_m are very hard to do on general multi-byte strings.
1150  We convert via ucs2 for now.
1151 **/
1152
1153 char *strchr_m(const char *src, char c)
1154 {
1155         smb_ucs2_t *ws = NULL;
1156         char *s2 = NULL;
1157         smb_ucs2_t *p;
1158         const char *s;
1159         char *ret;
1160         size_t converted_size;
1161
1162         /* characters below 0x3F are guaranteed to not appear in
1163            non-initial position in multi-byte charsets */
1164         if ((c & 0xC0) == 0) {
1165                 return strchr(src, c);
1166         }
1167
1168         /* this is quite a common operation, so we want it to be
1169            fast. We optimise for the ascii case, knowing that all our
1170            supported multi-byte character sets are ascii-compatible
1171            (ie. they match for the first 128 chars) */
1172
1173         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1174                 if (*s == c)
1175                         return (char *)s;
1176         }
1177
1178         if (!*s)
1179                 return NULL;
1180
1181 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1182         /* With compose characters we must restart from the beginning. JRA. */
1183         s = src;
1184 #endif
1185
1186         if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1187                 /* Wrong answer, but what can we do... */
1188                 return strchr(src, c);
1189         }
1190         p = strchr_w(ws, UCS2_CHAR(c));
1191         if (!p) {
1192                 TALLOC_FREE(ws);
1193                 return NULL;
1194         }
1195         *p = 0;
1196         if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1197                 SAFE_FREE(ws);
1198                 /* Wrong answer, but what can we do... */
1199                 return strchr(src, c);
1200         }
1201         ret = (char *)(s+strlen(s2));
1202         TALLOC_FREE(ws);
1203         TALLOC_FREE(s2);
1204         return ret;
1205 }
1206
1207 char *strrchr_m(const char *s, char c)
1208 {
1209         /* characters below 0x3F are guaranteed to not appear in
1210            non-initial position in multi-byte charsets */
1211         if ((c & 0xC0) == 0) {
1212                 return strrchr(s, c);
1213         }
1214
1215         /* this is quite a common operation, so we want it to be
1216            fast. We optimise for the ascii case, knowing that all our
1217            supported multi-byte character sets are ascii-compatible
1218            (ie. they match for the first 128 chars). Also, in Samba
1219            we only search for ascii characters in 'c' and that
1220            in all mb character sets with a compound character
1221            containing c, if 'c' is not a match at position
1222            p, then p[-1] > 0x7f. JRA. */
1223
1224         {
1225                 size_t len = strlen(s);
1226                 const char *cp = s;
1227                 bool got_mb = false;
1228
1229                 if (len == 0)
1230                         return NULL;
1231                 cp += (len - 1);
1232                 do {
1233                         if (c == *cp) {
1234                                 /* Could be a match. Part of a multibyte ? */
1235                                 if ((cp > s) &&
1236                                         (((unsigned char)cp[-1]) & 0x80)) {
1237                                         /* Yep - go slow :-( */
1238                                         got_mb = true;
1239                                         break;
1240                                 }
1241                                 /* No - we have a match ! */
1242                                 return (char *)cp;
1243                         }
1244                 } while (cp-- != s);
1245                 if (!got_mb)
1246                         return NULL;
1247         }
1248
1249         /* String contained a non-ascii char. Slow path. */
1250         {
1251                 smb_ucs2_t *ws = NULL;
1252                 char *s2 = NULL;
1253                 smb_ucs2_t *p;
1254                 char *ret;
1255                 size_t converted_size;
1256
1257                 if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1258                         /* Wrong answer, but what can we do. */
1259                         return strrchr(s, c);
1260                 }
1261                 p = strrchr_w(ws, UCS2_CHAR(c));
1262                 if (!p) {
1263                         TALLOC_FREE(ws);
1264                         return NULL;
1265                 }
1266                 *p = 0;
1267                 if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1268                         TALLOC_FREE(ws);
1269                         /* Wrong answer, but what can we do. */
1270                         return strrchr(s, c);
1271                 }
1272                 ret = (char *)(s+strlen(s2));
1273                 TALLOC_FREE(ws);
1274                 TALLOC_FREE(s2);
1275                 return ret;
1276         }
1277 }
1278
1279 /***********************************************************************
1280  Return the equivalent of doing strrchr 'n' times - always going
1281  backwards.
1282 ***********************************************************************/
1283
1284 char *strnrchr_m(const char *s, char c, unsigned int n)
1285 {
1286         smb_ucs2_t *ws = NULL;
1287         char *s2 = NULL;
1288         smb_ucs2_t *p;
1289         char *ret;
1290         size_t converted_size;
1291
1292         if (!push_ucs2_talloc(talloc_tos(), &ws, s, &converted_size)) {
1293                 /* Too hard to try and get right. */
1294                 return NULL;
1295         }
1296         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1297         if (!p) {
1298                 TALLOC_FREE(ws);
1299                 return NULL;
1300         }
1301         *p = 0;
1302         if (!pull_ucs2_talloc(talloc_tos(), &s2, ws, &converted_size)) {
1303                 TALLOC_FREE(ws);
1304                 /* Too hard to try and get right. */
1305                 return NULL;
1306         }
1307         ret = (char *)(s+strlen(s2));
1308         TALLOC_FREE(ws);
1309         TALLOC_FREE(s2);
1310         return ret;
1311 }
1312
1313 /***********************************************************************
1314  strstr_m - We convert via ucs2 for now.
1315 ***********************************************************************/
1316
1317 char *strstr_m(const char *src, const char *findstr)
1318 {
1319         smb_ucs2_t *p;
1320         smb_ucs2_t *src_w, *find_w;
1321         const char *s;
1322         char *s2;
1323         char *retp;
1324
1325         size_t converted_size, findstr_len = 0;
1326
1327         /* for correctness */
1328         if (!findstr[0]) {
1329                 return (char*)src;
1330         }
1331
1332         /* Samba does single character findstr calls a *lot*. */
1333         if (findstr[1] == '\0')
1334                 return strchr_m(src, *findstr);
1335
1336         /* We optimise for the ascii case, knowing that all our
1337            supported multi-byte character sets are ascii-compatible
1338            (ie. they match for the first 128 chars) */
1339
1340         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1341                 if (*s == *findstr) {
1342                         if (!findstr_len)
1343                                 findstr_len = strlen(findstr);
1344
1345                         if (strncmp(s, findstr, findstr_len) == 0) {
1346                                 return (char *)s;
1347                         }
1348                 }
1349         }
1350
1351         if (!*s)
1352                 return NULL;
1353
1354 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1355         /* 'make check' fails unless we do this */
1356
1357         /* With compose characters we must restart from the beginning. JRA. */
1358         s = src;
1359 #endif
1360
1361         if (!push_ucs2_talloc(talloc_tos(), &src_w, src, &converted_size)) {
1362                 DEBUG(0,("strstr_m: src malloc fail\n"));
1363                 return NULL;
1364         }
1365
1366         if (!push_ucs2_talloc(talloc_tos(), &find_w, findstr, &converted_size)) {
1367                 TALLOC_FREE(src_w);
1368                 DEBUG(0,("strstr_m: find malloc fail\n"));
1369                 return NULL;
1370         }
1371
1372         p = strstr_w(src_w, find_w);
1373
1374         if (!p) {
1375                 TALLOC_FREE(src_w);
1376                 TALLOC_FREE(find_w);
1377                 return NULL;
1378         }
1379
1380         *p = 0;
1381         if (!pull_ucs2_talloc(talloc_tos(), &s2, src_w, &converted_size)) {
1382                 TALLOC_FREE(src_w);
1383                 TALLOC_FREE(find_w);
1384                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1385                 return NULL;
1386         }
1387         retp = (char *)(s+strlen(s2));
1388         TALLOC_FREE(src_w);
1389         TALLOC_FREE(find_w);
1390         TALLOC_FREE(s2);
1391         return retp;
1392 }
1393
1394 /**
1395  Convert a string to lower case.
1396 **/
1397
1398 void strlower_m(char *s)
1399 {
1400         size_t len;
1401         int errno_save;
1402
1403         /* this is quite a common operation, so we want it to be
1404            fast. We optimise for the ascii case, knowing that all our
1405            supported multi-byte character sets are ascii-compatible
1406            (ie. they match for the first 128 chars) */
1407
1408         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1409                 *s = tolower_ascii((unsigned char)*s);
1410                 s++;
1411         }
1412
1413         if (!*s)
1414                 return;
1415
1416         /* I assume that lowercased string takes the same number of bytes
1417          * as source string even in UTF-8 encoding. (VIV) */
1418         len = strlen(s) + 1;
1419         errno_save = errno;
1420         errno = 0;
1421         unix_strlower(s,len,s,len);
1422         /* Catch mb conversion errors that may not terminate. */
1423         if (errno)
1424                 s[len-1] = '\0';
1425         errno = errno_save;
1426 }
1427
1428 /**
1429  Convert a string to upper case.
1430 **/
1431
1432 void strupper_m(char *s)
1433 {
1434         size_t len;
1435         int errno_save;
1436
1437         /* this is quite a common operation, so we want it to be
1438            fast. We optimise for the ascii case, knowing that all our
1439            supported multi-byte character sets are ascii-compatible
1440            (ie. they match for the first 128 chars) */
1441
1442         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1443                 *s = toupper_ascii_fast((unsigned char)*s);
1444                 s++;
1445         }
1446
1447         if (!*s)
1448                 return;
1449
1450         /* I assume that lowercased string takes the same number of bytes
1451          * as source string even in multibyte encoding. (VIV) */
1452         len = strlen(s) + 1;
1453         errno_save = errno;
1454         errno = 0;
1455         unix_strupper(s,len,s,len);
1456         /* Catch mb conversion errors that may not terminate. */
1457         if (errno)
1458                 s[len-1] = '\0';
1459         errno = errno_save;
1460 }
1461
1462 /**
1463  * Calculate the number of units (8 or 16-bit, depending on the
1464  * destination charset), that would be needed to convert the input
1465  * string which is expected to be in in CH_UNIX encoding to the
1466  * destination charset (which should be a unicode charset).
1467  */
1468 size_t strlen_m_ext(const char *s, const charset_t dst_charset)
1469 {
1470         size_t count = 0;
1471
1472         if (!s) {
1473                 return 0;
1474         }
1475
1476         while (*s && !(((uint8_t)*s) & 0x80)) {
1477                 s++;
1478                 count++;
1479         }
1480
1481         if (!*s) {
1482                 return count;
1483         }
1484
1485         while (*s) {
1486                 size_t c_size;
1487                 codepoint_t c = next_codepoint(s, &c_size);
1488                 s += c_size;
1489
1490                 switch(dst_charset) {
1491                 case CH_UTF16LE:
1492                 case CH_UTF16BE:
1493                 case CH_UTF16MUNGED:
1494                         if (c < 0x10000) {
1495                                 /* Unicode char fits into 16 bits. */
1496                                 count += 1;
1497                         } else {
1498                                 /* Double-width unicode char - 32 bits. */
1499                                 count += 2;
1500                         }
1501                         break;
1502                 case CH_UTF8:
1503                         /*
1504                          * this only checks ranges, and does not
1505                          * check for invalid codepoints
1506                          */
1507                         if (c < 0x80) {
1508                                 count += 1;
1509                         } else if (c < 0x800) {
1510                                 count += 2;
1511                         } else if (c < 0x1000) {
1512                                 count += 3;
1513                         } else {
1514                                 count += 4;
1515                         }
1516                         break;
1517                 default:
1518                         /*
1519                          * non-unicode encoding:
1520                          * assume that each codepoint fits into
1521                          * one unit in the destination encoding.
1522                          */
1523                         count += 1;
1524                 }
1525         }
1526
1527         return count;
1528 }
1529
1530 size_t strlen_m_ext_term(const char *s, const charset_t dst_charset)
1531 {
1532         if (!s) {
1533                 return 0;
1534         }
1535         return strlen_m_ext(s, dst_charset) + 1;
1536 }
1537
1538 /**
1539  Count the number of UCS2 characters in a string. Normally this will
1540  be the same as the number of bytes in a string for single byte strings,
1541  but will be different for multibyte.
1542 **/
1543
1544 size_t strlen_m(const char *s)
1545 {
1546         return strlen_m_ext(s, CH_UTF16LE);
1547 }
1548
1549 /**
1550  Count the number of UCS2 characters in a string including the null
1551  terminator.
1552 **/
1553
1554 size_t strlen_m_term(const char *s)
1555 {
1556         if (!s) {
1557                 return 0;
1558         }
1559         return strlen_m(s) + 1;
1560 }
1561
1562 /*
1563  * Weird helper routine for the winreg pipe: If nothing is around, return 0,
1564  * if a string is there, include the terminator.
1565  */
1566
1567 size_t strlen_m_term_null(const char *s)
1568 {
1569         size_t len;
1570         if (!s) {
1571                 return 0;
1572         }
1573         len = strlen_m(s);
1574         if (len == 0) {
1575                 return 0;
1576         }
1577
1578         return len+1;
1579 }
1580 /**
1581  Return a RFC2254 binary string representation of a buffer.
1582  Used in LDAP filters.
1583  Caller must free.
1584 **/
1585
1586 char *binary_string_rfc2254(TALLOC_CTX *mem_ctx, const uint8_t *buf, int len)
1587 {
1588         char *s;
1589         int i, j;
1590         const char *hex = "0123456789ABCDEF";
1591         s = talloc_array(mem_ctx, char, len * 3 + 1);
1592         if (s == NULL) {
1593                 return NULL;
1594         }
1595         for (j=i=0;i<len;i++) {
1596                 s[j] = '\\';
1597                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1598                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1599                 j += 3;
1600         }
1601         s[j] = 0;
1602         return s;
1603 }
1604
1605 char *binary_string(char *buf, int len)
1606 {
1607         char *s;
1608         int i, j;
1609         const char *hex = "0123456789ABCDEF";
1610         s = (char *)SMB_MALLOC(len * 2 + 1);
1611         if (!s)
1612                 return NULL;
1613         for (j=i=0;i<len;i++) {
1614                 s[j]   = hex[((unsigned char)buf[i]) >> 4];
1615                 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1616                 j += 2;
1617         }
1618         s[j] = 0;
1619         return s;
1620 }
1621
1622 /**
1623  Just a typesafety wrapper for snprintf into a fstring.
1624 **/
1625
1626 int fstr_sprintf(fstring s, const char *fmt, ...)
1627 {
1628         va_list ap;
1629         int ret;
1630
1631         va_start(ap, fmt);
1632         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1633         va_end(ap);
1634         return ret;
1635 }
1636
1637 /**
1638  List of Strings manipulation functions
1639 **/
1640
1641 #define S_LIST_ABS 16 /* List Allocation Block Size */
1642
1643 /******************************************************************************
1644  version of standard_sub_basic() for string lists; uses talloc_sub_basic()
1645  for the work
1646  *****************************************************************************/
1647
1648 bool str_list_sub_basic( char **list, const char *smb_name,
1649                          const char *domain_name )
1650 {
1651         TALLOC_CTX *ctx = list;
1652         char *s, *tmpstr;
1653
1654         while ( *list ) {
1655                 s = *list;
1656                 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
1657                 if ( !tmpstr ) {
1658                         DEBUG(0,("str_list_sub_basic: "
1659                                 "alloc_sub_basic() return NULL!\n"));
1660                         return false;
1661                 }
1662
1663                 TALLOC_FREE(*list);
1664                 *list = tmpstr;
1665
1666                 list++;
1667         }
1668
1669         return true;
1670 }
1671
1672 /******************************************************************************
1673  substitute a specific pattern in a string list
1674  *****************************************************************************/
1675
1676 bool str_list_substitute(char **list, const char *pattern, const char *insert)
1677 {
1678         TALLOC_CTX *ctx = list;
1679         char *p, *s, *t;
1680         ssize_t ls, lp, li, ld, i, d;
1681
1682         if (!list)
1683                 return false;
1684         if (!pattern)
1685                 return false;
1686         if (!insert)
1687                 return false;
1688
1689         lp = (ssize_t)strlen(pattern);
1690         li = (ssize_t)strlen(insert);
1691         ld = li -lp;
1692
1693         while (*list) {
1694                 s = *list;
1695                 ls = (ssize_t)strlen(s);
1696
1697                 while ((p = strstr_m(s, pattern))) {
1698                         t = *list;
1699                         d = p -t;
1700                         if (ld) {
1701                                 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
1702                                 if (!t) {
1703                                         DEBUG(0,("str_list_substitute: "
1704                                                 "Unable to allocate memory"));
1705                                         return false;
1706                                 }
1707                                 memcpy(t, *list, d);
1708                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1709                                 TALLOC_FREE(*list);
1710                                 *list = t;
1711                                 ls += ld;
1712                                 s = t +d +li;
1713                         }
1714
1715                         for (i = 0; i < li; i++) {
1716                                 switch (insert[i]) {
1717                                         case '`':
1718                                         case '"':
1719                                         case '\'':
1720                                         case ';':
1721                                         case '$':
1722                                         case '%':
1723                                         case '\r':
1724                                         case '\n':
1725                                                 t[d +i] = '_';
1726                                                 break;
1727                                         default:
1728                                                 t[d +i] = insert[i];
1729                                 }
1730                         }
1731                 }
1732
1733                 list++;
1734         }
1735
1736         return true;
1737 }
1738
1739
1740 #define IPSTR_LIST_SEP  ","
1741 #define IPSTR_LIST_CHAR ','
1742
1743 /**
1744  * Add ip string representation to ipstr list. Used also
1745  * as part of @function ipstr_list_make
1746  *
1747  * @param ipstr_list pointer to string containing ip list;
1748  *        MUST BE already allocated and IS reallocated if necessary
1749  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1750  *        as a result of reallocation)
1751  * @param ip IP address which is to be added to list
1752  * @return pointer to string appended with new ip and possibly
1753  *         reallocated to new length
1754  **/
1755
1756 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
1757 {
1758         char *new_ipstr = NULL;
1759         char addr_buf[INET6_ADDRSTRLEN];
1760         int ret;
1761
1762         /* arguments checking */
1763         if (!ipstr_list || !service) {
1764                 return NULL;
1765         }
1766
1767         print_sockaddr(addr_buf,
1768                         sizeof(addr_buf),
1769                         &service->ss);
1770
1771         /* attempt to convert ip to a string and append colon separator to it */
1772         if (*ipstr_list) {
1773                 if (service->ss.ss_family == AF_INET) {
1774                         /* IPv4 */
1775                         ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
1776                                        IPSTR_LIST_SEP, addr_buf,
1777                                        service->port);
1778                 } else {
1779                         /* IPv6 */
1780                         ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
1781                                        IPSTR_LIST_SEP, addr_buf,
1782                                        service->port);
1783                 }
1784                 SAFE_FREE(*ipstr_list);
1785         } else {
1786                 if (service->ss.ss_family == AF_INET) {
1787                         /* IPv4 */
1788                         ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
1789                                        service->port);
1790                 } else {
1791                         /* IPv6 */
1792                         ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
1793                                        service->port);
1794                 }
1795         }
1796         if (ret == -1) {
1797                 return NULL;
1798         }
1799         *ipstr_list = new_ipstr;
1800         return *ipstr_list;
1801 }
1802
1803 /**
1804  * Allocate and initialise an ipstr list using ip adresses
1805  * passed as arguments.
1806  *
1807  * @param ipstr_list pointer to string meant to be allocated and set
1808  * @param ip_list array of ip addresses to place in the list
1809  * @param ip_count number of addresses stored in ip_list
1810  * @return pointer to allocated ip string
1811  **/
1812
1813 char *ipstr_list_make(char **ipstr_list,
1814                         const struct ip_service *ip_list,
1815                         int ip_count)
1816 {
1817         int i;
1818
1819         /* arguments checking */
1820         if (!ip_list || !ipstr_list) {
1821                 return 0;
1822         }
1823
1824         *ipstr_list = NULL;
1825
1826         /* process ip addresses given as arguments */
1827         for (i = 0; i < ip_count; i++) {
1828                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
1829         }
1830
1831         return (*ipstr_list);
1832 }
1833
1834
1835 /**
1836  * Parse given ip string list into array of ip addresses
1837  * (as ip_service structures)
1838  *    e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
1839  *
1840  * @param ipstr ip string list to be parsed
1841  * @param ip_list pointer to array of ip addresses which is
1842  *        allocated by this function and must be freed by caller
1843  * @return number of successfully parsed addresses
1844  **/
1845
1846 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
1847 {
1848         TALLOC_CTX *frame;
1849         char *token_str = NULL;
1850         size_t count;
1851         int i;
1852
1853         if (!ipstr_list || !ip_list)
1854                 return 0;
1855
1856         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
1857         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
1858                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
1859                                         (unsigned long)count));
1860                 return 0;
1861         }
1862
1863         frame = talloc_stackframe();
1864         for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
1865                                 IPSTR_LIST_SEP) && i<count; i++ ) {
1866                 char *s = token_str;
1867                 char *p = strrchr(token_str, ':');
1868
1869                 if (p) {
1870                         *p = 0;
1871                         (*ip_list)[i].port = atoi(p+1);
1872                 }
1873
1874                 /* convert single token to ip address */
1875                 if (token_str[0] == '[') {
1876                         /* IPv6 address. */
1877                         s++;
1878                         p = strchr(token_str, ']');
1879                         if (!p) {
1880                                 continue;
1881                         }
1882                         *p = '\0';
1883                 }
1884                 if (!interpret_string_addr(&(*ip_list)[i].ss,
1885                                         s,
1886                                         AI_NUMERICHOST)) {
1887                         continue;
1888                 }
1889         }
1890         TALLOC_FREE(frame);
1891         return count;
1892 }
1893
1894 /**
1895  * Safely free ip string list
1896  *
1897  * @param ipstr_list ip string list to be freed
1898  **/
1899
1900 void ipstr_list_free(char* ipstr_list)
1901 {
1902         SAFE_FREE(ipstr_list);
1903 }
1904
1905 static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1906
1907 /**
1908  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
1909  **/
1910 DATA_BLOB base64_decode_data_blob(const char *s)
1911 {
1912         int bit_offset, byte_offset, idx, i, n;
1913         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
1914         unsigned char *d = decoded.data;
1915         char *p;
1916
1917         n=i=0;
1918
1919         while (*s && (p=strchr_m(b64,*s))) {
1920                 idx = (int)(p - b64);
1921                 byte_offset = (i*6)/8;
1922                 bit_offset = (i*6)%8;
1923                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
1924                 if (bit_offset < 3) {
1925                         d[byte_offset] |= (idx << (2-bit_offset));
1926                         n = byte_offset+1;
1927                 } else {
1928                         d[byte_offset] |= (idx >> (bit_offset-2));
1929                         d[byte_offset+1] = 0;
1930                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
1931                         n = byte_offset+2;
1932                 }
1933                 s++; i++;
1934         }
1935
1936         if ((n > 0) && (*s == '=')) {
1937                 n -= 1;
1938         }
1939
1940         /* fix up length */
1941         decoded.length = n;
1942         return decoded;
1943 }
1944
1945 /**
1946  * Decode a base64 string in-place - wrapper for the above
1947  **/
1948 void base64_decode_inplace(char *s)
1949 {
1950         DATA_BLOB decoded = base64_decode_data_blob(s);
1951
1952         if ( decoded.length != 0 ) {
1953                 memcpy(s, decoded.data, decoded.length);
1954
1955                 /* null terminate */
1956                 s[decoded.length] = '\0';
1957         } else {
1958                 *s = '\0';
1959         }
1960
1961         data_blob_free(&decoded);
1962 }
1963
1964 /**
1965  * Encode a base64 string into a talloc()ed string caller to free.
1966  *
1967  * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
1968  * with adjustments
1969  **/
1970
1971 char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
1972 {
1973         int bits = 0;
1974         int char_count = 0;
1975         size_t out_cnt, len, output_len;
1976         char *result;
1977
1978         if (!data.length || !data.data)
1979                 return NULL;
1980
1981         out_cnt = 0;
1982         len = data.length;
1983         output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
1984                                            * random but should be enough for
1985                                            * the = and \0 */
1986         result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
1987         SMB_ASSERT(result != NULL);
1988
1989         while (len--) {
1990                 int c = (unsigned char) *(data.data++);
1991                 bits += c;
1992                 char_count++;
1993                 if (char_count == 3) {
1994                         result[out_cnt++] = b64[bits >> 18];
1995                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
1996                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
1997                         result[out_cnt++] = b64[bits & 0x3f];
1998                         bits = 0;
1999                         char_count = 0;
2000                 } else {
2001                         bits <<= 8;
2002                 }
2003         }
2004         if (char_count != 0) {
2005                 bits <<= 16 - (8 * char_count);
2006                 result[out_cnt++] = b64[bits >> 18];
2007                 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2008                 if (char_count == 1) {
2009                         result[out_cnt++] = '=';
2010                         result[out_cnt++] = '=';
2011                 } else {
2012                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2013                         result[out_cnt++] = '=';
2014                 }
2015         }
2016         result[out_cnt] = '\0'; /* terminate */
2017         return result;
2018 }
2019
2020 /* read a SMB_BIG_UINT from a string */
2021 uint64_t STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2022 {
2023
2024         uint64_t val = -1;
2025         const char *p = nptr;
2026
2027         if (!p) {
2028                 if (entptr) {
2029                         *entptr = p;
2030                 }
2031                 return val;
2032         }
2033
2034         while (*p && isspace(*p))
2035                 p++;
2036
2037         sscanf(p,"%"PRIu64,&val);
2038         if (entptr) {
2039                 while (*p && isdigit(*p))
2040                         p++;
2041                 *entptr = p;
2042         }
2043
2044         return val;
2045 }
2046
2047 /* Convert a size specification to a count of bytes. We accept the following
2048  * suffixes:
2049  *          bytes if there is no suffix
2050  *      kK  kibibytes
2051  *      mM  mebibytes
2052  *      gG  gibibytes
2053  *      tT  tibibytes
2054  *      pP  whatever the ISO name for petabytes is
2055  *
2056  *  Returns 0 if the string can't be converted.
2057  */
2058 SMB_OFF_T conv_str_size(const char * str)
2059 {
2060         SMB_OFF_T lval;
2061         char * end;
2062
2063         if (str == NULL || *str == '\0') {
2064                 return 0;
2065         }
2066
2067 #ifdef HAVE_STRTOULL
2068         if (sizeof(SMB_OFF_T) == 8) {
2069             lval = strtoull(str, &end, 10 /* base */);
2070         } else {
2071             lval = strtoul(str, &end, 10 /* base */);
2072         }
2073 #else
2074         lval = strtoul(str, &end, 10 /* base */);
2075 #endif
2076
2077         if (end == NULL || end == str) {
2078                 return 0;
2079         }
2080
2081         if (*end) {
2082                 SMB_OFF_T lval_orig = lval;
2083
2084                 if (strwicmp(end, "K") == 0) {
2085                         lval *= (SMB_OFF_T)1024;
2086                 } else if (strwicmp(end, "M") == 0) {
2087                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2088                 } else if (strwicmp(end, "G") == 0) {
2089                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2090                                 (SMB_OFF_T)1024);
2091                 } else if (strwicmp(end, "T") == 0) {
2092                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2093                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2094                 } else if (strwicmp(end, "P") == 0) {
2095                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2096                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2097                                 (SMB_OFF_T)1024);
2098                 } else {
2099                         return 0;
2100                 }
2101
2102                 /* Primitive attempt to detect wrapping on platforms with
2103                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2104                  * a failure than some random number.
2105                  */
2106                 if (lval_orig <= lval) {
2107                         return 0;
2108                 }
2109         }
2110
2111         return lval;
2112 }
2113
2114 void string_append(char **left, const char *right)
2115 {
2116         int new_len = strlen(right) + 1;
2117
2118         if (*left == NULL) {
2119                 *left = (char *)SMB_MALLOC(new_len);
2120                 *left[0] = '\0';
2121         } else {
2122                 new_len += strlen(*left);
2123                 *left = (char *)SMB_REALLOC(*left, new_len);
2124         }
2125
2126         if (*left == NULL) {
2127                 return;
2128         }
2129
2130         safe_strcat(*left, right, new_len-1);
2131 }
2132
2133 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2134                          const char *str, const char ***strings,
2135                          int *num)
2136 {
2137         char *dup_str = talloc_strdup(mem_ctx, str);
2138
2139         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2140                         const char *, (*num)+1);
2141
2142         if ((*strings == NULL) || (dup_str == NULL)) {
2143                 *num = 0;
2144                 return false;
2145         }
2146
2147         (*strings)[*num] = dup_str;
2148         *num += 1;
2149         return true;
2150 }
2151
2152 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2153  * error checking in between. The indiation that something weird happened is
2154  * string==NULL */
2155
2156 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2157                     size_t *bufsize, const char *fmt, ...)
2158 {
2159         va_list ap;
2160         char *newstr;
2161         int ret;
2162         bool increased;
2163
2164         /* len<0 is an internal marker that something failed */
2165         if (*len < 0)
2166                 goto error;
2167
2168         if (*string == NULL) {
2169                 if (*bufsize == 0)
2170                         *bufsize = 128;
2171
2172                 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2173                 if (*string == NULL)
2174                         goto error;
2175         }
2176
2177         va_start(ap, fmt);
2178         ret = vasprintf(&newstr, fmt, ap);
2179         va_end(ap);
2180
2181         if (ret < 0)
2182                 goto error;
2183
2184         increased = false;
2185
2186         while ((*len)+ret >= *bufsize) {
2187                 increased = true;
2188                 *bufsize *= 2;
2189                 if (*bufsize >= (1024*1024*256))
2190                         goto error;
2191         }
2192
2193         if (increased) {
2194                 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2195                                                *bufsize);
2196                 if (*string == NULL) {
2197                         goto error;
2198                 }
2199         }
2200
2201         StrnCpy((*string)+(*len), newstr, ret);
2202         (*len) += ret;
2203         free(newstr);
2204         return;
2205
2206  error:
2207         *len = -1;
2208         *string = NULL;
2209 }
2210
2211 /*
2212  * asprintf into a string and strupper_m it after that.
2213  */
2214
2215 int asprintf_strupper_m(char **strp, const char *fmt, ...)
2216 {
2217         va_list ap;
2218         char *result;
2219         int ret;
2220
2221         va_start(ap, fmt);
2222         ret = vasprintf(&result, fmt, ap);
2223         va_end(ap);
2224
2225         if (ret == -1)
2226                 return -1;
2227
2228         strupper_m(result);
2229         *strp = result;
2230         return ret;
2231 }
2232
2233 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
2234 {
2235         va_list ap;
2236         char *ret;
2237
2238         va_start(ap, fmt);
2239         ret = talloc_vasprintf(t, fmt, ap);
2240         va_end(ap);
2241
2242         if (ret == NULL) {
2243                 return NULL;
2244         }
2245         strupper_m(ret);
2246         return ret;
2247 }
2248
2249 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
2250 {
2251         va_list ap;
2252         char *ret;
2253
2254         va_start(ap, fmt);
2255         ret = talloc_vasprintf(t, fmt, ap);
2256         va_end(ap);
2257
2258         if (ret == NULL) {
2259                 return NULL;
2260         }
2261         strlower_m(ret);
2262         return ret;
2263 }
2264
2265
2266 /*
2267    Returns the substring from src between the first occurrence of
2268    the char "front" and the first occurence of the char "back".
2269    Mallocs the return string which must be freed.  Not for use
2270    with wide character strings.
2271 */
2272 char *sstring_sub(const char *src, char front, char back)
2273 {
2274         char *temp1, *temp2, *temp3;
2275         ptrdiff_t len;
2276
2277         temp1 = strchr(src, front);
2278         if (temp1 == NULL) return NULL;
2279         temp2 = strchr(src, back);
2280         if (temp2 == NULL) return NULL;
2281         len = temp2 - temp1;
2282         if (len <= 0) return NULL;
2283         temp3 = (char*)SMB_MALLOC(len);
2284         if (temp3 == NULL) {
2285                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2286                 return NULL;
2287         }
2288         memcpy(temp3, temp1+1, len-1);
2289         temp3[len-1] = '\0';
2290         return temp3;
2291 }
2292
2293 /********************************************************************
2294  Check a string for any occurrences of a specified list of invalid
2295  characters.
2296 ********************************************************************/
2297
2298 bool validate_net_name( const char *name,
2299                 const char *invalid_chars,
2300                 int max_len)
2301 {
2302         int i;
2303
2304         for ( i=0; i<max_len && name[i]; i++ ) {
2305                 /* fail if strchr_m() finds one of the invalid characters */
2306                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2307                         return false;
2308                 }
2309         }
2310
2311         return true;
2312 }
2313
2314
2315 /*******************************************************************
2316  Add a shell escape character '\' to any character not in a known list
2317  of characters. UNIX charset format.
2318 *******************************************************************/
2319
2320 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2321 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2322
2323 char *escape_shell_string(const char *src)
2324 {
2325         size_t srclen = strlen(src);
2326         char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2327         char *dest = ret;
2328         bool in_s_quote = false;
2329         bool in_d_quote = false;
2330         bool next_escaped = false;
2331
2332         if (!ret) {
2333                 return NULL;
2334         }
2335
2336         while (*src) {
2337                 size_t c_size;
2338                 codepoint_t c = next_codepoint(src, &c_size);
2339
2340                 if (c == INVALID_CODEPOINT) {
2341                         SAFE_FREE(ret);
2342                         return NULL;
2343                 }
2344
2345                 if (c_size > 1) {
2346                         memcpy(dest, src, c_size);
2347                         src += c_size;
2348                         dest += c_size;
2349                         next_escaped = false;
2350                         continue;
2351                 }
2352
2353                 /*
2354                  * Deal with backslash escaped state.
2355                  * This only lasts for one character.
2356                  */
2357
2358                 if (next_escaped) {
2359                         *dest++ = *src++;
2360                         next_escaped = false;
2361                         continue;
2362                 }
2363
2364                 /*
2365                  * Deal with single quote state. The
2366                  * only thing we care about is exiting
2367                  * this state.
2368                  */
2369
2370                 if (in_s_quote) {
2371                         if (*src == '\'') {
2372                                 in_s_quote = false;
2373                         }
2374                         *dest++ = *src++;
2375                         continue;
2376                 }
2377
2378                 /*
2379                  * Deal with double quote state. The most
2380                  * complex state. We must cope with \, meaning
2381                  * possibly escape next char (depending what it
2382                  * is), ", meaning exit this state, and possibly
2383                  * add an \ escape to any unprotected character
2384                  * (listed in INSIDE_DQUOTE_LIST).
2385                  */
2386
2387                 if (in_d_quote) {
2388                         if (*src == '\\') {
2389                                 /*
2390                                  * Next character might be escaped.
2391                                  * We have to peek. Inside double
2392                                  * quotes only INSIDE_DQUOTE_LIST
2393                                  * characters are escaped by a \.
2394                                  */
2395
2396                                 char nextchar;
2397
2398                                 c = next_codepoint(&src[1], &c_size);
2399                                 if (c == INVALID_CODEPOINT) {
2400                                         SAFE_FREE(ret);
2401                                         return NULL;
2402                                 }
2403                                 if (c_size > 1) {
2404                                         /*
2405                                          * Don't escape the next char.
2406                                          * Just copy the \.
2407                                          */
2408                                         *dest++ = *src++;
2409                                         continue;
2410                                 }
2411
2412                                 nextchar = src[1];
2413
2414                                 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2415                                                         (int)nextchar)) {
2416                                         next_escaped = true;
2417                                 }
2418                                 *dest++ = *src++;
2419                                 continue;
2420                         }
2421
2422                         if (*src == '\"') {
2423                                 /* Exit double quote state. */
2424                                 in_d_quote = false;
2425                                 *dest++ = *src++;
2426                                 continue;
2427                         }
2428
2429                         /*
2430                          * We know the character isn't \ or ",
2431                          * so escape it if it's any of the other
2432                          * possible unprotected characters.
2433                          */
2434
2435                         if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2436                                 *dest++ = '\\';
2437                         }
2438                         *dest++ = *src++;
2439                         continue;
2440                 }
2441
2442                 /*
2443                  * From here to the end of the loop we're
2444                  * not in the single or double quote state.
2445                  */
2446
2447                 if (*src == '\\') {
2448                         /* Next character must be escaped. */
2449                         next_escaped = true;
2450                         *dest++ = *src++;
2451                         continue;
2452                 }
2453
2454                 if (*src == '\'') {
2455                         /* Go into single quote state. */
2456                         in_s_quote = true;
2457                         *dest++ = *src++;
2458                         continue;
2459                 }
2460
2461                 if (*src == '\"') {
2462                         /* Go into double quote state. */
2463                         in_d_quote = true;
2464                         *dest++ = *src++;
2465                         continue;
2466                 }
2467
2468                 /* Check if we need to escape the character. */
2469
2470                 if (!strchr(INCLUDE_LIST, (int)*src)) {
2471                         *dest++ = '\\';
2472                 }
2473                 *dest++ = *src++;
2474         }
2475         *dest++ = '\0';
2476         return ret;
2477 }
2478
2479 /***************************************************
2480  str_list_make, v3 version. The v4 version does not
2481  look at quoted strings with embedded blanks, so
2482  do NOT merge this function please!
2483 ***************************************************/
2484
2485 #define S_LIST_ABS 16 /* List Allocation Block Size */
2486
2487 char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string,
2488         const char *sep)
2489 {
2490         char **list;
2491         const char *str;
2492         char *s, *tok;
2493         int num, lsize;
2494
2495         if (!string || !*string)
2496                 return NULL;
2497
2498         list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
2499         if (list == NULL) {
2500                 return NULL;
2501         }
2502         lsize = S_LIST_ABS;
2503
2504         s = talloc_strdup(list, string);
2505         if (s == NULL) {
2506                 DEBUG(0,("str_list_make: Unable to allocate memory"));
2507                 TALLOC_FREE(list);
2508                 return NULL;
2509         }
2510         if (!sep) sep = LIST_SEP;
2511
2512         num = 0;
2513         str = s;
2514
2515         while (next_token_talloc(list, &str, &tok, sep)) {
2516
2517                 if (num == lsize) {
2518                         char **tmp;
2519
2520                         lsize += S_LIST_ABS;
2521
2522                         tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
2523                                                    lsize + 1);
2524                         if (tmp == NULL) {
2525                                 DEBUG(0,("str_list_make: "
2526                                         "Unable to allocate memory"));
2527                                 TALLOC_FREE(list);
2528                                 return NULL;
2529                         }
2530
2531                         list = tmp;
2532
2533                         memset (&list[num], 0,
2534                                 ((sizeof(char**)) * (S_LIST_ABS +1)));
2535                 }
2536
2537                 list[num] = tok;
2538                 num += 1;
2539         }
2540
2541         list[num] = NULL;
2542
2543         TALLOC_FREE(s);
2544         return list;
2545 }