r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
[vlendec/samba-autobuild/.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 = 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 = TALLOC_REALLOC(mem_ctx, string, ls + ld + 1);
1147                         if (!string) {
1148                                 DEBUG(0, ("talloc_string_sub: out of "
1149                                           "memory!\n"));
1150                                 SAFE_FREE(in);
1151                                 return NULL;
1152                         }
1153                         p = string + offset + (p - s);
1154                 }
1155                 if (li != lp) {
1156                         memmove(p+li,p+lp,strlen(p+lp)+1);
1157                 }
1158                 memcpy(p, in, li);
1159                 s = p + li;
1160                 ls += ld;
1161         }
1162         SAFE_FREE(in);
1163         return string;
1164 }
1165
1166 /**
1167  Similar to string_sub() but allows for any character to be substituted. 
1168  Use with caution!
1169  if len==0 then the string cannot be extended. This is different from the old
1170  use of len==0 which was for no length checks to be done.
1171 **/
1172
1173 void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
1174 {
1175         char *p;
1176         ssize_t ls,lp,li;
1177
1178         if (!insert || !pattern || !s)
1179                 return;
1180
1181         ls = (ssize_t)strlen(s);
1182         lp = (ssize_t)strlen(pattern);
1183         li = (ssize_t)strlen(insert);
1184
1185         if (!*pattern)
1186                 return;
1187         
1188         if (len == 0)
1189                 len = ls + 1; /* len is number of *bytes* */
1190         
1191         while (lp <= ls && (p = strstr_m(s,pattern))) {
1192                 if (ls + (li-lp) >= len) {
1193                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
1194                                  (int)(ls + (li-lp) - len),
1195                                  pattern, (int)len));
1196                         break;
1197                 }
1198                 if (li != lp) {
1199                         memmove(p+li,p+lp,strlen(p+lp)+1);
1200                 }
1201                 memcpy(p, insert, li);
1202                 s = p + li;
1203                 ls += (li-lp);
1204         }
1205 }
1206
1207 /**
1208  Similar to all_string_sub but for unicode strings.
1209  Return a new allocated unicode string.
1210  similar to string_sub() but allows for any character to be substituted.
1211  Use with caution!
1212 **/
1213
1214 static smb_ucs2_t *all_string_sub_w(const smb_ucs2_t *s, const smb_ucs2_t *pattern,
1215                                 const smb_ucs2_t *insert)
1216 {
1217         smb_ucs2_t *r, *rp;
1218         const smb_ucs2_t *sp;
1219         size_t  lr, lp, li, lt;
1220
1221         if (!insert || !pattern || !*pattern || !s)
1222                 return NULL;
1223
1224         lt = (size_t)strlen_w(s);
1225         lp = (size_t)strlen_w(pattern);
1226         li = (size_t)strlen_w(insert);
1227
1228         if (li > lp) {
1229                 const smb_ucs2_t *st = s;
1230                 int ld = li - lp;
1231                 while ((sp = strstr_w(st, pattern))) {
1232                         st = sp + lp;
1233                         lt += ld;
1234                 }
1235         }
1236
1237         r = rp = SMB_MALLOC_ARRAY(smb_ucs2_t, lt + 1);
1238         if (!r) {
1239                 DEBUG(0, ("all_string_sub_w: out of memory!\n"));
1240                 return NULL;
1241         }
1242
1243         while ((sp = strstr_w(s, pattern))) {
1244                 memcpy(rp, s, (sp - s));
1245                 rp += ((sp - s) / sizeof(smb_ucs2_t));
1246                 memcpy(rp, insert, (li * sizeof(smb_ucs2_t)));
1247                 s = sp + lp;
1248                 rp += li;
1249         }
1250         lr = ((rp - r) / sizeof(smb_ucs2_t));
1251         if (lr < lt) {
1252                 memcpy(rp, s, ((lt - lr) * sizeof(smb_ucs2_t)));
1253                 rp += (lt - lr);
1254         }
1255         *rp = 0;
1256
1257         return r;
1258 }
1259
1260 smb_ucs2_t *all_string_sub_wa(smb_ucs2_t *s, const char *pattern,
1261                                              const char *insert)
1262 {
1263         wpstring p, i;
1264
1265         if (!insert || !pattern || !s)
1266                 return NULL;
1267         push_ucs2(NULL, p, pattern, sizeof(wpstring) - 1, STR_TERMINATE);
1268         push_ucs2(NULL, i, insert, sizeof(wpstring) - 1, STR_TERMINATE);
1269         return all_string_sub_w(s, p, i);
1270 }
1271
1272 #if 0
1273 /**
1274  Splits out the front and back at a separator.
1275 **/
1276
1277 static void split_at_last_component(char *path, char *front, char sep, char *back)
1278 {
1279         char *p = strrchr_m(path, sep);
1280
1281         if (p != NULL)
1282                 *p = 0;
1283
1284         if (front != NULL)
1285                 pstrcpy(front, path);
1286
1287         if (p != NULL) {
1288                 if (back != NULL)
1289                         pstrcpy(back, p+1);
1290                 *p = '\\';
1291         } else {
1292                 if (back != NULL)
1293                         back[0] = 0;
1294         }
1295 }
1296 #endif
1297
1298 /**
1299  Write an octal as a string.
1300 **/
1301
1302 const char *octal_string(int i)
1303 {
1304         static char ret[64];
1305         if (i == -1)
1306                 return "-1";
1307         slprintf(ret, sizeof(ret)-1, "0%o", i);
1308         return ret;
1309 }
1310
1311
1312 /**
1313  Truncate a string at a specified length.
1314 **/
1315
1316 char *string_truncate(char *s, unsigned int length)
1317 {
1318         if (s && strlen(s) > length)
1319                 s[length] = 0;
1320         return s;
1321 }
1322
1323 /**
1324  Strchr and strrchr_m are very hard to do on general multi-byte strings. 
1325  We convert via ucs2 for now.
1326 **/
1327
1328 char *strchr_m(const char *src, char c)
1329 {
1330         wpstring ws;
1331         pstring s2;
1332         smb_ucs2_t *p;
1333         const char *s;
1334
1335         /* characters below 0x3F are guaranteed to not appear in
1336            non-initial position in multi-byte charsets */
1337         if ((c & 0xC0) == 0) {
1338                 return strchr(src, c);
1339         }
1340
1341         /* this is quite a common operation, so we want it to be
1342            fast. We optimise for the ascii case, knowing that all our
1343            supported multi-byte character sets are ascii-compatible
1344            (ie. they match for the first 128 chars) */
1345
1346         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1347                 if (*s == c)
1348                         return (char *)s;
1349         }
1350
1351         if (!*s)
1352                 return NULL;
1353
1354 #ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
1355         /* With compose characters we must restart from the beginning. JRA. */
1356         s = src;
1357 #endif
1358
1359         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1360         p = strchr_w(ws, UCS2_CHAR(c));
1361         if (!p)
1362                 return NULL;
1363         *p = 0;
1364         pull_ucs2_pstring(s2, ws);
1365         return (char *)(s+strlen(s2));
1366 }
1367
1368 char *strrchr_m(const char *s, char c)
1369 {
1370         /* characters below 0x3F are guaranteed to not appear in
1371            non-initial position in multi-byte charsets */
1372         if ((c & 0xC0) == 0) {
1373                 return strrchr(s, c);
1374         }
1375
1376         /* this is quite a common operation, so we want it to be
1377            fast. We optimise for the ascii case, knowing that all our
1378            supported multi-byte character sets are ascii-compatible
1379            (ie. they match for the first 128 chars). Also, in Samba
1380            we only search for ascii characters in 'c' and that
1381            in all mb character sets with a compound character
1382            containing c, if 'c' is not a match at position
1383            p, then p[-1] > 0x7f. JRA. */
1384
1385         {
1386                 size_t len = strlen(s);
1387                 const char *cp = s;
1388                 BOOL got_mb = False;
1389
1390                 if (len == 0)
1391                         return NULL;
1392                 cp += (len - 1);
1393                 do {
1394                         if (c == *cp) {
1395                                 /* Could be a match. Part of a multibyte ? */
1396                                 if ((cp > s) && (((unsigned char)cp[-1]) & 0x80)) {
1397                                         /* Yep - go slow :-( */
1398                                         got_mb = True;
1399                                         break;
1400                                 }
1401                                 /* No - we have a match ! */
1402                                 return (char *)cp;
1403                         }
1404                 } while (cp-- != s);
1405                 if (!got_mb)
1406                         return NULL;
1407         }
1408
1409         /* String contained a non-ascii char. Slow path. */
1410         {
1411                 wpstring ws;
1412                 pstring s2;
1413                 smb_ucs2_t *p;
1414
1415                 push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1416                 p = strrchr_w(ws, UCS2_CHAR(c));
1417                 if (!p)
1418                         return NULL;
1419                 *p = 0;
1420                 pull_ucs2_pstring(s2, ws);
1421                 return (char *)(s+strlen(s2));
1422         }
1423 }
1424
1425 /***********************************************************************
1426  Return the equivalent of doing strrchr 'n' times - always going
1427  backwards.
1428 ***********************************************************************/
1429
1430 char *strnrchr_m(const char *s, char c, unsigned int n)
1431 {
1432         wpstring ws;
1433         pstring s2;
1434         smb_ucs2_t *p;
1435
1436         push_ucs2(NULL, ws, s, sizeof(ws), STR_TERMINATE);
1437         p = strnrchr_w(ws, UCS2_CHAR(c), n);
1438         if (!p)
1439                 return NULL;
1440         *p = 0;
1441         pull_ucs2_pstring(s2, ws);
1442         return (char *)(s+strlen(s2));
1443 }
1444
1445 /***********************************************************************
1446  strstr_m - We convert via ucs2 for now.
1447 ***********************************************************************/
1448
1449 char *strstr_m(const char *src, const char *findstr)
1450 {
1451         smb_ucs2_t *p;
1452         smb_ucs2_t *src_w, *find_w;
1453         const char *s;
1454         char *s2;
1455         char *retp;
1456
1457         size_t findstr_len = 0;
1458
1459         /* for correctness */
1460         if (!findstr[0]) {
1461                 return (char*)src;
1462         }
1463
1464         /* Samba does single character findstr calls a *lot*. */
1465         if (findstr[1] == '\0')
1466                 return strchr_m(src, *findstr);
1467
1468         /* We optimise for the ascii case, knowing that all our
1469            supported multi-byte character sets are ascii-compatible
1470            (ie. they match for the first 128 chars) */
1471
1472         for (s = src; *s && !(((unsigned char)s[0]) & 0x80); s++) {
1473                 if (*s == *findstr) {
1474                         if (!findstr_len) 
1475                                 findstr_len = strlen(findstr);
1476
1477                         if (strncmp(s, findstr, findstr_len) == 0) {
1478                                 return (char *)s;
1479                         }
1480                 }
1481         }
1482
1483         if (!*s)
1484                 return NULL;
1485
1486 #if 1 /* def BROKEN_UNICODE_COMPOSE_CHARACTERS */
1487         /* 'make check' fails unless we do this */
1488
1489         /* With compose characters we must restart from the beginning. JRA. */
1490         s = src;
1491 #endif
1492
1493         if (push_ucs2_allocate(&src_w, src) == (size_t)-1) {
1494                 DEBUG(0,("strstr_m: src malloc fail\n"));
1495                 return NULL;
1496         }
1497         
1498         if (push_ucs2_allocate(&find_w, findstr) == (size_t)-1) {
1499                 SAFE_FREE(src_w);
1500                 DEBUG(0,("strstr_m: find malloc fail\n"));
1501                 return NULL;
1502         }
1503
1504         p = strstr_w(src_w, find_w);
1505
1506         if (!p) {
1507                 SAFE_FREE(src_w);
1508                 SAFE_FREE(find_w);
1509                 return NULL;
1510         }
1511         
1512         *p = 0;
1513         if (pull_ucs2_allocate(&s2, src_w) == (size_t)-1) {
1514                 SAFE_FREE(src_w);
1515                 SAFE_FREE(find_w);
1516                 DEBUG(0,("strstr_m: dest malloc fail\n"));
1517                 return NULL;
1518         }
1519         retp = (char *)(s+strlen(s2));
1520         SAFE_FREE(src_w);
1521         SAFE_FREE(find_w);
1522         SAFE_FREE(s2);
1523         return retp;
1524 }
1525
1526 /**
1527  Convert a string to lower case.
1528 **/
1529
1530 void strlower_m(char *s)
1531 {
1532         size_t len;
1533         int errno_save;
1534
1535         /* this is quite a common operation, so we want it to be
1536            fast. We optimise for the ascii case, knowing that all our
1537            supported multi-byte character sets are ascii-compatible
1538            (ie. they match for the first 128 chars) */
1539
1540         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1541                 *s = tolower_ascii((unsigned char)*s);
1542                 s++;
1543         }
1544
1545         if (!*s)
1546                 return;
1547
1548         /* I assume that lowercased string takes the same number of bytes
1549          * as source string even in UTF-8 encoding. (VIV) */
1550         len = strlen(s) + 1;
1551         errno_save = errno;
1552         errno = 0;
1553         unix_strlower(s,len,s,len);     
1554         /* Catch mb conversion errors that may not terminate. */
1555         if (errno)
1556                 s[len-1] = '\0';
1557         errno = errno_save;
1558 }
1559
1560 /**
1561  Convert a string to upper case.
1562 **/
1563
1564 void strupper_m(char *s)
1565 {
1566         size_t len;
1567         int errno_save;
1568
1569         /* this is quite a common operation, so we want it to be
1570            fast. We optimise for the ascii case, knowing that all our
1571            supported multi-byte character sets are ascii-compatible
1572            (ie. they match for the first 128 chars) */
1573
1574         while (*s && !(((unsigned char)s[0]) & 0x80)) {
1575                 *s = toupper_ascii((unsigned char)*s);
1576                 s++;
1577         }
1578
1579         if (!*s)
1580                 return;
1581
1582         /* I assume that lowercased string takes the same number of bytes
1583          * as source string even in multibyte encoding. (VIV) */
1584         len = strlen(s) + 1;
1585         errno_save = errno;
1586         errno = 0;
1587         unix_strupper(s,len,s,len);     
1588         /* Catch mb conversion errors that may not terminate. */
1589         if (errno)
1590                 s[len-1] = '\0';
1591         errno = errno_save;
1592 }
1593
1594 /**
1595  Return a RFC2254 binary string representation of a buffer.
1596  Used in LDAP filters.
1597  Caller must free.
1598 **/
1599
1600 char *binary_string_rfc2254(char *buf, int len)
1601 {
1602         char *s;
1603         int i, j;
1604         const char *hex = "0123456789ABCDEF";
1605         s = SMB_MALLOC(len * 3 + 1);
1606         if (!s)
1607                 return NULL;
1608         for (j=i=0;i<len;i++) {
1609                 s[j] = '\\';
1610                 s[j+1] = hex[((unsigned char)buf[i]) >> 4];
1611                 s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
1612                 j += 3;
1613         }
1614         s[j] = 0;
1615         return s;
1616 }
1617
1618 char *binary_string(char *buf, int len)
1619 {
1620         char *s;
1621         int i, j;
1622         const char *hex = "0123456789ABCDEF";
1623         s = SMB_MALLOC(len * 2 + 1);
1624         if (!s)
1625                 return NULL;
1626         for (j=i=0;i<len;i++) {
1627                 s[j]   = hex[((unsigned char)buf[i]) >> 4];
1628                 s[j+1] = hex[((unsigned char)buf[i]) & 0xF];
1629                 j += 2;
1630         }
1631         s[j] = 0;
1632         return s;
1633 }
1634 /**
1635  Just a typesafety wrapper for snprintf into a pstring.
1636 **/
1637
1638  int pstr_sprintf(pstring s, const char *fmt, ...)
1639 {
1640         va_list ap;
1641         int ret;
1642
1643         va_start(ap, fmt);
1644         ret = vsnprintf(s, PSTRING_LEN, fmt, ap);
1645         va_end(ap);
1646         return ret;
1647 }
1648
1649
1650 /**
1651  Just a typesafety wrapper for snprintf into a fstring.
1652 **/
1653
1654 int fstr_sprintf(fstring s, const char *fmt, ...)
1655 {
1656         va_list ap;
1657         int ret;
1658
1659         va_start(ap, fmt);
1660         ret = vsnprintf(s, FSTRING_LEN, fmt, ap);
1661         va_end(ap);
1662         return ret;
1663 }
1664
1665
1666 #if !defined(HAVE_STRNDUP) || defined(BROKEN_STRNDUP)
1667 /**
1668  Some platforms don't have strndup.
1669 **/
1670 #if defined(PARANOID_MALLOC_CHECKER)
1671 #undef strndup
1672 #endif
1673
1674  char *strndup(const char *s, size_t n)
1675 {
1676         char *ret;
1677         
1678         n = strnlen(s, n);
1679         ret = SMB_MALLOC(n+1);
1680         if (!ret)
1681                 return NULL;
1682         memcpy(ret, s, n);
1683         ret[n] = 0;
1684
1685         return ret;
1686 }
1687
1688 #if defined(PARANOID_MALLOC_CHECKER)
1689 #define strndup(s,n) __ERROR_DONT_USE_STRNDUP_DIRECTLY
1690 #endif
1691
1692 #endif
1693
1694 #if !defined(HAVE_STRNLEN) || defined(BROKEN_STRNLEN)
1695 /**
1696  Some platforms don't have strnlen
1697 **/
1698
1699  size_t strnlen(const char *s, size_t n)
1700 {
1701         size_t i;
1702         for (i=0; i<n && s[i] != '\0'; i++)
1703                 /* noop */ ;
1704         return i;
1705 }
1706 #endif
1707
1708 /**
1709  List of Strings manipulation functions
1710 **/
1711
1712 #define S_LIST_ABS 16 /* List Allocation Block Size */
1713
1714 static char **str_list_make_internal(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1715 {
1716         char **list, **rlist;
1717         const char *str;
1718         char *s;
1719         int num, lsize;
1720         pstring tok;
1721         
1722         if (!string || !*string)
1723                 return NULL;
1724         if (mem_ctx) {
1725                 s = talloc_strdup(mem_ctx, string);
1726         } else {
1727                 s = SMB_STRDUP(string);
1728         }
1729         if (!s) {
1730                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1731                 return NULL;
1732         }
1733         if (!sep) sep = LIST_SEP;
1734         
1735         num = lsize = 0;
1736         list = NULL;
1737         
1738         str = s;
1739         while (next_token(&str, tok, sep, sizeof(tok))) {               
1740                 if (num == lsize) {
1741                         lsize += S_LIST_ABS;
1742                         if (mem_ctx) {
1743                                 rlist = TALLOC_REALLOC_ARRAY(mem_ctx, list, char *, lsize +1);
1744                         } else {
1745                                 /* We need to keep the old list on error so we can free the elements
1746                                    if the realloc fails. */
1747                                 rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1748                         }
1749                         if (!rlist) {
1750                                 DEBUG(0,("str_list_make: Unable to allocate memory"));
1751                                 str_list_free(&list);
1752                                 if (mem_ctx) {
1753                                         TALLOC_FREE(s);
1754                                 } else {
1755                                         SAFE_FREE(s);
1756                                 }
1757                                 return NULL;
1758                         } else {
1759                                 list = rlist;
1760                         }
1761                         memset (&list[num], 0, ((sizeof(char**)) * (S_LIST_ABS +1)));
1762                 }
1763
1764                 if (mem_ctx) {
1765                         list[num] = talloc_strdup(mem_ctx, tok);
1766                 } else {
1767                         list[num] = SMB_STRDUP(tok);
1768                 }
1769                 
1770                 if (!list[num]) {
1771                         DEBUG(0,("str_list_make: Unable to allocate memory"));
1772                         str_list_free(&list);
1773                         if (mem_ctx) {
1774                                 TALLOC_FREE(s);
1775                         } else {
1776                                 SAFE_FREE(s);
1777                         }
1778                         return NULL;
1779                 }
1780         
1781                 num++;  
1782         }
1783
1784         if (mem_ctx) {
1785                 TALLOC_FREE(s);
1786         } else {
1787                 SAFE_FREE(s);
1788         }
1789
1790         return list;
1791 }
1792
1793 char **str_list_make_talloc(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
1794 {
1795         return str_list_make_internal(mem_ctx, string, sep);
1796 }
1797
1798 char **str_list_make(const char *string, const char *sep)
1799 {
1800         return str_list_make_internal(NULL, string, sep);
1801 }
1802
1803 BOOL str_list_copy(char ***dest, const char **src)
1804 {
1805         char **list, **rlist;
1806         int num, lsize;
1807         
1808         *dest = NULL;
1809         if (!src)
1810                 return False;
1811         
1812         num = lsize = 0;
1813         list = NULL;
1814                 
1815         while (src[num]) {
1816                 if (num == lsize) {
1817                         lsize += S_LIST_ABS;
1818                         rlist = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(list, char *, lsize +1);
1819                         if (!rlist) {
1820                                 DEBUG(0,("str_list_copy: Unable to re-allocate memory"));
1821                                 str_list_free(&list);
1822                                 return False;
1823                         } else {
1824                                 list = rlist;
1825                         }
1826                         memset (&list[num], 0, ((sizeof(char **)) * (S_LIST_ABS +1)));
1827                 }
1828                 
1829                 list[num] = SMB_STRDUP(src[num]);
1830                 if (!list[num]) {
1831                         DEBUG(0,("str_list_copy: Unable to allocate memory"));
1832                         str_list_free(&list);
1833                         return False;
1834                 }
1835
1836                 num++;
1837         }
1838         
1839         *dest = list;
1840         return True;    
1841 }
1842
1843 /**
1844  * Return true if all the elements of the list match exactly.
1845  **/
1846 BOOL str_list_compare(char **list1, char **list2)
1847 {
1848         int num;
1849         
1850         if (!list1 || !list2)
1851                 return (list1 == list2); 
1852         
1853         for (num = 0; list1[num]; num++) {
1854                 if (!list2[num])
1855                         return False;
1856                 if (!strcsequal(list1[num], list2[num]))
1857                         return False;
1858         }
1859         if (list2[num])
1860                 return False; /* if list2 has more elements than list1 fail */
1861         
1862         return True;
1863 }
1864
1865 static void str_list_free_internal(TALLOC_CTX *mem_ctx, char ***list)
1866 {
1867         char **tlist;
1868         
1869         if (!list || !*list)
1870                 return;
1871         tlist = *list;
1872         for(; *tlist; tlist++) {
1873                 if (mem_ctx) {
1874                         TALLOC_FREE(*tlist);
1875                 } else {
1876                         SAFE_FREE(*tlist);
1877                 }
1878         }
1879         if (mem_ctx) {
1880                 TALLOC_FREE(*tlist);
1881         } else {
1882                 SAFE_FREE(*list);
1883         }
1884 }
1885
1886 void str_list_free_talloc(TALLOC_CTX *mem_ctx, char ***list)
1887 {
1888         str_list_free_internal(mem_ctx, list);
1889 }
1890
1891 void str_list_free(char ***list)
1892 {
1893         str_list_free_internal(NULL, list);
1894 }
1895
1896 /******************************************************************************
1897  *****************************************************************************/
1898
1899 int str_list_count( const char **list )
1900 {
1901         int i = 0;
1902
1903         if ( ! list )
1904                 return 0;
1905
1906         /* count the number of list members */
1907         
1908         for ( i=0; *list; i++, list++ );
1909         
1910         return i;
1911 }
1912
1913 /******************************************************************************
1914  version of standard_sub_basic() for string lists; uses alloc_sub_basic() 
1915  for the work
1916  *****************************************************************************/
1917  
1918 BOOL str_list_sub_basic( char **list, const char *smb_name,
1919                          const char *domain_name )
1920 {
1921         char *s, *tmpstr;
1922         
1923         while ( *list ) {
1924                 s = *list;
1925                 tmpstr = alloc_sub_basic(smb_name, domain_name, s);
1926                 if ( !tmpstr ) {
1927                         DEBUG(0,("str_list_sub_basic: alloc_sub_basic() return NULL!\n"));
1928                         return False;
1929                 }
1930
1931                 SAFE_FREE(*list);
1932                 *list = tmpstr;
1933                         
1934                 list++;
1935         }
1936
1937         return True;
1938 }
1939
1940 /******************************************************************************
1941  substritute a specific pattern in a string list
1942  *****************************************************************************/
1943  
1944 BOOL str_list_substitute(char **list, const char *pattern, const char *insert)
1945 {
1946         char *p, *s, *t;
1947         ssize_t ls, lp, li, ld, i, d;
1948
1949         if (!list)
1950                 return False;
1951         if (!pattern)
1952                 return False;
1953         if (!insert)
1954                 return False;
1955
1956         lp = (ssize_t)strlen(pattern);
1957         li = (ssize_t)strlen(insert);
1958         ld = li -lp;
1959                         
1960         while (*list) {
1961                 s = *list;
1962                 ls = (ssize_t)strlen(s);
1963
1964                 while ((p = strstr_m(s, pattern))) {
1965                         t = *list;
1966                         d = p -t;
1967                         if (ld) {
1968                                 t = (char *) SMB_MALLOC(ls +ld +1);
1969                                 if (!t) {
1970                                         DEBUG(0,("str_list_substitute: Unable to allocate memory"));
1971                                         return False;
1972                                 }
1973                                 memcpy(t, *list, d);
1974                                 memcpy(t +d +li, p +lp, ls -d -lp +1);
1975                                 SAFE_FREE(*list);
1976                                 *list = t;
1977                                 ls += ld;
1978                                 s = t +d +li;
1979                         }
1980                         
1981                         for (i = 0; i < li; i++) {
1982                                 switch (insert[i]) {
1983                                         case '`':
1984                                         case '"':
1985                                         case '\'':
1986                                         case ';':
1987                                         case '$':
1988                                         case '%':
1989                                         case '\r':
1990                                         case '\n':
1991                                                 t[d +i] = '_';
1992                                                 break;
1993                                         default:
1994                                                 t[d +i] = insert[i];
1995                                 }
1996                         }       
1997                 }
1998                 
1999                 
2000                 list++;
2001         }
2002         
2003         return True;
2004 }
2005
2006
2007 #define IPSTR_LIST_SEP  ","
2008 #define IPSTR_LIST_CHAR ','
2009
2010 /**
2011  * Add ip string representation to ipstr list. Used also
2012  * as part of @function ipstr_list_make
2013  *
2014  * @param ipstr_list pointer to string containing ip list;
2015  *        MUST BE already allocated and IS reallocated if necessary
2016  * @param ipstr_size pointer to current size of ipstr_list (might be changed
2017  *        as a result of reallocation)
2018  * @param ip IP address which is to be added to list
2019  * @return pointer to string appended with new ip and possibly
2020  *         reallocated to new length
2021  **/
2022
2023 char* ipstr_list_add(char** ipstr_list, const struct ip_service *service)
2024 {
2025         char* new_ipstr = NULL;
2026         
2027         /* arguments checking */
2028         if (!ipstr_list || !service) return NULL;
2029
2030         /* attempt to convert ip to a string and append colon separator to it */
2031         if (*ipstr_list) {
2032                 asprintf(&new_ipstr, "%s%s%s:%d", *ipstr_list, IPSTR_LIST_SEP,
2033                         inet_ntoa(service->ip), service->port);
2034                 SAFE_FREE(*ipstr_list);
2035         } else {
2036                 asprintf(&new_ipstr, "%s:%d", inet_ntoa(service->ip), service->port);
2037         }
2038         *ipstr_list = new_ipstr;
2039         return *ipstr_list;
2040 }
2041
2042
2043 /**
2044  * Allocate and initialise an ipstr list using ip adresses
2045  * passed as arguments.
2046  *
2047  * @param ipstr_list pointer to string meant to be allocated and set
2048  * @param ip_list array of ip addresses to place in the list
2049  * @param ip_count number of addresses stored in ip_list
2050  * @return pointer to allocated ip string
2051  **/
2052  
2053 char* ipstr_list_make(char** ipstr_list, const struct ip_service* ip_list, int ip_count)
2054 {
2055         int i;
2056         
2057         /* arguments checking */
2058         if (!ip_list && !ipstr_list) return 0;
2059
2060         *ipstr_list = NULL;
2061         
2062         /* process ip addresses given as arguments */
2063         for (i = 0; i < ip_count; i++)
2064                 *ipstr_list = ipstr_list_add(ipstr_list, &ip_list[i]);
2065         
2066         return (*ipstr_list);
2067 }
2068
2069
2070 /**
2071  * Parse given ip string list into array of ip addresses
2072  * (as ip_service structures)  
2073  *    e.g. 192.168.1.100:389,192.168.1.78, ...
2074  *
2075  * @param ipstr ip string list to be parsed 
2076  * @param ip_list pointer to array of ip addresses which is
2077  *        allocated by this function and must be freed by caller
2078  * @return number of succesfully parsed addresses
2079  **/
2080  
2081 int ipstr_list_parse(const char* ipstr_list, struct ip_service **ip_list)
2082 {
2083         fstring token_str;
2084         size_t count;
2085         int i;
2086
2087         if (!ipstr_list || !ip_list) 
2088                 return 0;
2089         
2090         count = count_chars(ipstr_list, IPSTR_LIST_CHAR) + 1;
2091         if ( (*ip_list = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
2092                 DEBUG(0,("ipstr_list_parse: malloc failed for %lu entries\n", (unsigned long)count));
2093                 return 0;
2094         }
2095         
2096         for ( i=0; 
2097                 next_token(&ipstr_list, token_str, IPSTR_LIST_SEP, FSTRING_LEN) && i<count; 
2098                 i++ ) 
2099         {
2100                 struct in_addr addr;
2101                 unsigned port = 0;      
2102                 char *p = strchr(token_str, ':');
2103                 
2104                 if (p) {
2105                         *p = 0;
2106                         port = atoi(p+1);
2107                 }
2108
2109                 /* convert single token to ip address */
2110                 if ( (addr.s_addr = inet_addr(token_str)) == INADDR_NONE )
2111                         break;
2112                                 
2113                 (*ip_list)[i].ip = addr;
2114                 (*ip_list)[i].port = port;
2115         }
2116         
2117         return count;
2118 }
2119
2120
2121 /**
2122  * Safely free ip string list
2123  *
2124  * @param ipstr_list ip string list to be freed
2125  **/
2126
2127 void ipstr_list_free(char* ipstr_list)
2128 {
2129         SAFE_FREE(ipstr_list);
2130 }
2131
2132
2133 /**
2134  Unescape a URL encoded string, in place.
2135 **/
2136
2137 void rfc1738_unescape(char *buf)
2138 {
2139         char *p=buf;
2140
2141         while (p && *p && (p=strchr_m(p,'%'))) {
2142                 int c1 = p[1];
2143                 int c2 = p[2];
2144
2145                 if (c1 >= '0' && c1 <= '9')
2146                         c1 = c1 - '0';
2147                 else if (c1 >= 'A' && c1 <= 'F')
2148                         c1 = 10 + c1 - 'A';
2149                 else if (c1 >= 'a' && c1 <= 'f')
2150                         c1 = 10 + c1 - 'a';
2151                 else {p++; continue;}
2152
2153                 if (c2 >= '0' && c2 <= '9')
2154                         c2 = c2 - '0';
2155                 else if (c2 >= 'A' && c2 <= 'F')
2156                         c2 = 10 + c2 - 'A';
2157                 else if (c2 >= 'a' && c2 <= 'f')
2158                         c2 = 10 + c2 - 'a';
2159                 else {p++; continue;}
2160                         
2161                 *p = (c1<<4) | c2;
2162
2163                 memmove(p+1, p+3, strlen(p+3)+1);
2164                 p++;
2165         }
2166 }
2167
2168 static const char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2169
2170 /**
2171  * Decode a base64 string into a DATA_BLOB - simple and slow algorithm
2172  **/
2173 DATA_BLOB base64_decode_data_blob(const char *s)
2174 {
2175         int bit_offset, byte_offset, idx, i, n;
2176         DATA_BLOB decoded = data_blob(s, strlen(s)+1);
2177         unsigned char *d = decoded.data;
2178         char *p;
2179
2180         n=i=0;
2181
2182         while (*s && (p=strchr_m(b64,*s))) {
2183                 idx = (int)(p - b64);
2184                 byte_offset = (i*6)/8;
2185                 bit_offset = (i*6)%8;
2186                 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
2187                 if (bit_offset < 3) {
2188                         d[byte_offset] |= (idx << (2-bit_offset));
2189                         n = byte_offset+1;
2190                 } else {
2191                         d[byte_offset] |= (idx >> (bit_offset-2));
2192                         d[byte_offset+1] = 0;
2193                         d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
2194                         n = byte_offset+2;
2195                 }
2196                 s++; i++;
2197         }
2198
2199         if ((n > 0) && (*s == '=')) {
2200                 n -= 1;
2201         }
2202
2203         /* fix up length */
2204         decoded.length = n;
2205         return decoded;
2206 }
2207
2208 /**
2209  * Decode a base64 string in-place - wrapper for the above
2210  **/
2211 void base64_decode_inplace(char *s)
2212 {
2213         DATA_BLOB decoded = base64_decode_data_blob(s);
2214
2215         if ( decoded.length != 0 ) {
2216                 memcpy(s, decoded.data, decoded.length);
2217
2218                 /* null terminate */
2219                 s[decoded.length] = '\0';
2220         } else {
2221                 *s = '\0';
2222         }
2223
2224         data_blob_free(&decoded);
2225 }
2226
2227 /**
2228  * Encode a base64 string into a malloc()ed string caller to free.
2229  *
2230  *From SQUID: adopted from http://ftp.sunet.se/pub2/gnu/vm/base64-encode.c with adjustments
2231  **/
2232 char * base64_encode_data_blob(DATA_BLOB data)
2233 {
2234         int bits = 0;
2235         int char_count = 0;
2236         size_t out_cnt, len, output_len;
2237         char *result;
2238
2239         if (!data.length || !data.data)
2240                 return NULL;
2241
2242         out_cnt = 0;
2243         len = data.length;
2244         output_len = data.length * 2;
2245         result = SMB_MALLOC(output_len); /* get us plenty of space */
2246
2247         while (len-- && out_cnt < (data.length * 2) - 5) {
2248                 int c = (unsigned char) *(data.data++);
2249                 bits += c;
2250                 char_count++;
2251                 if (char_count == 3) {
2252                         result[out_cnt++] = b64[bits >> 18];
2253                         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2254                         result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2255             result[out_cnt++] = b64[bits & 0x3f];
2256             bits = 0;
2257             char_count = 0;
2258         } else {
2259             bits <<= 8;
2260         }
2261     }
2262     if (char_count != 0) {
2263         bits <<= 16 - (8 * char_count);
2264         result[out_cnt++] = b64[bits >> 18];
2265         result[out_cnt++] = b64[(bits >> 12) & 0x3f];
2266         if (char_count == 1) {
2267             result[out_cnt++] = '=';
2268             result[out_cnt++] = '=';
2269         } else {
2270             result[out_cnt++] = b64[(bits >> 6) & 0x3f];
2271             result[out_cnt++] = '=';
2272         }
2273     }
2274     result[out_cnt] = '\0';     /* terminate */
2275     return result;
2276 }
2277
2278 /* read a SMB_BIG_UINT from a string */
2279 SMB_BIG_UINT STR_TO_SMB_BIG_UINT(const char *nptr, const char **entptr)
2280 {
2281
2282         SMB_BIG_UINT val = -1;
2283         const char *p = nptr;
2284         
2285         if (!p) {
2286                 *entptr = p;
2287                 return val;
2288         }
2289
2290         while (*p && isspace(*p))
2291                 p++;
2292
2293 #ifdef LARGE_SMB_OFF_T
2294         sscanf(p,"%llu",&val);  
2295 #else /* LARGE_SMB_OFF_T */
2296         sscanf(p,"%lu",&val);
2297 #endif /* LARGE_SMB_OFF_T */
2298         if (entptr) {
2299                 while (*p && isdigit(*p))
2300                         p++;
2301                 *entptr = p;
2302         }
2303
2304         return val;
2305 }
2306
2307 /* Convert a size specification to a count of bytes. We accept the following
2308  * suffixes:
2309  *          bytes if there is no suffix
2310  *      kK  kibibytes
2311  *      mM  mebibytes
2312  *      gG  gibibytes
2313  *      tT  tibibytes
2314  *      pP  whatever the ISO name for petabytes is
2315  *
2316  *  Returns 0 if the string can't be converted.
2317  */
2318 SMB_OFF_T conv_str_size(const char * str)
2319 {
2320         SMB_OFF_T lval;
2321         char * end;
2322
2323         if (str == NULL || *str == '\0') {
2324                 return 0;
2325         }
2326
2327 #ifdef HAVE_STRTOULL
2328         if (sizeof(SMB_OFF_T) == 8) {
2329             lval = strtoull(str, &end, 10 /* base */);
2330         } else {
2331             lval = strtoul(str, &end, 10 /* base */);
2332         }
2333 #else
2334         lval = strtoul(str, &end, 10 /* base */);
2335 #endif
2336
2337         if (end == NULL || end == str) {
2338                 return 0;
2339         }
2340
2341         if (*end) {
2342                 SMB_OFF_T lval_orig = lval;
2343
2344                 if (strwicmp(end, "K") == 0) {
2345                         lval *= (SMB_OFF_T)1024;
2346                 } else if (strwicmp(end, "M") == 0) {
2347                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2348                 } else if (strwicmp(end, "G") == 0) {
2349                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2350                                 (SMB_OFF_T)1024);
2351                 } else if (strwicmp(end, "T") == 0) {
2352                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2353                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024);
2354                 } else if (strwicmp(end, "P") == 0) {
2355                         lval *= ((SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2356                                 (SMB_OFF_T)1024 * (SMB_OFF_T)1024 *
2357                                 (SMB_OFF_T)1024);
2358                 } else {
2359                         return 0;
2360                 }
2361
2362                 /* Primitive attempt to detect wrapping on platforms with
2363                  * 4-byte SMB_OFF_T. It's better to let the caller handle
2364                  * a failure than some random number.
2365                  */
2366                 if (lval_orig <= lval) {
2367                         return 0;
2368                 }
2369         }
2370
2371         return lval;
2372 }
2373
2374 void string_append(char **left, const char *right)
2375 {
2376         int new_len = strlen(right) + 1;
2377
2378         if (*left == NULL) {
2379                 *left = SMB_MALLOC(new_len);
2380                 *left[0] = '\0';
2381         } else {
2382                 new_len += strlen(*left);
2383                 *left = SMB_REALLOC(*left, new_len);
2384         }
2385
2386         if (*left == NULL) {
2387                 return;
2388         }
2389
2390         safe_strcat(*left, right, new_len-1);
2391 }
2392
2393 BOOL add_string_to_array(TALLOC_CTX *mem_ctx,
2394                          const char *str, const char ***strings,
2395                          int *num)
2396 {
2397         char *dup_str = talloc_strdup(mem_ctx, str);
2398
2399         *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1);
2400
2401         if ((*strings == NULL) || (dup_str == NULL))
2402                 return False;
2403
2404         (*strings)[*num] = dup_str;
2405         *num += 1;
2406         return True;
2407 }
2408
2409 /* Append an sprintf'ed string. Double buffer size on demand. Usable without
2410  * error checking in between. The indiation that something weird happened is
2411  * string==NULL */
2412
2413 void sprintf_append(TALLOC_CTX *mem_ctx, char **string, ssize_t *len,
2414                     size_t *bufsize, const char *fmt, ...)
2415 {
2416         va_list ap;
2417         char *newstr;
2418         int ret;
2419         BOOL increased;
2420
2421         /* len<0 is an internal marker that something failed */
2422         if (*len < 0)
2423                 goto error;
2424
2425         if (*string == NULL) {
2426                 if (*bufsize == 0)
2427                         *bufsize = 128;
2428
2429                 if (mem_ctx != NULL)
2430                         *string = TALLOC_ARRAY(mem_ctx, char, *bufsize);
2431                 else
2432                         *string = SMB_MALLOC_ARRAY(char, *bufsize);
2433
2434                 if (*string == NULL)
2435                         goto error;
2436         }
2437
2438         va_start(ap, fmt);
2439         ret = vasprintf(&newstr, fmt, ap);
2440         va_end(ap);
2441
2442         if (ret < 0)
2443                 goto error;
2444
2445         increased = False;
2446
2447         while ((*len)+ret >= *bufsize) {
2448                 increased = True;
2449                 *bufsize *= 2;
2450                 if (*bufsize >= (1024*1024*256))
2451                         goto error;
2452         }
2453
2454         if (increased) {
2455                 if (mem_ctx != NULL) {
2456                         *string = TALLOC_REALLOC_ARRAY(mem_ctx, *string, char,
2457                                                        *bufsize);
2458                 } else {
2459                         *string = SMB_REALLOC_ARRAY(*string, char, *bufsize);
2460                 }
2461
2462                 if (*string == NULL) {
2463                         goto error;
2464                 }
2465         }
2466
2467         StrnCpy((*string)+(*len), newstr, ret);
2468         (*len) += ret;
2469         free(newstr);
2470         return;
2471
2472  error:
2473         *len = -1;
2474         if (mem_ctx == NULL) {
2475                 SAFE_FREE(*string);
2476         }
2477         *string = NULL;
2478 }
2479
2480 /*
2481    Returns the substring from src between the first occurrence of
2482    the char "front" and the first occurence of the char "back".
2483    Mallocs the return string which must be freed.  Not for use
2484    with wide character strings.
2485 */
2486 char *sstring_sub(const char *src, char front, char back)
2487 {
2488         char *temp1, *temp2, *temp3;
2489         ptrdiff_t len;
2490
2491         temp1 = strchr(src, front);
2492         if (temp1 == NULL) return NULL;
2493         temp2 = strchr(src, back);
2494         if (temp2 == NULL) return NULL;
2495         len = temp2 - temp1;
2496         if (len <= 0) return NULL;
2497         temp3 = (char*)SMB_MALLOC(len);
2498         if (temp3 == NULL) {
2499                 DEBUG(1,("Malloc failure in sstring_sub\n"));
2500                 return NULL;
2501         }
2502         memcpy(temp3, temp1+1, len-1);
2503         temp3[len-1] = '\0';
2504         return temp3;
2505 }
2506
2507 /********************************************************************
2508  Check a string for any occurrences of a specified list of invalid
2509  characters.
2510 ********************************************************************/
2511
2512 BOOL validate_net_name( const char *name, const char *invalid_chars, int max_len )
2513 {
2514         int i;
2515
2516         for ( i=0; i<max_len && name[i]; i++ ) {
2517                 /* fail if strchr_m() finds one of the invalid characters */
2518                 if ( name[i] && strchr_m( invalid_chars, name[i] ) ) {
2519                         return False;
2520                 }
2521         }
2522
2523         return True;
2524 }
2525
2526
2527 /**
2528 return the number of bytes occupied by a buffer in ASCII format
2529 the result includes the null termination
2530 limited by 'n' bytes
2531 **/
2532 size_t ascii_len_n(const char *src, size_t n)
2533 {
2534         size_t len;
2535
2536         len = strnlen(src, n);
2537         if (len+1 <= n) {
2538                 len += 1;
2539         }
2540
2541         return len;
2542 }
2543
2544 /**
2545 return the number of bytes occupied by a buffer in CH_UTF16 format
2546 the result includes the null termination
2547 **/
2548 size_t utf16_len(const void *buf)
2549 {
2550         size_t len;
2551
2552         for (len = 0; SVAL(buf,len); len += 2) ;
2553
2554         return len + 2;
2555 }
2556
2557 /**
2558 return the number of bytes occupied by a buffer in CH_UTF16 format
2559 the result includes the null termination
2560 limited by 'n' bytes
2561 **/
2562 size_t utf16_len_n(const void *src, size_t n)
2563 {
2564         size_t len;
2565
2566         for (len = 0; (len+2 < n) && SVAL(src, len); len += 2) ;
2567
2568         if (len+2 <= n) {
2569                 len += 2;
2570         }
2571
2572         return len;
2573 }
2574