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