Merge branch 'master' of ssh://git.samba.org/data/git/samba into selftest
[kamenim/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_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 char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1847 {
1848         char **list;
1849         const char *str;
1850         char *s;
1851         int num, lsize;
1852         char *tok;
1853
1854         if (!string || !*string)
1855                 return NULL;
1856
1857         list = TALLOC_ARRAY(mem_ctx, char *, S_LIST_ABS+1);
1858         if (list == NULL) {
1859                 return NULL;
1860         }
1861         lsize = S_LIST_ABS;
1862
1863         s = talloc_strdup(list, string);
1864         if (s == NULL) {
1865                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1866                 TALLOC_FREE(list);
1867                 return NULL;
1868         }
1869         if (!sep) sep = LIST_SEP;
1870
1871         num = 0;
1872         str = s;
1873
1874         while (next_token_talloc(list, &str, &tok, sep)) {
1875
1876                 if (num == lsize) {
1877                         char **tmp;
1878
1879                         lsize += S_LIST_ABS;
1880
1881                         tmp = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *,
1882                                                    lsize + 1);
1883                         if (tmp == NULL) {
1884                                 DEBUG(0,("str_list_make: "
1885                                         "Unable to allocate memory"));
1886                                 TALLOC_FREE(list);
1887                                 return NULL;
1888                         }
1889
1890                         list = tmp;
1891
1892                         memset (&list[num], 0,
1893                                 ((sizeof(char**)) * (S_LIST_ABS +1)));
1894                 }
1895
1896                 list[num] = tok;
1897                 num += 1;
1898         }
1899
1900         list[num] = NULL;
1901
1902         TALLOC_FREE(s);
1903         return list;
1904 }
1905
1906 bool str_list_copy(TALLOC_CTX *mem_ctx, char ***dest, const char **src)
1907 {
1908         char **list;
1909         int i, num;
1910
1911         *dest = NULL;
1912         if (!src)
1913                 return false;
1914
1915         num = 0;
1916         while (src[num] != NULL) {
1917                 num += 1;
1918         }
1919
1920         list = TALLOC_ARRAY(mem_ctx, char *, num+1);
1921         if (list == NULL) {
1922                 return false;
1923         }
1924
1925         for (i=0; i<num; i++) {
1926                 list[i] = talloc_strdup(list, src[i]);
1927                 if (list[i] == NULL) {
1928                         TALLOC_FREE(list);
1929                         return false;
1930                 }
1931         }
1932         list[i] = NULL;
1933         *dest = list;
1934         return true;
1935 }
1936
1937 /**
1938  * Return true if all the elements of the list match exactly.
1939  **/
1940 bool str_list_compare(char **list1, char **list2)
1941 {
1942         int num;
1943
1944         if (!list1 || !list2)
1945                 return (list1 == list2);
1946
1947         for (num = 0; list1[num]; num++) {
1948                 if (!list2[num])
1949                         return false;
1950                 if (!strcsequal(list1[num], list2[num]))
1951                         return false;
1952         }
1953         if (list2[num])
1954                 return false; /* if list2 has more elements than list1 fail */
1955
1956         return true;
1957 }
1958
1959 /******************************************************************************
1960  *****************************************************************************/
1961
1962 int str_list_count( const char **list )
1963 {
1964         int i = 0;
1965
1966         if ( ! list )
1967                 return 0;
1968
1969         /* count the number of list members */
1970
1971         for ( i=0; *list; i++, list++ );
1972
1973         return i;
1974 }
1975
1976 /******************************************************************************
1977  version of standard_sub_basic() for string lists; uses talloc_sub_basic()
1978  for the work
1979  *****************************************************************************/
1980
1981 bool str_list_sub_basic( char **list, const char *smb_name,
1982                          const char *domain_name )
1983 {
1984         TALLOC_CTX *ctx = list;
1985         char *s, *tmpstr;
1986
1987         while ( *list ) {
1988                 s = *list;
1989                 tmpstr = talloc_sub_basic(ctx, smb_name, domain_name, s);
1990                 if ( !tmpstr ) {
1991                         DEBUG(0,("str_list_sub_basic: "
1992                                 "alloc_sub_basic() return NULL!\n"));
1993                         return false;
1994                 }
1995
1996                 TALLOC_FREE(*list);
1997                 *list = tmpstr;
1998
1999                 list++;
2000         }
2001
2002         return true;
2003 }
2004
2005 /******************************************************************************
2006  substritute a specific pattern in a string list
2007  *****************************************************************************/
2008
2009 bool str_list_substitute(char **list, const char *pattern, const char *insert)
2010 {
2011         TALLOC_CTX *ctx = list;
2012         char *p, *s, *t;
2013         ssize_t ls, lp, li, ld, i, d;
2014
2015         if (!list)
2016                 return false;
2017         if (!pattern)
2018                 return false;
2019         if (!insert)
2020                 return false;
2021
2022         lp = (ssize_t)strlen(pattern);
2023         li = (ssize_t)strlen(insert);
2024         ld = li -lp;
2025
2026         while (*list) {
2027                 s = *list;
2028                 ls = (ssize_t)strlen(s);
2029
2030                 while ((p = strstr_m(s, pattern))) {
2031                         t = *list;
2032                         d = p -t;
2033                         if (ld) {
2034                                 t = TALLOC_ARRAY(ctx, char, ls +ld +1);
2035                                 if (!t) {
2036                                         DEBUG(0,("str_list_substitute: "
2037                                                 "Unable to allocate memory"));
2038                                         return false;
2039                                 }
2040                                 memcpy(t, *list, d);
2041                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
2042                                 TALLOC_FREE(*list);
2043                                 *list = t;
2044                                 ls += ld;
2045                                 s = t +d +li;
2046                         }
2047
2048                         for (i = 0; i < li; i++) {
2049                                 switch (insert[i]) {
2050                                         case '`':
2051                                         case '"':
2052                                         case '\'':
2053                                         case ';':
2054                                         case '$':
2055                                         case '%':
2056                                         case '\r':
2057                                         case '\n':
2058                                                 t[d +i] = '_';
2059                                                 break;
2060                                         default:
2061                                                 t[d +i] = insert[i];
2062                                 }
2063                         }
2064                 }
2065
2066                 list++;
2067         }
2068
2069         return true;
2070 }
2071
2072
2073 #define IPSTR_LIST_SEP  ","
2074 #define IPSTR_LIST_CHAR ','
2075
2076 /**
2077  * Add ip string representation to ipstr list. Used also
2078  * as part of @function ipstr_list_make
2079  *
2080  * @param ipstr_list pointer to string containing ip list;
2081  *        MUST BE already allocated and IS reallocated if necessary
2082  * @param ipstr_size pointer to current size of ipstr_list (might be changed
2083  *        as a result of reallocation)
2084  * @param ip IP address which is to be added to list
2085  * @return pointer to string appended with new ip and possibly
2086  *         reallocated to new length
2087  **/
2088
2089 static char *ipstr_list_add(char **ipstr_list, const struct ip_service *service)
2090 {
2091         char *new_ipstr = NULL;
2092         char addr_buf[INET6_ADDRSTRLEN];
2093         int ret;
2094
2095         /* arguments checking */
2096         if (!ipstr_list || !service) {
2097                 return NULL;
2098         }
2099
2100         print_sockaddr(addr_buf,
2101                         sizeof(addr_buf),
2102                         &service->ss);
2103
2104         /* attempt to convert ip to a string and append colon separator to it */
2105         if (*ipstr_list) {
2106                 if (service->ss.ss_family == AF_INET) {
2107                         /* IPv4 */
2108                         ret = asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list,
2109                                        IPSTR_LIST_SEP, addr_buf,
2110                                        service->port);
2111                 } else {
2112                         /* IPv6 */
2113                         ret = asprintf(&new_ipstr, "%s%s[%s]:%d", *ipstr_list,
2114                                        IPSTR_LIST_SEP, addr_buf,
2115                                        service->port);
2116                 }
2117                 SAFE_FREE(*ipstr_list);
2118         } else {
2119                 if (service->ss.ss_family == AF_INET) {
2120                         /* IPv4 */
2121                         ret = asprintf(&new_ipstr, "%s:%d", addr_buf,
2122                                        service->port);
2123                 } else {
2124                         /* IPv6 */
2125                         ret = asprintf(&new_ipstr, "[%s]:%d", addr_buf,
2126                                        service->port);
2127                 }
2128         }
2129         if (ret == -1) {
2130                 return NULL;
2131         }
2132         *ipstr_list = new_ipstr;
2133         return *ipstr_list;
2134 }
2135
2136 /**
2137  * Allocate and initialise an ipstr list using ip adresses
2138  * passed as arguments.
2139  *
2140  * @param ipstr_list pointer to string meant to be allocated and set
2141  * @param ip_list array of ip addresses to place in the list
2142  * @param ip_count number of addresses stored in ip_list
2143  * @return pointer to allocated ip string
2144  **/
2145
2146 char *ipstr_list_make(char **ipstr_list,
2147                         const struct ip_service *ip_list,
2148                         int ip_count)
2149 {
2150         int i;
2151
2152         /* arguments checking */
2153         if (!ip_list || !ipstr_list) {
2154                 return 0;
2155         }
2156
2157         *ipstr_list = NULL;
2158
2159         /* process ip addresses given as arguments */
2160         for (i = 0; i < ip_count; i++) {
2161                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2162         }
2163
2164         return (*ipstr_list);
2165 }
2166
2167
2168 /**
2169  * Parse given ip string list into array of ip addresses
2170  * (as ip_service structures)
2171  *    e.g. [IPv6]:port,192.168.1.100:389,192.168.1.78, ...
2172  *
2173  * @param ipstr ip string list to be parsed
2174  * @param ip_list pointer to array of ip addresses which is
2175  *        allocated by this function and must be freed by caller
2176  * @return number of successfully parsed addresses
2177  **/
2178
2179 int ipstr_list_parse(const char *ipstr_list, struct ip_service **ip_list)
2180 {
2181         TALLOC_CTX *frame;
2182         char *token_str = NULL;
2183         size_t count;
2184         int i;
2185
2186         if (!ipstr_list || !ip_list)
2187                 return 0;
2188
2189         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2190         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2191                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n",
2192                                         (unsigned long)count));
2193                 return 0;
2194         }
2195
2196         frame = talloc_stackframe();
2197         for ( i=0; next_token_talloc(frame, &ipstr_list, &token_str,
2198                                 IPSTR_LIST_SEP) && i<count; i++ ) {
2199                 char *s = token_str;
2200                 char *p = strrchr(token_str, ':');
2201
2202                 if (p) {
2203                         *p = 0;
2204                         (*ip_list)[i].port = atoi(p+1);
2205                 }
2206
2207                 /* convert single token to ip address */
2208                 if (token_str[0] == '[') {
2209                         /* IPv6 address. */
2210                         s++;
2211                         p = strchr(token_str, ']');
2212                         if (!p) {
2213                                 continue;
2214                         }
2215                         *p = '\0';
2216                 }
2217                 if (!interpret_string_addr(&(*ip_list)[i].ss,
2218                                         s,
2219                                         AI_NUMERICHOST)) {
2220                         continue;
2221                 }
2222         }
2223         TALLOC_FREE(frame);
2224         return count;
2225 }
2226
2227 /**
2228  * Safely free ip string list
2229  *
2230  * @param ipstr_list ip string list to be freed
2231  **/
2232
2233 void ipstr_list_free(char* ipstr_list)
2234 {
2235         SAFE_FREE(ipstr_list);
2236 }
2237
2238 /**
2239  Unescape a URL encoded string, in place.
2240 **/
2241
2242 void rfc1738_unescape(char *buf)
2243 {
2244         char *p=buf;
2245
2246         while (p && *p && (p=strchr_m(p,'%'))) {
2247                 int c1 = p[1];
2248                 int c2 = p[2];
2249
2250                 if (c1 >= '0' && c1 <= '9')
2251                         c1 = c1 - '0';
2252                 else if (c1 >= 'A' && c1 <= 'F')
2253                         c1 = 10 + c1 - 'A';
2254                 else if (c1 >= 'a' && c1 <= 'f')
2255                         c1 = 10 + c1 - 'a';
2256                 else {p++; continue;}
2257
2258                 if (c2 >= '0' && c2 <= '9')
2259                         c2 = c2 - '0';
2260                 else if (c2 >= 'A' && c2 <= 'F')
2261                         c2 = 10 + c2 - 'A';
2262                 else if (c2 >= 'a' && c2 <= 'f')
2263                         c2 = 10 + c2 - 'a';
2264                 else {p++; continue;}
2265
2266                 *p = (c1<<4) | c2;
2267
2268                 memmove(p+1, p+3, strlen(p+3)+1);
2269                 p++;
2270         }
2271 }
2272
2273 static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2274
2275 /**
2276  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2277  **/
2278 DATA_BLOB base64_decode_data_blob(const char *s)
2279 {
2280         int bit_offset, byte_offset, idx, i, n;
2281         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2282         unsigned char *d = decoded.data;
2283         char *p;
2284
2285         n=i=0;
2286
2287         while (*s && (p=strchr_m(b64,*s))) {
2288                 idx = (int)(p - b64);
2289                 byte_offset = (i*6)/8;
2290                 bit_offset = (i*6)%8;
2291                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2292                 if (bit_offset < 3) {
2293                         d[byte_offset] |= (idx << (2-bit_offset));
2294                         n = byte_offset+1;
2295                 } else {
2296                         d[byte_offset] |= (idx >> (bit_offset-2));
2297                         d[byte_offset+1] = 0;
2298                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2299                         n = byte_offset+2;
2300                 }
2301                 s++; i++;
2302         }
2303
2304         if ((n > 0) && (*s == '=')) {
2305                 n -= 1;
2306         }
2307
2308         /* fix up length */
2309         decoded.length = n;
2310         return decoded;
2311 }
2312
2313 /**
2314  * Decode a base64 string in-place - wrapper for the above
2315  **/
2316 void base64_decode_inplace(char *s)
2317 {
2318         DATA_BLOB decoded = base64_decode_data_blob(s);
2319
2320         if ( decoded.length != 0 ) {
2321                 memcpy(s, decoded.data, decoded.length);
2322
2323                 /* null terminate */
2324                 s[decoded.length] = '\0';
2325         } else {
2326                 *s = '\0';
2327         }
2328
2329         data_blob_free(&decoded);
2330 }
2331
2332 /**
2333  * Encode a base64 string into a talloc()ed string caller to free.
2334  *
2335  * From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c
2336  * with adjustments
2337  **/
2338
2339 char *base64_encode_data_blob(TALLOC_CTX *mem_ctx, DATA_BLOB data)
2340 {
2341         int bits = 0;
2342         int char_count = 0;
2343         size_t out_cnt, len, output_len;
2344         char *result;
2345
2346         if (!data.length || !data.data)
2347                 return NULL;
2348
2349         out_cnt = 0;
2350         len = data.length;
2351         output_len = data.length * 2 + 4; /* Account for closing bytes. 4 is
2352                                            * random but should be enough for
2353                                            * the = and \0 */
2354         result = TALLOC_ARRAY(mem_ctx, char, output_len); /* get us plenty of space */
2355         SMB_ASSERT(result != NULL);
2356
2357         while (len-- && out_cnt < (data.length * 2) - 5) {
2358                 int c = (unsigned char) *(data.data++);
2359                 bits += c;
2360                 char_count++;
2361                 if (char_count == 3) {
2362                         result[out_cnt++] = b64[bits >> 18];
2363                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2364                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2365                         result[out_cnt++] = b64[bits & 0x3f];
2366                         bits = 0;
2367                         char_count = 0;
2368                 } else {
2369                         bits <<= 8;
2370                 }
2371         }
2372         if (char_count != 0) {
2373                 bits <<= 16 - (8 * char_count);
2374                 result[out_cnt++] = b64[bits >> 18];
2375                 result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2376                 if (char_count == 1) {
2377                         result[out_cnt++] = '=';
2378                         result[out_cnt++] = '=';
2379                 } else {
2380                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2381                         result[out_cnt++] = '=';
2382                 }
2383         }
2384         result[out_cnt] = '\0'; /* terminate */
2385         return result;
2386 }
2387
2388 /* read a SMB_BIG_UINT from a string */
2389 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2390 {
2391
2392         SMB_BIG_UINT val = -1;
2393         const char *p = nptr;
2394
2395         if (!p) {
2396                 if (entptr) {
2397                         *entptr = p;
2398                 }
2399                 return val;
2400         }
2401
2402         while (*p && isspace(*p))
2403                 p++;
2404
2405 #ifdef LARGE_SMB_OFF_T
2406         sscanf(p,"%llu",&val);
2407 #else /* LARGE_SMB_OFF_T */
2408         sscanf(p,"%lu",&val);
2409 #endif /* LARGE_SMB_OFF_T */
2410         if (entptr) {
2411                 while (*p && isdigit(*p))
2412                         p++;
2413                 *entptr = p;
2414         }
2415
2416         return val;
2417 }
2418
2419 /* Convert a size specification to a count of bytes. We accept the following
2420  * suffixes:
2421  *          bytes if there is no suffix
2422  *      kK  kibibytes
2423  *      mM  mebibytes
2424  *      gG  gibibytes
2425  *      tT  tibibytes
2426  *      pP  whatever the ISO name for petabytes is
2427  *
2428  *  Returns 0 if the string can't be converted.
2429  */
2430 SMB_OFF_T conv_str_size(const char * str)
2431 {
2432         SMB_OFF_T lval;
2433         char * end;
2434
2435         if (str == NULL || *str == '\0') {
2436                 return 0;
2437         }
2438
2439 #ifdef HAVE_STRTOULL
2440         if (sizeof(SMB_OFF_T) == 8) {
2441             lval = strtoull(str, &end, 10 /* base */);
2442         } else {
2443             lval = strtoul(str, &end, 10 /* base */);
2444         }
2445 #else
2446         lval = strtoul(str, &end, 10 /* base */);
2447 #endif
2448
2449         if (end == NULL || end == str) {
2450                 return 0;
2451         }
2452
2453         if (*end) {
2454                 SMB_OFF_T lval_orig = lval;
2455
2456                 if (strwicmp(end, "K") == 0) {
2457                         lval *= (SMB_OFF_T)1024;
2458                 } else if (strwicmp(end, "M") == 0) {
2459                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2460                 } else if (strwicmp(end, "G") == 0) {
2461                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2462                                 (SMB_OFF_T)1024);
2463                 } else if (strwicmp(end, "T") == 0) {
2464                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2465                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2466                 } else if (strwicmp(end, "P") == 0) {
2467                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2468                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2469                                 (SMB_OFF_T)1024);
2470                 } else {
2471                         return 0;
2472                 }
2473
2474                 /* Primitive attempt to detect wrapping on platforms with
2475                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2476                  * a failure than some random number.
2477                  */
2478                 if (lval_orig <= lval) {
2479                         return 0;
2480                 }
2481         }
2482
2483         return lval;
2484 }
2485
2486 void string_append(char **left, const char *right)
2487 {
2488         int new_len = strlen(right) + 1;
2489
2490         if (*left == NULL) {
2491                 *left = (char *)SMB_MALLOC(new_len);
2492                 *left[0] = '\0';
2493         } else {
2494                 new_len += strlen(*left);
2495                 *left = (char *)SMB_REALLOC(*left, new_len);
2496         }
2497
2498         if (*left == NULL) {
2499                 return;
2500         }
2501
2502         safe_strcat(*left, right, new_len-1);
2503 }
2504
2505 bool add_string_to_array(TALLOC_CTX *mem_ctx,
2506                          const char *str, const char ***strings,
2507                          int *num)
2508 {
2509         char *dup_str = talloc_strdup(mem_ctx, str);
2510
2511         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings,
2512                         const char *, (*num)+1);
2513
2514         if ((*strings == NULL) || (dup_str == NULL)) {
2515                 *num = 0;
2516                 return false;
2517         }
2518
2519         (*strings)[*num] = dup_str;
2520         *num += 1;
2521         return true;
2522 }
2523
2524 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2525  * error checking in between. The indiation that something weird happened is
2526  * string==NULL */
2527
2528 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2529                     size_t *bufsize, const char *fmt, ...)
2530 {
2531         va_list ap;
2532         char *newstr;
2533         int ret;
2534         bool increased;
2535
2536         /* len<0 is an internal marker that something failed */
2537         if (*len < 0)
2538                 goto error;
2539
2540         if (*string == NULL) {
2541                 if (*bufsize == 0)
2542                         *bufsize = 128;
2543
2544                 *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2545                 if (*string == NULL)
2546                         goto error;
2547         }
2548
2549         va_start(ap, fmt);
2550         ret = vasprintf(&newstr, fmt, ap);
2551         va_end(ap);
2552
2553         if (ret < 0)
2554                 goto error;
2555
2556         increased = false;
2557
2558         while ((*len)+ret >= *bufsize) {
2559                 increased = true;
2560                 *bufsize *= 2;
2561                 if (*bufsize >= (1024*1024*256))
2562                         goto error;
2563         }
2564
2565         if (increased) {
2566                 *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2567                                                *bufsize);
2568                 if (*string == NULL) {
2569                         goto error;
2570                 }
2571         }
2572
2573         StrnCpy((*string)+(*len), newstr, ret);
2574         (*len) += ret;
2575         free(newstr);
2576         return;
2577
2578  error:
2579         *len = -1;
2580         *string = NULL;
2581 }
2582
2583 /*
2584  * asprintf into a string and strupper_m it after that.
2585  */
2586
2587 int asprintf_strupper_m(char **strp, const char *fmt, ...)
2588 {
2589         va_list ap;
2590         char *result;
2591         int ret;
2592
2593         va_start(ap, fmt);
2594         ret = vasprintf(&result, fmt, ap);
2595         va_end(ap);
2596
2597         if (ret == -1)
2598                 return -1;
2599
2600         strupper_m(result);
2601         *strp = result;
2602         return ret;
2603 }
2604
2605 char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...)
2606 {
2607         va_list ap;
2608         char *ret;
2609
2610         va_start(ap, fmt);
2611         ret = talloc_vasprintf(t, fmt, ap);
2612         va_end(ap);
2613
2614         if (ret == NULL) {
2615                 return NULL;
2616         }
2617         strupper_m(ret);
2618         return ret;
2619 }
2620
2621 char *talloc_asprintf_strlower_m(TALLOC_CTX *t, const char *fmt, ...)
2622 {
2623         va_list ap;
2624         char *ret;
2625
2626         va_start(ap, fmt);
2627         ret = talloc_vasprintf(t, fmt, ap);
2628         va_end(ap);
2629
2630         if (ret == NULL) {
2631                 return NULL;
2632         }
2633         strlower_m(ret);
2634         return ret;
2635 }
2636
2637
2638 /*
2639    Returns the substring from src between the first occurrence of
2640    the char "front" and the first occurence of the char "back".
2641    Mallocs the return string which must be freed.  Not for use
2642    with wide character strings.
2643 */
2644 char *sstring_sub(const char *src, char front, char back)
2645 {
2646         char *temp1, *temp2, *temp3;
2647         ptrdiff_t len;
2648
2649         temp1 = strchr(src, front);
2650         if (temp1 == NULL) return NULL;
2651         temp2 = strchr(src, back);
2652         if (temp2 == NULL) return NULL;
2653         len = temp2 - temp1;
2654         if (len <= 0) return NULL;
2655         temp3 = (char*)SMB_MALLOC(len);
2656         if (temp3 == NULL) {
2657                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2658                 return NULL;
2659         }
2660         memcpy(temp3, temp1+1, len-1);
2661         temp3[len-1] = '\0';
2662         return temp3;
2663 }
2664
2665 /********************************************************************
2666  Check a string for any occurrences of a specified list of invalid
2667  characters.
2668 ********************************************************************/
2669
2670 bool validate_net_name( const char *name,
2671                 const char *invalid_chars,
2672                 int max_len)
2673 {
2674         int i;
2675
2676         for ( i=0; i<max_len && name[i]; i++ ) {
2677                 /* fail if strchr_m() finds one of the invalid characters */
2678                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2679                         return false;
2680                 }
2681         }
2682
2683         return true;
2684 }
2685
2686
2687 /**
2688 return the number of bytes occupied by a buffer in ASCII format
2689 the result includes the null termination
2690 limited by 'n' bytes
2691 **/
2692 size_t ascii_len_n(const char *src, size_t n)
2693 {
2694         size_t len;
2695
2696         len = strnlen(src, n);
2697         if (len+1 <= n) {
2698                 len += 1;
2699         }
2700
2701         return len;
2702 }
2703
2704 /**
2705 return the number of bytes occupied by a buffer in CH_UTF16 format
2706 the result includes the null termination
2707 **/
2708 size_t utf16_len(const void *buf)
2709 {
2710         size_t len;
2711
2712         for (len = 0; SVAL(buf,len); len += 2) ;
2713
2714         return len + 2;
2715 }
2716
2717 /**
2718 return the number of bytes occupied by a buffer in CH_UTF16 format
2719 the result includes the null termination
2720 limited by 'n' bytes
2721 **/
2722 size_t utf16_len_n(const void *src, size_t n)
2723 {
2724         size_t len;
2725
2726         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2727
2728         if (len+2 <= n) {
2729                 len += 2;
2730         }
2731
2732         return len;
2733 }
2734
2735 /*******************************************************************
2736  Add a shell escape character '\' to any character not in a known list
2737  of characters. UNIX charset format.
2738 *******************************************************************/
2739
2740 #define INCLUDE_LIST "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_/ \t.,"
2741 #define INSIDE_DQUOTE_LIST "$`\n\"\\"
2742
2743 char *escape_shell_string(const char *src)
2744 {
2745         size_t srclen = strlen(src);
2746         char *ret = SMB_MALLOC_ARRAY(char, (srclen * 2) + 1);
2747         char *dest = ret;
2748         bool in_s_quote = false;
2749         bool in_d_quote = false;
2750         bool next_escaped = false;
2751
2752         if (!ret) {
2753                 return NULL;
2754         }
2755
2756         while (*src) {
2757                 size_t c_size;
2758                 codepoint_t c = next_codepoint(src, &c_size);
2759
2760                 if (c == INVALID_CODEPOINT) {
2761                         SAFE_FREE(ret);
2762                         return NULL;
2763                 }
2764
2765                 if (c_size > 1) {
2766                         memcpy(dest, src, c_size);
2767                         src += c_size;
2768                         dest += c_size;
2769                         next_escaped = false;
2770                         continue;
2771                 }
2772
2773                 /*
2774                  * Deal with backslash escaped state.
2775                  * This only lasts for one character.
2776                  */
2777
2778                 if (next_escaped) {
2779                         *dest++ = *src++;
2780                         next_escaped = false;
2781                         continue;
2782                 }
2783
2784                 /*
2785                  * Deal with single quote state. The
2786                  * only thing we care about is exiting
2787                  * this state.
2788                  */
2789
2790                 if (in_s_quote) {
2791                         if (*src == '\'') {
2792                                 in_s_quote = false;
2793                         }
2794                         *dest++ = *src++;
2795                         continue;
2796                 }
2797
2798                 /*
2799                  * Deal with double quote state. The most
2800                  * complex state. We must cope with \, meaning
2801                  * possibly escape next char (depending what it
2802                  * is), ", meaning exit this state, and possibly
2803                  * add an \ escape to any unprotected character
2804                  * (listed in INSIDE_DQUOTE_LIST).
2805                  */
2806
2807                 if (in_d_quote) {
2808                         if (*src == '\\') {
2809                                 /*
2810                                  * Next character might be escaped.
2811                                  * We have to peek. Inside double
2812                                  * quotes only INSIDE_DQUOTE_LIST
2813                                  * characters are escaped by a \.
2814                                  */
2815
2816                                 char nextchar;
2817
2818                                 c = next_codepoint(&src[1], &c_size);
2819                                 if (c == INVALID_CODEPOINT) {
2820                                         SAFE_FREE(ret);
2821                                         return NULL;
2822                                 }
2823                                 if (c_size > 1) {
2824                                         /*
2825                                          * Don't escape the next char.
2826                                          * Just copy the \.
2827                                          */
2828                                         *dest++ = *src++;
2829                                         continue;
2830                                 }
2831
2832                                 nextchar = src[1];
2833
2834                                 if (nextchar && strchr(INSIDE_DQUOTE_LIST,
2835                                                         (int)nextchar)) {
2836                                         next_escaped = true;
2837                                 }
2838                                 *dest++ = *src++;
2839                                 continue;
2840                         }
2841
2842                         if (*src == '\"') {
2843                                 /* Exit double quote state. */
2844                                 in_d_quote = false;
2845                                 *dest++ = *src++;
2846                                 continue;
2847                         }
2848
2849                         /*
2850                          * We know the character isn't \ or ",
2851                          * so escape it if it's any of the other
2852                          * possible unprotected characters.
2853                          */
2854
2855                         if (strchr(INSIDE_DQUOTE_LIST, (int)*src)) {
2856                                 *dest++ = '\\';
2857                         }
2858                         *dest++ = *src++;
2859                         continue;
2860                 }
2861
2862                 /*
2863                  * From here to the end of the loop we're
2864                  * not in the single or double quote state.
2865                  */
2866
2867                 if (*src == '\\') {
2868                         /* Next character must be escaped. */
2869                         next_escaped = true;
2870                         *dest++ = *src++;
2871                         continue;
2872                 }
2873
2874                 if (*src == '\'') {
2875                         /* Go into single quote state. */
2876                         in_s_quote = true;
2877                         *dest++ = *src++;
2878                         continue;
2879                 }
2880
2881                 if (*src == '\"') {
2882                         /* Go into double quote state. */
2883                         in_d_quote = true;
2884                         *dest++ = *src++;
2885                         continue;
2886                 }
2887
2888                 /* Check if we need to escape the character. */
2889
2890                 if (!strchr(INCLUDE_LIST, (int)*src)) {
2891                         *dest++ = '\\';
2892                 }
2893                 *dest++ = *src++;
2894         }
2895         *dest++ = '\0';
2896         return ret;
2897 }