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