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