r18652: libreplace has replacements for strndup and strnlen
[samba.git] / source / 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  List of Strings manipulation functions
1668 **/
1669
1670 #define S_LIST_ABS 16 /* List Allocation Block Size */
1671
1672 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1673 {
1674         char **list, **rlist;
1675         const char *str;
1676         char *s;
1677         int num, lsize;
1678         pstring tok;
1679         
1680         if (!string || !*string)
1681                 return NULL;
1682         if (mem_ctx) {
1683                 s = talloc_strdup(mem_ctx, string);
1684         } else {
1685                 s = SMB_STRDUP(string);
1686         }
1687         if (!s) {
1688                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1689                 return NULL;
1690         }
1691         if (!sep) sep = LIST_SEP;
1692         
1693         num = lsize = 0;
1694         list = NULL;
1695         
1696         str = s;
1697         while (next_token(&str, tok, sep, sizeof(tok))) {               
1698                 if (num == lsize) {
1699                         lsize += S_LIST_ABS;
1700                         if (mem_ctx) {
1701                                 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1702                         } else {
1703                                 /* We need to keep the old list on error so we can free the elements
1704                                    if the realloc fails. */
1705                                 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1706                         }
1707                         if (!rlist) {
1708                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1709                                 str_list_free(&list);
1710                                 if (mem_ctx) {
1711                                         TALLOC_FREE(s);
1712                                 } else {
1713                                         SAFE_FREE(s);
1714                                 }
1715                                 return NULL;
1716                         } else {
1717                                 list = rlist;
1718                         }
1719                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1720                 }
1721
1722                 if (mem_ctx) {
1723                         list[num] = talloc_strdup(mem_ctx, tok);
1724                 } else {
1725                         list[num] = SMB_STRDUP(tok);
1726                 }
1727                 
1728                 if (!list[num]) {
1729                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1730                         str_list_free(&list);
1731                         if (mem_ctx) {
1732                                 TALLOC_FREE(s);
1733                         } else {
1734                                 SAFE_FREE(s);
1735                         }
1736                         return NULL;
1737                 }
1738         
1739                 num++;  
1740         }
1741
1742         if (mem_ctx) {
1743                 TALLOC_FREE(s);
1744         } else {
1745                 SAFE_FREE(s);
1746         }
1747
1748         return list;
1749 }
1750
1751 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1752 {
1753         return str_list_make_internal(mem_ctx, string, sep);
1754 }
1755
1756 char **str_list_make(const char *string, const char *sep)
1757 {
1758         return str_list_make_internal(NULL, string, sep);
1759 }
1760
1761 BOOL str_list_copy(char ***dest, const char **src)
1762 {
1763         char **list, **rlist;
1764         int num, lsize;
1765         
1766         *dest = NULL;
1767         if (!src)
1768                 return False;
1769         
1770         num = lsize = 0;
1771         list = NULL;
1772                 
1773         while (src[num]) {
1774                 if (num == lsize) {
1775                         lsize += S_LIST_ABS;
1776                         rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1777                         if (!rlist) {
1778                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1779                                 str_list_free(&list);
1780                                 return False;
1781                         } else {
1782                                 list = rlist;
1783                         }
1784                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1785                 }
1786                 
1787                 list[num] = SMB_STRDUP(src[num]);
1788                 if (!list[num]) {
1789                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1790                         str_list_free(&list);
1791                         return False;
1792                 }
1793
1794                 num++;
1795         }
1796         
1797         *dest = list;
1798         return True;    
1799 }
1800
1801 /**
1802  * Return true if all the elements of the list match exactly.
1803  **/
1804 BOOL str_list_compare(char **list1, char **list2)
1805 {
1806         int num;
1807         
1808         if (!list1 || !list2)
1809                 return (list1 == list2); 
1810         
1811         for (num = 0; list1[num]; num++) {
1812                 if (!list2[num])
1813                         return False;
1814                 if (!strcsequal(list1[num], list2[num]))
1815                         return False;
1816         }
1817         if (list2[num])
1818                 return False; /* if list2 has more elements than list1 fail */
1819         
1820         return True;
1821 }
1822
1823 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1824 {
1825         char **tlist;
1826         
1827         if (!list || !*list)
1828                 return;
1829         tlist = *list;
1830         for(; *tlist; tlist++) {
1831                 if (mem_ctx) {
1832                         TALLOC_FREE(*tlist);
1833                 } else {
1834                         SAFE_FREE(*tlist);
1835                 }
1836         }
1837         if (mem_ctx) {
1838                 TALLOC_FREE(*tlist);
1839         } else {
1840                 SAFE_FREE(*list);
1841         }
1842 }
1843
1844 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1845 {
1846         str_list_free_internal(mem_ctx, list);
1847 }
1848
1849 void str_list_free(char ***list)
1850 {
1851         str_list_free_internal(NULL, list);
1852 }
1853
1854 /******************************************************************************
1855  *****************************************************************************/
1856
1857 int str_list_count( const char **list )
1858 {
1859         int i = 0;
1860
1861         if ( ! list )
1862                 return 0;
1863
1864         /* count the number of list members */
1865         
1866         for ( i=0; *list; i++, list++ );
1867         
1868         return i;
1869 }
1870
1871 /******************************************************************************
1872  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1873  for the work
1874  *****************************************************************************/
1875  
1876 BOOL str_list_sub_basic( char **list, const char *smb_name,
1877                          const char *domain_name )
1878 {
1879         char *s, *tmpstr;
1880         
1881         while ( *list ) {
1882                 s = *list;
1883                 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
1884                 if ( !tmpstr ) {
1885                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1886                         return False;
1887                 }
1888
1889                 SAFE_FREE(*list);
1890                 *list = tmpstr;
1891                         
1892                 list++;
1893         }
1894
1895         return True;
1896 }
1897
1898 /******************************************************************************
1899  substritute a specific pattern in a string list
1900  *****************************************************************************/
1901  
1902 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1903 {
1904         char *p, *s, *t;
1905         ssize_t ls, lp, li, ld, i, d;
1906
1907         if (!list)
1908                 return False;
1909         if (!pattern)
1910                 return False;
1911         if (!insert)
1912                 return False;
1913
1914         lp = (ssize_t)strlen(pattern);
1915         li = (ssize_t)strlen(insert);
1916         ld = li -lp;
1917                         
1918         while (*list) {
1919                 s = *list;
1920                 ls = (ssize_t)strlen(s);
1921
1922                 while ((p = strstr_m(s, pattern))) {
1923                         t = *list;
1924                         d = p -t;
1925                         if (ld) {
1926                                 t = (char *) SMB_MALLOC(ls +ld +1);
1927                                 if (!t) {
1928                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1929                                         return False;
1930                                 }
1931                                 memcpy(t, *list, d);
1932                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1933                                 SAFE_FREE(*list);
1934                                 *list = t;
1935                                 ls += ld;
1936                                 s = t +d +li;
1937                         }
1938                         
1939                         for (i = 0; i < li; i++) {
1940                                 switch (insert[i]) {
1941                                         case '`':
1942                                         case '"':
1943                                         case '\'':
1944                                         case ';':
1945                                         case '$':
1946                                         case '%':
1947                                         case '\r':
1948                                         case '\n':
1949                                                 t[d +i] = '_';
1950                                                 break;
1951                                         default:
1952                                                 t[d +i] = insert[i];
1953                                 }
1954                         }       
1955                 }
1956                 
1957                 
1958                 list++;
1959         }
1960         
1961         return True;
1962 }
1963
1964
1965 #define IPSTR_LIST_SEP  ","
1966 #define IPSTR_LIST_CHAR ','
1967
1968 /**
1969  * Add ip string representation to ipstr list. Used also
1970  * as part of @function ipstr_list_make
1971  *
1972  * @param ipstr_list pointer to string containing ip list;
1973  *        MUST BE already allocated and IS reallocated if necessary
1974  * @param ipstr_size pointer to current size of ipstr_list (might be changed
1975  *        as a result of reallocation)
1976  * @param ip IP address which is to be added to list
1977  * @return pointer to string appended with new ip and possibly
1978  *         reallocated to new length
1979  **/
1980
1981 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
1982 {
1983         char* new_ipstr = NULL;
1984         
1985         /* arguments checking */
1986         if (!ipstr_list || !service) return NULL;
1987
1988         /* attempt to convert ip to a string and append colon separator to it */
1989         if (*ipstr_list) {
1990                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
1991                         inet_ntoa(service->ip), service->port);
1992                 SAFE_FREE(*ipstr_list);
1993         } else {
1994                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
1995         }
1996         *ipstr_list = new_ipstr;
1997         return *ipstr_list;
1998 }
1999
2000
2001 /**
2002  * Allocate and initialise an ipstr list using ip adresses
2003  * passed as arguments.
2004  *
2005  * @param ipstr_list pointer to string meant to be allocated and set
2006  * @param ip_list array of ip addresses to place in the list
2007  * @param ip_count number of addresses stored in ip_list
2008  * @return pointer to allocated ip string
2009  **/
2010  
2011 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2012 {
2013         int i;
2014         
2015         /* arguments checking */
2016         if (!ip_list || !ipstr_list) return 0;
2017
2018         *ipstr_list = NULL;
2019         
2020         /* process ip addresses given as arguments */
2021         for (i = 0; i < ip_count; i++)
2022                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2023         
2024         return (*ipstr_list);
2025 }
2026
2027
2028 /**
2029  * Parse given ip string list into array of ip addresses
2030  * (as ip_service structures)  
2031  *    e.g. 192.168.1.100:389,192.168.1.78, ...
2032  *
2033  * @param ipstr ip string list to be parsed 
2034  * @param ip_list pointer to array of ip addresses which is
2035  *        allocated by this function and must be freed by caller
2036  * @return number of succesfully parsed addresses
2037  **/
2038  
2039 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2040 {
2041         fstring token_str;
2042         size_t count;
2043         int i;
2044
2045         if (!ipstr_list || !ip_list) 
2046                 return 0;
2047         
2048         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2049         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2050                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2051                 return 0;
2052         }
2053         
2054         for ( i=0; 
2055                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
2056                 i++ ) 
2057         {
2058                 struct in_addr addr;
2059                 unsigned port = 0;      
2060                 char *p = strchr(token_str, ':');
2061                 
2062                 if (p) {
2063                         *p = 0;
2064                         port = atoi(p+1);
2065                 }
2066
2067                 /* convert single token to ip address */
2068                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2069                         break;
2070                                 
2071                 (*ip_list)[i].ip = addr;
2072                 (*ip_list)[i].port = port;
2073         }
2074         
2075         return count;
2076 }
2077
2078
2079 /**
2080  * Safely free ip string list
2081  *
2082  * @param ipstr_list ip string list to be freed
2083  **/
2084
2085 void ipstr_list_free(char* ipstr_list)
2086 {
2087         SAFE_FREE(ipstr_list);
2088 }
2089
2090
2091 /**
2092  Unescape a URL encoded string, in place.
2093 **/
2094
2095 void rfc1738_unescape(char *buf)
2096 {
2097         char *p=buf;
2098
2099         while (p && *p && (p=strchr_m(p,'%'))) {
2100                 int c1 = p[1];
2101                 int c2 = p[2];
2102
2103                 if (c1 >= '0' && c1 <= '9')
2104                         c1 = c1 - '0';
2105                 else if (c1 >= 'A' && c1 <= 'F')
2106                         c1 = 10 + c1 - 'A';
2107                 else if (c1 >= 'a' && c1 <= 'f')
2108                         c1 = 10 + c1 - 'a';
2109                 else {p++; continue;}
2110
2111                 if (c2 >= '0' && c2 <= '9')
2112                         c2 = c2 - '0';
2113                 else if (c2 >= 'A' && c2 <= 'F')
2114                         c2 = 10 + c2 - 'A';
2115                 else if (c2 >= 'a' && c2 <= 'f')
2116                         c2 = 10 + c2 - 'a';
2117                 else {p++; continue;}
2118                         
2119                 *p = (c1<<4) | c2;
2120
2121                 memmove(p+1, p+3, strlen(p+3)+1);
2122                 p++;
2123         }
2124 }
2125
2126 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2127
2128 /**
2129  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2130  **/
2131 DATA_BLOB base64_decode_data_blob(const char *s)
2132 {
2133         int bit_offset, byte_offset, idx, i, n;
2134         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2135         unsigned char *d = decoded.data;
2136         char *p;
2137
2138         n=i=0;
2139
2140         while (*s && (p=strchr_m(b64,*s))) {
2141                 idx = (int)(p - b64);
2142                 byte_offset = (i*6)/8;
2143                 bit_offset = (i*6)%8;
2144                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2145                 if (bit_offset < 3) {
2146                         d[byte_offset] |= (idx << (2-bit_offset));
2147                         n = byte_offset+1;
2148                 } else {
2149                         d[byte_offset] |= (idx >> (bit_offset-2));
2150                         d[byte_offset+1] = 0;
2151                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2152                         n = byte_offset+2;
2153                 }
2154                 s++; i++;
2155         }
2156
2157         if ((n > 0) && (*s == '=')) {
2158                 n -= 1;
2159         }
2160
2161         /* fix up length */
2162         decoded.length = n;
2163         return decoded;
2164 }
2165
2166 /**
2167  * Decode a base64 string in-place - wrapper for the above
2168  **/
2169 void base64_decode_inplace(char *s)
2170 {
2171         DATA_BLOB decoded = base64_decode_data_blob(s);
2172
2173         if ( decoded.length != 0 ) {
2174                 memcpy(s, decoded.data, decoded.length);
2175
2176                 /* null terminate */
2177                 s[decoded.length] = '\0';
2178         } else {
2179                 *s = '\0';
2180         }
2181
2182         data_blob_free(&decoded);
2183 }
2184
2185 /**
2186  * Encode a base64 string into a malloc()ed string caller to free.
2187  *
2188  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2189  **/
2190 char * base64_encode_data_blob(DATA_BLOB data)
2191 {
2192         int bits = 0;
2193         int char_count = 0;
2194         size_t out_cnt, len, output_len;
2195         char *result;
2196
2197         if (!data.length || !data.data)
2198                 return NULL;
2199
2200         out_cnt = 0;
2201         len = data.length;
2202         output_len = data.length * 2;
2203         result = (char *)SMB_MALLOC(output_len); /* get us plenty of space */
2204
2205         while (len-- && out_cnt < (data.length * 2) - 5) {
2206                 int c = (unsigned char) *(data.data++);
2207                 bits += c;
2208                 char_count++;
2209                 if (char_count == 3) {
2210                         result[out_cnt++] = b64[bits >> 18];
2211                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2212                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2213             result[out_cnt++] = b64[bits & 0x3f];
2214             bits = 0;
2215             char_count = 0;
2216         } else {
2217             bits <<= 8;
2218         }
2219     }
2220     if (char_count != 0) {
2221         bits <<= 16 - (8 * char_count);
2222         result[out_cnt++] = b64[bits >> 18];
2223         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2224         if (char_count == 1) {
2225             result[out_cnt++] = '=';
2226             result[out_cnt++] = '=';
2227         } else {
2228             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2229             result[out_cnt++] = '=';
2230         }
2231     }
2232     result[out_cnt] = '\0';     /* terminate */
2233     return result;
2234 }
2235
2236 /* read a SMB_BIG_UINT from a string */
2237 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2238 {
2239
2240         SMB_BIG_UINT val = -1;
2241         const char *p = nptr;
2242         
2243         if (!p) {
2244                 if (entptr) {
2245                         *entptr = p;
2246                 }
2247                 return val;
2248         }
2249
2250         while (*p && isspace(*p))
2251                 p++;
2252
2253 #ifdef LARGE_SMB_OFF_T
2254         sscanf(p,"%llu",&val);  
2255 #else /* LARGE_SMB_OFF_T */
2256         sscanf(p,"%lu",&val);
2257 #endif /* LARGE_SMB_OFF_T */
2258         if (entptr) {
2259                 while (*p && isdigit(*p))
2260                         p++;
2261                 *entptr = p;
2262         }
2263
2264         return val;
2265 }
2266
2267 /* Convert a size specification to a count of bytes. We accept the following
2268  * suffixes:
2269  *          bytes if there is no suffix
2270  *      kK  kibibytes
2271  *      mM  mebibytes
2272  *      gG  gibibytes
2273  *      tT  tibibytes
2274  *      pP  whatever the ISO name for petabytes is
2275  *
2276  *  Returns 0 if the string can't be converted.
2277  */
2278 SMB_OFF_T conv_str_size(const char * str)
2279 {
2280         SMB_OFF_T lval;
2281         char * end;
2282
2283         if (str == NULL || *str == '\0') {
2284                 return 0;
2285         }
2286
2287 #ifdef HAVE_STRTOULL
2288         if (sizeof(SMB_OFF_T) == 8) {
2289             lval = strtoull(str, &end, 10 /* base */);
2290         } else {
2291             lval = strtoul(str, &end, 10 /* base */);
2292         }
2293 #else
2294         lval = strtoul(str, &end, 10 /* base */);
2295 #endif
2296
2297         if (end == NULL || end == str) {
2298                 return 0;
2299         }
2300
2301         if (*end) {
2302                 SMB_OFF_T lval_orig = lval;
2303
2304                 if (strwicmp(end, "K") == 0) {
2305                         lval *= (SMB_OFF_T)1024;
2306                 } else if (strwicmp(end, "M") == 0) {
2307                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2308                 } else if (strwicmp(end, "G") == 0) {
2309                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2310                                 (SMB_OFF_T)1024);
2311                 } else if (strwicmp(end, "T") == 0) {
2312                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2313                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2314                 } else if (strwicmp(end, "P") == 0) {
2315                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2316                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2317                                 (SMB_OFF_T)1024);
2318                 } else {
2319                         return 0;
2320                 }
2321
2322                 /* Primitive attempt to detect wrapping on platforms with
2323                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2324                  * a failure than some random number.
2325                  */
2326                 if (lval_orig <= lval) {
2327                         return 0;
2328                 }
2329         }
2330
2331         return lval;
2332 }
2333
2334 void string_append(char **left, const char *right)
2335 {
2336         int new_len = strlen(right) + 1;
2337
2338         if (*left == NULL) {
2339                 *left = (char *)SMB_MALLOC(new_len);
2340                 *left[0] = '\0';
2341         } else {
2342                 new_len += strlen(*left);
2343                 *left = (char *)SMB_REALLOC(*left, new_len);
2344         }
2345
2346         if (*left == NULL) {
2347                 return;
2348         }
2349
2350         safe_strcat(*left, right, new_len-1);
2351 }
2352
2353 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2354                          const char *str, const char ***strings,
2355                          int *num)
2356 {
2357         char *dup_str = talloc_strdup(mem_ctx, str);
2358
2359         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2360
2361         if ((*strings == NULL) || (dup_str == NULL))
2362                 return False;
2363
2364         (*strings)[*num] = dup_str;
2365         *num += 1;
2366         return True;
2367 }
2368
2369 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2370  * error checking in between. The indiation that something weird happened is
2371  * string==NULL */
2372
2373 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2374                     size_t *bufsize, const char *fmt, ...)
2375 {
2376         va_list ap;
2377         char *newstr;
2378         int ret;
2379         BOOL increased;
2380
2381         /* len<0 is an internal marker that something failed */
2382         if (*len < 0)
2383                 goto error;
2384
2385         if (*string == NULL) {
2386                 if (*bufsize == 0)
2387                         *bufsize = 128;
2388
2389                 if (mem_ctx != NULL)
2390                         *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2391                 else
2392                         *string = SMB_MALLOC_ARRAY(char, *bufsize);
2393
2394                 if (*string == NULL)
2395                         goto error;
2396         }
2397
2398         va_start(ap, fmt);
2399         ret = vasprintf(&newstr, fmt, ap);
2400         va_end(ap);
2401
2402         if (ret < 0)
2403                 goto error;
2404
2405         increased = False;
2406
2407         while ((*len)+ret >= *bufsize) {
2408                 increased = True;
2409                 *bufsize *= 2;
2410                 if (*bufsize >= (1024*1024*256))
2411                         goto error;
2412         }
2413
2414         if (increased) {
2415                 if (mem_ctx != NULL) {
2416                         *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2417                                                        *bufsize);
2418                 } else {
2419                         *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2420                 }
2421
2422                 if (*string == NULL) {
2423                         goto error;
2424                 }
2425         }
2426
2427         StrnCpy((*string)+(*len), newstr, ret);
2428         (*len) += ret;
2429         free(newstr);
2430         return;
2431
2432  error:
2433         *len = -1;
2434         if (mem_ctx == NULL) {
2435                 SAFE_FREE(*string);
2436         }
2437         *string = NULL;
2438 }
2439
2440 /*
2441    Returns the substring from src between the first occurrence of
2442    the char "front" and the first occurence of the char "back".
2443    Mallocs the return string which must be freed.  Not for use
2444    with wide character strings.
2445 */
2446 char *sstring_sub(const char *src, char front, char back)
2447 {
2448         char *temp1, *temp2, *temp3;
2449         ptrdiff_t len;
2450
2451         temp1 = strchr(src, front);
2452         if (temp1 == NULL) return NULL;
2453         temp2 = strchr(src, back);
2454         if (temp2 == NULL) return NULL;
2455         len = temp2 - temp1;
2456         if (len <= 0) return NULL;
2457         temp3 = (char*)SMB_MALLOC(len);
2458         if (temp3 == NULL) {
2459                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2460                 return NULL;
2461         }
2462         memcpy(temp3, temp1+1, len-1);
2463         temp3[len-1] = '\0';
2464         return temp3;
2465 }
2466
2467 /********************************************************************
2468  Check a string for any occurrences of a specified list of invalid
2469  characters.
2470 ********************************************************************/
2471
2472 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2473 {
2474         int i;
2475
2476         for ( i=0; i<max_len && name[i]; i++ ) {
2477                 /* fail if strchr_m() finds one of the invalid characters */
2478                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2479                         return False;
2480                 }
2481         }
2482
2483         return True;
2484 }
2485
2486
2487 /**
2488 return the number of bytes occupied by a buffer in ASCII format
2489 the result includes the null termination
2490 limited by 'n' bytes
2491 **/
2492 size_t ascii_len_n(const char *src, size_t n)
2493 {
2494         size_t len;
2495
2496         len = strnlen(src, n);
2497         if (len+1 <= n) {
2498                 len += 1;
2499         }
2500
2501         return len;
2502 }
2503
2504 /**
2505 return the number of bytes occupied by a buffer in CH_UTF16 format
2506 the result includes the null termination
2507 **/
2508 size_t utf16_len(const void *buf)
2509 {
2510         size_t len;
2511
2512         for (len = 0; SVAL(buf,len); len += 2) ;
2513
2514         return len + 2;
2515 }
2516
2517 /**
2518 return the number of bytes occupied by a buffer in CH_UTF16 format
2519 the result includes the null termination
2520 limited by 'n' bytes
2521 **/
2522 size_t utf16_len_n(const void *src, size_t n)
2523 {
2524         size_t len;
2525
2526         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2527
2528         if (len+2 <= n) {
2529                 len += 2;
2530         }
2531
2532         return len;
2533 }
2534