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