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