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